@palettelab/sdk 0.1.14 → 0.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -21,8 +21,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var src_exports = {};
22
22
  __export(src_exports, {
23
23
  DataRoomClient: () => DataRoomClient,
24
+ Link: () => Link,
24
25
  OrganizationClient: () => OrganizationClient,
25
26
  PaletteApiError: () => PaletteApiError,
27
+ PaletteAppRouter: () => PaletteAppRouter,
26
28
  PlatformCtx: () => PlatformCtx,
27
29
  PluginProvider: () => PluginProvider,
28
30
  StorageClient: () => StorageClient,
@@ -42,15 +44,20 @@ __export(src_exports, {
42
44
  isPaletteApiError: () => isPaletteApiError,
43
45
  isSandboxRuntime: () => isSandboxRuntime,
44
46
  normalizePaletteLanguage: () => normalizePaletteLanguage,
47
+ notFound: () => notFound,
45
48
  setBaseUrl: () => setBaseUrl,
46
49
  translate: () => translate,
47
50
  updateInstallConfig: () => updateInstallConfig,
48
51
  uploadToSignedUrl: () => uploadToSignedUrl,
52
+ useParams: () => useParams,
53
+ usePathname: () => usePathname,
49
54
  usePlatform: () => usePlatform,
50
55
  usePluginChat: () => usePluginChat,
51
56
  usePluginDataRooms: () => usePluginDataRooms,
52
57
  usePluginTasks: () => usePluginTasks,
53
58
  usePluginTranslations: () => usePluginTranslations,
59
+ useRouter: () => useRouter,
60
+ useSearchParams: () => useSearchParams,
54
61
  withPluginProvider: () => withPluginProvider
55
62
  });
56
63
  module.exports = __toCommonJS(src_exports);
@@ -228,6 +235,7 @@ function createMockPlatformContext(overrides = {}) {
228
235
  apiFetch: async () => new Response(JSON.stringify({}), { status: 200 }),
229
236
  navigate: () => {
230
237
  },
238
+ routePath: "/",
231
239
  showToast: () => {
232
240
  },
233
241
  ...overrides
@@ -359,6 +367,8 @@ function hasAllPermissions(ctx, permissions) {
359
367
  }
360
368
 
361
369
  // src/storage.ts
370
+ var DEFAULT_CHUNK_SIZE = 8 * 1024 * 1024;
371
+ var MIN_CHUNK_SIZE = 256 * 1024;
362
372
  async function uploadToSignedUrl(uploadUrl, file, contentType = "application/octet-stream") {
363
373
  const res = await fetch(uploadUrl, {
364
374
  method: "PUT",
@@ -367,10 +377,178 @@ async function uploadToSignedUrl(uploadUrl, file, contentType = "application/oct
367
377
  });
368
378
  if (!res.ok) throw new Error(`Upload failed: ${res.statusText}`);
369
379
  }
380
+ function normalizeChunkSize(value) {
381
+ const raw = Math.max(value || DEFAULT_CHUNK_SIZE, MIN_CHUNK_SIZE);
382
+ return Math.ceil(raw / MIN_CHUNK_SIZE) * MIN_CHUNK_SIZE;
383
+ }
384
+ function defaultPluginId() {
385
+ if (typeof window === "undefined") return "";
386
+ const match = window.location.pathname.match(/\/apps\/([^/?#]+)/);
387
+ return match ? decodeURIComponent(match[1]) : "";
388
+ }
389
+ function fileFingerprint(pluginId, file, key) {
390
+ return [pluginId, key || file.name, file.size, file.lastModified].join(":");
391
+ }
392
+ function sessionStorageKey(pluginId, fingerprint) {
393
+ return `palette:storage-upload:${pluginId}:${fingerprint}`;
394
+ }
395
+ function readStoredSession(pluginId, fingerprint) {
396
+ if (typeof window === "undefined") return null;
397
+ try {
398
+ const raw = window.localStorage.getItem(sessionStorageKey(pluginId, fingerprint));
399
+ if (!raw) return null;
400
+ const session = JSON.parse(raw);
401
+ return session.plugin_id === pluginId && session.fingerprint === fingerprint ? session : null;
402
+ } catch {
403
+ return null;
404
+ }
405
+ }
406
+ function writeStoredSession(pluginId, fingerprint, session) {
407
+ if (typeof window === "undefined") return;
408
+ const stored = { ...session, plugin_id: pluginId, fingerprint, updated_at: Date.now() };
409
+ window.localStorage.setItem(sessionStorageKey(pluginId, fingerprint), JSON.stringify(stored));
410
+ }
411
+ function clearStoredSession(pluginId, fingerprint) {
412
+ if (typeof window === "undefined") return;
413
+ window.localStorage.removeItem(sessionStorageKey(pluginId, fingerprint));
414
+ }
415
+ function absoluteApiUrl(pathOrUrl) {
416
+ return /^https?:\/\//i.test(pathOrUrl) ? pathOrUrl : `${getBaseUrl()}${pathOrUrl}`;
417
+ }
418
+ function isPaletteApiUpload(url) {
419
+ return url.startsWith(getBaseUrl()) || url.startsWith("/");
420
+ }
421
+ function report(loaded, total, chunkIndex, chunkCount, state, onProgress) {
422
+ onProgress?.({
423
+ loaded,
424
+ total,
425
+ percentage: total > 0 ? Math.min(100, Math.round(loaded / total * 1e4) / 100) : 100,
426
+ chunkIndex,
427
+ chunkCount,
428
+ state
429
+ });
430
+ }
431
+ function xhrPut(url, body, headers, signal, onUploadProgress) {
432
+ return new Promise((resolve, reject) => {
433
+ const xhr = new XMLHttpRequest();
434
+ xhr.open("PUT", absoluteApiUrl(url), true);
435
+ xhr.withCredentials = isPaletteApiUpload(url);
436
+ for (const [key, value] of Object.entries(headers)) xhr.setRequestHeader(key, value);
437
+ xhr.upload.onprogress = (event) => {
438
+ if (event.lengthComputable) onUploadProgress?.(event.loaded);
439
+ };
440
+ xhr.onload = () => {
441
+ const ok = [200, 201, 204, 308].includes(xhr.status);
442
+ if (!ok) reject(new Error(`Upload failed: ${xhr.status} ${xhr.statusText}`));
443
+ else resolve({ status: xhr.status, range: xhr.getResponseHeader("Range") });
444
+ };
445
+ xhr.onerror = () => reject(new Error("Upload failed"));
446
+ xhr.onabort = () => reject(new DOMException("Upload aborted", "AbortError"));
447
+ if (signal) {
448
+ if (signal.aborted) {
449
+ xhr.abort();
450
+ return;
451
+ }
452
+ signal.addEventListener("abort", () => xhr.abort(), { once: true });
453
+ }
454
+ xhr.send(body);
455
+ });
456
+ }
457
+ function uploadedFromRange(range) {
458
+ if (!range) return 0;
459
+ const match = range.match(/bytes=0-(\d+)/);
460
+ return match ? Number(match[1]) + 1 : 0;
461
+ }
462
+ async function queryGcsOffset(session) {
463
+ try {
464
+ const result = await xhrPut(session.upload_url, new Blob([]), {
465
+ "Content-Range": `bytes */${session.size}`
466
+ });
467
+ if ([200, 201, 204].includes(result.status)) return session.size;
468
+ return uploadedFromRange(result.range);
469
+ } catch {
470
+ return 0;
471
+ }
472
+ }
473
+ async function queryLocalOffset(session) {
474
+ const res = await fetch(absoluteApiUrl(session.status_url), { credentials: "include" });
475
+ if (!res.ok) return 0;
476
+ const body = await res.json();
477
+ return Number(body.uploaded_bytes || 0);
478
+ }
479
+ async function queryOffset(session) {
480
+ if (session.mode === "local_resumable") return queryLocalOffset(session);
481
+ return queryGcsOffset(session);
482
+ }
370
483
  var StorageClient = class {
371
- constructor() {
484
+ constructor(ctx) {
485
+ this.ctx = ctx;
372
486
  this.uploadToSignedUrl = uploadToSignedUrl;
373
487
  }
488
+ pluginId(explicit) {
489
+ const resolved = explicit || this.ctx?.pluginId || defaultPluginId();
490
+ if (!resolved) throw new Error("pluginId is required for app storage uploads");
491
+ return resolved;
492
+ }
493
+ async createSession(pluginId, file, options) {
494
+ const res = await (this.ctx?.apiFetch || apiFetch)(`/api/v1/app-storage/${encodeURIComponent(pluginId)}/uploads`, {
495
+ method: "POST",
496
+ body: JSON.stringify({
497
+ filename: file.name,
498
+ content_type: options.contentType || file.type || "application/octet-stream",
499
+ size: file.size,
500
+ key: options.key || null,
501
+ resumable: options.resumable ?? true,
502
+ chunk_size: normalizeChunkSize(options.chunkSize)
503
+ })
504
+ });
505
+ return res.json();
506
+ }
507
+ async upload(file, options = {}) {
508
+ const pluginId = this.pluginId(options.pluginId);
509
+ const fingerprint = fileFingerprint(pluginId, file, options.key);
510
+ const stored = options.resumable === false ? null : readStoredSession(pluginId, fingerprint);
511
+ const session = stored || await this.createSession(pluginId, file, options);
512
+ writeStoredSession(pluginId, fingerprint, session);
513
+ const chunkSize = normalizeChunkSize(options.chunkSize || session.chunk_size);
514
+ const chunkCount = Math.max(1, Math.ceil(file.size / chunkSize));
515
+ let offset = stored ? await queryOffset(session) : 0;
516
+ report(offset, file.size, Math.floor(offset / chunkSize), chunkCount, "starting", options.onProgress);
517
+ while (offset < file.size) {
518
+ if (options.signal?.aborted) throw new DOMException("Upload aborted", "AbortError");
519
+ const start = offset;
520
+ const end = Math.min(file.size, start + chunkSize) - 1;
521
+ const chunk = file.slice(start, end + 1);
522
+ const chunkIndex = Math.floor(start / chunkSize) + 1;
523
+ const lastReportedBase = start;
524
+ await xhrPut(
525
+ session.upload_url,
526
+ chunk,
527
+ {
528
+ "Content-Type": session.content_type,
529
+ "Content-Range": `bytes ${start}-${end}/${file.size}`
530
+ },
531
+ options.signal,
532
+ (loaded) => report(lastReportedBase + loaded, file.size, chunkIndex, chunkCount, "uploading", options.onProgress)
533
+ );
534
+ offset = end + 1;
535
+ report(offset, file.size, chunkIndex, chunkCount, offset >= file.size ? "complete" : "uploading", options.onProgress);
536
+ writeStoredSession(pluginId, fingerprint, session);
537
+ }
538
+ clearStoredSession(pluginId, fingerprint);
539
+ return {
540
+ uploadId: session.upload_id,
541
+ mode: session.mode,
542
+ bucket: session.bucket,
543
+ objectPath: session.object_path,
544
+ fileUrl: session.file_url,
545
+ contentType: session.content_type,
546
+ size: session.size
547
+ };
548
+ }
549
+ async resume(file, options = {}) {
550
+ return this.upload(file, { ...options, resumable: true });
551
+ }
374
552
  };
375
553
 
376
554
  // src/user-org.ts
@@ -448,7 +626,7 @@ var OrganizationClient = class {
448
626
 
449
627
  // src/palette-client.ts
450
628
  function createPaletteClient(ctx) {
451
- const defaultPluginId = () => {
629
+ const defaultPluginId2 = () => {
452
630
  if (ctx?.pluginId) return ctx.pluginId;
453
631
  if (typeof window === "undefined") return "";
454
632
  const match = window.location.pathname.match(/\/apps\/([^/?#]+)/);
@@ -458,15 +636,15 @@ function createPaletteClient(ctx) {
458
636
  user: new UserClient(ctx),
459
637
  organization: new OrganizationClient(ctx),
460
638
  dataRooms: new DataRoomClient(),
461
- storage: new StorageClient(),
639
+ storage: new StorageClient(ctx),
462
640
  config: {
463
641
  get: (pluginId = ctx?.pluginId ?? "") => {
464
- const resolved = pluginId || defaultPluginId();
642
+ const resolved = pluginId || defaultPluginId2();
465
643
  if (!resolved) throw new Error("pluginId is required to read install config");
466
644
  return getInstallConfig(resolved);
467
645
  },
468
646
  update: (values, pluginId = ctx?.pluginId ?? "") => {
469
- const resolved = pluginId || defaultPluginId();
647
+ const resolved = pluginId || defaultPluginId2();
470
648
  if (!resolved) throw new Error("pluginId is required to update install config");
471
649
  return updateInstallConfig(resolved, values);
472
650
  }
@@ -547,14 +725,207 @@ function usePluginTranslations(resources, options = {}) {
547
725
  };
548
726
  }
549
727
 
550
- // src/hooks/use-plugin-tasks.ts
728
+ // src/router.tsx
551
729
  var import_react4 = require("react");
730
+ var RouterCtx = (0, import_react4.createContext)(null);
731
+ var NOT_FOUND = /* @__PURE__ */ Symbol.for("palette.router.not-found");
732
+ function notFound() {
733
+ throw Object.assign(new Error("Palette route not found"), { code: NOT_FOUND });
734
+ }
735
+ function normalizePath(path) {
736
+ const clean = String(path || "/").split("#")[0].split("?")[0] || "/";
737
+ return `/${clean.replace(/^\/+/, "").replace(/\/+$/, "")}`.replace(/^\/$/, "/");
738
+ }
739
+ function splitPath(path) {
740
+ return normalizePath(path).split("/").filter(Boolean).map(decodeURIComponent);
741
+ }
742
+ function routeScore(route) {
743
+ if (typeof route.score === "number") return route.score;
744
+ return route.segments.reduce((score, segment) => {
745
+ if (segment.kind === "static") return score + 10;
746
+ if (segment.kind === "dynamic") return score + 5;
747
+ return score + (segment.optional ? 1 : 2);
748
+ }, route.segments.length);
749
+ }
750
+ function matchRoute(route, path) {
751
+ const parts = splitPath(path);
752
+ const params = {};
753
+ let index = 0;
754
+ for (const segment of route.segments) {
755
+ if (segment.kind === "catchAll") {
756
+ const rest = parts.slice(index);
757
+ if (!segment.optional && rest.length === 0) return null;
758
+ params[segment.name] = rest;
759
+ index = parts.length;
760
+ break;
761
+ }
762
+ const value = parts[index];
763
+ if (value === void 0) return null;
764
+ if (segment.kind === "static") {
765
+ if (value !== segment.value) return null;
766
+ } else {
767
+ params[segment.name] = value;
768
+ }
769
+ index += 1;
770
+ }
771
+ return index === parts.length ? params : null;
772
+ }
773
+ function currentPluginPath(pluginId, routePath) {
774
+ if (routePath) return normalizePath(routePath);
775
+ if (typeof window === "undefined") return "/";
776
+ const path = window.location.pathname;
777
+ if (pluginId) {
778
+ const prefix = `/apps/${pluginId}`;
779
+ if (path === prefix) return "/";
780
+ if (path.startsWith(`${prefix}/`)) return normalizePath(path.slice(prefix.length));
781
+ }
782
+ return normalizePath(path);
783
+ }
784
+ function currentSearchParams() {
785
+ if (typeof window === "undefined") return new URLSearchParams();
786
+ return new URLSearchParams(window.location.search);
787
+ }
788
+ var PaletteRouteErrorBoundary = class extends import_react4.Component {
789
+ constructor() {
790
+ super(...arguments);
791
+ this.state = { error: null };
792
+ this.reset = () => this.setState({ error: null });
793
+ }
794
+ static getDerivedStateFromError(error) {
795
+ return { error };
796
+ }
797
+ componentDidCatch(_error, _info) {
798
+ }
799
+ render() {
800
+ const error = this.state.error;
801
+ if (!error) return this.props.children;
802
+ if (error.code === NOT_FOUND && this.props.notFound) {
803
+ return (0, import_react4.createElement)(this.props.notFound);
804
+ }
805
+ if (this.props.fallback) {
806
+ return (0, import_react4.createElement)(this.props.fallback, { error, reset: this.reset });
807
+ }
808
+ throw error;
809
+ }
810
+ };
811
+ function renderRoute(route) {
812
+ const page = (0, import_react4.createElement)(route.page);
813
+ const wrapped = (route.layouts || []).reduceRight(
814
+ (children, Layout) => (0, import_react4.createElement)(Layout, null, children),
815
+ page
816
+ );
817
+ return (0, import_react4.createElement)(
818
+ PaletteRouteErrorBoundary,
819
+ { fallback: route.error, notFound: route.notFound },
820
+ wrapped
821
+ );
822
+ }
823
+ function PaletteAppRouter({
824
+ routes,
825
+ notFound: NotFound
826
+ }) {
827
+ const platform = usePlatform();
828
+ const [location, setLocation] = (0, import_react4.useState)(() => ({
829
+ pathname: currentPluginPath(platform.pluginId, platform.routePath),
830
+ searchParams: currentSearchParams()
831
+ }));
832
+ (0, import_react4.useEffect)(() => {
833
+ setLocation({
834
+ pathname: currentPluginPath(platform.pluginId, platform.routePath),
835
+ searchParams: currentSearchParams()
836
+ });
837
+ }, [platform.pluginId, platform.routePath]);
838
+ (0, import_react4.useEffect)(() => {
839
+ const sync = () => setLocation({
840
+ pathname: currentPluginPath(platform.pluginId, platform.routePath),
841
+ searchParams: currentSearchParams()
842
+ });
843
+ window.addEventListener("popstate", sync);
844
+ return () => window.removeEventListener("popstate", sync);
845
+ }, [platform.pluginId, platform.routePath]);
846
+ const sortedRoutes = (0, import_react4.useMemo)(
847
+ () => [...routes].sort((a, b) => routeScore(b) - routeScore(a)),
848
+ [routes]
849
+ );
850
+ const matched = (0, import_react4.useMemo)(() => {
851
+ for (const route of sortedRoutes) {
852
+ const params = matchRoute(route, location.pathname);
853
+ if (params) return { route, params };
854
+ }
855
+ return null;
856
+ }, [location.pathname, sortedRoutes]);
857
+ const navigate = (0, import_react4.useCallback)((target, replace = false) => {
858
+ const [pathPart, queryPart = ""] = String(target || "/").split("?");
859
+ const pathname = normalizePath(pathPart);
860
+ const next = `${pathname}${queryPart ? `?${queryPart}` : ""}`;
861
+ setLocation({ pathname, searchParams: new URLSearchParams(queryPart) });
862
+ const currentPath = typeof window === "undefined" ? "" : window.location.pathname;
863
+ const inPalettePath = platform.pluginId && (currentPath.startsWith(`/apps/${platform.pluginId}`) || platform.routePath !== void 0);
864
+ const osPath = inPalettePath && platform.pluginId ? `/apps/${platform.pluginId}${pathname === "/" ? "" : pathname}${queryPart ? `?${queryPart}` : ""}` : next;
865
+ if (replace && typeof window !== "undefined") window.history.replaceState(null, "", osPath);
866
+ else platform.navigate(osPath);
867
+ }, [platform]);
868
+ const state = (0, import_react4.useMemo)(() => ({
869
+ pathname: location.pathname,
870
+ searchParams: location.searchParams,
871
+ params: matched?.params || {},
872
+ push: (path) => navigate(path, false),
873
+ replace: (path) => navigate(path, true)
874
+ }), [location.pathname, location.searchParams, matched?.params, navigate]);
875
+ const content = matched ? renderRoute(matched.route) : NotFound ? (0, import_react4.createElement)(NotFound) : (0, import_react4.createElement)("div", null, "Page not found");
876
+ return (0, import_react4.createElement)(RouterCtx.Provider, { value: state }, content);
877
+ }
878
+ function useRouterState() {
879
+ const value = (0, import_react4.useContext)(RouterCtx);
880
+ if (!value) throw new Error("Palette app router hooks must be used inside PaletteAppRouter");
881
+ return value;
882
+ }
883
+ function useRouter() {
884
+ const { push, replace } = useRouterState();
885
+ return { push, replace, back: () => window.history.back(), forward: () => window.history.forward() };
886
+ }
887
+ function usePathname() {
888
+ return useRouterState().pathname;
889
+ }
890
+ function useSearchParams() {
891
+ return useRouterState().searchParams;
892
+ }
893
+ function useParams() {
894
+ return useRouterState().params;
895
+ }
896
+ function Link({
897
+ href,
898
+ replace,
899
+ onClick,
900
+ children,
901
+ ...props
902
+ }) {
903
+ const router = useRouter();
904
+ return (0, import_react4.createElement)(
905
+ "a",
906
+ {
907
+ ...props,
908
+ href,
909
+ onClick: (event) => {
910
+ onClick?.(event);
911
+ if (event.defaultPrevented || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
912
+ event.preventDefault();
913
+ if (replace) router.replace(href);
914
+ else router.push(href);
915
+ }
916
+ },
917
+ children
918
+ );
919
+ }
920
+
921
+ // src/hooks/use-plugin-tasks.ts
922
+ var import_react5 = require("react");
552
923
  function usePluginTasks(agentId) {
553
924
  const { apiFetch: apiFetch2 } = usePlatform();
554
- const [tasks, setTasks] = (0, import_react4.useState)([]);
555
- const [stats, setStats] = (0, import_react4.useState)(null);
556
- const [loading, setLoading] = (0, import_react4.useState)(true);
557
- const fetchTasks = (0, import_react4.useCallback)(async () => {
925
+ const [tasks, setTasks] = (0, import_react5.useState)([]);
926
+ const [stats, setStats] = (0, import_react5.useState)(null);
927
+ const [loading, setLoading] = (0, import_react5.useState)(true);
928
+ const fetchTasks = (0, import_react5.useCallback)(async () => {
558
929
  try {
559
930
  const params = new URLSearchParams();
560
931
  if (agentId) params.set("agent_id", String(agentId));
@@ -563,18 +934,18 @@ function usePluginTasks(agentId) {
563
934
  } catch {
564
935
  }
565
936
  }, [apiFetch2, agentId]);
566
- const fetchStats = (0, import_react4.useCallback)(async () => {
937
+ const fetchStats = (0, import_react5.useCallback)(async () => {
567
938
  try {
568
939
  const res = await apiFetch2("/api/v1/tasks/stats");
569
940
  setStats(await res.json());
570
941
  } catch {
571
942
  }
572
943
  }, [apiFetch2]);
573
- (0, import_react4.useEffect)(() => {
944
+ (0, import_react5.useEffect)(() => {
574
945
  setLoading(true);
575
946
  Promise.all([fetchTasks(), fetchStats()]).finally(() => setLoading(false));
576
947
  }, [fetchTasks, fetchStats]);
577
- const createTask = (0, import_react4.useCallback)(async (payload) => {
948
+ const createTask = (0, import_react5.useCallback)(async (payload) => {
578
949
  const res = await apiFetch2("/api/v1/tasks", {
579
950
  method: "POST",
580
951
  body: JSON.stringify(payload)
@@ -583,7 +954,7 @@ function usePluginTasks(agentId) {
583
954
  await Promise.all([fetchTasks(), fetchStats()]);
584
955
  return task;
585
956
  }, [apiFetch2, fetchTasks, fetchStats]);
586
- const updateTask = (0, import_react4.useCallback)(async (taskId, payload) => {
957
+ const updateTask = (0, import_react5.useCallback)(async (taskId, payload) => {
587
958
  const res = await apiFetch2(`/api/v1/tasks/${taskId}`, {
588
959
  method: "PATCH",
589
960
  body: JSON.stringify(payload)
@@ -592,7 +963,7 @@ function usePluginTasks(agentId) {
592
963
  await Promise.all([fetchTasks(), fetchStats()]);
593
964
  return task;
594
965
  }, [apiFetch2, fetchTasks, fetchStats]);
595
- const deleteTask = (0, import_react4.useCallback)(async (taskId) => {
966
+ const deleteTask = (0, import_react5.useCallback)(async (taskId) => {
596
967
  await apiFetch2(`/api/v1/tasks/${taskId}`, { method: "DELETE" });
597
968
  await Promise.all([fetchTasks(), fetchStats()]);
598
969
  }, [apiFetch2, fetchTasks, fetchStats]);
@@ -600,23 +971,23 @@ function usePluginTasks(agentId) {
600
971
  }
601
972
 
602
973
  // src/hooks/use-plugin-data-rooms.ts
603
- var import_react5 = require("react");
974
+ var import_react6 = require("react");
604
975
  function usePluginDataRooms() {
605
976
  const { apiFetch: apiFetch2 } = usePlatform();
606
- const [rooms, setRooms] = (0, import_react5.useState)([]);
607
- const [loading, setLoading] = (0, import_react5.useState)(true);
608
- const fetchRooms = (0, import_react5.useCallback)(async () => {
977
+ const [rooms, setRooms] = (0, import_react6.useState)([]);
978
+ const [loading, setLoading] = (0, import_react6.useState)(true);
979
+ const fetchRooms = (0, import_react6.useCallback)(async () => {
609
980
  try {
610
981
  const res = await apiFetch2("/api/v1/data-rooms");
611
982
  setRooms(await res.json());
612
983
  } catch {
613
984
  }
614
985
  }, [apiFetch2]);
615
- (0, import_react5.useEffect)(() => {
986
+ (0, import_react6.useEffect)(() => {
616
987
  setLoading(true);
617
988
  fetchRooms().finally(() => setLoading(false));
618
989
  }, [fetchRooms]);
619
- const fetchFolder = (0, import_react5.useCallback)(async (roomId, folderId) => {
990
+ const fetchFolder = (0, import_react6.useCallback)(async (roomId, folderId) => {
620
991
  const path = folderId ? `/api/v1/data-rooms/${roomId}/folders/${folderId}` : `/api/v1/data-rooms/${roomId}`;
621
992
  const res = await apiFetch2(path);
622
993
  return res.json();
@@ -625,19 +996,19 @@ function usePluginDataRooms() {
625
996
  }
626
997
 
627
998
  // src/hooks/use-plugin-chat.ts
628
- var import_react6 = require("react");
999
+ var import_react7 = require("react");
629
1000
  function usePluginChat(agentId) {
630
1001
  const { apiFetch: apiFetch2 } = usePlatform();
631
- const [threads, setThreads] = (0, import_react6.useState)([]);
632
- const [messages, setMessages] = (0, import_react6.useState)([]);
633
- const [streaming, setStreaming] = (0, import_react6.useState)(false);
634
- const [activeThreadId, setActiveThreadId] = (0, import_react6.useState)(null);
635
- const abortRef = (0, import_react6.useRef)(null);
636
- const fetchThreads = (0, import_react6.useCallback)(async () => {
1002
+ const [threads, setThreads] = (0, import_react7.useState)([]);
1003
+ const [messages, setMessages] = (0, import_react7.useState)([]);
1004
+ const [streaming, setStreaming] = (0, import_react7.useState)(false);
1005
+ const [activeThreadId, setActiveThreadId] = (0, import_react7.useState)(null);
1006
+ const abortRef = (0, import_react7.useRef)(null);
1007
+ const fetchThreads = (0, import_react7.useCallback)(async () => {
637
1008
  const res = await apiFetch2(`/api/v1/chat/${agentId}/threads`);
638
1009
  setThreads(await res.json());
639
1010
  }, [apiFetch2, agentId]);
640
- const createThread = (0, import_react6.useCallback)(async () => {
1011
+ const createThread = (0, import_react7.useCallback)(async () => {
641
1012
  const res = await apiFetch2(`/api/v1/chat/${agentId}/threads`, { method: "POST" });
642
1013
  const thread = await res.json();
643
1014
  setActiveThreadId(thread.id);
@@ -645,13 +1016,13 @@ function usePluginChat(agentId) {
645
1016
  await fetchThreads();
646
1017
  return thread;
647
1018
  }, [apiFetch2, agentId, fetchThreads]);
648
- const fetchMessages = (0, import_react6.useCallback)(async (threadId) => {
1019
+ const fetchMessages = (0, import_react7.useCallback)(async (threadId) => {
649
1020
  const res = await apiFetch2(`/api/v1/chat/threads/${threadId}/messages`);
650
1021
  const msgs = await res.json();
651
1022
  setMessages(msgs);
652
1023
  setActiveThreadId(threadId);
653
1024
  }, [apiFetch2]);
654
- const sendMessage = (0, import_react6.useCallback)(async (threadId, content) => {
1025
+ const sendMessage = (0, import_react7.useCallback)(async (threadId, content) => {
655
1026
  setStreaming(true);
656
1027
  abortRef.current = new AbortController();
657
1028
  const userMsg = {
@@ -719,7 +1090,7 @@ function usePluginChat(agentId) {
719
1090
  abortRef.current = null;
720
1091
  }
721
1092
  }, []);
722
- const stopStreaming = (0, import_react6.useCallback)(() => {
1093
+ const stopStreaming = (0, import_react7.useCallback)(() => {
723
1094
  abortRef.current?.abort();
724
1095
  }, []);
725
1096
  return {
@@ -737,8 +1108,10 @@ function usePluginChat(agentId) {
737
1108
  // Annotate the CommonJS export names for ESM import in node:
738
1109
  0 && (module.exports = {
739
1110
  DataRoomClient,
1111
+ Link,
740
1112
  OrganizationClient,
741
1113
  PaletteApiError,
1114
+ PaletteAppRouter,
742
1115
  PlatformCtx,
743
1116
  PluginProvider,
744
1117
  StorageClient,
@@ -758,14 +1131,19 @@ function usePluginChat(agentId) {
758
1131
  isPaletteApiError,
759
1132
  isSandboxRuntime,
760
1133
  normalizePaletteLanguage,
1134
+ notFound,
761
1135
  setBaseUrl,
762
1136
  translate,
763
1137
  updateInstallConfig,
764
1138
  uploadToSignedUrl,
1139
+ useParams,
1140
+ usePathname,
765
1141
  usePlatform,
766
1142
  usePluginChat,
767
1143
  usePluginDataRooms,
768
1144
  usePluginTasks,
769
1145
  usePluginTranslations,
1146
+ useRouter,
1147
+ useSearchParams,
770
1148
  withPluginProvider
771
1149
  });