@shadowob/sdk 1.1.3-dev.281 → 1.1.4

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
@@ -87,12 +87,13 @@ var ShadowClient = class {
87
87
  const url = `${this.baseUrl}${path}`;
88
88
  const controller = new AbortController();
89
89
  const timeout = setTimeout(() => controller.abort(), 6e4);
90
+ const isFormData = init?.body instanceof FormData;
90
91
  try {
91
92
  const res = await fetch(url, {
92
93
  ...init,
93
94
  signal: init?.signal ?? controller.signal,
94
95
  headers: {
95
- "Content-Type": "application/json",
96
+ ...!isFormData ? { "Content-Type": "application/json" } : {},
96
97
  Authorization: `Bearer ${this.token}`,
97
98
  ...init?.headers
98
99
  }
@@ -337,15 +338,113 @@ var ShadowClient = class {
337
338
  async getServerAccess(serverIdOrSlug) {
338
339
  return this.request(`/api/servers/${serverIdOrSlug}/access`);
339
340
  }
341
+ // ── Server App Integrations ───────────────────────────────────────────
342
+ async listServerApps(serverIdOrSlug) {
343
+ return this.request(`/api/servers/${serverIdOrSlug}/apps`);
344
+ }
345
+ async listServerAppCatalog(serverIdOrSlug) {
346
+ return this.request(`/api/servers/${serverIdOrSlug}/apps/catalog`);
347
+ }
348
+ async discoverServerApp(serverIdOrSlug, data) {
349
+ return this.request(`/api/servers/${serverIdOrSlug}/apps/discover`, {
350
+ method: "POST",
351
+ body: JSON.stringify(data)
352
+ });
353
+ }
354
+ async installServerApp(serverIdOrSlug, data) {
355
+ return this.request(`/api/servers/${serverIdOrSlug}/apps`, {
356
+ method: "POST",
357
+ body: JSON.stringify(data)
358
+ });
359
+ }
360
+ async installServerAppFromCatalog(serverIdOrSlug, catalogEntryId, data = {}) {
361
+ return this.request(
362
+ `/api/servers/${serverIdOrSlug}/apps/catalog/${encodeURIComponent(catalogEntryId)}/install`,
363
+ {
364
+ method: "POST",
365
+ body: JSON.stringify(data)
366
+ }
367
+ );
368
+ }
369
+ async getServerApp(serverIdOrSlug, appKey) {
370
+ return this.request(`/api/servers/${serverIdOrSlug}/apps/${encodeURIComponent(appKey)}`);
371
+ }
372
+ async deleteServerApp(serverIdOrSlug, appKey) {
373
+ return this.request(`/api/servers/${serverIdOrSlug}/apps/${encodeURIComponent(appKey)}`, {
374
+ method: "DELETE"
375
+ });
376
+ }
377
+ async grantServerAppToBuddy(serverIdOrSlug, appKey, data) {
378
+ return this.request(
379
+ `/api/servers/${serverIdOrSlug}/apps/${encodeURIComponent(appKey)}/grants`,
380
+ {
381
+ method: "POST",
382
+ body: JSON.stringify(data)
383
+ }
384
+ );
385
+ }
386
+ async getServerAppSkills(serverIdOrSlug, appKey) {
387
+ return this.request(`/api/servers/${serverIdOrSlug}/apps/${encodeURIComponent(appKey)}/skills`);
388
+ }
389
+ async createServerAppLaunch(serverIdOrSlug, appKey) {
390
+ return this.request(
391
+ `/api/servers/${serverIdOrSlug}/apps/${encodeURIComponent(appKey)}/launch`,
392
+ {
393
+ method: "POST"
394
+ }
395
+ );
396
+ }
397
+ async introspectServerAppToken(serverIdOrSlug, appKey, token) {
398
+ const url = `${this.baseUrl}/api/servers/${serverIdOrSlug}/apps/${encodeURIComponent(
399
+ appKey
400
+ )}/oauth/introspect`;
401
+ const res = await fetch(url, {
402
+ method: "POST",
403
+ headers: {
404
+ Authorization: `Bearer ${token}`,
405
+ "Content-Type": "application/json"
406
+ },
407
+ body: JSON.stringify({ token })
408
+ });
409
+ if (!res.ok) {
410
+ const body = await res.text().catch(() => "");
411
+ const message = sanitizeErrorBody(body);
412
+ throw new Error(`Shadow API POST /oauth/introspect failed (${res.status}): ${message}`);
413
+ }
414
+ return await res.json();
415
+ }
416
+ async callServerAppCommand(serverIdOrSlug, appKey, commandName, data) {
417
+ return this.request(
418
+ `/api/servers/${serverIdOrSlug}/apps/${encodeURIComponent(appKey)}/commands/${encodeURIComponent(
419
+ commandName
420
+ )}`,
421
+ {
422
+ method: "POST",
423
+ body: JSON.stringify(data ?? {})
424
+ }
425
+ );
426
+ }
427
+ async callServerAppCommandMultipart(serverIdOrSlug, appKey, commandName, data) {
428
+ const form = new FormData();
429
+ form.set("input", JSON.stringify(data.input ?? {}));
430
+ if (data.channelId) form.set("channelId", data.channelId);
431
+ form.set(data.field ?? "file", data.file, data.filename);
432
+ return this.request(
433
+ `/api/servers/${serverIdOrSlug}/apps/${encodeURIComponent(appKey)}/commands/${encodeURIComponent(
434
+ commandName
435
+ )}`,
436
+ {
437
+ method: "POST",
438
+ body: form
439
+ }
440
+ );
441
+ }
340
442
  async updateServer(serverIdOrSlug, data) {
341
443
  return this.request(`/api/servers/${serverIdOrSlug}`, {
342
444
  method: "PATCH",
343
445
  body: JSON.stringify(data)
344
446
  });
345
447
  }
346
- async updateServerHomepage(serverIdOrSlug, homepageHtml) {
347
- return this.updateServer(serverIdOrSlug, { homepageHtml });
348
- }
349
448
  async deleteServer(serverId) {
350
449
  return this.request(`/api/servers/${serverId}`, { method: "DELETE" });
351
450
  }
@@ -410,6 +509,14 @@ var ShadowClient = class {
410
509
  const ch = await this.request(`/api/channels/${channelId}`);
411
510
  return { ...ch, description: ch.topic };
412
511
  }
512
+ async getChannelBootstrap(channelId, options) {
513
+ const params = new URLSearchParams();
514
+ if (options?.messagesLimit) params.set("messagesLimit", String(options.messagesLimit));
515
+ const query = params.toString();
516
+ return this.request(
517
+ `/api/channels/${channelId}/bootstrap${query ? `?${query}` : ""}`
518
+ );
519
+ }
413
520
  async getChannelAccess(channelId) {
414
521
  return this.request(`/api/channels/${channelId}/access`);
415
522
  }
@@ -673,9 +780,11 @@ var ShadowClient = class {
673
780
  return res.json();
674
781
  }
675
782
  async resolveAttachmentMediaUrl(attachmentId, options) {
676
- const disposition = options?.disposition ?? "inline";
783
+ const params = new URLSearchParams();
784
+ params.set("disposition", options?.disposition ?? "inline");
785
+ if (options?.variant) params.set("variant", options.variant);
677
786
  return this.request(
678
- `/api/attachments/${attachmentId}/media-url?disposition=${disposition}`
787
+ `/api/attachments/${attachmentId}/media-url?${params}`
679
788
  );
680
789
  }
681
790
  async resolveWorkspaceMediaUrl(serverId, fileId, options) {
@@ -909,9 +1018,21 @@ var ShadowClient = class {
909
1018
  async listOAuthAccounts() {
910
1019
  return this.request("/api/auth/oauth/accounts");
911
1020
  }
1021
+ async createOAuthConnectUrl(provider, redirect) {
1022
+ return this.request(`/api/auth/oauth/${provider}/link`, {
1023
+ method: "POST",
1024
+ body: JSON.stringify({ redirect })
1025
+ });
1026
+ }
912
1027
  async unlinkOAuthAccount(accountId) {
913
1028
  return this.request(`/api/auth/oauth/accounts/${accountId}`, { method: "DELETE" });
914
1029
  }
1030
+ async listAuthSessions() {
1031
+ return this.request("/api/auth/sessions");
1032
+ }
1033
+ async revokeAuthSession(sessionId) {
1034
+ return this.request(`/api/auth/sessions/${sessionId}`, { method: "DELETE" });
1035
+ }
915
1036
  async changePassword(data) {
916
1037
  return this.request("/api/auth/password", {
917
1038
  method: "PUT",
package/dist/index.d.cts CHANGED
@@ -120,6 +120,149 @@ interface ShadowSignedMediaUrl {
120
120
  url: string;
121
121
  expiresAt: string;
122
122
  }
123
+ type ShadowMediaVariant = 'avatar' | 'preview' | 'banner';
124
+ type ShadowServerAppAction = 'read' | 'write' | 'manage' | 'delete' | 'generate';
125
+ type ShadowServerAppDataClass = 'public' | 'server-private' | 'channel-private' | 'financial' | 'secret' | 'cloud-secret';
126
+ interface ShadowServerAppCommand {
127
+ name: string;
128
+ title?: string;
129
+ description?: string;
130
+ path: string;
131
+ method?: 'POST';
132
+ input?: 'json' | 'multipart';
133
+ inputSchema?: Record<string, unknown>;
134
+ permission: string;
135
+ action: ShadowServerAppAction;
136
+ dataClass: ShadowServerAppDataClass;
137
+ approvalMode?: 'none' | 'first_time' | 'every_time' | 'policy';
138
+ binary?: {
139
+ supported?: boolean;
140
+ field?: string;
141
+ maxBytes?: number;
142
+ contentTypes?: string[];
143
+ };
144
+ }
145
+ interface ShadowServerAppManifest {
146
+ schemaVersion: 'shadow.app/1';
147
+ appKey: string;
148
+ name: string;
149
+ description?: string;
150
+ version?: string;
151
+ iconUrl: string;
152
+ iframe?: {
153
+ entry: string;
154
+ allowedOrigins: string[];
155
+ };
156
+ api: {
157
+ baseUrl: string;
158
+ auth?: {
159
+ type: 'oauth2-bearer';
160
+ };
161
+ };
162
+ commands: ShadowServerAppCommand[];
163
+ skills?: Array<{
164
+ name: string;
165
+ description: string;
166
+ commandHints?: string[];
167
+ }>;
168
+ events?: string[];
169
+ binary?: {
170
+ supported: boolean;
171
+ maxBytes?: number;
172
+ contentTypes?: string[];
173
+ };
174
+ }
175
+ interface ShadowServerAppIntegration {
176
+ id: string;
177
+ serverId: string;
178
+ appKey: string;
179
+ name: string;
180
+ description?: string | null;
181
+ iconUrl?: string | null;
182
+ manifestUrl?: string | null;
183
+ manifest: ShadowServerAppManifest;
184
+ iframeEntry?: string | null;
185
+ allowedOrigins: string[];
186
+ apiBaseUrl: string;
187
+ status: string;
188
+ installedByUserId: string;
189
+ createdAt: string;
190
+ updatedAt: string;
191
+ }
192
+ interface ShadowServerAppDiscovery {
193
+ manifest: ShadowServerAppManifest;
194
+ installed: ShadowServerAppIntegration | null;
195
+ permissions: Array<{
196
+ name: string;
197
+ title: string;
198
+ description?: string | null;
199
+ permission: string;
200
+ action: ShadowServerAppAction;
201
+ dataClass: ShadowServerAppDataClass;
202
+ approvalMode: 'none' | 'first_time' | 'every_time' | 'policy';
203
+ }>;
204
+ }
205
+ interface ShadowServerAppCatalogEntry {
206
+ id: string;
207
+ appKey: string;
208
+ name: string;
209
+ description?: string | null;
210
+ iconUrl?: string | null;
211
+ manifestUrl?: string | null;
212
+ manifest: ShadowServerAppManifest;
213
+ status: string;
214
+ installed?: ShadowServerAppIntegration | null;
215
+ permissions?: ShadowServerAppDiscovery['permissions'];
216
+ createdAt: string;
217
+ updatedAt: string;
218
+ }
219
+ interface ShadowServerAppLaunchContext {
220
+ serverId: string;
221
+ serverAppId: string;
222
+ appKey: string;
223
+ iframeEntry: string | null;
224
+ allowedOrigins: string[];
225
+ launchToken: string;
226
+ eventStreamPath: string;
227
+ expiresIn: number;
228
+ }
229
+ interface ShadowServerAppSkillDocument {
230
+ appKey: string;
231
+ markdown: string;
232
+ skills: Array<{
233
+ name: string;
234
+ description: string;
235
+ commandHints?: string[];
236
+ }>;
237
+ }
238
+ interface ShadowServerAppTokenIntrospection {
239
+ active: boolean;
240
+ token_type?: 'Bearer';
241
+ iss?: string;
242
+ aud?: string;
243
+ sub?: string;
244
+ scope?: string;
245
+ client_id?: string;
246
+ exp?: number;
247
+ iat?: number;
248
+ shadow?: {
249
+ protocol: 'shadow.app/1';
250
+ serverId: string;
251
+ serverAppId: string;
252
+ appKey: string;
253
+ command?: string;
254
+ actor: {
255
+ kind?: string;
256
+ userId?: string | null;
257
+ buddyAgentId?: string | null;
258
+ ownerId?: string | null;
259
+ };
260
+ channelId?: string | null;
261
+ permission?: string;
262
+ action?: string;
263
+ dataClass?: string;
264
+ };
265
+ }
123
266
  interface ShadowChannel {
124
267
  id: string;
125
268
  name: string;
@@ -217,7 +360,6 @@ interface ShadowServer {
217
360
  description: string | null;
218
361
  iconUrl: string | null;
219
362
  bannerUrl: string | null;
220
- homepageHtml: string | null;
221
363
  isPublic: boolean;
222
364
  }
223
365
  interface ShadowUser {
@@ -411,6 +553,20 @@ interface ShadowChannelSlashCommand extends ShadowSlashCommand {
411
553
  botUsername: string;
412
554
  botDisplayName?: string | null;
413
555
  }
556
+ interface ShadowChannelBootstrap {
557
+ access: ShadowChannelAccess;
558
+ channel: ShadowChannel;
559
+ server: ShadowServer | null;
560
+ channels: ShadowChannel[];
561
+ members: ShadowMember[];
562
+ messages: {
563
+ messages: ShadowMessage[];
564
+ hasMore: boolean;
565
+ };
566
+ slashCommands: {
567
+ commands: ShadowChannelSlashCommand[];
568
+ };
569
+ }
414
570
  interface ShadowRemoteChannel {
415
571
  id: string;
416
572
  name: string;
@@ -1548,14 +1704,50 @@ declare class ShadowClient {
1548
1704
  listServers(): Promise<ShadowServer[]>;
1549
1705
  getServer(serverIdOrSlug: string): Promise<ShadowServer>;
1550
1706
  getServerAccess(serverIdOrSlug: string): Promise<ShadowServerAccess>;
1707
+ listServerApps(serverIdOrSlug: string): Promise<ShadowServerAppIntegration[]>;
1708
+ listServerAppCatalog(serverIdOrSlug: string): Promise<ShadowServerAppCatalogEntry[]>;
1709
+ discoverServerApp(serverIdOrSlug: string, data: {
1710
+ manifestUrl?: string;
1711
+ manifest?: ShadowServerAppManifest;
1712
+ }): Promise<ShadowServerAppDiscovery>;
1713
+ installServerApp(serverIdOrSlug: string, data: {
1714
+ manifestUrl?: string;
1715
+ manifest?: ShadowServerAppManifest;
1716
+ }): Promise<ShadowServerAppIntegration>;
1717
+ installServerAppFromCatalog(serverIdOrSlug: string, catalogEntryId: string, data?: Record<string, never>): Promise<ShadowServerAppIntegration>;
1718
+ getServerApp(serverIdOrSlug: string, appKey: string): Promise<ShadowServerAppIntegration & {
1719
+ grants?: Record<string, unknown>[];
1720
+ }>;
1721
+ deleteServerApp(serverIdOrSlug: string, appKey: string): Promise<{
1722
+ ok: boolean;
1723
+ }>;
1724
+ grantServerAppToBuddy(serverIdOrSlug: string, appKey: string, data: {
1725
+ buddyAgentId: string;
1726
+ permissions: string[];
1727
+ resourceRules?: Record<string, unknown>;
1728
+ approvalMode?: 'none' | 'first_time' | 'every_time' | 'policy';
1729
+ expiresAt?: string;
1730
+ }): Promise<Record<string, unknown>>;
1731
+ getServerAppSkills(serverIdOrSlug: string, appKey: string): Promise<ShadowServerAppSkillDocument>;
1732
+ createServerAppLaunch(serverIdOrSlug: string, appKey: string): Promise<ShadowServerAppLaunchContext>;
1733
+ introspectServerAppToken(serverIdOrSlug: string, appKey: string, token: string): Promise<ShadowServerAppTokenIntrospection>;
1734
+ callServerAppCommand(serverIdOrSlug: string, appKey: string, commandName: string, data?: {
1735
+ input?: unknown;
1736
+ channelId?: string;
1737
+ }): Promise<unknown>;
1738
+ callServerAppCommandMultipart(serverIdOrSlug: string, appKey: string, commandName: string, data: {
1739
+ input?: unknown;
1740
+ channelId?: string;
1741
+ file: Blob;
1742
+ filename: string;
1743
+ field?: string;
1744
+ }): Promise<unknown>;
1551
1745
  updateServer(serverIdOrSlug: string, data: {
1552
1746
  name?: string;
1553
1747
  description?: string | null;
1554
1748
  slug?: string | null;
1555
- homepageHtml?: string | null;
1556
1749
  isPublic?: boolean;
1557
1750
  }): Promise<ShadowServer>;
1558
- updateServerHomepage(serverIdOrSlug: string, homepageHtml: string | null): Promise<ShadowServer>;
1559
1751
  deleteServer(serverId: string): Promise<{
1560
1752
  success: boolean;
1561
1753
  }>;
@@ -1588,6 +1780,9 @@ declare class ShadowClient {
1588
1780
  isPrivate?: boolean;
1589
1781
  }): Promise<ShadowChannel>;
1590
1782
  getChannel(channelId: string): Promise<ShadowChannel>;
1783
+ getChannelBootstrap(channelId: string, options?: {
1784
+ messagesLimit?: number;
1785
+ }): Promise<ShadowChannelBootstrap>;
1591
1786
  getChannelAccess(channelId: string): Promise<ShadowChannelAccess>;
1592
1787
  getChannelMembers(channelId: string): Promise<ShadowMember[]>;
1593
1788
  updateChannel(channelId: string, data: {
@@ -1723,6 +1918,7 @@ declare class ShadowClient {
1723
1918
  }>;
1724
1919
  resolveAttachmentMediaUrl(attachmentId: string, options?: {
1725
1920
  disposition?: 'inline' | 'attachment';
1921
+ variant?: ShadowMediaVariant;
1726
1922
  }): Promise<ShadowSignedMediaUrl>;
1727
1923
  resolveWorkspaceMediaUrl(serverId: string, fileId: string, options?: {
1728
1924
  disposition?: 'inline' | 'attachment';
@@ -1816,11 +2012,28 @@ declare class ShadowClient {
1816
2012
  listOAuthAccounts(): Promise<{
1817
2013
  id: string;
1818
2014
  provider: string;
1819
- providerAccountId: string;
2015
+ providerEmail: string | null;
2016
+ createdAt: string;
1820
2017
  }[]>;
2018
+ createOAuthConnectUrl(provider: 'google' | 'github', redirect?: string): Promise<{
2019
+ url: string;
2020
+ }>;
1821
2021
  unlinkOAuthAccount(accountId: string): Promise<{
1822
2022
  success: boolean;
1823
2023
  }>;
2024
+ listAuthSessions(): Promise<Array<{
2025
+ id: string;
2026
+ deviceName: string | null;
2027
+ userAgent: string | null;
2028
+ ipAddress: string | null;
2029
+ lastSeenAt: string;
2030
+ createdAt: string;
2031
+ revokedAt: string | null;
2032
+ current: boolean;
2033
+ }>>;
2034
+ revokeAuthSession(sessionId: string): Promise<{
2035
+ ok: boolean;
2036
+ }>;
1824
2037
  changePassword(data: {
1825
2038
  currentPassword: string;
1826
2039
  newPassword: string;
@@ -2542,4 +2755,4 @@ declare class ShadowSocket {
2542
2755
  updateActivity(channelId: string, activity: string | null): void;
2543
2756
  }
2544
2757
 
2545
- export { type ChannelCreatedPayload, type ChannelMemberAddedPayload, type ChannelMemberRemovedPayload, type ClientEventMap, type MemberJoinPayload, type MemberLeavePayload, type MessageDeletedPayload, type PolicyChangedPayload, type PresenceActivityPayload, type PresenceChangePayload, type ReactionPayload, type ServerEventMap, type ServerJoinedPayload, type ShadowAddAgentsToServerResult, type ShadowAgentUsageSnapshotInput, type ShadowAttachment, type ShadowCartItem, type ShadowCategory, type ShadowChannel, type ShadowChannelAccess, type ShadowChannelJoinRequestResult, type ShadowChannelJoinRequestStatus, type ShadowChannelPolicy, type ShadowChannelSlashCommand, ShadowClient, type ShadowCloudDeploymentBackup, type ShadowCloudDeploymentRuntimeResponse, type ShadowCloudDeploymentStatus, type ShadowCloudProviderCatalog, type ShadowCloudProviderEnvVar, type ShadowCloudProviderModel, type ShadowCloudProviderProfile, type ShadowContract, type ShadowDiyCloudRun, type ShadowDiyCloudRunEvent, type ShadowDiyCloudRunStatus, type ShadowFriendship, type ShadowInteractiveActionInput, type ShadowInteractiveActionResult, type ShadowInteractiveBlock, type ShadowInteractiveResponse, type ShadowInteractiveState, type ShadowInteractiveSubmissionPending, type ShadowInviteCode, type ShadowListing, type ShadowMember, type ShadowMentionSuggestion, type ShadowMentionSuggestionTrigger, type ShadowMessage, type ShadowMessageMention, type ShadowModelProxyBilling, type ShadowModelProxyChatCompletionRequest, type ShadowModelProxyChatCompletionResponse, type ShadowModelProxyModel, type ShadowModelProxyModelsResponse, type ShadowNotification, type ShadowNotificationPreferences, type ShadowOAuthApp, type ShadowOAuthConsent, type ShadowOAuthToken, type ShadowOrder, type ShadowProduct, type ShadowRemoteChannel, type ShadowRemoteConfig, type ShadowRemoteServer, type ShadowReview, type ShadowServer, type ShadowServerAccess, type ShadowServerJoinRequestResult, type ShadowServerJoinRequestStatus, type ShadowShop, type ShadowSlashCommand, ShadowSocket, type ShadowSocketOptions, type ShadowTask, type ShadowThread, type ShadowTransaction, type ShadowUsageProviderSnapshot, type ShadowUser, type ShadowWallet, type TypingPayload, channelRoom, threadRoom, userRoom };
2758
+ export { type ChannelCreatedPayload, type ChannelMemberAddedPayload, type ChannelMemberRemovedPayload, type ClientEventMap, type MemberJoinPayload, type MemberLeavePayload, type MessageDeletedPayload, type PolicyChangedPayload, type PresenceActivityPayload, type PresenceChangePayload, type ReactionPayload, type ServerEventMap, type ServerJoinedPayload, type ShadowAddAgentsToServerResult, type ShadowAgentUsageSnapshotInput, type ShadowAttachment, type ShadowCartItem, type ShadowCategory, type ShadowChannel, type ShadowChannelAccess, type ShadowChannelBootstrap, type ShadowChannelJoinRequestResult, type ShadowChannelJoinRequestStatus, type ShadowChannelPolicy, type ShadowChannelSlashCommand, ShadowClient, type ShadowCloudDeploymentBackup, type ShadowCloudDeploymentRuntimeResponse, type ShadowCloudDeploymentStatus, type ShadowCloudProviderCatalog, type ShadowCloudProviderEnvVar, type ShadowCloudProviderModel, type ShadowCloudProviderProfile, type ShadowContract, type ShadowDiyCloudRun, type ShadowDiyCloudRunEvent, type ShadowDiyCloudRunStatus, type ShadowFriendship, type ShadowInteractiveActionInput, type ShadowInteractiveActionResult, type ShadowInteractiveBlock, type ShadowInteractiveResponse, type ShadowInteractiveState, type ShadowInteractiveSubmissionPending, type ShadowInviteCode, type ShadowListing, type ShadowMediaVariant, type ShadowMember, type ShadowMentionSuggestion, type ShadowMentionSuggestionTrigger, type ShadowMessage, type ShadowMessageMention, type ShadowModelProxyBilling, type ShadowModelProxyChatCompletionRequest, type ShadowModelProxyChatCompletionResponse, type ShadowModelProxyModel, type ShadowModelProxyModelsResponse, type ShadowNotification, type ShadowNotificationPreferences, type ShadowOAuthApp, type ShadowOAuthConsent, type ShadowOAuthToken, type ShadowOrder, type ShadowProduct, type ShadowRemoteChannel, type ShadowRemoteConfig, type ShadowRemoteServer, type ShadowReview, type ShadowServer, type ShadowServerAccess, type ShadowServerAppCatalogEntry, type ShadowServerAppCommand, type ShadowServerAppDiscovery, type ShadowServerAppIntegration, type ShadowServerAppLaunchContext, type ShadowServerAppManifest, type ShadowServerAppSkillDocument, type ShadowServerAppTokenIntrospection, type ShadowServerJoinRequestResult, type ShadowServerJoinRequestStatus, type ShadowShop, type ShadowSlashCommand, ShadowSocket, type ShadowSocketOptions, type ShadowTask, type ShadowThread, type ShadowTransaction, type ShadowUsageProviderSnapshot, type ShadowUser, type ShadowWallet, type TypingPayload, channelRoom, threadRoom, userRoom };
package/dist/index.d.ts CHANGED
@@ -120,6 +120,149 @@ interface ShadowSignedMediaUrl {
120
120
  url: string;
121
121
  expiresAt: string;
122
122
  }
123
+ type ShadowMediaVariant = 'avatar' | 'preview' | 'banner';
124
+ type ShadowServerAppAction = 'read' | 'write' | 'manage' | 'delete' | 'generate';
125
+ type ShadowServerAppDataClass = 'public' | 'server-private' | 'channel-private' | 'financial' | 'secret' | 'cloud-secret';
126
+ interface ShadowServerAppCommand {
127
+ name: string;
128
+ title?: string;
129
+ description?: string;
130
+ path: string;
131
+ method?: 'POST';
132
+ input?: 'json' | 'multipart';
133
+ inputSchema?: Record<string, unknown>;
134
+ permission: string;
135
+ action: ShadowServerAppAction;
136
+ dataClass: ShadowServerAppDataClass;
137
+ approvalMode?: 'none' | 'first_time' | 'every_time' | 'policy';
138
+ binary?: {
139
+ supported?: boolean;
140
+ field?: string;
141
+ maxBytes?: number;
142
+ contentTypes?: string[];
143
+ };
144
+ }
145
+ interface ShadowServerAppManifest {
146
+ schemaVersion: 'shadow.app/1';
147
+ appKey: string;
148
+ name: string;
149
+ description?: string;
150
+ version?: string;
151
+ iconUrl: string;
152
+ iframe?: {
153
+ entry: string;
154
+ allowedOrigins: string[];
155
+ };
156
+ api: {
157
+ baseUrl: string;
158
+ auth?: {
159
+ type: 'oauth2-bearer';
160
+ };
161
+ };
162
+ commands: ShadowServerAppCommand[];
163
+ skills?: Array<{
164
+ name: string;
165
+ description: string;
166
+ commandHints?: string[];
167
+ }>;
168
+ events?: string[];
169
+ binary?: {
170
+ supported: boolean;
171
+ maxBytes?: number;
172
+ contentTypes?: string[];
173
+ };
174
+ }
175
+ interface ShadowServerAppIntegration {
176
+ id: string;
177
+ serverId: string;
178
+ appKey: string;
179
+ name: string;
180
+ description?: string | null;
181
+ iconUrl?: string | null;
182
+ manifestUrl?: string | null;
183
+ manifest: ShadowServerAppManifest;
184
+ iframeEntry?: string | null;
185
+ allowedOrigins: string[];
186
+ apiBaseUrl: string;
187
+ status: string;
188
+ installedByUserId: string;
189
+ createdAt: string;
190
+ updatedAt: string;
191
+ }
192
+ interface ShadowServerAppDiscovery {
193
+ manifest: ShadowServerAppManifest;
194
+ installed: ShadowServerAppIntegration | null;
195
+ permissions: Array<{
196
+ name: string;
197
+ title: string;
198
+ description?: string | null;
199
+ permission: string;
200
+ action: ShadowServerAppAction;
201
+ dataClass: ShadowServerAppDataClass;
202
+ approvalMode: 'none' | 'first_time' | 'every_time' | 'policy';
203
+ }>;
204
+ }
205
+ interface ShadowServerAppCatalogEntry {
206
+ id: string;
207
+ appKey: string;
208
+ name: string;
209
+ description?: string | null;
210
+ iconUrl?: string | null;
211
+ manifestUrl?: string | null;
212
+ manifest: ShadowServerAppManifest;
213
+ status: string;
214
+ installed?: ShadowServerAppIntegration | null;
215
+ permissions?: ShadowServerAppDiscovery['permissions'];
216
+ createdAt: string;
217
+ updatedAt: string;
218
+ }
219
+ interface ShadowServerAppLaunchContext {
220
+ serverId: string;
221
+ serverAppId: string;
222
+ appKey: string;
223
+ iframeEntry: string | null;
224
+ allowedOrigins: string[];
225
+ launchToken: string;
226
+ eventStreamPath: string;
227
+ expiresIn: number;
228
+ }
229
+ interface ShadowServerAppSkillDocument {
230
+ appKey: string;
231
+ markdown: string;
232
+ skills: Array<{
233
+ name: string;
234
+ description: string;
235
+ commandHints?: string[];
236
+ }>;
237
+ }
238
+ interface ShadowServerAppTokenIntrospection {
239
+ active: boolean;
240
+ token_type?: 'Bearer';
241
+ iss?: string;
242
+ aud?: string;
243
+ sub?: string;
244
+ scope?: string;
245
+ client_id?: string;
246
+ exp?: number;
247
+ iat?: number;
248
+ shadow?: {
249
+ protocol: 'shadow.app/1';
250
+ serverId: string;
251
+ serverAppId: string;
252
+ appKey: string;
253
+ command?: string;
254
+ actor: {
255
+ kind?: string;
256
+ userId?: string | null;
257
+ buddyAgentId?: string | null;
258
+ ownerId?: string | null;
259
+ };
260
+ channelId?: string | null;
261
+ permission?: string;
262
+ action?: string;
263
+ dataClass?: string;
264
+ };
265
+ }
123
266
  interface ShadowChannel {
124
267
  id: string;
125
268
  name: string;
@@ -217,7 +360,6 @@ interface ShadowServer {
217
360
  description: string | null;
218
361
  iconUrl: string | null;
219
362
  bannerUrl: string | null;
220
- homepageHtml: string | null;
221
363
  isPublic: boolean;
222
364
  }
223
365
  interface ShadowUser {
@@ -411,6 +553,20 @@ interface ShadowChannelSlashCommand extends ShadowSlashCommand {
411
553
  botUsername: string;
412
554
  botDisplayName?: string | null;
413
555
  }
556
+ interface ShadowChannelBootstrap {
557
+ access: ShadowChannelAccess;
558
+ channel: ShadowChannel;
559
+ server: ShadowServer | null;
560
+ channels: ShadowChannel[];
561
+ members: ShadowMember[];
562
+ messages: {
563
+ messages: ShadowMessage[];
564
+ hasMore: boolean;
565
+ };
566
+ slashCommands: {
567
+ commands: ShadowChannelSlashCommand[];
568
+ };
569
+ }
414
570
  interface ShadowRemoteChannel {
415
571
  id: string;
416
572
  name: string;
@@ -1548,14 +1704,50 @@ declare class ShadowClient {
1548
1704
  listServers(): Promise<ShadowServer[]>;
1549
1705
  getServer(serverIdOrSlug: string): Promise<ShadowServer>;
1550
1706
  getServerAccess(serverIdOrSlug: string): Promise<ShadowServerAccess>;
1707
+ listServerApps(serverIdOrSlug: string): Promise<ShadowServerAppIntegration[]>;
1708
+ listServerAppCatalog(serverIdOrSlug: string): Promise<ShadowServerAppCatalogEntry[]>;
1709
+ discoverServerApp(serverIdOrSlug: string, data: {
1710
+ manifestUrl?: string;
1711
+ manifest?: ShadowServerAppManifest;
1712
+ }): Promise<ShadowServerAppDiscovery>;
1713
+ installServerApp(serverIdOrSlug: string, data: {
1714
+ manifestUrl?: string;
1715
+ manifest?: ShadowServerAppManifest;
1716
+ }): Promise<ShadowServerAppIntegration>;
1717
+ installServerAppFromCatalog(serverIdOrSlug: string, catalogEntryId: string, data?: Record<string, never>): Promise<ShadowServerAppIntegration>;
1718
+ getServerApp(serverIdOrSlug: string, appKey: string): Promise<ShadowServerAppIntegration & {
1719
+ grants?: Record<string, unknown>[];
1720
+ }>;
1721
+ deleteServerApp(serverIdOrSlug: string, appKey: string): Promise<{
1722
+ ok: boolean;
1723
+ }>;
1724
+ grantServerAppToBuddy(serverIdOrSlug: string, appKey: string, data: {
1725
+ buddyAgentId: string;
1726
+ permissions: string[];
1727
+ resourceRules?: Record<string, unknown>;
1728
+ approvalMode?: 'none' | 'first_time' | 'every_time' | 'policy';
1729
+ expiresAt?: string;
1730
+ }): Promise<Record<string, unknown>>;
1731
+ getServerAppSkills(serverIdOrSlug: string, appKey: string): Promise<ShadowServerAppSkillDocument>;
1732
+ createServerAppLaunch(serverIdOrSlug: string, appKey: string): Promise<ShadowServerAppLaunchContext>;
1733
+ introspectServerAppToken(serverIdOrSlug: string, appKey: string, token: string): Promise<ShadowServerAppTokenIntrospection>;
1734
+ callServerAppCommand(serverIdOrSlug: string, appKey: string, commandName: string, data?: {
1735
+ input?: unknown;
1736
+ channelId?: string;
1737
+ }): Promise<unknown>;
1738
+ callServerAppCommandMultipart(serverIdOrSlug: string, appKey: string, commandName: string, data: {
1739
+ input?: unknown;
1740
+ channelId?: string;
1741
+ file: Blob;
1742
+ filename: string;
1743
+ field?: string;
1744
+ }): Promise<unknown>;
1551
1745
  updateServer(serverIdOrSlug: string, data: {
1552
1746
  name?: string;
1553
1747
  description?: string | null;
1554
1748
  slug?: string | null;
1555
- homepageHtml?: string | null;
1556
1749
  isPublic?: boolean;
1557
1750
  }): Promise<ShadowServer>;
1558
- updateServerHomepage(serverIdOrSlug: string, homepageHtml: string | null): Promise<ShadowServer>;
1559
1751
  deleteServer(serverId: string): Promise<{
1560
1752
  success: boolean;
1561
1753
  }>;
@@ -1588,6 +1780,9 @@ declare class ShadowClient {
1588
1780
  isPrivate?: boolean;
1589
1781
  }): Promise<ShadowChannel>;
1590
1782
  getChannel(channelId: string): Promise<ShadowChannel>;
1783
+ getChannelBootstrap(channelId: string, options?: {
1784
+ messagesLimit?: number;
1785
+ }): Promise<ShadowChannelBootstrap>;
1591
1786
  getChannelAccess(channelId: string): Promise<ShadowChannelAccess>;
1592
1787
  getChannelMembers(channelId: string): Promise<ShadowMember[]>;
1593
1788
  updateChannel(channelId: string, data: {
@@ -1723,6 +1918,7 @@ declare class ShadowClient {
1723
1918
  }>;
1724
1919
  resolveAttachmentMediaUrl(attachmentId: string, options?: {
1725
1920
  disposition?: 'inline' | 'attachment';
1921
+ variant?: ShadowMediaVariant;
1726
1922
  }): Promise<ShadowSignedMediaUrl>;
1727
1923
  resolveWorkspaceMediaUrl(serverId: string, fileId: string, options?: {
1728
1924
  disposition?: 'inline' | 'attachment';
@@ -1816,11 +2012,28 @@ declare class ShadowClient {
1816
2012
  listOAuthAccounts(): Promise<{
1817
2013
  id: string;
1818
2014
  provider: string;
1819
- providerAccountId: string;
2015
+ providerEmail: string | null;
2016
+ createdAt: string;
1820
2017
  }[]>;
2018
+ createOAuthConnectUrl(provider: 'google' | 'github', redirect?: string): Promise<{
2019
+ url: string;
2020
+ }>;
1821
2021
  unlinkOAuthAccount(accountId: string): Promise<{
1822
2022
  success: boolean;
1823
2023
  }>;
2024
+ listAuthSessions(): Promise<Array<{
2025
+ id: string;
2026
+ deviceName: string | null;
2027
+ userAgent: string | null;
2028
+ ipAddress: string | null;
2029
+ lastSeenAt: string;
2030
+ createdAt: string;
2031
+ revokedAt: string | null;
2032
+ current: boolean;
2033
+ }>>;
2034
+ revokeAuthSession(sessionId: string): Promise<{
2035
+ ok: boolean;
2036
+ }>;
1824
2037
  changePassword(data: {
1825
2038
  currentPassword: string;
1826
2039
  newPassword: string;
@@ -2542,4 +2755,4 @@ declare class ShadowSocket {
2542
2755
  updateActivity(channelId: string, activity: string | null): void;
2543
2756
  }
2544
2757
 
2545
- export { type ChannelCreatedPayload, type ChannelMemberAddedPayload, type ChannelMemberRemovedPayload, type ClientEventMap, type MemberJoinPayload, type MemberLeavePayload, type MessageDeletedPayload, type PolicyChangedPayload, type PresenceActivityPayload, type PresenceChangePayload, type ReactionPayload, type ServerEventMap, type ServerJoinedPayload, type ShadowAddAgentsToServerResult, type ShadowAgentUsageSnapshotInput, type ShadowAttachment, type ShadowCartItem, type ShadowCategory, type ShadowChannel, type ShadowChannelAccess, type ShadowChannelJoinRequestResult, type ShadowChannelJoinRequestStatus, type ShadowChannelPolicy, type ShadowChannelSlashCommand, ShadowClient, type ShadowCloudDeploymentBackup, type ShadowCloudDeploymentRuntimeResponse, type ShadowCloudDeploymentStatus, type ShadowCloudProviderCatalog, type ShadowCloudProviderEnvVar, type ShadowCloudProviderModel, type ShadowCloudProviderProfile, type ShadowContract, type ShadowDiyCloudRun, type ShadowDiyCloudRunEvent, type ShadowDiyCloudRunStatus, type ShadowFriendship, type ShadowInteractiveActionInput, type ShadowInteractiveActionResult, type ShadowInteractiveBlock, type ShadowInteractiveResponse, type ShadowInteractiveState, type ShadowInteractiveSubmissionPending, type ShadowInviteCode, type ShadowListing, type ShadowMember, type ShadowMentionSuggestion, type ShadowMentionSuggestionTrigger, type ShadowMessage, type ShadowMessageMention, type ShadowModelProxyBilling, type ShadowModelProxyChatCompletionRequest, type ShadowModelProxyChatCompletionResponse, type ShadowModelProxyModel, type ShadowModelProxyModelsResponse, type ShadowNotification, type ShadowNotificationPreferences, type ShadowOAuthApp, type ShadowOAuthConsent, type ShadowOAuthToken, type ShadowOrder, type ShadowProduct, type ShadowRemoteChannel, type ShadowRemoteConfig, type ShadowRemoteServer, type ShadowReview, type ShadowServer, type ShadowServerAccess, type ShadowServerJoinRequestResult, type ShadowServerJoinRequestStatus, type ShadowShop, type ShadowSlashCommand, ShadowSocket, type ShadowSocketOptions, type ShadowTask, type ShadowThread, type ShadowTransaction, type ShadowUsageProviderSnapshot, type ShadowUser, type ShadowWallet, type TypingPayload, channelRoom, threadRoom, userRoom };
2758
+ export { type ChannelCreatedPayload, type ChannelMemberAddedPayload, type ChannelMemberRemovedPayload, type ClientEventMap, type MemberJoinPayload, type MemberLeavePayload, type MessageDeletedPayload, type PolicyChangedPayload, type PresenceActivityPayload, type PresenceChangePayload, type ReactionPayload, type ServerEventMap, type ServerJoinedPayload, type ShadowAddAgentsToServerResult, type ShadowAgentUsageSnapshotInput, type ShadowAttachment, type ShadowCartItem, type ShadowCategory, type ShadowChannel, type ShadowChannelAccess, type ShadowChannelBootstrap, type ShadowChannelJoinRequestResult, type ShadowChannelJoinRequestStatus, type ShadowChannelPolicy, type ShadowChannelSlashCommand, ShadowClient, type ShadowCloudDeploymentBackup, type ShadowCloudDeploymentRuntimeResponse, type ShadowCloudDeploymentStatus, type ShadowCloudProviderCatalog, type ShadowCloudProviderEnvVar, type ShadowCloudProviderModel, type ShadowCloudProviderProfile, type ShadowContract, type ShadowDiyCloudRun, type ShadowDiyCloudRunEvent, type ShadowDiyCloudRunStatus, type ShadowFriendship, type ShadowInteractiveActionInput, type ShadowInteractiveActionResult, type ShadowInteractiveBlock, type ShadowInteractiveResponse, type ShadowInteractiveState, type ShadowInteractiveSubmissionPending, type ShadowInviteCode, type ShadowListing, type ShadowMediaVariant, type ShadowMember, type ShadowMentionSuggestion, type ShadowMentionSuggestionTrigger, type ShadowMessage, type ShadowMessageMention, type ShadowModelProxyBilling, type ShadowModelProxyChatCompletionRequest, type ShadowModelProxyChatCompletionResponse, type ShadowModelProxyModel, type ShadowModelProxyModelsResponse, type ShadowNotification, type ShadowNotificationPreferences, type ShadowOAuthApp, type ShadowOAuthConsent, type ShadowOAuthToken, type ShadowOrder, type ShadowProduct, type ShadowRemoteChannel, type ShadowRemoteConfig, type ShadowRemoteServer, type ShadowReview, type ShadowServer, type ShadowServerAccess, type ShadowServerAppCatalogEntry, type ShadowServerAppCommand, type ShadowServerAppDiscovery, type ShadowServerAppIntegration, type ShadowServerAppLaunchContext, type ShadowServerAppManifest, type ShadowServerAppSkillDocument, type ShadowServerAppTokenIntrospection, type ShadowServerJoinRequestResult, type ShadowServerJoinRequestStatus, type ShadowShop, type ShadowSlashCommand, ShadowSocket, type ShadowSocketOptions, type ShadowTask, type ShadowThread, type ShadowTransaction, type ShadowUsageProviderSnapshot, type ShadowUser, type ShadowWallet, type TypingPayload, channelRoom, threadRoom, userRoom };
package/dist/index.js CHANGED
@@ -45,12 +45,13 @@ var ShadowClient = class {
45
45
  const url = `${this.baseUrl}${path}`;
46
46
  const controller = new AbortController();
47
47
  const timeout = setTimeout(() => controller.abort(), 6e4);
48
+ const isFormData = init?.body instanceof FormData;
48
49
  try {
49
50
  const res = await fetch(url, {
50
51
  ...init,
51
52
  signal: init?.signal ?? controller.signal,
52
53
  headers: {
53
- "Content-Type": "application/json",
54
+ ...!isFormData ? { "Content-Type": "application/json" } : {},
54
55
  Authorization: `Bearer ${this.token}`,
55
56
  ...init?.headers
56
57
  }
@@ -295,15 +296,113 @@ var ShadowClient = class {
295
296
  async getServerAccess(serverIdOrSlug) {
296
297
  return this.request(`/api/servers/${serverIdOrSlug}/access`);
297
298
  }
299
+ // ── Server App Integrations ───────────────────────────────────────────
300
+ async listServerApps(serverIdOrSlug) {
301
+ return this.request(`/api/servers/${serverIdOrSlug}/apps`);
302
+ }
303
+ async listServerAppCatalog(serverIdOrSlug) {
304
+ return this.request(`/api/servers/${serverIdOrSlug}/apps/catalog`);
305
+ }
306
+ async discoverServerApp(serverIdOrSlug, data) {
307
+ return this.request(`/api/servers/${serverIdOrSlug}/apps/discover`, {
308
+ method: "POST",
309
+ body: JSON.stringify(data)
310
+ });
311
+ }
312
+ async installServerApp(serverIdOrSlug, data) {
313
+ return this.request(`/api/servers/${serverIdOrSlug}/apps`, {
314
+ method: "POST",
315
+ body: JSON.stringify(data)
316
+ });
317
+ }
318
+ async installServerAppFromCatalog(serverIdOrSlug, catalogEntryId, data = {}) {
319
+ return this.request(
320
+ `/api/servers/${serverIdOrSlug}/apps/catalog/${encodeURIComponent(catalogEntryId)}/install`,
321
+ {
322
+ method: "POST",
323
+ body: JSON.stringify(data)
324
+ }
325
+ );
326
+ }
327
+ async getServerApp(serverIdOrSlug, appKey) {
328
+ return this.request(`/api/servers/${serverIdOrSlug}/apps/${encodeURIComponent(appKey)}`);
329
+ }
330
+ async deleteServerApp(serverIdOrSlug, appKey) {
331
+ return this.request(`/api/servers/${serverIdOrSlug}/apps/${encodeURIComponent(appKey)}`, {
332
+ method: "DELETE"
333
+ });
334
+ }
335
+ async grantServerAppToBuddy(serverIdOrSlug, appKey, data) {
336
+ return this.request(
337
+ `/api/servers/${serverIdOrSlug}/apps/${encodeURIComponent(appKey)}/grants`,
338
+ {
339
+ method: "POST",
340
+ body: JSON.stringify(data)
341
+ }
342
+ );
343
+ }
344
+ async getServerAppSkills(serverIdOrSlug, appKey) {
345
+ return this.request(`/api/servers/${serverIdOrSlug}/apps/${encodeURIComponent(appKey)}/skills`);
346
+ }
347
+ async createServerAppLaunch(serverIdOrSlug, appKey) {
348
+ return this.request(
349
+ `/api/servers/${serverIdOrSlug}/apps/${encodeURIComponent(appKey)}/launch`,
350
+ {
351
+ method: "POST"
352
+ }
353
+ );
354
+ }
355
+ async introspectServerAppToken(serverIdOrSlug, appKey, token) {
356
+ const url = `${this.baseUrl}/api/servers/${serverIdOrSlug}/apps/${encodeURIComponent(
357
+ appKey
358
+ )}/oauth/introspect`;
359
+ const res = await fetch(url, {
360
+ method: "POST",
361
+ headers: {
362
+ Authorization: `Bearer ${token}`,
363
+ "Content-Type": "application/json"
364
+ },
365
+ body: JSON.stringify({ token })
366
+ });
367
+ if (!res.ok) {
368
+ const body = await res.text().catch(() => "");
369
+ const message = sanitizeErrorBody(body);
370
+ throw new Error(`Shadow API POST /oauth/introspect failed (${res.status}): ${message}`);
371
+ }
372
+ return await res.json();
373
+ }
374
+ async callServerAppCommand(serverIdOrSlug, appKey, commandName, data) {
375
+ return this.request(
376
+ `/api/servers/${serverIdOrSlug}/apps/${encodeURIComponent(appKey)}/commands/${encodeURIComponent(
377
+ commandName
378
+ )}`,
379
+ {
380
+ method: "POST",
381
+ body: JSON.stringify(data ?? {})
382
+ }
383
+ );
384
+ }
385
+ async callServerAppCommandMultipart(serverIdOrSlug, appKey, commandName, data) {
386
+ const form = new FormData();
387
+ form.set("input", JSON.stringify(data.input ?? {}));
388
+ if (data.channelId) form.set("channelId", data.channelId);
389
+ form.set(data.field ?? "file", data.file, data.filename);
390
+ return this.request(
391
+ `/api/servers/${serverIdOrSlug}/apps/${encodeURIComponent(appKey)}/commands/${encodeURIComponent(
392
+ commandName
393
+ )}`,
394
+ {
395
+ method: "POST",
396
+ body: form
397
+ }
398
+ );
399
+ }
298
400
  async updateServer(serverIdOrSlug, data) {
299
401
  return this.request(`/api/servers/${serverIdOrSlug}`, {
300
402
  method: "PATCH",
301
403
  body: JSON.stringify(data)
302
404
  });
303
405
  }
304
- async updateServerHomepage(serverIdOrSlug, homepageHtml) {
305
- return this.updateServer(serverIdOrSlug, { homepageHtml });
306
- }
307
406
  async deleteServer(serverId) {
308
407
  return this.request(`/api/servers/${serverId}`, { method: "DELETE" });
309
408
  }
@@ -368,6 +467,14 @@ var ShadowClient = class {
368
467
  const ch = await this.request(`/api/channels/${channelId}`);
369
468
  return { ...ch, description: ch.topic };
370
469
  }
470
+ async getChannelBootstrap(channelId, options) {
471
+ const params = new URLSearchParams();
472
+ if (options?.messagesLimit) params.set("messagesLimit", String(options.messagesLimit));
473
+ const query = params.toString();
474
+ return this.request(
475
+ `/api/channels/${channelId}/bootstrap${query ? `?${query}` : ""}`
476
+ );
477
+ }
371
478
  async getChannelAccess(channelId) {
372
479
  return this.request(`/api/channels/${channelId}/access`);
373
480
  }
@@ -631,9 +738,11 @@ var ShadowClient = class {
631
738
  return res.json();
632
739
  }
633
740
  async resolveAttachmentMediaUrl(attachmentId, options) {
634
- const disposition = options?.disposition ?? "inline";
741
+ const params = new URLSearchParams();
742
+ params.set("disposition", options?.disposition ?? "inline");
743
+ if (options?.variant) params.set("variant", options.variant);
635
744
  return this.request(
636
- `/api/attachments/${attachmentId}/media-url?disposition=${disposition}`
745
+ `/api/attachments/${attachmentId}/media-url?${params}`
637
746
  );
638
747
  }
639
748
  async resolveWorkspaceMediaUrl(serverId, fileId, options) {
@@ -867,9 +976,21 @@ var ShadowClient = class {
867
976
  async listOAuthAccounts() {
868
977
  return this.request("/api/auth/oauth/accounts");
869
978
  }
979
+ async createOAuthConnectUrl(provider, redirect) {
980
+ return this.request(`/api/auth/oauth/${provider}/link`, {
981
+ method: "POST",
982
+ body: JSON.stringify({ redirect })
983
+ });
984
+ }
870
985
  async unlinkOAuthAccount(accountId) {
871
986
  return this.request(`/api/auth/oauth/accounts/${accountId}`, { method: "DELETE" });
872
987
  }
988
+ async listAuthSessions() {
989
+ return this.request("/api/auth/sessions");
990
+ }
991
+ async revokeAuthSession(sessionId) {
992
+ return this.request(`/api/auth/sessions/${sessionId}`, { method: "DELETE" });
993
+ }
873
994
  async changePassword(data) {
874
995
  return this.request("/api/auth/password", {
875
996
  method: "PUT",
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@shadowob/sdk",
3
- "version": "1.1.3-dev.281",
3
+ "version": "1.1.4",
4
4
  "description": "Shadow SDK — typed REST client and real-time Socket.IO event listener for Shadow servers",
5
+ "license": "MIT",
5
6
  "type": "module",
6
7
  "main": "./dist/index.js",
7
8
  "module": "./dist/index.js",
@@ -21,7 +22,7 @@
21
22
  ],
22
23
  "dependencies": {
23
24
  "socket.io-client": "^4.8.1",
24
- "@shadowob/shared": "1.1.3-dev.281"
25
+ "@shadowob/shared": "1.1.4"
25
26
  },
26
27
  "devDependencies": {
27
28
  "tsup": "^8.5.0",