@palettelab/sdk 0.1.8 → 0.1.9

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/README.md CHANGED
@@ -121,6 +121,7 @@ the developer can immediately test the app inside the OS preview URL.
121
121
  import {
122
122
  PluginProvider,
123
123
  usePlatform,
124
+ createPaletteClient,
124
125
  usePluginTasks,
125
126
  usePluginDataRooms,
126
127
  usePluginChat,
@@ -168,6 +169,53 @@ export default function PluginRoot(props: PluginComponentProps) {
168
169
  }
169
170
  ```
170
171
 
172
+ ## Palette Client
173
+
174
+ Use `createPaletteClient()` when an app needs common Palette OS services without
175
+ remembering raw API routes.
176
+
177
+ ```tsx
178
+ import { createPaletteClient, usePlatform } from "@palettelab/sdk"
179
+
180
+ function App() {
181
+ const platform = usePlatform()
182
+ const palette = createPaletteClient(platform)
183
+
184
+ async function upload(file: File) {
185
+ const rooms = await palette.dataRooms.list()
186
+ await palette.dataRooms.uploadFile(rooms[0].id, file)
187
+ palette.toast.success("Uploaded")
188
+ }
189
+
190
+ return <button onClick={() => palette.user.current()}>Load profile</button>
191
+ }
192
+ ```
193
+
194
+ Included clients:
195
+
196
+ - `palette.user.current()` and `palette.user.updateProfile()`
197
+ - `palette.organization.currentId()`, `currentRole()`, and `listMine()`
198
+ - `palette.dataRooms.list()`, `create()`, `get()`, `folder()`, and `uploadFile()`
199
+ - `palette.config.get()` and `palette.config.update(values)`, with optional plugin ID override
200
+ - `palette.permissions.has()`, `hasAny()`, and `hasAll()`
201
+ - `palette.storage.uploadToSignedUrl()`
202
+ - `palette.toast.success()`, `error()`, and `info()`
203
+
204
+ These helpers are intentionally thin wrappers over platform APIs. Apps can still
205
+ use `apiFetch()` directly for custom backend routes.
206
+
207
+ ## Permissions
208
+
209
+ Use permission helpers to keep UI actions aligned with backend permission gates.
210
+
211
+ ```tsx
212
+ const palette = createPaletteClient(usePlatform())
213
+ const canWrite = palette.permissions.has("resources:write")
214
+ ```
215
+
216
+ Backend routes should still enforce permissions with the Python SDK. Frontend
217
+ permission checks are for UX only.
218
+
171
219
  ## API Helpers
172
220
 
173
221
  Use `apiFetch` for authenticated platform API calls. It includes credentials and performs the platform refresh flow for normal portal runtime.
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import react__default from 'react';
3
- import { P as PlatformContext } from '../plugin-DzSTKgkz.mjs';
3
+ import { P as PlatformContext } from '../plugin-o-qmdCBl.mjs';
4
4
 
5
5
  /**
6
6
  * Provider that wraps plugin components with the platform context.
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import react__default from 'react';
3
- import { P as PlatformContext } from '../plugin-DzSTKgkz.js';
3
+ import { P as PlatformContext } from '../plugin-o-qmdCBl.js';
4
4
 
5
5
  /**
6
6
  * Provider that wraps plugin components with the platform context.
@@ -122,4 +122,4 @@ interface DataRoomFile {
122
122
  updated_at: string;
123
123
  }
124
124
 
125
- export type { ChatAttachment as C, DataRoom as D, Task as T, ChatMessage as a, ChatThread as b, DataRoomFile as c, DataRoomFolder as d, DataRoomPermission as e, TaskAgentSnippet as f, TaskCreatePayload as g, TaskPriority as h, TaskStats as i, TaskStatus as j, TaskType as k, TaskUpdatePayload as l };
125
+ export type { ChatAttachment as C, DataRoom as D, Task as T, DataRoomFolder as a, DataRoomFile as b, ChatMessage as c, ChatThread as d, DataRoomPermission as e, TaskAgentSnippet as f, TaskCreatePayload as g, TaskPriority as h, TaskStats as i, TaskStatus as j, TaskType as k, TaskUpdatePayload as l };
@@ -122,4 +122,4 @@ interface DataRoomFile {
122
122
  updated_at: string;
123
123
  }
124
124
 
125
- export type { ChatAttachment as C, DataRoom as D, Task as T, ChatMessage as a, ChatThread as b, DataRoomFile as c, DataRoomFolder as d, DataRoomPermission as e, TaskAgentSnippet as f, TaskCreatePayload as g, TaskPriority as h, TaskStats as i, TaskStatus as j, TaskType as k, TaskUpdatePayload as l };
125
+ export type { ChatAttachment as C, DataRoom as D, Task as T, DataRoomFolder as a, DataRoomFile as b, ChatMessage as c, ChatThread as d, DataRoomPermission as e, TaskAgentSnippet as f, TaskCreatePayload as g, TaskPriority as h, TaskStats as i, TaskStatus as j, TaskType as k, TaskUpdatePayload as l };
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
- import { P as PlatformContext } from '../plugin-DzSTKgkz.mjs';
3
- import { T as Task, i as TaskStats, g as TaskCreatePayload, l as TaskUpdatePayload, D as DataRoom, d as DataRoomFolder, c as DataRoomFile, b as ChatThread, a as ChatMessage } from '../data-room-BP0PjYoe.mjs';
2
+ import { P as PlatformContext } from '../plugin-o-qmdCBl.mjs';
3
+ import { T as Task, i as TaskStats, g as TaskCreatePayload, l as TaskUpdatePayload, D as DataRoom, a as DataRoomFolder, b as DataRoomFile, d as ChatThread, c as ChatMessage } from '../data-room-Dtd9LLHf.mjs';
4
4
 
5
5
  /**
6
6
  * React context for platform services.
@@ -1,6 +1,6 @@
1
1
  import * as react from 'react';
2
- import { P as PlatformContext } from '../plugin-DzSTKgkz.js';
3
- import { T as Task, i as TaskStats, g as TaskCreatePayload, l as TaskUpdatePayload, D as DataRoom, d as DataRoomFolder, c as DataRoomFile, b as ChatThread, a as ChatMessage } from '../data-room-BP0PjYoe.js';
2
+ import { P as PlatformContext } from '../plugin-o-qmdCBl.js';
3
+ import { T as Task, i as TaskStats, g as TaskCreatePayload, l as TaskUpdatePayload, D as DataRoom, a as DataRoomFolder, b as DataRoomFile, d as ChatThread, c as ChatMessage } from '../data-room-Dtd9LLHf.js';
4
4
 
5
5
  /**
6
6
  * React context for platform services.
package/dist/index.d.mts CHANGED
@@ -1,6 +1,7 @@
1
- import { P as PlatformContext } from './plugin-DzSTKgkz.mjs';
2
- export { A as Agent, a as AgentConfig, b as AppCategory, c as AuthContextValue, O as OrgSummary, d as PluginAgentDefinition, e as PluginComponentProps, f as PluginManifest, g as PluginToolDefinition, U as User } from './plugin-DzSTKgkz.mjs';
3
- export { C as ChatAttachment, a as ChatMessage, b as ChatThread, D as DataRoom, c as DataRoomFile, d as DataRoomFolder, e as DataRoomPermission, T as Task, f as TaskAgentSnippet, g as TaskCreatePayload, h as TaskPriority, i as TaskStats, j as TaskStatus, k as TaskType, l as TaskUpdatePayload } from './data-room-BP0PjYoe.mjs';
1
+ import { P as PlatformContext, O as OrgSummary, U as User } from './plugin-o-qmdCBl.mjs';
2
+ export { A as Agent, a as AgentConfig, b as AppCategory, c as AuthContextValue, d as PluginAgentDefinition, e as PluginComponentProps, f as PluginManifest, g as PluginToolDefinition } from './plugin-o-qmdCBl.mjs';
3
+ import { D as DataRoom, a as DataRoomFolder, b as DataRoomFile } from './data-room-Dtd9LLHf.mjs';
4
+ export { C as ChatAttachment, c as ChatMessage, d as ChatThread, e as DataRoomPermission, T as Task, f as TaskAgentSnippet, g as TaskCreatePayload, h as TaskPriority, i as TaskStats, j as TaskStatus, k as TaskType, l as TaskUpdatePayload } from './data-room-Dtd9LLHf.mjs';
4
5
  export { AgentResource, ResourcesByGroup } from './types/index.mjs';
5
6
  import { ReactElement } from 'react';
6
7
  export { PlatformCtx, usePlatform, usePluginChat, usePluginDataRooms, usePluginTasks } from './hooks/index.mjs';
@@ -53,4 +54,81 @@ declare function updateInstallConfig(pluginId: string, config: InstallConfig): P
53
54
  declare function createMockPlatformContext(overrides?: Partial<PlatformContext>): PlatformContext;
54
55
  declare function withPluginProvider(element: ReactElement, platform?: Partial<PlatformContext>): ReactElement;
55
56
 
56
- export { type InstallConfig, PaletteApiError, PlatformContext, type SandboxBridge, apiFetch, apiUpload, createMockPlatformContext, createSandboxBridge, errorFromResponse, getBaseUrl, getInstallConfig, isPaletteApiError, isSandboxRuntime, setBaseUrl, updateInstallConfig, withPluginProvider };
57
+ interface DataRoomContents {
58
+ room?: DataRoom;
59
+ folders: DataRoomFolder[];
60
+ files: DataRoomFile[];
61
+ }
62
+ interface DataRoomUploadOptions {
63
+ folderId?: number | null;
64
+ contentType?: string;
65
+ }
66
+ declare class DataRoomClient {
67
+ list(): Promise<DataRoom[]>;
68
+ create(input: {
69
+ name: string;
70
+ description?: string | null;
71
+ }): Promise<DataRoom>;
72
+ get(roomId: number): Promise<DataRoomContents>;
73
+ folder(roomId: number, folderId: number): Promise<DataRoomContents>;
74
+ requestUpload(roomId: number, file: File, options?: DataRoomUploadOptions): Promise<{
75
+ upload_url: string;
76
+ blob_path: string;
77
+ file_url: string;
78
+ }>;
79
+ confirmUpload(roomId: number, file: File, upload: {
80
+ blob_path: string;
81
+ }, options?: DataRoomUploadOptions): Promise<DataRoomFile>;
82
+ uploadFile(roomId: number, file: File, options?: DataRoomUploadOptions): Promise<DataRoomFile>;
83
+ }
84
+ declare const dataRooms: DataRoomClient;
85
+
86
+ declare function uploadToSignedUrl(uploadUrl: string, file: Blob, contentType?: string): Promise<void>;
87
+ declare class StorageClient {
88
+ uploadToSignedUrl: typeof uploadToSignedUrl;
89
+ }
90
+
91
+ declare class UserClient {
92
+ private readonly ctx?;
93
+ constructor(ctx?: PlatformContext | undefined);
94
+ current(): Promise<User>;
95
+ updateProfile(input: {
96
+ name?: string;
97
+ company_name?: string | null;
98
+ }): Promise<User>;
99
+ }
100
+ declare class OrganizationClient {
101
+ private readonly ctx?;
102
+ constructor(ctx?: PlatformContext | undefined);
103
+ currentId(): number | null;
104
+ currentRole(): string | null;
105
+ listMine(): Promise<OrgSummary[]>;
106
+ }
107
+
108
+ declare function createPaletteClient(ctx?: PlatformContext): {
109
+ user: UserClient;
110
+ organization: OrganizationClient;
111
+ dataRooms: DataRoomClient;
112
+ storage: StorageClient;
113
+ config: {
114
+ get: (pluginId?: string) => Promise<InstallConfig>;
115
+ update: (values: Record<string, unknown>, pluginId?: string) => Promise<InstallConfig>;
116
+ };
117
+ permissions: {
118
+ has: (permission: string) => boolean;
119
+ hasAny: (permissions: string[]) => boolean;
120
+ hasAll: (permissions: string[]) => boolean;
121
+ };
122
+ toast: {
123
+ success: (message: string) => void | undefined;
124
+ error: (message: string) => void | undefined;
125
+ info: (message: string) => void | undefined;
126
+ };
127
+ };
128
+ type PaletteClient = ReturnType<typeof createPaletteClient>;
129
+
130
+ declare function hasPermission(ctx: PlatformContext, permission: string): boolean;
131
+ declare function hasAnyPermission(ctx: PlatformContext, permissions: string[]): boolean;
132
+ declare function hasAllPermissions(ctx: PlatformContext, permissions: string[]): boolean;
133
+
134
+ export { DataRoom, DataRoomClient, type DataRoomContents, DataRoomFile, DataRoomFolder, type DataRoomUploadOptions, type InstallConfig, OrgSummary, OrganizationClient, PaletteApiError, type PaletteClient, PlatformContext, type SandboxBridge, StorageClient, User, UserClient, apiFetch, apiUpload, createMockPlatformContext, createPaletteClient, createSandboxBridge, dataRooms, errorFromResponse, getBaseUrl, getInstallConfig, hasAllPermissions, hasAnyPermission, hasPermission, isPaletteApiError, isSandboxRuntime, setBaseUrl, updateInstallConfig, uploadToSignedUrl, withPluginProvider };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
- import { P as PlatformContext } from './plugin-DzSTKgkz.js';
2
- export { A as Agent, a as AgentConfig, b as AppCategory, c as AuthContextValue, O as OrgSummary, d as PluginAgentDefinition, e as PluginComponentProps, f as PluginManifest, g as PluginToolDefinition, U as User } from './plugin-DzSTKgkz.js';
3
- export { C as ChatAttachment, a as ChatMessage, b as ChatThread, D as DataRoom, c as DataRoomFile, d as DataRoomFolder, e as DataRoomPermission, T as Task, f as TaskAgentSnippet, g as TaskCreatePayload, h as TaskPriority, i as TaskStats, j as TaskStatus, k as TaskType, l as TaskUpdatePayload } from './data-room-BP0PjYoe.js';
1
+ import { P as PlatformContext, O as OrgSummary, U as User } from './plugin-o-qmdCBl.js';
2
+ export { A as Agent, a as AgentConfig, b as AppCategory, c as AuthContextValue, d as PluginAgentDefinition, e as PluginComponentProps, f as PluginManifest, g as PluginToolDefinition } from './plugin-o-qmdCBl.js';
3
+ import { D as DataRoom, a as DataRoomFolder, b as DataRoomFile } from './data-room-Dtd9LLHf.js';
4
+ export { C as ChatAttachment, c as ChatMessage, d as ChatThread, e as DataRoomPermission, T as Task, f as TaskAgentSnippet, g as TaskCreatePayload, h as TaskPriority, i as TaskStats, j as TaskStatus, k as TaskType, l as TaskUpdatePayload } from './data-room-Dtd9LLHf.js';
4
5
  export { AgentResource, ResourcesByGroup } from './types/index.js';
5
6
  import { ReactElement } from 'react';
6
7
  export { PlatformCtx, usePlatform, usePluginChat, usePluginDataRooms, usePluginTasks } from './hooks/index.js';
@@ -53,4 +54,81 @@ declare function updateInstallConfig(pluginId: string, config: InstallConfig): P
53
54
  declare function createMockPlatformContext(overrides?: Partial<PlatformContext>): PlatformContext;
54
55
  declare function withPluginProvider(element: ReactElement, platform?: Partial<PlatformContext>): ReactElement;
55
56
 
56
- export { type InstallConfig, PaletteApiError, PlatformContext, type SandboxBridge, apiFetch, apiUpload, createMockPlatformContext, createSandboxBridge, errorFromResponse, getBaseUrl, getInstallConfig, isPaletteApiError, isSandboxRuntime, setBaseUrl, updateInstallConfig, withPluginProvider };
57
+ interface DataRoomContents {
58
+ room?: DataRoom;
59
+ folders: DataRoomFolder[];
60
+ files: DataRoomFile[];
61
+ }
62
+ interface DataRoomUploadOptions {
63
+ folderId?: number | null;
64
+ contentType?: string;
65
+ }
66
+ declare class DataRoomClient {
67
+ list(): Promise<DataRoom[]>;
68
+ create(input: {
69
+ name: string;
70
+ description?: string | null;
71
+ }): Promise<DataRoom>;
72
+ get(roomId: number): Promise<DataRoomContents>;
73
+ folder(roomId: number, folderId: number): Promise<DataRoomContents>;
74
+ requestUpload(roomId: number, file: File, options?: DataRoomUploadOptions): Promise<{
75
+ upload_url: string;
76
+ blob_path: string;
77
+ file_url: string;
78
+ }>;
79
+ confirmUpload(roomId: number, file: File, upload: {
80
+ blob_path: string;
81
+ }, options?: DataRoomUploadOptions): Promise<DataRoomFile>;
82
+ uploadFile(roomId: number, file: File, options?: DataRoomUploadOptions): Promise<DataRoomFile>;
83
+ }
84
+ declare const dataRooms: DataRoomClient;
85
+
86
+ declare function uploadToSignedUrl(uploadUrl: string, file: Blob, contentType?: string): Promise<void>;
87
+ declare class StorageClient {
88
+ uploadToSignedUrl: typeof uploadToSignedUrl;
89
+ }
90
+
91
+ declare class UserClient {
92
+ private readonly ctx?;
93
+ constructor(ctx?: PlatformContext | undefined);
94
+ current(): Promise<User>;
95
+ updateProfile(input: {
96
+ name?: string;
97
+ company_name?: string | null;
98
+ }): Promise<User>;
99
+ }
100
+ declare class OrganizationClient {
101
+ private readonly ctx?;
102
+ constructor(ctx?: PlatformContext | undefined);
103
+ currentId(): number | null;
104
+ currentRole(): string | null;
105
+ listMine(): Promise<OrgSummary[]>;
106
+ }
107
+
108
+ declare function createPaletteClient(ctx?: PlatformContext): {
109
+ user: UserClient;
110
+ organization: OrganizationClient;
111
+ dataRooms: DataRoomClient;
112
+ storage: StorageClient;
113
+ config: {
114
+ get: (pluginId?: string) => Promise<InstallConfig>;
115
+ update: (values: Record<string, unknown>, pluginId?: string) => Promise<InstallConfig>;
116
+ };
117
+ permissions: {
118
+ has: (permission: string) => boolean;
119
+ hasAny: (permissions: string[]) => boolean;
120
+ hasAll: (permissions: string[]) => boolean;
121
+ };
122
+ toast: {
123
+ success: (message: string) => void | undefined;
124
+ error: (message: string) => void | undefined;
125
+ info: (message: string) => void | undefined;
126
+ };
127
+ };
128
+ type PaletteClient = ReturnType<typeof createPaletteClient>;
129
+
130
+ declare function hasPermission(ctx: PlatformContext, permission: string): boolean;
131
+ declare function hasAnyPermission(ctx: PlatformContext, permissions: string[]): boolean;
132
+ declare function hasAllPermissions(ctx: PlatformContext, permissions: string[]): boolean;
133
+
134
+ export { DataRoom, DataRoomClient, type DataRoomContents, DataRoomFile, DataRoomFolder, type DataRoomUploadOptions, type InstallConfig, OrgSummary, OrganizationClient, PaletteApiError, type PaletteClient, PlatformContext, type SandboxBridge, StorageClient, User, UserClient, apiFetch, apiUpload, createMockPlatformContext, createPaletteClient, createSandboxBridge, dataRooms, errorFromResponse, getBaseUrl, getInstallConfig, hasAllPermissions, hasAnyPermission, hasPermission, isPaletteApiError, isSandboxRuntime, setBaseUrl, updateInstallConfig, uploadToSignedUrl, withPluginProvider };
package/dist/index.js CHANGED
@@ -20,20 +20,30 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var src_exports = {};
22
22
  __export(src_exports, {
23
+ DataRoomClient: () => DataRoomClient,
24
+ OrganizationClient: () => OrganizationClient,
23
25
  PaletteApiError: () => PaletteApiError,
24
26
  PlatformCtx: () => PlatformCtx,
25
27
  PluginProvider: () => PluginProvider,
28
+ StorageClient: () => StorageClient,
29
+ UserClient: () => UserClient,
26
30
  apiFetch: () => apiFetch,
27
31
  apiUpload: () => apiUpload,
28
32
  createMockPlatformContext: () => createMockPlatformContext,
33
+ createPaletteClient: () => createPaletteClient,
29
34
  createSandboxBridge: () => createSandboxBridge,
35
+ dataRooms: () => dataRooms,
30
36
  errorFromResponse: () => errorFromResponse,
31
37
  getBaseUrl: () => getBaseUrl,
32
38
  getInstallConfig: () => getInstallConfig,
39
+ hasAllPermissions: () => hasAllPermissions,
40
+ hasAnyPermission: () => hasAnyPermission,
41
+ hasPermission: () => hasPermission,
33
42
  isPaletteApiError: () => isPaletteApiError,
34
43
  isSandboxRuntime: () => isSandboxRuntime,
35
44
  setBaseUrl: () => setBaseUrl,
36
45
  updateInstallConfig: () => updateInstallConfig,
46
+ uploadToSignedUrl: () => uploadToSignedUrl,
37
47
  usePlatform: () => usePlatform,
38
48
  usePluginChat: () => usePluginChat,
39
49
  usePluginDataRooms: () => usePluginDataRooms,
@@ -203,6 +213,7 @@ function createMockPlatformContext(overrides = {}) {
203
213
  orgRole: "owner",
204
214
  orgs: [],
205
215
  agents: [],
216
+ permissions: [],
206
217
  apiFetch: async () => new Response(JSON.stringify({}), { status: 200 }),
207
218
  navigate: () => {
208
219
  },
@@ -218,6 +229,164 @@ function withPluginProvider(element, platform = {}) {
218
229
  );
219
230
  }
220
231
 
232
+ // src/data-rooms.ts
233
+ var DataRoomClient = class {
234
+ async list() {
235
+ const res = await apiFetch("/api/v1/data-rooms");
236
+ return res.json();
237
+ }
238
+ async create(input) {
239
+ const res = await apiFetch("/api/v1/data-rooms", {
240
+ method: "POST",
241
+ body: JSON.stringify(input)
242
+ });
243
+ return res.json();
244
+ }
245
+ async get(roomId) {
246
+ const res = await apiFetch(`/api/v1/data-rooms/${roomId}`);
247
+ return res.json();
248
+ }
249
+ async folder(roomId, folderId) {
250
+ const res = await apiFetch(`/api/v1/data-rooms/${roomId}/folders/${folderId}`);
251
+ return res.json();
252
+ }
253
+ async requestUpload(roomId, file, options = {}) {
254
+ const res = await apiFetch(`/api/v1/data-rooms/${roomId}/files/request-upload`, {
255
+ method: "POST",
256
+ body: JSON.stringify({
257
+ filename: file.name,
258
+ content_type: options.contentType ?? file.type ?? "application/octet-stream",
259
+ file_size: file.size,
260
+ folder_id: options.folderId ?? null
261
+ })
262
+ });
263
+ return res.json();
264
+ }
265
+ async confirmUpload(roomId, file, upload, options = {}) {
266
+ const res = await apiFetch(`/api/v1/data-rooms/${roomId}/files/confirm-upload`, {
267
+ method: "POST",
268
+ body: JSON.stringify({
269
+ blob_path: upload.blob_path,
270
+ original_filename: file.name,
271
+ file_size: file.size,
272
+ mime_type: options.contentType ?? file.type ?? "application/octet-stream",
273
+ folder_id: options.folderId ?? null
274
+ })
275
+ });
276
+ return res.json();
277
+ }
278
+ async uploadFile(roomId, file, options = {}) {
279
+ const upload = await this.requestUpload(roomId, file, options);
280
+ const put = await fetch(upload.upload_url, {
281
+ method: "PUT",
282
+ headers: { "Content-Type": options.contentType ?? file.type ?? "application/octet-stream" },
283
+ body: file
284
+ });
285
+ if (!put.ok) throw new Error(`Upload failed: ${put.statusText}`);
286
+ return this.confirmUpload(roomId, file, upload, options);
287
+ }
288
+ };
289
+ var dataRooms = new DataRoomClient();
290
+
291
+ // src/permissions.ts
292
+ function hasPermission(ctx, permission) {
293
+ return ctx.permissions?.includes(permission) ?? false;
294
+ }
295
+ function hasAnyPermission(ctx, permissions) {
296
+ return permissions.some((permission) => hasPermission(ctx, permission));
297
+ }
298
+ function hasAllPermissions(ctx, permissions) {
299
+ return permissions.every((permission) => hasPermission(ctx, permission));
300
+ }
301
+
302
+ // src/storage.ts
303
+ async function uploadToSignedUrl(uploadUrl, file, contentType = "application/octet-stream") {
304
+ const res = await fetch(uploadUrl, {
305
+ method: "PUT",
306
+ headers: { "Content-Type": contentType },
307
+ body: file
308
+ });
309
+ if (!res.ok) throw new Error(`Upload failed: ${res.statusText}`);
310
+ }
311
+ var StorageClient = class {
312
+ constructor() {
313
+ this.uploadToSignedUrl = uploadToSignedUrl;
314
+ }
315
+ };
316
+
317
+ // src/user-org.ts
318
+ var UserClient = class {
319
+ constructor(ctx) {
320
+ this.ctx = ctx;
321
+ }
322
+ async current() {
323
+ if (this.ctx?.user) return this.ctx.user;
324
+ const res = await apiFetch("/api/v1/auth/me");
325
+ return res.json();
326
+ }
327
+ async updateProfile(input) {
328
+ const res = await apiFetch("/api/v1/auth/profile", {
329
+ method: "PATCH",
330
+ body: JSON.stringify(input)
331
+ });
332
+ return res.json();
333
+ }
334
+ };
335
+ var OrganizationClient = class {
336
+ constructor(ctx) {
337
+ this.ctx = ctx;
338
+ }
339
+ currentId() {
340
+ return this.ctx?.organizationId ?? null;
341
+ }
342
+ currentRole() {
343
+ return this.ctx?.orgRole ?? null;
344
+ }
345
+ async listMine() {
346
+ if (this.ctx?.orgs?.length) return this.ctx.orgs;
347
+ const res = await apiFetch("/api/v1/auth/my-orgs");
348
+ return res.json();
349
+ }
350
+ };
351
+
352
+ // src/palette-client.ts
353
+ function createPaletteClient(ctx) {
354
+ const defaultPluginId = () => {
355
+ if (ctx?.pluginId) return ctx.pluginId;
356
+ if (typeof window === "undefined") return "";
357
+ const match = window.location.pathname.match(/\/apps\/([^/?#]+)/);
358
+ return match ? decodeURIComponent(match[1]) : "";
359
+ };
360
+ return {
361
+ user: new UserClient(ctx),
362
+ organization: new OrganizationClient(ctx),
363
+ dataRooms: new DataRoomClient(),
364
+ storage: new StorageClient(),
365
+ config: {
366
+ get: (pluginId = ctx?.pluginId ?? "") => {
367
+ const resolved = pluginId || defaultPluginId();
368
+ if (!resolved) throw new Error("pluginId is required to read install config");
369
+ return getInstallConfig(resolved);
370
+ },
371
+ update: (values, pluginId = ctx?.pluginId ?? "") => {
372
+ const resolved = pluginId || defaultPluginId();
373
+ if (!resolved) throw new Error("pluginId is required to update install config");
374
+ return updateInstallConfig(resolved, values);
375
+ }
376
+ },
377
+ permissions: {
378
+ has: (permission) => ctx ? hasPermission(ctx, permission) : false,
379
+ hasAny: (permissions) => ctx ? hasAnyPermission(ctx, permissions) : false,
380
+ hasAll: (permissions) => ctx ? hasAllPermissions(ctx, permissions) : false
381
+ },
382
+ toast: {
383
+ success: (message) => ctx?.showToast(message, "success"),
384
+ error: (message) => ctx?.showToast(message, "error"),
385
+ info: (message) => ctx?.showToast(message, "info")
386
+ }
387
+ };
388
+ }
389
+
221
390
  // src/hooks/use-plugin-tasks.ts
222
391
  var import_react3 = require("react");
223
392
  function usePluginTasks(agentId) {
@@ -407,20 +576,30 @@ function usePluginChat(agentId) {
407
576
  }
408
577
  // Annotate the CommonJS export names for ESM import in node:
409
578
  0 && (module.exports = {
579
+ DataRoomClient,
580
+ OrganizationClient,
410
581
  PaletteApiError,
411
582
  PlatformCtx,
412
583
  PluginProvider,
584
+ StorageClient,
585
+ UserClient,
413
586
  apiFetch,
414
587
  apiUpload,
415
588
  createMockPlatformContext,
589
+ createPaletteClient,
416
590
  createSandboxBridge,
591
+ dataRooms,
417
592
  errorFromResponse,
418
593
  getBaseUrl,
419
594
  getInstallConfig,
595
+ hasAllPermissions,
596
+ hasAnyPermission,
597
+ hasPermission,
420
598
  isPaletteApiError,
421
599
  isSandboxRuntime,
422
600
  setBaseUrl,
423
601
  updateInstallConfig,
602
+ uploadToSignedUrl,
424
603
  usePlatform,
425
604
  usePluginChat,
426
605
  usePluginDataRooms,
package/dist/index.mjs CHANGED
@@ -159,6 +159,7 @@ function createMockPlatformContext(overrides = {}) {
159
159
  orgRole: "owner",
160
160
  orgs: [],
161
161
  agents: [],
162
+ permissions: [],
162
163
  apiFetch: async () => new Response(JSON.stringify({}), { status: 200 }),
163
164
  navigate: () => {
164
165
  },
@@ -174,6 +175,164 @@ function withPluginProvider(element, platform = {}) {
174
175
  );
175
176
  }
176
177
 
178
+ // src/data-rooms.ts
179
+ var DataRoomClient = class {
180
+ async list() {
181
+ const res = await apiFetch("/api/v1/data-rooms");
182
+ return res.json();
183
+ }
184
+ async create(input) {
185
+ const res = await apiFetch("/api/v1/data-rooms", {
186
+ method: "POST",
187
+ body: JSON.stringify(input)
188
+ });
189
+ return res.json();
190
+ }
191
+ async get(roomId) {
192
+ const res = await apiFetch(`/api/v1/data-rooms/${roomId}`);
193
+ return res.json();
194
+ }
195
+ async folder(roomId, folderId) {
196
+ const res = await apiFetch(`/api/v1/data-rooms/${roomId}/folders/${folderId}`);
197
+ return res.json();
198
+ }
199
+ async requestUpload(roomId, file, options = {}) {
200
+ const res = await apiFetch(`/api/v1/data-rooms/${roomId}/files/request-upload`, {
201
+ method: "POST",
202
+ body: JSON.stringify({
203
+ filename: file.name,
204
+ content_type: options.contentType ?? file.type ?? "application/octet-stream",
205
+ file_size: file.size,
206
+ folder_id: options.folderId ?? null
207
+ })
208
+ });
209
+ return res.json();
210
+ }
211
+ async confirmUpload(roomId, file, upload, options = {}) {
212
+ const res = await apiFetch(`/api/v1/data-rooms/${roomId}/files/confirm-upload`, {
213
+ method: "POST",
214
+ body: JSON.stringify({
215
+ blob_path: upload.blob_path,
216
+ original_filename: file.name,
217
+ file_size: file.size,
218
+ mime_type: options.contentType ?? file.type ?? "application/octet-stream",
219
+ folder_id: options.folderId ?? null
220
+ })
221
+ });
222
+ return res.json();
223
+ }
224
+ async uploadFile(roomId, file, options = {}) {
225
+ const upload = await this.requestUpload(roomId, file, options);
226
+ const put = await fetch(upload.upload_url, {
227
+ method: "PUT",
228
+ headers: { "Content-Type": options.contentType ?? file.type ?? "application/octet-stream" },
229
+ body: file
230
+ });
231
+ if (!put.ok) throw new Error(`Upload failed: ${put.statusText}`);
232
+ return this.confirmUpload(roomId, file, upload, options);
233
+ }
234
+ };
235
+ var dataRooms = new DataRoomClient();
236
+
237
+ // src/permissions.ts
238
+ function hasPermission(ctx, permission) {
239
+ return ctx.permissions?.includes(permission) ?? false;
240
+ }
241
+ function hasAnyPermission(ctx, permissions) {
242
+ return permissions.some((permission) => hasPermission(ctx, permission));
243
+ }
244
+ function hasAllPermissions(ctx, permissions) {
245
+ return permissions.every((permission) => hasPermission(ctx, permission));
246
+ }
247
+
248
+ // src/storage.ts
249
+ async function uploadToSignedUrl(uploadUrl, file, contentType = "application/octet-stream") {
250
+ const res = await fetch(uploadUrl, {
251
+ method: "PUT",
252
+ headers: { "Content-Type": contentType },
253
+ body: file
254
+ });
255
+ if (!res.ok) throw new Error(`Upload failed: ${res.statusText}`);
256
+ }
257
+ var StorageClient = class {
258
+ constructor() {
259
+ this.uploadToSignedUrl = uploadToSignedUrl;
260
+ }
261
+ };
262
+
263
+ // src/user-org.ts
264
+ var UserClient = class {
265
+ constructor(ctx) {
266
+ this.ctx = ctx;
267
+ }
268
+ async current() {
269
+ if (this.ctx?.user) return this.ctx.user;
270
+ const res = await apiFetch("/api/v1/auth/me");
271
+ return res.json();
272
+ }
273
+ async updateProfile(input) {
274
+ const res = await apiFetch("/api/v1/auth/profile", {
275
+ method: "PATCH",
276
+ body: JSON.stringify(input)
277
+ });
278
+ return res.json();
279
+ }
280
+ };
281
+ var OrganizationClient = class {
282
+ constructor(ctx) {
283
+ this.ctx = ctx;
284
+ }
285
+ currentId() {
286
+ return this.ctx?.organizationId ?? null;
287
+ }
288
+ currentRole() {
289
+ return this.ctx?.orgRole ?? null;
290
+ }
291
+ async listMine() {
292
+ if (this.ctx?.orgs?.length) return this.ctx.orgs;
293
+ const res = await apiFetch("/api/v1/auth/my-orgs");
294
+ return res.json();
295
+ }
296
+ };
297
+
298
+ // src/palette-client.ts
299
+ function createPaletteClient(ctx) {
300
+ const defaultPluginId = () => {
301
+ if (ctx?.pluginId) return ctx.pluginId;
302
+ if (typeof window === "undefined") return "";
303
+ const match = window.location.pathname.match(/\/apps\/([^/?#]+)/);
304
+ return match ? decodeURIComponent(match[1]) : "";
305
+ };
306
+ return {
307
+ user: new UserClient(ctx),
308
+ organization: new OrganizationClient(ctx),
309
+ dataRooms: new DataRoomClient(),
310
+ storage: new StorageClient(),
311
+ config: {
312
+ get: (pluginId = ctx?.pluginId ?? "") => {
313
+ const resolved = pluginId || defaultPluginId();
314
+ if (!resolved) throw new Error("pluginId is required to read install config");
315
+ return getInstallConfig(resolved);
316
+ },
317
+ update: (values, pluginId = ctx?.pluginId ?? "") => {
318
+ const resolved = pluginId || defaultPluginId();
319
+ if (!resolved) throw new Error("pluginId is required to update install config");
320
+ return updateInstallConfig(resolved, values);
321
+ }
322
+ },
323
+ permissions: {
324
+ has: (permission) => ctx ? hasPermission(ctx, permission) : false,
325
+ hasAny: (permissions) => ctx ? hasAnyPermission(ctx, permissions) : false,
326
+ hasAll: (permissions) => ctx ? hasAllPermissions(ctx, permissions) : false
327
+ },
328
+ toast: {
329
+ success: (message) => ctx?.showToast(message, "success"),
330
+ error: (message) => ctx?.showToast(message, "error"),
331
+ info: (message) => ctx?.showToast(message, "info")
332
+ }
333
+ };
334
+ }
335
+
177
336
  // src/hooks/use-plugin-tasks.ts
178
337
  import { useCallback, useEffect, useState } from "react";
179
338
  function usePluginTasks(agentId) {
@@ -362,20 +521,30 @@ function usePluginChat(agentId) {
362
521
  };
363
522
  }
364
523
  export {
524
+ DataRoomClient,
525
+ OrganizationClient,
365
526
  PaletteApiError,
366
527
  PlatformCtx,
367
528
  PluginProvider,
529
+ StorageClient,
530
+ UserClient,
368
531
  apiFetch,
369
532
  apiUpload,
370
533
  createMockPlatformContext,
534
+ createPaletteClient,
371
535
  createSandboxBridge,
536
+ dataRooms,
372
537
  errorFromResponse,
373
538
  getBaseUrl,
374
539
  getInstallConfig,
540
+ hasAllPermissions,
541
+ hasAnyPermission,
542
+ hasPermission,
375
543
  isPaletteApiError,
376
544
  isSandboxRuntime,
377
545
  setBaseUrl,
378
546
  updateInstallConfig,
547
+ uploadToSignedUrl,
379
548
  usePlatform,
380
549
  usePluginChat,
381
550
  usePluginDataRooms,
@@ -141,6 +141,8 @@ interface PlatformContext {
141
141
  user: User;
142
142
  /** Current organization ID */
143
143
  organizationId: number;
144
+ /** Current plugin ID */
145
+ pluginId?: string;
144
146
  /** User's org role */
145
147
  orgRole: string | null;
146
148
  /** Available orgs */
@@ -153,6 +155,8 @@ interface PlatformContext {
153
155
  navigate: (path: string) => void;
154
156
  /** Show a toast notification */
155
157
  showToast: (message: string, type?: "success" | "error" | "info") => void;
158
+ /** Permissions declared for the current plugin install/runtime */
159
+ permissions?: string[];
156
160
  }
157
161
  /** Props passed to a plugin's root component */
158
162
  interface PluginComponentProps {
@@ -141,6 +141,8 @@ interface PlatformContext {
141
141
  user: User;
142
142
  /** Current organization ID */
143
143
  organizationId: number;
144
+ /** Current plugin ID */
145
+ pluginId?: string;
144
146
  /** User's org role */
145
147
  orgRole: string | null;
146
148
  /** Available orgs */
@@ -153,6 +155,8 @@ interface PlatformContext {
153
155
  navigate: (path: string) => void;
154
156
  /** Show a toast notification */
155
157
  showToast: (message: string, type?: "success" | "error" | "info") => void;
158
+ /** Permissions declared for the current plugin install/runtime */
159
+ permissions?: string[];
156
160
  }
157
161
  /** Props passed to a plugin's root component */
158
162
  interface PluginComponentProps {
@@ -1,5 +1,5 @@
1
- export { A as Agent, a as AgentConfig, b as AppCategory, c as AuthContextValue, O as OrgSummary, P as PlatformContext, d as PluginAgentDefinition, e as PluginComponentProps, f as PluginManifest, g as PluginToolDefinition, U as User } from '../plugin-DzSTKgkz.mjs';
2
- export { C as ChatAttachment, a as ChatMessage, b as ChatThread, D as DataRoom, c as DataRoomFile, d as DataRoomFolder, e as DataRoomPermission, T as Task, f as TaskAgentSnippet, g as TaskCreatePayload, h as TaskPriority, i as TaskStats, j as TaskStatus, k as TaskType, l as TaskUpdatePayload } from '../data-room-BP0PjYoe.mjs';
1
+ export { A as Agent, a as AgentConfig, b as AppCategory, c as AuthContextValue, O as OrgSummary, P as PlatformContext, d as PluginAgentDefinition, e as PluginComponentProps, f as PluginManifest, g as PluginToolDefinition, U as User } from '../plugin-o-qmdCBl.mjs';
2
+ export { C as ChatAttachment, c as ChatMessage, d as ChatThread, D as DataRoom, b as DataRoomFile, a as DataRoomFolder, e as DataRoomPermission, T as Task, f as TaskAgentSnippet, g as TaskCreatePayload, h as TaskPriority, i as TaskStats, j as TaskStatus, k as TaskType, l as TaskUpdatePayload } from '../data-room-Dtd9LLHf.mjs';
3
3
 
4
4
  interface AgentResource {
5
5
  id: number;
@@ -1,5 +1,5 @@
1
- export { A as Agent, a as AgentConfig, b as AppCategory, c as AuthContextValue, O as OrgSummary, P as PlatformContext, d as PluginAgentDefinition, e as PluginComponentProps, f as PluginManifest, g as PluginToolDefinition, U as User } from '../plugin-DzSTKgkz.js';
2
- export { C as ChatAttachment, a as ChatMessage, b as ChatThread, D as DataRoom, c as DataRoomFile, d as DataRoomFolder, e as DataRoomPermission, T as Task, f as TaskAgentSnippet, g as TaskCreatePayload, h as TaskPriority, i as TaskStats, j as TaskStatus, k as TaskType, l as TaskUpdatePayload } from '../data-room-BP0PjYoe.js';
1
+ export { A as Agent, a as AgentConfig, b as AppCategory, c as AuthContextValue, O as OrgSummary, P as PlatformContext, d as PluginAgentDefinition, e as PluginComponentProps, f as PluginManifest, g as PluginToolDefinition, U as User } from '../plugin-o-qmdCBl.js';
2
+ export { C as ChatAttachment, c as ChatMessage, d as ChatThread, D as DataRoom, b as DataRoomFile, a as DataRoomFolder, e as DataRoomPermission, T as Task, f as TaskAgentSnippet, g as TaskCreatePayload, h as TaskPriority, i as TaskStats, j as TaskStatus, k as TaskType, l as TaskUpdatePayload } from '../data-room-Dtd9LLHf.js';
3
3
 
4
4
  interface AgentResource {
5
5
  id: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@palettelab/sdk",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Palette Platform SDK for building plugins and apps",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",