@invergent/agent-chat-react 1.5.2 → 1.5.3
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 +332 -69
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +332 -70
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.d.cts
CHANGED
|
@@ -292,6 +292,17 @@ interface AgentChatAdapter {
|
|
|
292
292
|
sessionId: string;
|
|
293
293
|
path: string;
|
|
294
294
|
}): Promise<void>;
|
|
295
|
+
/**
|
|
296
|
+
* Build a same-origin URL the browser can navigate to (or anchor at via
|
|
297
|
+
* ``<a href download>``) to download the workspace file. The adapter
|
|
298
|
+
* is responsible for embedding any auth credential the server expects
|
|
299
|
+
* — typically as a query-string token, since cross-origin/anchor
|
|
300
|
+
* downloads can't carry custom headers.
|
|
301
|
+
*/
|
|
302
|
+
getWorkspaceDownloadUrl(input: {
|
|
303
|
+
sessionId: string;
|
|
304
|
+
path: string;
|
|
305
|
+
}): string;
|
|
295
306
|
openEventStream(input: {
|
|
296
307
|
sessionId: string;
|
|
297
308
|
after: number;
|
package/dist/index.d.ts
CHANGED
|
@@ -292,6 +292,17 @@ interface AgentChatAdapter {
|
|
|
292
292
|
sessionId: string;
|
|
293
293
|
path: string;
|
|
294
294
|
}): Promise<void>;
|
|
295
|
+
/**
|
|
296
|
+
* Build a same-origin URL the browser can navigate to (or anchor at via
|
|
297
|
+
* ``<a href download>``) to download the workspace file. The adapter
|
|
298
|
+
* is responsible for embedding any auth credential the server expects
|
|
299
|
+
* — typically as a query-string token, since cross-origin/anchor
|
|
300
|
+
* downloads can't carry custom headers.
|
|
301
|
+
*/
|
|
302
|
+
getWorkspaceDownloadUrl(input: {
|
|
303
|
+
sessionId: string;
|
|
304
|
+
path: string;
|
|
305
|
+
}): string;
|
|
295
306
|
openEventStream(input: {
|
|
296
307
|
sessionId: string;
|
|
297
308
|
after: number;
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { Collapsible as Collapsible$1, Slot, Dialog as Dialog$1, ScrollArea as S
|
|
|
4
4
|
import { clsx } from 'clsx';
|
|
5
5
|
import { twMerge } from 'tailwind-merge';
|
|
6
6
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
7
|
-
import { ChevronDownIcon, AlertTriangle, ChevronDown, ChevronRight, RefreshCw, ChevronRightIcon, GitBranchIcon, XIcon, ThumbsUpIcon, ThumbsDownIcon, ActivityIcon, Loader2Icon, GlobeIcon, SearchIcon, ListTodoIcon, XCircleIcon, CheckCircle2Icon, Code, CheckIcon, CopyIcon, TerminalIcon, Trash2Icon, CircleDotIcon, CircleCheckIcon, CircleXIcon, SkullIcon, ClockIcon, CheckCircleIcon, CircleIcon, UsersIcon, MessageSquareIcon, FolderOpenIcon, UploadIcon, RefreshCwIcon, AlertCircleIcon, SquareIcon, ArrowDownIcon, DownloadIcon, TrashIcon, ImageIcon, FileTextIcon, Maximize2Icon, FolderIcon, FileIcon, PlusIcon, CornerDownLeftIcon } from 'lucide-react';
|
|
7
|
+
import { ChevronDownIcon, AlertTriangle, ChevronDown, ChevronRight, RefreshCw, ChevronRightIcon, GitBranchIcon, XIcon, ThumbsUpIcon, ThumbsDownIcon, ActivityIcon, Loader2Icon, GlobeIcon, SearchIcon, ListTodoIcon, XCircleIcon, CheckCircle2Icon, Code, CheckIcon, CopyIcon, TerminalIcon, Trash2Icon, CircleDotIcon, CircleCheckIcon, CircleXIcon, SkullIcon, ClockIcon, CheckCircleIcon, CircleIcon, UsersIcon, MessageSquareIcon, FolderOpenIcon, UploadIcon, RefreshCwIcon, AlertCircleIcon, SquareIcon, ArrowDownIcon, DownloadIcon, TrashIcon, ImageIcon, FileTextIcon, Maximize2Icon, FolderIcon, FileIcon, ChevronLeftIcon, MinusIcon, PlusIcon, CornerDownLeftIcon } from 'lucide-react';
|
|
8
8
|
import { StickToBottom, useStickToBottomContext } from 'use-stick-to-bottom';
|
|
9
9
|
import { cjk } from '@streamdown/cjk';
|
|
10
10
|
import { code } from '@streamdown/code';
|
|
@@ -18,6 +18,7 @@ import Ansi from 'ansi-to-react';
|
|
|
18
18
|
import { getUsage } from 'tokenlens';
|
|
19
19
|
import { Command as Command$1 } from 'cmdk';
|
|
20
20
|
import { nanoid } from 'nanoid';
|
|
21
|
+
import 'pdfjs-dist/web/pdf_viewer.css';
|
|
21
22
|
import { formatDistanceToNow } from 'date-fns';
|
|
22
23
|
|
|
23
24
|
// src/agent-chat.tsx
|
|
@@ -6360,17 +6361,24 @@ function getLanguageHint(path) {
|
|
|
6360
6361
|
return map[ext] ?? "plaintext";
|
|
6361
6362
|
}
|
|
6362
6363
|
var SKELETON_WIDTHS = [70, 85, 55, 90, 60, 78, 45, 82, 65, 72];
|
|
6364
|
+
var PDF_WORKER_SRC = new URL(
|
|
6365
|
+
"pdfjs-dist/legacy/build/pdf.worker.mjs",
|
|
6366
|
+
import.meta.url
|
|
6367
|
+
).toString();
|
|
6363
6368
|
function FileViewer({
|
|
6364
6369
|
file,
|
|
6365
6370
|
loading,
|
|
6366
6371
|
error,
|
|
6372
|
+
downloadUrl,
|
|
6373
|
+
onDelete,
|
|
6367
6374
|
onClose
|
|
6368
6375
|
}) {
|
|
6369
6376
|
const visible = loading || file !== null || error !== null;
|
|
6370
6377
|
if (!visible) return null;
|
|
6371
6378
|
const fileName2 = file?.path.split("/").pop() ?? "File";
|
|
6372
6379
|
const lang = file ? getLanguageHint(file.path) : "";
|
|
6373
|
-
const
|
|
6380
|
+
const isPdf = file?.mime_type === "application/pdf" || file?.path.toLowerCase().endsWith(".pdf") || false;
|
|
6381
|
+
const isImage = file?.encoding === "base64" && !isPdf;
|
|
6374
6382
|
const HeaderIcon = isImage ? ImageIcon : FileTextIcon;
|
|
6375
6383
|
return /* @__PURE__ */ jsxs("div", { className: "flex min-h-0 flex-1 flex-col border-t border-line", children: [
|
|
6376
6384
|
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-2 border-b border-line px-3 py-2", children: [
|
|
@@ -6385,6 +6393,28 @@ function FileViewer({
|
|
|
6385
6393
|
] })
|
|
6386
6394
|
] })
|
|
6387
6395
|
] }),
|
|
6396
|
+
downloadUrl && /* @__PURE__ */ jsx(
|
|
6397
|
+
"a",
|
|
6398
|
+
{
|
|
6399
|
+
href: downloadUrl,
|
|
6400
|
+
download: fileName2,
|
|
6401
|
+
className: "shrink-0 rounded p-0.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
6402
|
+
"aria-label": `Download ${fileName2}`,
|
|
6403
|
+
title: "Download",
|
|
6404
|
+
children: /* @__PURE__ */ jsx(DownloadIcon, { className: "size-3.5" })
|
|
6405
|
+
}
|
|
6406
|
+
),
|
|
6407
|
+
onDelete && /* @__PURE__ */ jsx(
|
|
6408
|
+
"button",
|
|
6409
|
+
{
|
|
6410
|
+
type: "button",
|
|
6411
|
+
onClick: onDelete,
|
|
6412
|
+
className: "shrink-0 rounded p-0.5 text-muted-foreground transition-colors hover:bg-destructive/10 hover:text-destructive",
|
|
6413
|
+
"aria-label": `Delete ${fileName2}`,
|
|
6414
|
+
title: "Delete",
|
|
6415
|
+
children: /* @__PURE__ */ jsx(TrashIcon, { className: "size-3.5" })
|
|
6416
|
+
}
|
|
6417
|
+
),
|
|
6388
6418
|
/* @__PURE__ */ jsx(
|
|
6389
6419
|
"button",
|
|
6390
6420
|
{
|
|
@@ -6411,6 +6441,8 @@ function FileViewer({
|
|
|
6411
6441
|
/* @__PURE__ */ jsx(AlertCircleIcon, { className: "mt-0.5 size-3.5 shrink-0" }),
|
|
6412
6442
|
/* @__PURE__ */ jsx("span", { children: error })
|
|
6413
6443
|
] }),
|
|
6444
|
+
file && isPdf && file.encoding !== "base64" && /* @__PURE__ */ jsx(FileViewerError, { message: "PDF preview requires base64 file content." }),
|
|
6445
|
+
file && isPdf && file.encoding === "base64" && /* @__PURE__ */ jsx(PdfPreview, { file, fileName: fileName2 }),
|
|
6414
6446
|
file && isImage && /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center p-4", children: /* @__PURE__ */ jsx(
|
|
6415
6447
|
"img",
|
|
6416
6448
|
{
|
|
@@ -6419,66 +6451,290 @@ function FileViewer({
|
|
|
6419
6451
|
className: "max-h-[60vh] max-w-full rounded object-contain"
|
|
6420
6452
|
}
|
|
6421
6453
|
) }),
|
|
6422
|
-
file && !isImage && /* @__PURE__ */ jsx("pre", { className: "wrap-break-word whitespace-pre-wrap p-3 text-[11px] leading-relaxed text-foreground", children: /* @__PURE__ */ jsx("code", { "data-language": lang, children: file.content }) })
|
|
6454
|
+
file && !isImage && !isPdf && /* @__PURE__ */ jsx("pre", { className: "wrap-break-word whitespace-pre-wrap p-3 text-[11px] leading-relaxed text-foreground", children: /* @__PURE__ */ jsx("code", { "data-language": lang, children: file.content }) })
|
|
6423
6455
|
] })
|
|
6424
6456
|
] });
|
|
6425
6457
|
}
|
|
6426
|
-
|
|
6427
|
-
"
|
|
6428
|
-
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6437
|
-
|
|
6438
|
-
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
|
|
6445
|
-
"
|
|
6446
|
-
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
|
|
6450
|
-
|
|
6451
|
-
|
|
6452
|
-
|
|
6453
|
-
|
|
6454
|
-
|
|
6455
|
-
|
|
6456
|
-
|
|
6457
|
-
|
|
6458
|
-
|
|
6459
|
-
|
|
6460
|
-
|
|
6461
|
-
|
|
6462
|
-
|
|
6463
|
-
|
|
6464
|
-
|
|
6465
|
-
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6472
|
-
|
|
6458
|
+
function FileViewerError({ message }) {
|
|
6459
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2 p-3 text-xs text-destructive", children: [
|
|
6460
|
+
/* @__PURE__ */ jsx(AlertCircleIcon, { className: "mt-0.5 size-3.5 shrink-0" }),
|
|
6461
|
+
/* @__PURE__ */ jsx("span", { children: message })
|
|
6462
|
+
] });
|
|
6463
|
+
}
|
|
6464
|
+
function PdfPreview({
|
|
6465
|
+
file,
|
|
6466
|
+
fileName: fileName2
|
|
6467
|
+
}) {
|
|
6468
|
+
const containerRef = useRef(null);
|
|
6469
|
+
const viewerRef = useRef(null);
|
|
6470
|
+
const pdfViewerRef = useRef(null);
|
|
6471
|
+
const eventBusRef = useRef(null);
|
|
6472
|
+
const findControllerRef = useRef(null);
|
|
6473
|
+
const [error, setError] = useState(null);
|
|
6474
|
+
const [pageNumber, setPageNumber] = useState(1);
|
|
6475
|
+
const [pagesCount, setPagesCount] = useState(0);
|
|
6476
|
+
const [scale, setScale] = useState(1);
|
|
6477
|
+
const [query, setQuery] = useState("");
|
|
6478
|
+
useEffect(() => {
|
|
6479
|
+
let cancelled = false;
|
|
6480
|
+
let loadingTask = null;
|
|
6481
|
+
let pdfDocument = null;
|
|
6482
|
+
const renderPdf = async () => {
|
|
6483
|
+
setError(null);
|
|
6484
|
+
const container = containerRef.current;
|
|
6485
|
+
const viewerElement = viewerRef.current;
|
|
6486
|
+
if (!container || !viewerElement) return;
|
|
6487
|
+
const pdfBytes = decodeBase64(file.content);
|
|
6488
|
+
const pdfjs = await import('pdfjs-dist/legacy/build/pdf.mjs');
|
|
6489
|
+
pdfjs.GlobalWorkerOptions.workerSrc = PDF_WORKER_SRC;
|
|
6490
|
+
globalThis.pdfjsLib = pdfjs;
|
|
6491
|
+
const pdfViewerModule = await import('pdfjs-dist/web/pdf_viewer.mjs');
|
|
6492
|
+
loadingTask = pdfjs.getDocument({ data: pdfBytes });
|
|
6493
|
+
const pdf = await loadingTask.promise;
|
|
6494
|
+
pdfDocument = pdf;
|
|
6495
|
+
if (cancelled) return;
|
|
6496
|
+
const eventBus = new pdfViewerModule.EventBus();
|
|
6497
|
+
const linkService = new pdfViewerModule.PDFLinkService({ eventBus });
|
|
6498
|
+
const findController = new pdfViewerModule.PDFFindController({
|
|
6499
|
+
eventBus,
|
|
6500
|
+
linkService
|
|
6501
|
+
});
|
|
6502
|
+
const pdfViewer = new pdfViewerModule.PDFViewer({
|
|
6503
|
+
container,
|
|
6504
|
+
viewer: viewerElement,
|
|
6505
|
+
eventBus,
|
|
6506
|
+
linkService,
|
|
6507
|
+
findController,
|
|
6508
|
+
removePageBorders: true
|
|
6509
|
+
});
|
|
6510
|
+
linkService.setViewer(pdfViewer);
|
|
6511
|
+
linkService.setDocument(pdf);
|
|
6512
|
+
findController.setDocument(pdf);
|
|
6513
|
+
const onPagesInit = () => {
|
|
6514
|
+
pdfViewer.currentScaleValue = "page-width";
|
|
6515
|
+
setScale(pdfViewer.currentScale || 1);
|
|
6516
|
+
setPagesCount(pdfViewer.pagesCount);
|
|
6517
|
+
setPageNumber(pdfViewer.currentPageNumber);
|
|
6518
|
+
};
|
|
6519
|
+
const onPageChanging = (event) => {
|
|
6520
|
+
if (typeof event.pageNumber === "number") {
|
|
6521
|
+
setPageNumber(event.pageNumber);
|
|
6522
|
+
}
|
|
6523
|
+
};
|
|
6524
|
+
const onScaleChanging = (event) => {
|
|
6525
|
+
if (typeof event.scale === "number") {
|
|
6526
|
+
setScale(event.scale);
|
|
6527
|
+
}
|
|
6528
|
+
};
|
|
6529
|
+
eventBus.on("pagesinit", onPagesInit);
|
|
6530
|
+
eventBus.on("pagechanging", onPageChanging);
|
|
6531
|
+
eventBus.on("scalechanging", onScaleChanging);
|
|
6532
|
+
pdfViewerRef.current = pdfViewer;
|
|
6533
|
+
eventBusRef.current = eventBus;
|
|
6534
|
+
findControllerRef.current = findController;
|
|
6535
|
+
setPagesCount(pdf.numPages);
|
|
6536
|
+
pdfViewer.setDocument(pdf);
|
|
6537
|
+
};
|
|
6538
|
+
void renderPdf().catch((nextError) => {
|
|
6539
|
+
if (cancelled) return;
|
|
6540
|
+
if (nextError instanceof Error && nextError.name === "RenderingCancelledException") {
|
|
6541
|
+
return;
|
|
6542
|
+
}
|
|
6543
|
+
setError(formatPdfPreviewError(nextError));
|
|
6544
|
+
});
|
|
6545
|
+
return () => {
|
|
6546
|
+
cancelled = true;
|
|
6547
|
+
loadingTask?.destroy();
|
|
6548
|
+
pdfDocument?.destroy();
|
|
6549
|
+
pdfViewerRef.current?.cleanup();
|
|
6550
|
+
pdfViewerRef.current = null;
|
|
6551
|
+
eventBusRef.current = null;
|
|
6552
|
+
findControllerRef.current = null;
|
|
6553
|
+
};
|
|
6554
|
+
}, [file.content]);
|
|
6555
|
+
const setViewerPage = (nextPage) => {
|
|
6556
|
+
const viewer = pdfViewerRef.current;
|
|
6557
|
+
if (!viewer) return;
|
|
6558
|
+
const clampedPage = Math.min(
|
|
6559
|
+
Math.max(1, nextPage),
|
|
6560
|
+
Math.max(1, viewer.pagesCount)
|
|
6561
|
+
);
|
|
6562
|
+
viewer.currentPageNumber = clampedPage;
|
|
6563
|
+
setPageNumber(clampedPage);
|
|
6564
|
+
};
|
|
6565
|
+
const setViewerScale = (nextScale) => {
|
|
6566
|
+
const viewer = pdfViewerRef.current;
|
|
6567
|
+
if (!viewer) return;
|
|
6568
|
+
const clampedScale = Math.min(3, Math.max(0.5, nextScale));
|
|
6569
|
+
viewer.currentScale = clampedScale;
|
|
6570
|
+
setScale(clampedScale);
|
|
6571
|
+
};
|
|
6572
|
+
const runFind = (findPrevious = false) => {
|
|
6573
|
+
const eventBus = eventBusRef.current;
|
|
6574
|
+
if (!eventBus || !query.trim()) return;
|
|
6575
|
+
eventBus.dispatch("find", {
|
|
6576
|
+
source: eventBus,
|
|
6577
|
+
type: "again",
|
|
6578
|
+
query,
|
|
6579
|
+
phraseSearch: true,
|
|
6580
|
+
caseSensitive: false,
|
|
6581
|
+
entireWord: false,
|
|
6582
|
+
highlightAll: true,
|
|
6583
|
+
findPrevious,
|
|
6584
|
+
matchDiacritics: true
|
|
6585
|
+
});
|
|
6586
|
+
};
|
|
6587
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex min-h-full flex-col", children: [
|
|
6588
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 flex-wrap items-center gap-1.5 border-b border-line px-2 py-1.5", children: [
|
|
6589
|
+
/* @__PURE__ */ jsx(
|
|
6590
|
+
Button,
|
|
6591
|
+
{
|
|
6592
|
+
type: "button",
|
|
6593
|
+
variant: "ghost",
|
|
6594
|
+
size: "icon-xs",
|
|
6595
|
+
onClick: () => setViewerPage(pageNumber - 1),
|
|
6596
|
+
disabled: pageNumber <= 1,
|
|
6597
|
+
"aria-label": "Previous PDF page",
|
|
6598
|
+
title: "Previous page",
|
|
6599
|
+
children: /* @__PURE__ */ jsx(ChevronLeftIcon, { className: "size-3.5" })
|
|
6600
|
+
}
|
|
6601
|
+
),
|
|
6602
|
+
/* @__PURE__ */ jsx(
|
|
6603
|
+
Input,
|
|
6604
|
+
{
|
|
6605
|
+
type: "number",
|
|
6606
|
+
min: 1,
|
|
6607
|
+
max: pagesCount || 1,
|
|
6608
|
+
value: pageNumber,
|
|
6609
|
+
onChange: (event) => setViewerPage(Number(event.target.value)),
|
|
6610
|
+
"aria-label": "PDF page number",
|
|
6611
|
+
className: "h-7 w-12 border-input px-1 text-center text-xs"
|
|
6612
|
+
}
|
|
6613
|
+
),
|
|
6614
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
|
|
6615
|
+
"/ ",
|
|
6616
|
+
pagesCount || "-"
|
|
6617
|
+
] }),
|
|
6618
|
+
/* @__PURE__ */ jsx(
|
|
6619
|
+
Button,
|
|
6620
|
+
{
|
|
6621
|
+
type: "button",
|
|
6622
|
+
variant: "ghost",
|
|
6623
|
+
size: "icon-xs",
|
|
6624
|
+
onClick: () => setViewerPage(pageNumber + 1),
|
|
6625
|
+
disabled: pagesCount > 0 && pageNumber >= pagesCount,
|
|
6626
|
+
"aria-label": "Next PDF page",
|
|
6627
|
+
title: "Next page",
|
|
6628
|
+
children: /* @__PURE__ */ jsx(ChevronRightIcon, { className: "size-3.5" })
|
|
6629
|
+
}
|
|
6630
|
+
),
|
|
6631
|
+
/* @__PURE__ */ jsx("div", { className: "mx-1 h-5 w-px bg-line" }),
|
|
6632
|
+
/* @__PURE__ */ jsx(
|
|
6633
|
+
Button,
|
|
6634
|
+
{
|
|
6635
|
+
type: "button",
|
|
6636
|
+
variant: "ghost",
|
|
6637
|
+
size: "icon-xs",
|
|
6638
|
+
onClick: () => setViewerScale(scale - 0.1),
|
|
6639
|
+
disabled: scale <= 0.5,
|
|
6640
|
+
"aria-label": "Zoom out PDF",
|
|
6641
|
+
title: "Zoom out",
|
|
6642
|
+
children: /* @__PURE__ */ jsx(MinusIcon, { className: "size-3.5" })
|
|
6643
|
+
}
|
|
6644
|
+
),
|
|
6645
|
+
/* @__PURE__ */ jsxs(
|
|
6646
|
+
"button",
|
|
6647
|
+
{
|
|
6648
|
+
type: "button",
|
|
6649
|
+
className: "h-7 min-w-12 px-1 text-xs text-muted-foreground hover:text-foreground",
|
|
6650
|
+
onClick: () => {
|
|
6651
|
+
const viewer = pdfViewerRef.current;
|
|
6652
|
+
if (!viewer) return;
|
|
6653
|
+
viewer.currentScaleValue = "page-width";
|
|
6654
|
+
setScale(viewer.currentScale || 1);
|
|
6655
|
+
},
|
|
6656
|
+
"aria-label": "Fit PDF to width",
|
|
6657
|
+
title: "Fit width",
|
|
6658
|
+
children: [
|
|
6659
|
+
Math.round(scale * 100),
|
|
6660
|
+
"%"
|
|
6661
|
+
]
|
|
6662
|
+
}
|
|
6663
|
+
),
|
|
6664
|
+
/* @__PURE__ */ jsx(
|
|
6665
|
+
Button,
|
|
6666
|
+
{
|
|
6667
|
+
type: "button",
|
|
6668
|
+
variant: "ghost",
|
|
6669
|
+
size: "icon-xs",
|
|
6670
|
+
onClick: () => setViewerScale(scale + 0.1),
|
|
6671
|
+
disabled: scale >= 3,
|
|
6672
|
+
"aria-label": "Zoom in PDF",
|
|
6673
|
+
title: "Zoom in",
|
|
6674
|
+
children: /* @__PURE__ */ jsx(PlusIcon, { className: "size-3.5" })
|
|
6675
|
+
}
|
|
6676
|
+
),
|
|
6677
|
+
/* @__PURE__ */ jsx("div", { className: "mx-1 h-5 w-px bg-line" }),
|
|
6678
|
+
/* @__PURE__ */ jsx(SearchIcon, { className: "size-3.5 text-muted-foreground" }),
|
|
6679
|
+
/* @__PURE__ */ jsx(
|
|
6680
|
+
Input,
|
|
6681
|
+
{
|
|
6682
|
+
type: "search",
|
|
6683
|
+
value: query,
|
|
6684
|
+
onChange: (event) => setQuery(event.target.value),
|
|
6685
|
+
onKeyDown: (event) => {
|
|
6686
|
+
if (event.key === "Enter") runFind(event.shiftKey);
|
|
6687
|
+
},
|
|
6688
|
+
placeholder: "Find",
|
|
6689
|
+
"aria-label": "Find in PDF",
|
|
6690
|
+
className: "h-7 w-28 border-input px-1 text-xs"
|
|
6691
|
+
}
|
|
6692
|
+
),
|
|
6693
|
+
/* @__PURE__ */ jsx(
|
|
6694
|
+
Button,
|
|
6695
|
+
{
|
|
6696
|
+
type: "button",
|
|
6697
|
+
variant: "ghost",
|
|
6698
|
+
size: "xs",
|
|
6699
|
+
onClick: () => runFind(false),
|
|
6700
|
+
disabled: !query.trim(),
|
|
6701
|
+
children: "Find"
|
|
6702
|
+
}
|
|
6703
|
+
)
|
|
6704
|
+
] }),
|
|
6705
|
+
error && /* @__PURE__ */ jsxs("div", { className: "flex w-full items-start gap-2 p-3 text-xs text-destructive", children: [
|
|
6706
|
+
/* @__PURE__ */ jsx(AlertCircleIcon, { className: "mt-0.5 size-3.5 shrink-0" }),
|
|
6707
|
+
/* @__PURE__ */ jsx("span", { children: error })
|
|
6708
|
+
] }),
|
|
6709
|
+
!error && /* @__PURE__ */ jsx("div", { className: "relative h-[70vh] min-h-[420px] flex-1 bg-muted/20", children: /* @__PURE__ */ jsx(
|
|
6710
|
+
"div",
|
|
6711
|
+
{
|
|
6712
|
+
ref: containerRef,
|
|
6713
|
+
"aria-label": `PDF viewer for ${fileName2}`,
|
|
6714
|
+
className: "absolute inset-0 overflow-auto",
|
|
6715
|
+
children: /* @__PURE__ */ jsx("div", { ref: viewerRef, className: "pdfViewer" })
|
|
6716
|
+
}
|
|
6717
|
+
) })
|
|
6718
|
+
] });
|
|
6719
|
+
}
|
|
6720
|
+
function decodeBase64(content) {
|
|
6721
|
+
const binary = globalThis.atob(content);
|
|
6722
|
+
const bytes = new Uint8Array(binary.length);
|
|
6723
|
+
for (let index = 0; index < binary.length; index += 1) {
|
|
6724
|
+
bytes[index] = binary.charCodeAt(index);
|
|
6725
|
+
}
|
|
6726
|
+
return bytes;
|
|
6727
|
+
}
|
|
6728
|
+
function formatPdfPreviewError(error) {
|
|
6729
|
+
if (error instanceof Error && (error.name === "InvalidCharacterError" || error.message === "Invalid character")) {
|
|
6730
|
+
return "PDF preview data is not valid base64.";
|
|
6731
|
+
}
|
|
6732
|
+
return error instanceof Error ? error.message : "Failed to render PDF preview.";
|
|
6733
|
+
}
|
|
6473
6734
|
var SKELETON_WIDTHS2 = [75, 60, 90, 65, 80, 70, 85, 55];
|
|
6474
6735
|
var DEFAULT_WIDTH = 500;
|
|
6475
6736
|
var MIN_WIDTH = 300;
|
|
6476
6737
|
var MAX_WIDTH = 900;
|
|
6477
|
-
function isViewable(name) {
|
|
6478
|
-
const dot = name.lastIndexOf(".");
|
|
6479
|
-
const ext = dot >= 0 ? name.slice(dot).toLowerCase() : "";
|
|
6480
|
-
return TEXT_EXTENSIONS.has(ext) || IMAGE_EXTENSIONS.has(ext);
|
|
6481
|
-
}
|
|
6482
6738
|
function collectExpandedPaths(entries, depth = 0) {
|
|
6483
6739
|
const paths = [];
|
|
6484
6740
|
for (const entry of entries) {
|
|
@@ -6503,8 +6759,8 @@ function findEntry(entries, path) {
|
|
|
6503
6759
|
}
|
|
6504
6760
|
function RenderEntries({
|
|
6505
6761
|
entries,
|
|
6506
|
-
|
|
6507
|
-
|
|
6762
|
+
onDelete,
|
|
6763
|
+
downloadUrlFor
|
|
6508
6764
|
}) {
|
|
6509
6765
|
return /* @__PURE__ */ jsx(Fragment, { children: entries.map((entry) => {
|
|
6510
6766
|
if (entry.kind === "dir") {
|
|
@@ -6512,27 +6768,26 @@ function RenderEntries({
|
|
|
6512
6768
|
RenderEntries,
|
|
6513
6769
|
{
|
|
6514
6770
|
entries: entry.children,
|
|
6515
|
-
|
|
6516
|
-
|
|
6771
|
+
onDelete,
|
|
6772
|
+
downloadUrlFor
|
|
6517
6773
|
}
|
|
6518
6774
|
) }, entry.path);
|
|
6519
6775
|
}
|
|
6520
|
-
const
|
|
6776
|
+
const fileName2 = entry.name;
|
|
6521
6777
|
return /* @__PURE__ */ jsxs(FileTreeFile, { name: entry.name, path: entry.path, children: [
|
|
6522
6778
|
/* @__PURE__ */ jsx("span", { className: "size-4 shrink-0" }),
|
|
6523
6779
|
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: entry.name }),
|
|
6524
6780
|
entry.size != null && /* @__PURE__ */ jsx("span", { className: "ml-1 shrink-0 text-xs text-muted-foreground/60", children: formatFileSize(entry.size) }),
|
|
6525
6781
|
/* @__PURE__ */ jsxs("div", { className: "ml-1 flex shrink-0 items-center gap-0 opacity-0 transition-opacity group-hover:opacity-100", children: [
|
|
6526
|
-
|
|
6527
|
-
"
|
|
6782
|
+
/* @__PURE__ */ jsx(
|
|
6783
|
+
"a",
|
|
6528
6784
|
{
|
|
6529
|
-
|
|
6785
|
+
href: downloadUrlFor(entry.path),
|
|
6786
|
+
download: fileName2,
|
|
6530
6787
|
className: "rounded p-0.5 text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
6531
|
-
onClick: (event) =>
|
|
6532
|
-
|
|
6533
|
-
|
|
6534
|
-
},
|
|
6535
|
-
title: "View",
|
|
6788
|
+
onClick: (event) => event.stopPropagation(),
|
|
6789
|
+
title: "Download",
|
|
6790
|
+
"aria-label": `Download ${fileName2}`,
|
|
6536
6791
|
children: /* @__PURE__ */ jsx(DownloadIcon, { className: "size-3" })
|
|
6537
6792
|
}
|
|
6538
6793
|
),
|
|
@@ -6546,6 +6801,7 @@ function RenderEntries({
|
|
|
6546
6801
|
onDelete(entry.path);
|
|
6547
6802
|
},
|
|
6548
6803
|
title: "Delete",
|
|
6804
|
+
"aria-label": `Delete ${fileName2}`,
|
|
6549
6805
|
children: /* @__PURE__ */ jsx(TrashIcon, { className: "size-3" })
|
|
6550
6806
|
}
|
|
6551
6807
|
)
|
|
@@ -6863,8 +7119,8 @@ function WorkspacePanel({
|
|
|
6863
7119
|
RenderEntries,
|
|
6864
7120
|
{
|
|
6865
7121
|
entries,
|
|
6866
|
-
|
|
6867
|
-
|
|
7122
|
+
onDelete: setDeleteTarget,
|
|
7123
|
+
downloadUrlFor: (path) => sessionId ? adapter.getWorkspaceDownloadUrl({ sessionId, path }) : "#"
|
|
6868
7124
|
}
|
|
6869
7125
|
)
|
|
6870
7126
|
}
|
|
@@ -6876,7 +7132,13 @@ function WorkspacePanel({
|
|
|
6876
7132
|
file,
|
|
6877
7133
|
loading: fileLoading,
|
|
6878
7134
|
error: fileError,
|
|
7135
|
+
downloadUrl: file && sessionId ? adapter.getWorkspaceDownloadUrl({
|
|
7136
|
+
sessionId,
|
|
7137
|
+
path: file.path
|
|
7138
|
+
}) : null,
|
|
7139
|
+
onDelete: file ? () => setDeleteTarget(file.path) : null,
|
|
6879
7140
|
onClose: () => {
|
|
7141
|
+
onSelectedPathChange(null);
|
|
6880
7142
|
setFile(null);
|
|
6881
7143
|
setFileError(null);
|
|
6882
7144
|
}
|