@invergent/agent-chat-react 2.17.7 → 2.18.0
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 +156 -282
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -3
- package/dist/index.d.ts +30 -3
- package/dist/index.js +158 -282
- package/dist/index.js.map +1 -1
- package/package.json +1 -2
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { cn, __publicField } from './chunk-47MF6JUW.js';
|
|
2
2
|
import { createContext, memo, useRef, useEffect, useCallback, useMemo, useState, useLayoutEffect, forwardRef, useId, lazy, useContext, useSyncExternalStore, Fragment as Fragment$1, Suspense, Children } from 'react';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
|
-
import { ChevronDownIcon, AlertTriangle, ChevronDown, ChevronRight as ChevronRight$1, RefreshCw, CreditCard, File as File$1, FileImage, FileAudio, FileVideo, FileText, FileCode, FileArchive, FileSpreadsheet, PlugZapIcon, ChevronRightIcon, ArrowLeftIcon, Loader2Icon, InboxIcon, Loader2, AlertCircle, Pause, Play, Ban, TargetIcon, CalendarClockIcon, UsersIcon, Pen, Eraser, Type, MousePointer2, Hand, Maximize2, Undo2, Redo2, CheckIcon, CopyIcon, DownloadIcon, Maximize2Icon, LaptopIcon, GlobeIcon, FolderIcon, MessageSquareIcon, UploadIcon, RefreshCwIcon, AlertCircleIcon, ExternalLinkIcon, ClipboardCheckIcon, ShieldAlertIcon, TimerIcon, CircleDotIcon, ChevronLeftIcon, XIcon, Trash2Icon, SquareIcon, ArrowDownIcon, TrashIcon,
|
|
4
|
+
import { ChevronDownIcon, AlertTriangle, ChevronDown, ChevronRight as ChevronRight$1, RefreshCw, CreditCard, File as File$1, FileImage, FileAudio, FileVideo, FileText, FileCode, FileArchive, FileSpreadsheet, PlugZapIcon, ChevronRightIcon, ArrowLeftIcon, Loader2Icon, InboxIcon, Loader2, AlertCircle, Pause, Play, Ban, TargetIcon, CalendarClockIcon, UsersIcon, Pen, Eraser, Type, MousePointer2, Hand, Maximize2, Undo2, Redo2, CheckIcon, CopyIcon, DownloadIcon, Maximize2Icon, LaptopIcon, GlobeIcon, FolderIcon, MessageSquareIcon, UploadIcon, RefreshCwIcon, AlertCircleIcon, ExternalLinkIcon, ClipboardCheckIcon, ShieldAlertIcon, TimerIcon, CircleDotIcon, ChevronLeftIcon, XIcon, Trash2Icon, SquareIcon, ArrowDownIcon, TrashIcon, FileTextIcon, Clock, ArrowRight, ListTreeIcon, PenLineIcon, TerminalIcon, SparklesIcon, ClockIcon, PaperclipIcon, CloudIcon, HardDriveIcon, IdCardIcon, PlusIcon, ShrinkIcon, FolderOpenIcon, FileIcon, ImageIcon, CircleDot, XCircle, CheckCircle2, SearchIcon, ZapIcon, ArrowUpIcon, CircleCheckIcon, ThumbsUpIcon, ThumbsDownIcon, BookOpenIcon, GitBranchIcon, ActivityIcon, EyeIcon, LibraryIcon, ListTodoIcon, BotIcon, ListIcon, FileEditIcon, WrenchIcon, FileCodeIcon, CodeIcon, FileArchiveIcon, FileVideoIcon, FileAudioIcon, FileImageIcon, FileChartLineIcon, FileSpreadsheetIcon, XCircleIcon, CheckCircle2Icon, Code, CircleXIcon, SkullIcon, CheckCircleIcon, CircleIcon } from 'lucide-react';
|
|
5
5
|
import { cva } from 'class-variance-authority';
|
|
6
6
|
import { Collapsible as Collapsible$1, Slot, Tooltip as Tooltip$1, Checkbox as Checkbox$1, Label as Label$1, Progress as Progress$1, Tabs as Tabs$1, Dialog as Dialog$1, ScrollArea as ScrollArea$1, Popover as Popover$1, DropdownMenu as DropdownMenu$1 } from 'radix-ui';
|
|
7
7
|
import { StickToBottom, useStickToBottomContext } from 'use-stick-to-bottom';
|
|
@@ -18,7 +18,7 @@ import AnsiImport from 'ansi-to-react';
|
|
|
18
18
|
import { Command as Command$1 } from 'cmdk';
|
|
19
19
|
import { nanoid } from 'nanoid';
|
|
20
20
|
import 'tokenlens';
|
|
21
|
-
import '
|
|
21
|
+
import { useTheme } from 'next-themes';
|
|
22
22
|
import { formatDistanceToNow } from 'date-fns';
|
|
23
23
|
|
|
24
24
|
var AgentChatAdapterContext = createContext(null);
|
|
@@ -9918,7 +9918,6 @@ function ChatComposerInner({
|
|
|
9918
9918
|
{ value: "/loop 30m summarize new threads in support inbox", label: "/loop 30m support inbox", description: "Every 30 minutes: summarize support traffic" },
|
|
9919
9919
|
{ value: "/loop 1h review the on-call dashboard and flag anomalies", label: "/loop 1h on-call check", description: "Hourly: review the on-call dashboard" },
|
|
9920
9920
|
{ value: "/loop 2h scan production error rates and alert if elevated", label: "/loop 2h error scan", description: "Every 2 hours: production error scan" },
|
|
9921
|
-
{ value: "/loop 1d give me a morning briefing of yesterday's activity", label: "/loop 1d daily briefing", description: "Daily: morning briefing of prior day" },
|
|
9922
9921
|
{ value: "/loop every 5 minutes check whether CI on the current branch has finished", label: "/loop every 5 minutes (verbose)", description: "Verbose interval form" },
|
|
9923
9922
|
{ value: "/loop watch the active deploy and notify me when it stabilises or rolls back", label: "/loop <prompt> (dynamic)", description: "Dynamic loop \u2014 model self-paces 1m\u20131h via loop_wait" },
|
|
9924
9923
|
{ value: "/loop babysit the long-running data migration and only ping me on errors or completion", label: "/loop migration watcher (dynamic)", description: "Dynamic loop \u2014 best when cadence is unpredictable" }
|
|
@@ -12285,7 +12284,7 @@ function messageToEntries(msg, isLast, artifactFallbacks) {
|
|
|
12285
12284
|
if (msg.systemKind === "worker" || msg.systemKind === "thread_proposal") {
|
|
12286
12285
|
return [{ kind: "thread_card", key: msg.id, message: msg }];
|
|
12287
12286
|
}
|
|
12288
|
-
if (msg.systemKind === "browser_marker" || msg.systemKind === "browser_marker_warning") {
|
|
12287
|
+
if (msg.systemKind === "browser_marker" || msg.systemKind === "browser_marker_warning" || msg.systemKind === "notice") {
|
|
12289
12288
|
return [{
|
|
12290
12289
|
kind: "browser_marker",
|
|
12291
12290
|
key: msg.id,
|
|
@@ -12496,7 +12495,7 @@ function OrphanSystemMarker({
|
|
|
12496
12495
|
}
|
|
12497
12496
|
);
|
|
12498
12497
|
}
|
|
12499
|
-
if (message.systemKind === "browser_marker" || message.systemKind === "browser_marker_warning") {
|
|
12498
|
+
if (message.systemKind === "browser_marker" || message.systemKind === "browser_marker_warning" || message.systemKind === "notice") {
|
|
12500
12499
|
const warning = message.systemKind === "browser_marker_warning";
|
|
12501
12500
|
return /* @__PURE__ */ jsxs(
|
|
12502
12501
|
"div",
|
|
@@ -13577,7 +13576,9 @@ var AGENT_CHAT_LISTENED_EVENTS = [
|
|
|
13577
13576
|
"worker.spawned",
|
|
13578
13577
|
"worker.complete",
|
|
13579
13578
|
"worker.failed",
|
|
13580
|
-
"thread.proposed"
|
|
13579
|
+
"thread.proposed",
|
|
13580
|
+
"office.conflict",
|
|
13581
|
+
"office.save_failed"
|
|
13581
13582
|
];
|
|
13582
13583
|
var AGENT_CHAT_LISTENED_EVENT_SET = new Set(
|
|
13583
13584
|
AGENT_CHAT_LISTENED_EVENTS
|
|
@@ -13822,7 +13823,8 @@ function createInitialAgentChatState(options = {}) {
|
|
|
13822
13823
|
browserTabs: [],
|
|
13823
13824
|
viewMode: options.viewMode ?? "simple",
|
|
13824
13825
|
researchSources: [],
|
|
13825
|
-
deviceWait: null
|
|
13826
|
+
deviceWait: null,
|
|
13827
|
+
officeEvents: {}
|
|
13826
13828
|
};
|
|
13827
13829
|
}
|
|
13828
13830
|
function applyAgentChatEvent(state, event) {
|
|
@@ -13982,6 +13984,21 @@ function applyAgentChatEvent(state, event) {
|
|
|
13982
13984
|
};
|
|
13983
13985
|
case "device.resumed":
|
|
13984
13986
|
return { ...nextState, deviceWait: null };
|
|
13987
|
+
case "office.conflict":
|
|
13988
|
+
case "office.save_failed": {
|
|
13989
|
+
const path = stringValue2(event.data.path);
|
|
13990
|
+
if (!path) return nextState;
|
|
13991
|
+
const conflict = event.type === "office.conflict";
|
|
13992
|
+
return {
|
|
13993
|
+
...nextState,
|
|
13994
|
+
officeEvents: {
|
|
13995
|
+
...nextState.officeEvents,
|
|
13996
|
+
[path]: conflict ? { type: event.type, eventId: event.eventId, conflictPath: stringValue2(event.data.conflict_path) } : { type: event.type, eventId: event.eventId }
|
|
13997
|
+
},
|
|
13998
|
+
// The copy the conflicting save landed as shows in the tree.
|
|
13999
|
+
workspaceRefreshKey: nextState.workspaceRefreshKey + (conflict ? 1 : 0)
|
|
14000
|
+
};
|
|
14001
|
+
}
|
|
13985
14002
|
case "worker.spawned":
|
|
13986
14003
|
return withMessages(nextState, applyWorkerSpawned(nextState.messages, event));
|
|
13987
14004
|
case "worker.complete":
|
|
@@ -14322,6 +14339,21 @@ function applyLlmResponse(state, event) {
|
|
|
14322
14339
|
const messages = [...state.messages];
|
|
14323
14340
|
const message = objectValue(event.data.message);
|
|
14324
14341
|
const responseContent = stringValue2(message?.content) || stringValue2(event.data.content);
|
|
14342
|
+
if (event.data.notice === true) {
|
|
14343
|
+
return {
|
|
14344
|
+
...state,
|
|
14345
|
+
messages: [...messages, {
|
|
14346
|
+
id: `evt-${event.eventId}`,
|
|
14347
|
+
role: "system",
|
|
14348
|
+
systemKind: "notice",
|
|
14349
|
+
content: responseContent,
|
|
14350
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
14351
|
+
status: "complete"
|
|
14352
|
+
}],
|
|
14353
|
+
hadDeltas: false,
|
|
14354
|
+
isRunning: false
|
|
14355
|
+
};
|
|
14356
|
+
}
|
|
14325
14357
|
const toolCalls = Array.isArray(message?.tool_calls) ? message?.tool_calls : [];
|
|
14326
14358
|
const hasToolCalls = toolCalls.length > 0;
|
|
14327
14359
|
const responseToolCallIds = toolCallIdsFromResponse(toolCalls);
|
|
@@ -19028,11 +19060,41 @@ function chunkPairs(flat) {
|
|
|
19028
19060
|
for (let i = 0; i + 1 < flat.length; i += 2) pairs.push([flat[i], flat[i + 1]]);
|
|
19029
19061
|
return pairs;
|
|
19030
19062
|
}
|
|
19063
|
+
|
|
19064
|
+
// src/lib/office.ts
|
|
19065
|
+
var OFFICE_EXTENSIONS = /* @__PURE__ */ new Set(["docx", "xlsx", "pptx", "pdf", "doc", "odt", "rtf", "xls", "ods", "ppt", "odp"]);
|
|
19066
|
+
function isOfficeDocument(path) {
|
|
19067
|
+
const dot = path.lastIndexOf(".");
|
|
19068
|
+
return dot >= 0 && OFFICE_EXTENSIONS.has(path.slice(dot + 1).toLowerCase());
|
|
19069
|
+
}
|
|
19070
|
+
var loads = /* @__PURE__ */ new Map();
|
|
19071
|
+
var LOAD_TIMEOUT_MS = 3e4;
|
|
19072
|
+
function loadDocsApi(documentServerUrl) {
|
|
19073
|
+
const src = `${documentServerUrl.replace(/\/$/, "")}/web-apps/apps/api/documents/api.js`;
|
|
19074
|
+
let load = loads.get(src);
|
|
19075
|
+
if (!load) {
|
|
19076
|
+
load = new Promise((resolve, reject) => {
|
|
19077
|
+
const script = document.createElement("script");
|
|
19078
|
+
const settle = (loaded) => {
|
|
19079
|
+
clearTimeout(timer);
|
|
19080
|
+
script.onload = script.onerror = null;
|
|
19081
|
+
if (loaded) return resolve();
|
|
19082
|
+
loads.delete(src);
|
|
19083
|
+
script.remove();
|
|
19084
|
+
reject(new Error("The document editor could not be loaded."));
|
|
19085
|
+
};
|
|
19086
|
+
const timer = setTimeout(() => settle(false), LOAD_TIMEOUT_MS);
|
|
19087
|
+
script.src = src;
|
|
19088
|
+
script.async = true;
|
|
19089
|
+
script.onload = () => settle(Boolean(window.DocsAPI));
|
|
19090
|
+
script.onerror = () => settle(false);
|
|
19091
|
+
document.head.appendChild(script);
|
|
19092
|
+
});
|
|
19093
|
+
loads.set(src, load);
|
|
19094
|
+
}
|
|
19095
|
+
return load;
|
|
19096
|
+
}
|
|
19031
19097
|
var SKELETON_WIDTHS = [70, 85, 55, 90, 60, 78, 45, 82, 65, 72];
|
|
19032
|
-
var PDF_WORKER_SRC = new URL(
|
|
19033
|
-
"pdfjs-dist/legacy/build/pdf.worker.mjs",
|
|
19034
|
-
import.meta.url
|
|
19035
|
-
).toString();
|
|
19036
19098
|
function FileViewer({
|
|
19037
19099
|
file,
|
|
19038
19100
|
loading,
|
|
@@ -19047,8 +19109,8 @@ function FileViewer({
|
|
|
19047
19109
|
if (!visible) return null;
|
|
19048
19110
|
const fileName2 = file?.path.split("/").pop() ?? "File";
|
|
19049
19111
|
const lang = file ? getLanguageHint(file.path) : "";
|
|
19050
|
-
const
|
|
19051
|
-
const
|
|
19112
|
+
const isImage = file?.encoding === "base64" && (file.mime_type?.startsWith("image/") ?? false);
|
|
19113
|
+
const isBinary = file?.encoding === "base64" && !isImage;
|
|
19052
19114
|
const HeaderIcon = isImage ? ImageIcon : FileTextIcon;
|
|
19053
19115
|
return /* @__PURE__ */ jsxs("div", { className: cn("flex min-h-0 flex-1 flex-col border-t border-line", className), children: [
|
|
19054
19116
|
!hideHeader && /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-2 border-b border-line px-3 py-2", children: [
|
|
@@ -19096,12 +19158,7 @@ function FileViewer({
|
|
|
19096
19158
|
}
|
|
19097
19159
|
)
|
|
19098
19160
|
] }),
|
|
19099
|
-
|
|
19100
|
-
// PDF has its own scrollable container — bypass ScrollArea so
|
|
19101
|
-
// it can grow with the parent's flex height (Radix Viewport's
|
|
19102
|
-
// internal table wrapper sizes to content and breaks h-full).
|
|
19103
|
-
/* @__PURE__ */ jsx(PdfPreview, { file, fileName: fileName2 })
|
|
19104
|
-
) : /* @__PURE__ */ jsxs(ScrollArea, { className: "min-h-0 flex-1", children: [
|
|
19161
|
+
/* @__PURE__ */ jsxs(ScrollArea, { className: "min-h-0 flex-1", children: [
|
|
19105
19162
|
loading && /* @__PURE__ */ jsx("div", { className: "space-y-1.5 p-3", children: Array.from({ length: 10 }).map((_, index) => /* @__PURE__ */ jsx(
|
|
19106
19163
|
Skeleton,
|
|
19107
19164
|
{
|
|
@@ -19116,7 +19173,7 @@ function FileViewer({
|
|
|
19116
19173
|
/* @__PURE__ */ jsx(AlertCircleIcon, { className: "mt-0.5 size-3.5 shrink-0" }),
|
|
19117
19174
|
/* @__PURE__ */ jsx("span", { children: error })
|
|
19118
19175
|
] }),
|
|
19119
|
-
file &&
|
|
19176
|
+
file && isBinary && /* @__PURE__ */ jsx(FileViewerError, { message: "Preview not available. Download the file to open it." }),
|
|
19120
19177
|
file && isImage && /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center p-4", children: /* @__PURE__ */ jsx(
|
|
19121
19178
|
"img",
|
|
19122
19179
|
{
|
|
@@ -19125,7 +19182,7 @@ function FileViewer({
|
|
|
19125
19182
|
className: "max-h-[60vh] max-w-full rounded object-contain"
|
|
19126
19183
|
}
|
|
19127
19184
|
) }),
|
|
19128
|
-
file && !isImage && !
|
|
19185
|
+
file && !isImage && !isBinary && /* @__PURE__ */ jsx("pre", { className: "wrap-break-word whitespace-pre-wrap p-3 text-base leading-relaxed text-foreground", children: /* @__PURE__ */ jsx("code", { "data-language": lang, children: file.content }) })
|
|
19129
19186
|
] })
|
|
19130
19187
|
] });
|
|
19131
19188
|
}
|
|
@@ -19135,277 +19192,94 @@ function FileViewerError({ message }) {
|
|
|
19135
19192
|
/* @__PURE__ */ jsx("span", { children: message })
|
|
19136
19193
|
] });
|
|
19137
19194
|
}
|
|
19138
|
-
function
|
|
19139
|
-
|
|
19140
|
-
|
|
19141
|
-
|
|
19142
|
-
const containerRef = useRef(null);
|
|
19143
|
-
const viewerRef = useRef(null);
|
|
19144
|
-
const pdfViewerRef = useRef(null);
|
|
19145
|
-
const eventBusRef = useRef(null);
|
|
19146
|
-
const findControllerRef = useRef(null);
|
|
19195
|
+
function OfficeEditorPane({ adapter, sessionId, path, view, officeEvent, onClose }) {
|
|
19196
|
+
const { resolvedTheme } = useTheme();
|
|
19197
|
+
const theme = resolvedTheme === "dark" ? "dark" : "light";
|
|
19198
|
+
const placeholderId = `office-editor-${useId().replace(/[^a-zA-Z0-9_-]/g, "")}`;
|
|
19147
19199
|
const [error, setError] = useState(null);
|
|
19148
|
-
const [
|
|
19149
|
-
const [
|
|
19150
|
-
const
|
|
19151
|
-
const [
|
|
19200
|
+
const [loading, setLoading] = useState(true);
|
|
19201
|
+
const [openedAfter] = useState(() => officeEvent?.eventId ?? 0);
|
|
19202
|
+
const notice = officeEvent && officeEvent.eventId > openedAfter ? officeEvent : null;
|
|
19203
|
+
const [reopenedFor, setReopenedFor] = useState(0);
|
|
19204
|
+
if (notice?.type === "office.conflict" && notice.eventId !== reopenedFor) setReopenedFor(notice.eventId);
|
|
19152
19205
|
useEffect(() => {
|
|
19153
19206
|
let cancelled = false;
|
|
19154
|
-
let
|
|
19155
|
-
|
|
19156
|
-
|
|
19157
|
-
|
|
19158
|
-
|
|
19159
|
-
|
|
19160
|
-
|
|
19161
|
-
|
|
19162
|
-
|
|
19163
|
-
|
|
19164
|
-
|
|
19165
|
-
|
|
19166
|
-
|
|
19167
|
-
|
|
19168
|
-
|
|
19169
|
-
if (cancelled) return;
|
|
19170
|
-
const eventBus = new pdfViewerModule.EventBus();
|
|
19171
|
-
const linkService = new pdfViewerModule.PDFLinkService({ eventBus });
|
|
19172
|
-
const findController = new pdfViewerModule.PDFFindController({
|
|
19173
|
-
eventBus,
|
|
19174
|
-
linkService
|
|
19175
|
-
});
|
|
19176
|
-
const pdfViewer = new pdfViewerModule.PDFViewer({
|
|
19177
|
-
container,
|
|
19178
|
-
viewer: viewerElement,
|
|
19179
|
-
eventBus,
|
|
19180
|
-
linkService,
|
|
19181
|
-
findController,
|
|
19182
|
-
removePageBorders: true
|
|
19183
|
-
});
|
|
19184
|
-
linkService.setViewer(pdfViewer);
|
|
19185
|
-
linkService.setDocument(pdf);
|
|
19186
|
-
findController.setDocument(pdf);
|
|
19187
|
-
const onPagesInit = () => {
|
|
19188
|
-
pdfViewer.currentScaleValue = "page-width";
|
|
19189
|
-
setScale(pdfViewer.currentScale || 1);
|
|
19190
|
-
setPagesCount(pdfViewer.pagesCount);
|
|
19191
|
-
setPageNumber(pdfViewer.currentPageNumber);
|
|
19192
|
-
};
|
|
19193
|
-
const onPageChanging = (event) => {
|
|
19194
|
-
if (typeof event.pageNumber === "number") {
|
|
19195
|
-
setPageNumber(event.pageNumber);
|
|
19196
|
-
}
|
|
19197
|
-
};
|
|
19198
|
-
const onScaleChanging = (event) => {
|
|
19199
|
-
if (typeof event.scale === "number") {
|
|
19200
|
-
setScale(event.scale);
|
|
19201
|
-
}
|
|
19202
|
-
};
|
|
19203
|
-
eventBus.on("pagesinit", onPagesInit);
|
|
19204
|
-
eventBus.on("pagechanging", onPageChanging);
|
|
19205
|
-
eventBus.on("scalechanging", onScaleChanging);
|
|
19206
|
-
pdfViewerRef.current = pdfViewer;
|
|
19207
|
-
eventBusRef.current = eventBus;
|
|
19208
|
-
findControllerRef.current = findController;
|
|
19209
|
-
setPagesCount(pdf.numPages);
|
|
19210
|
-
pdfViewer.setDocument(pdf);
|
|
19211
|
-
};
|
|
19212
|
-
void renderPdf().catch((nextError) => {
|
|
19213
|
-
if (cancelled) return;
|
|
19214
|
-
if (nextError instanceof Error && nextError.name === "RenderingCancelledException") {
|
|
19215
|
-
return;
|
|
19207
|
+
let editor = null;
|
|
19208
|
+
setError(null);
|
|
19209
|
+
setLoading(true);
|
|
19210
|
+
void (async () => {
|
|
19211
|
+
try {
|
|
19212
|
+
if (!adapter.getWorkspaceEditorConfig) throw new Error("Preview not available. Download the file to open it.");
|
|
19213
|
+
const opened = await adapter.getWorkspaceEditorConfig({ sessionId, path, theme, view });
|
|
19214
|
+
await loadDocsApi(opened.document_server_url);
|
|
19215
|
+
if (cancelled) return;
|
|
19216
|
+
if (!window.DocsAPI) throw new Error("The document editor could not be loaded.");
|
|
19217
|
+
editor = new window.DocsAPI.DocEditor(placeholderId, opened.config);
|
|
19218
|
+
} catch (openError) {
|
|
19219
|
+
if (!cancelled) setError(openError.message);
|
|
19220
|
+
} finally {
|
|
19221
|
+
if (!cancelled) setLoading(false);
|
|
19216
19222
|
}
|
|
19217
|
-
|
|
19218
|
-
});
|
|
19223
|
+
})();
|
|
19219
19224
|
return () => {
|
|
19220
19225
|
cancelled = true;
|
|
19221
|
-
|
|
19222
|
-
pdfDocument?.destroy();
|
|
19223
|
-
pdfViewerRef.current?.cleanup();
|
|
19224
|
-
pdfViewerRef.current = null;
|
|
19225
|
-
eventBusRef.current = null;
|
|
19226
|
-
findControllerRef.current = null;
|
|
19226
|
+
editor?.destroyEditor();
|
|
19227
19227
|
};
|
|
19228
|
-
}, [
|
|
19229
|
-
const
|
|
19230
|
-
|
|
19231
|
-
|
|
19232
|
-
|
|
19233
|
-
|
|
19234
|
-
|
|
19235
|
-
|
|
19236
|
-
|
|
19237
|
-
|
|
19238
|
-
|
|
19239
|
-
|
|
19240
|
-
|
|
19241
|
-
|
|
19242
|
-
|
|
19243
|
-
|
|
19244
|
-
|
|
19245
|
-
|
|
19246
|
-
|
|
19247
|
-
|
|
19248
|
-
|
|
19249
|
-
|
|
19250
|
-
|
|
19251
|
-
|
|
19252
|
-
|
|
19253
|
-
|
|
19254
|
-
|
|
19255
|
-
|
|
19256
|
-
|
|
19257
|
-
|
|
19258
|
-
|
|
19259
|
-
|
|
19260
|
-
|
|
19261
|
-
|
|
19262
|
-
|
|
19263
|
-
|
|
19264
|
-
|
|
19265
|
-
{
|
|
19266
|
-
|
|
19267
|
-
|
|
19268
|
-
|
|
19269
|
-
|
|
19270
|
-
|
|
19271
|
-
|
|
19272
|
-
|
|
19273
|
-
|
|
19274
|
-
|
|
19275
|
-
),
|
|
19276
|
-
/* @__PURE__ */ jsx(
|
|
19277
|
-
Input,
|
|
19278
|
-
{
|
|
19279
|
-
type: "number",
|
|
19280
|
-
min: 1,
|
|
19281
|
-
max: pagesCount || 1,
|
|
19282
|
-
value: pageNumber,
|
|
19283
|
-
onChange: (event) => setViewerPage(Number(event.target.value)),
|
|
19284
|
-
"aria-label": "PDF page number",
|
|
19285
|
-
className: "h-7 w-12 border-input px-1 text-center text-xs"
|
|
19286
|
-
}
|
|
19287
|
-
),
|
|
19288
|
-
/* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
|
|
19289
|
-
"/ ",
|
|
19290
|
-
pagesCount || "-"
|
|
19291
|
-
] }),
|
|
19292
|
-
/* @__PURE__ */ jsx(
|
|
19293
|
-
Button,
|
|
19294
|
-
{
|
|
19295
|
-
type: "button",
|
|
19296
|
-
variant: "ghost",
|
|
19297
|
-
size: "icon-xs",
|
|
19298
|
-
onClick: () => setViewerPage(pageNumber + 1),
|
|
19299
|
-
disabled: pagesCount > 0 && pageNumber >= pagesCount,
|
|
19300
|
-
"aria-label": "Next PDF page",
|
|
19301
|
-
title: "Next page",
|
|
19302
|
-
children: /* @__PURE__ */ jsx(ChevronRightIcon, { className: "size-3.5" })
|
|
19303
|
-
}
|
|
19304
|
-
),
|
|
19305
|
-
/* @__PURE__ */ jsx("div", { className: "mx-1 h-5 w-px bg-line" }),
|
|
19306
|
-
/* @__PURE__ */ jsx(
|
|
19307
|
-
Button,
|
|
19308
|
-
{
|
|
19309
|
-
type: "button",
|
|
19310
|
-
variant: "ghost",
|
|
19311
|
-
size: "icon-xs",
|
|
19312
|
-
onClick: () => setViewerScale(scale - 0.1),
|
|
19313
|
-
disabled: scale <= 0.5,
|
|
19314
|
-
"aria-label": "Zoom out PDF",
|
|
19315
|
-
title: "Zoom out",
|
|
19316
|
-
children: /* @__PURE__ */ jsx(MinusIcon, { className: "size-3.5" })
|
|
19317
|
-
}
|
|
19318
|
-
),
|
|
19319
|
-
/* @__PURE__ */ jsxs(
|
|
19320
|
-
"button",
|
|
19321
|
-
{
|
|
19322
|
-
type: "button",
|
|
19323
|
-
className: "h-7 min-w-12 px-1 text-xs text-muted-foreground hover:text-foreground",
|
|
19324
|
-
onClick: () => {
|
|
19325
|
-
const viewer = pdfViewerRef.current;
|
|
19326
|
-
if (!viewer) return;
|
|
19327
|
-
viewer.currentScaleValue = "page-width";
|
|
19328
|
-
setScale(viewer.currentScale || 1);
|
|
19329
|
-
},
|
|
19330
|
-
"aria-label": "Fit PDF to width",
|
|
19331
|
-
title: "Fit width",
|
|
19332
|
-
children: [
|
|
19333
|
-
Math.round(scale * 100),
|
|
19334
|
-
"%"
|
|
19335
|
-
]
|
|
19336
|
-
}
|
|
19337
|
-
),
|
|
19338
|
-
/* @__PURE__ */ jsx(
|
|
19339
|
-
Button,
|
|
19340
|
-
{
|
|
19341
|
-
type: "button",
|
|
19342
|
-
variant: "ghost",
|
|
19343
|
-
size: "icon-xs",
|
|
19344
|
-
onClick: () => setViewerScale(scale + 0.1),
|
|
19345
|
-
disabled: scale >= 3,
|
|
19346
|
-
"aria-label": "Zoom in PDF",
|
|
19347
|
-
title: "Zoom in",
|
|
19348
|
-
children: /* @__PURE__ */ jsx(PlusIcon, { className: "size-3.5" })
|
|
19349
|
-
}
|
|
19350
|
-
),
|
|
19351
|
-
/* @__PURE__ */ jsx("div", { className: "mx-1 h-5 w-px bg-line" }),
|
|
19352
|
-
/* @__PURE__ */ jsx(SearchIcon, { className: "size-3.5 text-muted-foreground" }),
|
|
19353
|
-
/* @__PURE__ */ jsx(
|
|
19354
|
-
Input,
|
|
19355
|
-
{
|
|
19356
|
-
type: "search",
|
|
19357
|
-
value: query,
|
|
19358
|
-
onChange: (event) => setQuery(event.target.value),
|
|
19359
|
-
onKeyDown: (event) => {
|
|
19360
|
-
if (event.key === "Enter") runFind(event.shiftKey);
|
|
19361
|
-
},
|
|
19362
|
-
placeholder: "Find",
|
|
19363
|
-
"aria-label": "Find in PDF",
|
|
19364
|
-
className: "h-7 w-28 border-input px-1 text-xs"
|
|
19365
|
-
}
|
|
19366
|
-
),
|
|
19367
|
-
/* @__PURE__ */ jsx(
|
|
19368
|
-
Button,
|
|
19369
|
-
{
|
|
19370
|
-
type: "button",
|
|
19371
|
-
variant: "ghost",
|
|
19372
|
-
size: "xs",
|
|
19373
|
-
onClick: () => runFind(false),
|
|
19374
|
-
disabled: !query.trim(),
|
|
19375
|
-
children: "Find"
|
|
19376
|
-
}
|
|
19377
|
-
)
|
|
19378
|
-
] }),
|
|
19379
|
-
error && /* @__PURE__ */ jsxs("div", { className: "flex w-full items-start gap-2 p-3 text-xs text-destructive", children: [
|
|
19380
|
-
/* @__PURE__ */ jsx(AlertCircleIcon, { className: "mt-0.5 size-3.5 shrink-0" }),
|
|
19381
|
-
/* @__PURE__ */ jsx("span", { children: error })
|
|
19382
|
-
] }),
|
|
19383
|
-
!error && /* @__PURE__ */ jsx("div", { className: "relative min-h-105 flex-1 bg-muted/20", children: /* @__PURE__ */ jsx(
|
|
19384
|
-
"div",
|
|
19385
|
-
{
|
|
19386
|
-
ref: containerRef,
|
|
19387
|
-
"aria-label": `PDF viewer for ${fileName2}`,
|
|
19388
|
-
className: "absolute inset-0 overflow-auto",
|
|
19389
|
-
children: /* @__PURE__ */ jsx("div", { ref: viewerRef, className: "pdfViewer" })
|
|
19390
|
-
}
|
|
19391
|
-
) })
|
|
19392
|
-
] });
|
|
19393
|
-
}
|
|
19394
|
-
function decodeBase64(content) {
|
|
19395
|
-
const binary = globalThis.atob(content);
|
|
19396
|
-
const bytes = new Uint8Array(binary.length);
|
|
19397
|
-
for (let index = 0; index < binary.length; index += 1) {
|
|
19398
|
-
bytes[index] = binary.charCodeAt(index);
|
|
19399
|
-
}
|
|
19400
|
-
return bytes;
|
|
19228
|
+
}, [adapter, sessionId, path, theme, view, placeholderId, reopenedFor]);
|
|
19229
|
+
const fileName2 = path.split("/").pop() ?? path;
|
|
19230
|
+
return /* @__PURE__ */ jsxs(
|
|
19231
|
+
"aside",
|
|
19232
|
+
{
|
|
19233
|
+
"data-testid": "file-preview-panel",
|
|
19234
|
+
className: "flex h-full min-h-0 w-full flex-col overflow-hidden border-l border-line bg-card",
|
|
19235
|
+
children: [
|
|
19236
|
+
/* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center gap-2 border-b border-line px-3 py-2", children: [
|
|
19237
|
+
/* @__PURE__ */ jsx(FileTextIcon, { className: "size-4 shrink-0 text-muted-foreground" }),
|
|
19238
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1 truncate font-medium", children: fileName2 }),
|
|
19239
|
+
/* @__PURE__ */ jsx(
|
|
19240
|
+
"a",
|
|
19241
|
+
{
|
|
19242
|
+
href: adapter.getWorkspaceDownloadUrl({ sessionId, path }),
|
|
19243
|
+
download: fileName2,
|
|
19244
|
+
"aria-label": `Download ${fileName2}`,
|
|
19245
|
+
title: "Download",
|
|
19246
|
+
className: "shrink-0 rounded p-0.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
19247
|
+
children: /* @__PURE__ */ jsx(DownloadIcon, { className: "size-4" })
|
|
19248
|
+
}
|
|
19249
|
+
),
|
|
19250
|
+
/* @__PURE__ */ jsx(
|
|
19251
|
+
"button",
|
|
19252
|
+
{
|
|
19253
|
+
type: "button",
|
|
19254
|
+
onClick: onClose,
|
|
19255
|
+
"aria-label": "Close file",
|
|
19256
|
+
className: "shrink-0 rounded p-0.5 text-muted-foreground transition-colors hover:bg-muted hover:text-foreground",
|
|
19257
|
+
children: /* @__PURE__ */ jsx(XIcon, { className: "size-4" })
|
|
19258
|
+
}
|
|
19259
|
+
)
|
|
19260
|
+
] }),
|
|
19261
|
+
error && /* @__PURE__ */ jsxs("div", { role: "alert", className: "flex items-start gap-2 p-3 text-xs text-destructive", children: [
|
|
19262
|
+
/* @__PURE__ */ jsx(AlertCircleIcon, { className: "mt-0.5 size-3.5 shrink-0" }),
|
|
19263
|
+
/* @__PURE__ */ jsx("span", { children: error })
|
|
19264
|
+
] }),
|
|
19265
|
+
notice && /* @__PURE__ */ jsx("div", { role: "status", className: "border-b border-line px-3 py-2 text-xs text-muted-foreground", children: notice.type === "office.conflict" ? `This document changed outside the editor. Your edits were saved to ${notice.conflictPath}.` : "Your latest changes could not be saved yet." }),
|
|
19266
|
+
loading && !error && /* @__PURE__ */ jsxs("div", { className: "p-3 text-sm text-muted-foreground", children: [
|
|
19267
|
+
"Opening ",
|
|
19268
|
+
fileName2,
|
|
19269
|
+
"\u2026"
|
|
19270
|
+
] }),
|
|
19271
|
+
/* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1", children: /* @__PURE__ */ jsx("div", { id: placeholderId }) })
|
|
19272
|
+
]
|
|
19273
|
+
}
|
|
19274
|
+
);
|
|
19401
19275
|
}
|
|
19402
|
-
function
|
|
19403
|
-
if (
|
|
19404
|
-
return
|
|
19276
|
+
function WorkspaceFileDrawer({ adapter, sessionId, path, view = false, officeEvent, onClose }) {
|
|
19277
|
+
if (isOfficeDocument(path)) {
|
|
19278
|
+
return /* @__PURE__ */ jsx(OfficeEditorPane, { adapter, sessionId, path, view, officeEvent, onClose });
|
|
19405
19279
|
}
|
|
19406
|
-
return
|
|
19280
|
+
return /* @__PURE__ */ jsx(WorkspaceFilePreview, { adapter, sessionId, path, onClose });
|
|
19407
19281
|
}
|
|
19408
|
-
function
|
|
19282
|
+
function WorkspaceFilePreview({
|
|
19409
19283
|
adapter,
|
|
19410
19284
|
sessionId,
|
|
19411
19285
|
path,
|
|
@@ -20526,6 +20400,8 @@ function AgentChat({
|
|
|
20526
20400
|
adapter,
|
|
20527
20401
|
sessionId,
|
|
20528
20402
|
path: previewPath,
|
|
20403
|
+
view: effectiveDisabled,
|
|
20404
|
+
officeEvent: runtime.state.officeEvents[previewPath],
|
|
20529
20405
|
onClose: () => setOpenPane(null)
|
|
20530
20406
|
}
|
|
20531
20407
|
)
|