@ottocode/web-sdk 0.1.275 → 0.1.277
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/components/chat/ChatInputContainer.d.ts.map +1 -1
- package/dist/components/chat/InputQueueBar.d.ts.map +1 -1
- package/dist/components/file-browser/FileViewerPanel.d.ts +2 -1
- package/dist/components/file-browser/FileViewerPanel.d.ts.map +1 -1
- package/dist/components/git/GitDiffViewer.d.ts.map +1 -1
- package/dist/components/index.js +1078 -433
- package/dist/components/index.js.map +23 -23
- package/dist/components/messages/MessagePartItem.d.ts.map +1 -1
- package/dist/components/messages/MessageThread.d.ts.map +1 -1
- package/dist/components/messages/MessageThreadContainer.d.ts.map +1 -1
- package/dist/components/messages/renderers/DiffView.d.ts.map +1 -1
- package/dist/components/session-files/SessionFilesDiffPanel.d.ts.map +1 -1
- package/dist/components/ui/CodeMirrorViewer.d.ts +2 -1
- package/dist/components/ui/CodeMirrorViewer.d.ts.map +1 -1
- package/dist/components/ui/Toaster.d.ts.map +1 -1
- package/dist/components/workspace/ToolPreviewPanel.d.ts.map +1 -1
- package/dist/components/workspace/ViewerTabs.d.ts.map +1 -1
- package/dist/hooks/index.js +309 -60
- package/dist/hooks/index.js.map +8 -8
- package/dist/hooks/useProviderUsage.d.ts +1 -1
- package/dist/hooks/useProviderUsage.d.ts.map +1 -1
- package/dist/hooks/useQueueState.d.ts +9 -0
- package/dist/hooks/useQueueState.d.ts.map +1 -1
- package/dist/hooks/useSessionStream.d.ts.map +1 -1
- package/dist/index.js +1096 -450
- package/dist/index.js.map +23 -23
- package/dist/lib/api-client/index.d.ts +13 -0
- package/dist/lib/api-client/index.d.ts.map +1 -1
- package/dist/lib/api-client/sessions.d.ts +13 -0
- package/dist/lib/api-client/sessions.d.ts.map +1 -1
- package/dist/lib/commands.d.ts.map +1 -1
- package/dist/lib/index.js +25 -1
- package/dist/lib/index.js.map +4 -4
- package/dist/stores/index.js +77 -16
- package/dist/stores/index.js.map +3 -3
- package/dist/stores/viewerTabsStore.d.ts +9 -0
- package/dist/stores/viewerTabsStore.d.ts.map +1 -1
- package/dist/types/api.d.ts +1 -1
- package/dist/types/api.d.ts.map +1 -1
- package/package.json +5 -3
package/dist/components/index.js
CHANGED
|
@@ -480,6 +480,8 @@ function ToastItem({ toast: toast2 }) {
|
|
|
480
480
|
};
|
|
481
481
|
const style = typeStyles[toast2.type];
|
|
482
482
|
const transitionClass = phase === "enter" ? "opacity-0 translate-y-2 scale-95" : phase === "exit" ? "opacity-0 translate-y-1 scale-95" : "opacity-100 translate-y-0 scale-100";
|
|
483
|
+
const rowAlignmentClass = toast2.type === "loading" ? "items-center" : "items-start";
|
|
484
|
+
const iconOffsetClass = toast2.type === "loading" ? "" : "mt-px";
|
|
483
485
|
return /* @__PURE__ */ jsxs3("div", {
|
|
484
486
|
className: `
|
|
485
487
|
relative overflow-hidden
|
|
@@ -494,10 +496,10 @@ function ToastItem({ toast: toast2 }) {
|
|
|
494
496
|
role: "alert",
|
|
495
497
|
children: [
|
|
496
498
|
/* @__PURE__ */ jsxs3("div", {
|
|
497
|
-
className:
|
|
499
|
+
className: `flex ${rowAlignmentClass} gap-2.5 px-3 py-2.5`,
|
|
498
500
|
children: [
|
|
499
501
|
/* @__PURE__ */ jsx7("span", {
|
|
500
|
-
className:
|
|
502
|
+
className: `${iconOffsetClass} shrink-0`,
|
|
501
503
|
children: style.icon
|
|
502
504
|
}),
|
|
503
505
|
/* @__PURE__ */ jsx7("div", {
|
|
@@ -1191,6 +1193,21 @@ var sessionsMixin = {
|
|
|
1191
1193
|
throw new Error(extractErrorMessage(response.error));
|
|
1192
1194
|
return response.data;
|
|
1193
1195
|
},
|
|
1196
|
+
async createHandoff(sessionId) {
|
|
1197
|
+
const response = await fetch(`${getBaseUrl()}/v1/sessions/${encodeURIComponent(sessionId)}/handoff`, { method: "POST" });
|
|
1198
|
+
const data = await response.json().catch(() => null);
|
|
1199
|
+
if (!response.ok)
|
|
1200
|
+
throw new Error(extractErrorMessage(data));
|
|
1201
|
+
if (!data?.session || !data?.sessionId) {
|
|
1202
|
+
throw new Error("No data returned from handoff");
|
|
1203
|
+
}
|
|
1204
|
+
return {
|
|
1205
|
+
session: convertSession(data.session),
|
|
1206
|
+
sessionId: String(data.sessionId),
|
|
1207
|
+
sourceSessionId: String(data.sourceSessionId),
|
|
1208
|
+
message: String(data.message ?? "")
|
|
1209
|
+
};
|
|
1210
|
+
},
|
|
1194
1211
|
async abortSession(sessionId) {
|
|
1195
1212
|
const response = await apiAbortSession({ path: { sessionId } });
|
|
1196
1213
|
if (response.error)
|
|
@@ -1219,6 +1236,13 @@ var sessionsMixin = {
|
|
|
1219
1236
|
throw new Error("Failed to remove from queue");
|
|
1220
1237
|
return response.data;
|
|
1221
1238
|
},
|
|
1239
|
+
async sendQueuedMessageNow(sessionId, messageId) {
|
|
1240
|
+
const response = await fetch(`${getBaseUrl()}/v1/sessions/${encodeURIComponent(sessionId)}/queue/${encodeURIComponent(messageId)}/send-now`, { method: "POST" });
|
|
1241
|
+
const data = await response.json().catch(() => null);
|
|
1242
|
+
if (!response.ok)
|
|
1243
|
+
throw new Error(extractErrorMessage(data));
|
|
1244
|
+
return data;
|
|
1245
|
+
},
|
|
1222
1246
|
async getMessages(sessionId) {
|
|
1223
1247
|
const response = await apiListMessages({ path: { id: sessionId } });
|
|
1224
1248
|
if (response.error)
|
|
@@ -1925,10 +1949,12 @@ class ApiClient {
|
|
|
1925
1949
|
updateSession = sessionsMixin.updateSession;
|
|
1926
1950
|
markSessionViewed = sessionsMixin.markSessionViewed;
|
|
1927
1951
|
deleteSession = sessionsMixin.deleteSession;
|
|
1952
|
+
createHandoff = sessionsMixin.createHandoff;
|
|
1928
1953
|
abortSession = sessionsMixin.abortSession;
|
|
1929
1954
|
abortMessage = sessionsMixin.abortMessage;
|
|
1930
1955
|
getQueueState = sessionsMixin.getQueueState;
|
|
1931
1956
|
removeFromQueue = sessionsMixin.removeFromQueue;
|
|
1957
|
+
sendQueuedMessageNow = sessionsMixin.sendQueuedMessageNow;
|
|
1932
1958
|
getMessages = sessionsMixin.getMessages;
|
|
1933
1959
|
sendMessage = sessionsMixin.sendMessage;
|
|
1934
1960
|
getStreamUrl = sessionsMixin.getStreamUrl;
|
|
@@ -2199,7 +2225,8 @@ import {
|
|
|
2199
2225
|
Trash2,
|
|
2200
2226
|
Share2,
|
|
2201
2227
|
RefreshCw,
|
|
2202
|
-
FileText as FileText2
|
|
2228
|
+
FileText as FileText2,
|
|
2229
|
+
ArrowRightLeft
|
|
2203
2230
|
} from "lucide-react";
|
|
2204
2231
|
var COMMANDS = [
|
|
2205
2232
|
{
|
|
@@ -2268,6 +2295,12 @@ var COMMANDS = [
|
|
|
2268
2295
|
description: "Generate AGENTS.md and .agents docs from the real repo structure",
|
|
2269
2296
|
icon: FileText2
|
|
2270
2297
|
},
|
|
2298
|
+
{
|
|
2299
|
+
id: "handoff",
|
|
2300
|
+
label: "/handoff",
|
|
2301
|
+
description: "Create a new session with current context",
|
|
2302
|
+
icon: ArrowRightLeft
|
|
2303
|
+
},
|
|
2271
2304
|
{
|
|
2272
2305
|
id: "branch",
|
|
2273
2306
|
label: "/branch",
|
|
@@ -3828,6 +3861,7 @@ import {
|
|
|
3828
3861
|
Clock,
|
|
3829
3862
|
ListOrdered,
|
|
3830
3863
|
RotateCcw,
|
|
3864
|
+
Send,
|
|
3831
3865
|
Trash2 as Trash22
|
|
3832
3866
|
} from "lucide-react";
|
|
3833
3867
|
import { useQueryClient as useQueryClient4 } from "@tanstack/react-query";
|
|
@@ -3840,14 +3874,26 @@ import { useQuery as useQuery4 } from "@tanstack/react-query";
|
|
|
3840
3874
|
var defaultQueueState = {
|
|
3841
3875
|
currentMessageId: null,
|
|
3842
3876
|
queuedMessages: [],
|
|
3843
|
-
queueLength: 0
|
|
3877
|
+
queueLength: 0,
|
|
3878
|
+
isRunning: false
|
|
3844
3879
|
};
|
|
3880
|
+
function normalizeQueueState(state) {
|
|
3881
|
+
const isRunning = state.isRunning ?? Boolean(state.currentMessageId);
|
|
3882
|
+
const currentMessageId = isRunning ? state.currentMessageId : null;
|
|
3883
|
+
const hasActiveTurn = Boolean(currentMessageId);
|
|
3884
|
+
const queuedMessages = hasActiveTurn ? state.queuedMessages : [];
|
|
3885
|
+
return {
|
|
3886
|
+
currentMessageId,
|
|
3887
|
+
queuedMessages,
|
|
3888
|
+
queueLength: queuedMessages.length,
|
|
3889
|
+
isRunning: hasActiveTurn
|
|
3890
|
+
};
|
|
3891
|
+
}
|
|
3845
3892
|
function optimisticallyQueueMessage(queryClient, sessionId, messageId) {
|
|
3846
3893
|
queryClient.setQueryData(["queueState", sessionId], (current) => {
|
|
3847
3894
|
if (!current)
|
|
3848
3895
|
return current;
|
|
3849
|
-
|
|
3850
|
-
if (!isBusy)
|
|
3896
|
+
if (!current.isRunning || !current.currentMessageId)
|
|
3851
3897
|
return current;
|
|
3852
3898
|
if (current.currentMessageId === messageId)
|
|
3853
3899
|
return current;
|
|
@@ -3872,11 +3918,7 @@ function useQueueState(sessionId) {
|
|
|
3872
3918
|
if (!sessionId)
|
|
3873
3919
|
return defaultQueueState;
|
|
3874
3920
|
const queueState = await apiClient.getQueueState(sessionId);
|
|
3875
|
-
return
|
|
3876
|
-
currentMessageId: queueState.currentMessageId,
|
|
3877
|
-
queuedMessages: queueState.queuedMessages,
|
|
3878
|
-
queueLength: queueState.queuedMessages.length
|
|
3879
|
-
};
|
|
3921
|
+
return normalizeQueueState(queueState);
|
|
3880
3922
|
},
|
|
3881
3923
|
enabled: !!sessionId,
|
|
3882
3924
|
placeholderData: defaultQueueState,
|
|
@@ -4082,6 +4124,7 @@ function getQueuedPreviews(messages, queuedMessages) {
|
|
|
4082
4124
|
}
|
|
4083
4125
|
function QueueRow({
|
|
4084
4126
|
item,
|
|
4127
|
+
onSendNow,
|
|
4085
4128
|
onCancel,
|
|
4086
4129
|
onDelete
|
|
4087
4130
|
}) {
|
|
@@ -4099,6 +4142,15 @@ function QueueRow({
|
|
|
4099
4142
|
/* @__PURE__ */ jsxs11("div", {
|
|
4100
4143
|
className: "flex items-center gap-1 flex-shrink-0",
|
|
4101
4144
|
children: [
|
|
4145
|
+
/* @__PURE__ */ jsx17("button", {
|
|
4146
|
+
type: "button",
|
|
4147
|
+
onClick: () => onSendNow(item),
|
|
4148
|
+
className: "flex h-7 w-7 items-center justify-center rounded bg-transparent text-muted-foreground transition-colors hover:bg-primary/10 hover:text-primary",
|
|
4149
|
+
title: "Send now",
|
|
4150
|
+
children: /* @__PURE__ */ jsx17(Send, {
|
|
4151
|
+
className: "h-3.5 w-3.5"
|
|
4152
|
+
})
|
|
4153
|
+
}),
|
|
4102
4154
|
/* @__PURE__ */ jsx17("button", {
|
|
4103
4155
|
type: "button",
|
|
4104
4156
|
onClick: () => onCancel(item),
|
|
@@ -4148,6 +4200,15 @@ var InputQueueBar = memo4(function InputQueueBar2({
|
|
|
4148
4200
|
console.error("Failed to remove queued message:", error);
|
|
4149
4201
|
}
|
|
4150
4202
|
};
|
|
4203
|
+
const sendQueuedItemNow = async (item) => {
|
|
4204
|
+
try {
|
|
4205
|
+
await apiClient.sendQueuedMessageNow(sessionId, item.assistantMessageId);
|
|
4206
|
+
queryClient.invalidateQueries({ queryKey: ["messages", sessionId] });
|
|
4207
|
+
queryClient.invalidateQueries({ queryKey: ["queueState", sessionId] });
|
|
4208
|
+
} catch (error) {
|
|
4209
|
+
console.error("Failed to send queued message now:", error);
|
|
4210
|
+
}
|
|
4211
|
+
};
|
|
4151
4212
|
return /* @__PURE__ */ jsx17("div", {
|
|
4152
4213
|
className: "grid transition-[grid-template-rows,opacity] duration-200 ease-out",
|
|
4153
4214
|
style: {
|
|
@@ -4246,6 +4307,7 @@ var InputQueueBar = memo4(function InputQueueBar2({
|
|
|
4246
4307
|
className: "divide-y divide-border",
|
|
4247
4308
|
children: queuedItems.map((item) => /* @__PURE__ */ jsx17(QueueRow, {
|
|
4248
4309
|
item,
|
|
4310
|
+
onSendNow: sendQueuedItemNow,
|
|
4249
4311
|
onCancel: (queuedItem) => removeQueuedItem(queuedItem, true),
|
|
4250
4312
|
onDelete: (queuedItem) => removeQueuedItem(queuedItem, false)
|
|
4251
4313
|
}, item.assistantMessageId))
|
|
@@ -5219,6 +5281,53 @@ function mergeChangedLines(existing, incoming) {
|
|
|
5219
5281
|
return existing;
|
|
5220
5282
|
return [...new Set([...existing, ...incoming])].sort((a, b) => a - b);
|
|
5221
5283
|
}
|
|
5284
|
+
function countContentLines(content) {
|
|
5285
|
+
return content.length === 0 ? 1 : content.split(`
|
|
5286
|
+
`).length;
|
|
5287
|
+
}
|
|
5288
|
+
function annotationId(preview, targetPath) {
|
|
5289
|
+
return `${preview.toolName}:${preview.callId ?? `${normalizeViewerPath(targetPath)}:${preview.patch ?? preview.content ?? ""}`}`;
|
|
5290
|
+
}
|
|
5291
|
+
function buildAnnotation(preview, targetPath, existing) {
|
|
5292
|
+
if (preview.status === "error")
|
|
5293
|
+
return existing;
|
|
5294
|
+
const id = annotationId(preview, targetPath);
|
|
5295
|
+
if (preview.toolName === "write") {
|
|
5296
|
+
const content = preview.content;
|
|
5297
|
+
if (content === undefined)
|
|
5298
|
+
return existing;
|
|
5299
|
+
return {
|
|
5300
|
+
id,
|
|
5301
|
+
reason: "write",
|
|
5302
|
+
callId: preview.callId,
|
|
5303
|
+
status: preview.status,
|
|
5304
|
+
lineTones: Array.from({ length: countContentLines(content) }, (_, index) => [index + 1, "add"]),
|
|
5305
|
+
createdAt: existing?.createdAt ?? Date.now()
|
|
5306
|
+
};
|
|
5307
|
+
}
|
|
5308
|
+
const lineTones = preview.previewLineTones?.length ? preview.previewLineTones : preview.changedLines?.length ? preview.changedLines.map((line) => [line, "add"]) : existing?.lineTones;
|
|
5309
|
+
if (!lineTones?.length)
|
|
5310
|
+
return existing;
|
|
5311
|
+
return {
|
|
5312
|
+
id,
|
|
5313
|
+
reason: "apply_patch",
|
|
5314
|
+
callId: preview.callId,
|
|
5315
|
+
status: preview.status,
|
|
5316
|
+
lineTones,
|
|
5317
|
+
createdAt: existing?.createdAt ?? Date.now()
|
|
5318
|
+
};
|
|
5319
|
+
}
|
|
5320
|
+
function upsertAnnotation(annotations, annotation) {
|
|
5321
|
+
if (!annotation)
|
|
5322
|
+
return annotations;
|
|
5323
|
+
const existing = annotations ?? [];
|
|
5324
|
+
const index = existing.findIndex((item) => item.id === annotation.id);
|
|
5325
|
+
if (index === -1)
|
|
5326
|
+
return [...existing, annotation];
|
|
5327
|
+
const next = [...existing];
|
|
5328
|
+
next[index] = annotation;
|
|
5329
|
+
return next;
|
|
5330
|
+
}
|
|
5222
5331
|
var useViewerTabsStore = create8((set) => ({
|
|
5223
5332
|
tabs: [],
|
|
5224
5333
|
activeTabId: null,
|
|
@@ -5265,7 +5374,11 @@ var useViewerTabsStore = create8((set) => ({
|
|
|
5265
5374
|
id: targetId,
|
|
5266
5375
|
type: "file",
|
|
5267
5376
|
title: existingFile?.title ?? titleFromPath(targetPath),
|
|
5268
|
-
path: targetPath
|
|
5377
|
+
path: targetPath,
|
|
5378
|
+
highlight: existingFile?.highlight,
|
|
5379
|
+
annotations: existingFile?.annotations,
|
|
5380
|
+
patchPreview: existingFile?.patchPreview,
|
|
5381
|
+
writePreview: existingFile?.writePreview
|
|
5269
5382
|
}),
|
|
5270
5383
|
activeTabId: targetId
|
|
5271
5384
|
};
|
|
@@ -5286,6 +5399,7 @@ var useViewerTabsStore = create8((set) => ({
|
|
|
5286
5399
|
title: existingFile?.title ?? titleFromPath(targetPath),
|
|
5287
5400
|
path: targetPath,
|
|
5288
5401
|
highlight,
|
|
5402
|
+
annotations: existingFile?.annotations,
|
|
5289
5403
|
patchPreview: undefined,
|
|
5290
5404
|
writePreview: undefined
|
|
5291
5405
|
}),
|
|
@@ -5307,6 +5421,12 @@ var useViewerTabsStore = create8((set) => ({
|
|
|
5307
5421
|
const samePatchCall = isSamePatchCall(existingPatchPreview, preview);
|
|
5308
5422
|
const baseContent = preview.baseContent ?? (samePatchCall ? existingPatchPreview?.baseContent : existingPatchPreview?.resultContent ?? existingPatchPreview?.baseContent);
|
|
5309
5423
|
const changedLines = samePatchCall ? preview.changedLines ?? existingPatchPreview?.changedLines : mergeChangedLines(existingPatchPreview?.changedLines, preview.changedLines);
|
|
5424
|
+
const annotationPreview = {
|
|
5425
|
+
...preview,
|
|
5426
|
+
changedLines: preview.changedLines
|
|
5427
|
+
};
|
|
5428
|
+
const existingAnnotation = existingFile?.annotations?.find((annotation2) => annotation2.id === annotationId(annotationPreview, targetPath));
|
|
5429
|
+
const annotations = upsertAnnotation(existingFile?.annotations, buildAnnotation(annotationPreview, targetPath, existingAnnotation));
|
|
5310
5430
|
return {
|
|
5311
5431
|
tabs: upsertTab(tabs, {
|
|
5312
5432
|
id: targetId,
|
|
@@ -5314,6 +5434,7 @@ var useViewerTabsStore = create8((set) => ({
|
|
|
5314
5434
|
title: existingFile?.title ?? titleFromPath(targetPath),
|
|
5315
5435
|
path: targetPath,
|
|
5316
5436
|
highlight: undefined,
|
|
5437
|
+
annotations,
|
|
5317
5438
|
writePreview: undefined,
|
|
5318
5439
|
patchPreview: {
|
|
5319
5440
|
path: targetPath,
|
|
@@ -5336,10 +5457,13 @@ var useViewerTabsStore = create8((set) => ({
|
|
|
5336
5457
|
}
|
|
5337
5458
|
if (existingFile) {
|
|
5338
5459
|
const existingWritePreview = existingFile.writePreview;
|
|
5460
|
+
const existingAnnotation = existingFile.annotations?.find((annotation2) => annotation2.id === annotationId(preview, targetPath));
|
|
5461
|
+
const annotations = upsertAnnotation(existingFile.annotations, buildAnnotation(preview, targetPath, existingAnnotation));
|
|
5339
5462
|
return {
|
|
5340
5463
|
tabs: upsertTab(tabs, {
|
|
5341
5464
|
...existingFile,
|
|
5342
5465
|
highlight: undefined,
|
|
5466
|
+
annotations,
|
|
5343
5467
|
patchPreview: undefined,
|
|
5344
5468
|
writePreview: {
|
|
5345
5469
|
path: targetPath,
|
|
@@ -5354,25 +5478,24 @@ var useViewerTabsStore = create8((set) => ({
|
|
|
5354
5478
|
};
|
|
5355
5479
|
}
|
|
5356
5480
|
const existingWrite = existing?.toolName === "write" ? existing : undefined;
|
|
5481
|
+
const annotation = buildAnnotation(preview, preview.path);
|
|
5357
5482
|
return {
|
|
5358
5483
|
tabs: upsertTab(tabs, {
|
|
5359
5484
|
id,
|
|
5360
|
-
type: "
|
|
5485
|
+
type: "file",
|
|
5361
5486
|
title: titleFromPath(preview.path),
|
|
5362
5487
|
path: preview.path,
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
status: preview.status,
|
|
5375
|
-
error: preview.error ?? existingWrite?.error
|
|
5488
|
+
highlight: undefined,
|
|
5489
|
+
annotations: annotation ? [annotation] : undefined,
|
|
5490
|
+
patchPreview: undefined,
|
|
5491
|
+
writePreview: {
|
|
5492
|
+
path: preview.path,
|
|
5493
|
+
toolName: "write",
|
|
5494
|
+
callId: preview.callId,
|
|
5495
|
+
content: preview.content ?? existingWrite?.content,
|
|
5496
|
+
status: preview.status,
|
|
5497
|
+
error: preview.error ?? existingWrite?.error
|
|
5498
|
+
}
|
|
5376
5499
|
}),
|
|
5377
5500
|
activeTabId: id
|
|
5378
5501
|
};
|
|
@@ -7280,6 +7403,24 @@ ${content}` : content;
|
|
|
7280
7403
|
handleSendMessage("/compact");
|
|
7281
7404
|
} else if (commandId === "init") {
|
|
7282
7405
|
handleSendMessage("/init");
|
|
7406
|
+
} else if (commandId === "handoff") {
|
|
7407
|
+
const toastId2 = toast.loading("Creating handoff...");
|
|
7408
|
+
try {
|
|
7409
|
+
const result = await apiClient.createHandoff(sessionId);
|
|
7410
|
+
queryClient.invalidateQueries({ queryKey: ["sessions"] });
|
|
7411
|
+
queryClient.invalidateQueries({
|
|
7412
|
+
queryKey: ["messages", sessionId]
|
|
7413
|
+
});
|
|
7414
|
+
queryClient.invalidateQueries({
|
|
7415
|
+
queryKey: ["messages", result.sessionId]
|
|
7416
|
+
});
|
|
7417
|
+
openPlatformSession(result.sessionId);
|
|
7418
|
+
toast.success("Handoff created");
|
|
7419
|
+
} catch (error) {
|
|
7420
|
+
toast.error(error instanceof Error ? error.message : "Failed to create handoff");
|
|
7421
|
+
} finally {
|
|
7422
|
+
useToastStore.getState().removeToast(toastId2);
|
|
7423
|
+
}
|
|
7283
7424
|
} else if (commandId === "delete") {
|
|
7284
7425
|
deleteSession.mutate(sessionId, {
|
|
7285
7426
|
onSuccess: () => {
|
|
@@ -7913,7 +8054,9 @@ function getLanguageFromPath(path) {
|
|
|
7913
8054
|
html: "html",
|
|
7914
8055
|
css: "css",
|
|
7915
8056
|
scss: "scss",
|
|
7916
|
-
md: "
|
|
8057
|
+
md: "text",
|
|
8058
|
+
markdown: "text",
|
|
8059
|
+
mdx: "text",
|
|
7917
8060
|
txt: "text",
|
|
7918
8061
|
svelte: "svelte"
|
|
7919
8062
|
};
|
|
@@ -7928,6 +8071,11 @@ function parseDiff(patch) {
|
|
|
7928
8071
|
let inHunk = false;
|
|
7929
8072
|
let filePath = "";
|
|
7930
8073
|
for (const line of lines) {
|
|
8074
|
+
const lineModePath = line.match(/^\*\*\* (?:Delete Lines in|Replace Lines in|Insert Before in|Insert After in): (.+)$/);
|
|
8075
|
+
if (lineModePath?.[1]) {
|
|
8076
|
+
filePath = lineModePath[1];
|
|
8077
|
+
inHunk = false;
|
|
8078
|
+
}
|
|
7931
8079
|
if (line.startsWith("*** Update File:") || line.startsWith("*** Add File:")) {
|
|
7932
8080
|
const match = line.match(/\*\*\* (?:Update|Add) File: (.+)/);
|
|
7933
8081
|
if (match)
|
|
@@ -12913,101 +13061,83 @@ var MessagePartItem = memo10(function MessagePartItem2({
|
|
|
12913
13061
|
} else if (data) {
|
|
12914
13062
|
content = JSON.stringify(data, null, 2);
|
|
12915
13063
|
}
|
|
12916
|
-
return /* @__PURE__ */
|
|
13064
|
+
return /* @__PURE__ */ jsx59("div", {
|
|
12917
13065
|
className: "relative group",
|
|
12918
|
-
children:
|
|
12919
|
-
|
|
12920
|
-
|
|
12921
|
-
|
|
12922
|
-
|
|
12923
|
-
|
|
12924
|
-
|
|
12925
|
-
|
|
12926
|
-
|
|
12927
|
-
|
|
12928
|
-
|
|
12929
|
-
|
|
12930
|
-
|
|
12931
|
-
|
|
12932
|
-
|
|
12933
|
-
href
|
|
12934
|
-
|
|
12935
|
-
|
|
12936
|
-
|
|
12937
|
-
|
|
12938
|
-
|
|
12939
|
-
|
|
12940
|
-
|
|
12941
|
-
|
|
12942
|
-
|
|
12943
|
-
|
|
12944
|
-
|
|
12945
|
-
|
|
12946
|
-
|
|
12947
|
-
|
|
13066
|
+
children: /* @__PURE__ */ jsx59("div", {
|
|
13067
|
+
className: `${isCompactThread ? "text-[16.5px]" : "text-[17px]"} text-foreground leading-relaxed markdown-content max-w-full overflow-x-auto`,
|
|
13068
|
+
children: /* @__PURE__ */ jsx59(ReactMarkdown, {
|
|
13069
|
+
remarkPlugins: [remarkGfm],
|
|
13070
|
+
components: {
|
|
13071
|
+
a: ({
|
|
13072
|
+
href,
|
|
13073
|
+
children,
|
|
13074
|
+
...props
|
|
13075
|
+
}) => /* @__PURE__ */ jsx59("a", {
|
|
13076
|
+
href,
|
|
13077
|
+
target: "_blank",
|
|
13078
|
+
rel: "noopener noreferrer",
|
|
13079
|
+
className: "text-primary underline decoration-primary/35 underline-offset-2 transition-colors hover:text-primary/90 hover:decoration-primary",
|
|
13080
|
+
onClick: (e) => {
|
|
13081
|
+
if (window.self !== window.top && href) {
|
|
13082
|
+
e.preventDefault();
|
|
13083
|
+
window.parent.postMessage({
|
|
13084
|
+
type: "otto-open-url",
|
|
13085
|
+
url: href
|
|
13086
|
+
}, "*");
|
|
13087
|
+
}
|
|
13088
|
+
},
|
|
13089
|
+
...props,
|
|
13090
|
+
children
|
|
13091
|
+
}),
|
|
13092
|
+
pre: ({
|
|
13093
|
+
children,
|
|
13094
|
+
...props
|
|
13095
|
+
}) => {
|
|
13096
|
+
const codeContent = (() => {
|
|
13097
|
+
if (!children)
|
|
13098
|
+
return "";
|
|
13099
|
+
const child = Array.isArray(children) ? children[0] : children;
|
|
13100
|
+
if (child && typeof child === "object" && "props" in child) {
|
|
13101
|
+
const codeProps = child.props;
|
|
13102
|
+
if (typeof codeProps.children === "string") {
|
|
13103
|
+
return codeProps.children;
|
|
12948
13104
|
}
|
|
12949
|
-
}
|
|
13105
|
+
}
|
|
13106
|
+
return "";
|
|
13107
|
+
})();
|
|
13108
|
+
return /* @__PURE__ */ jsxs50("div", {
|
|
13109
|
+
className: "relative group/code my-3",
|
|
13110
|
+
children: [
|
|
13111
|
+
/* @__PURE__ */ jsx59("div", {
|
|
13112
|
+
className: "absolute top-2 right-2 opacity-0 group-hover/code:opacity-100 transition-opacity z-10",
|
|
13113
|
+
children: /* @__PURE__ */ jsx59(CopyButton, {
|
|
13114
|
+
text: codeContent,
|
|
13115
|
+
className: "bg-background/80 backdrop-blur-sm border border-border/50 shadow-sm",
|
|
13116
|
+
size: "sm"
|
|
13117
|
+
})
|
|
13118
|
+
}),
|
|
13119
|
+
/* @__PURE__ */ jsx59("pre", {
|
|
13120
|
+
...props,
|
|
13121
|
+
className: "overflow-x-auto",
|
|
13122
|
+
children
|
|
13123
|
+
})
|
|
13124
|
+
]
|
|
13125
|
+
});
|
|
13126
|
+
},
|
|
13127
|
+
table: ({
|
|
13128
|
+
children,
|
|
13129
|
+
...props
|
|
13130
|
+
}) => /* @__PURE__ */ jsx59("div", {
|
|
13131
|
+
className: "overflow-x-auto max-w-full min-w-0 my-3",
|
|
13132
|
+
children: /* @__PURE__ */ jsx59("table", {
|
|
12950
13133
|
...props,
|
|
12951
13134
|
children
|
|
12952
|
-
}),
|
|
12953
|
-
pre: ({
|
|
12954
|
-
children,
|
|
12955
|
-
...props
|
|
12956
|
-
}) => {
|
|
12957
|
-
const codeContent = (() => {
|
|
12958
|
-
if (!children)
|
|
12959
|
-
return "";
|
|
12960
|
-
const child = Array.isArray(children) ? children[0] : children;
|
|
12961
|
-
if (child && typeof child === "object" && "props" in child) {
|
|
12962
|
-
const codeProps = child.props;
|
|
12963
|
-
if (typeof codeProps.children === "string") {
|
|
12964
|
-
return codeProps.children;
|
|
12965
|
-
}
|
|
12966
|
-
}
|
|
12967
|
-
return "";
|
|
12968
|
-
})();
|
|
12969
|
-
return /* @__PURE__ */ jsxs50("div", {
|
|
12970
|
-
className: "relative group/code my-3",
|
|
12971
|
-
children: [
|
|
12972
|
-
/* @__PURE__ */ jsx59("div", {
|
|
12973
|
-
className: "absolute top-2 right-2 opacity-0 group-hover/code:opacity-100 transition-opacity z-10",
|
|
12974
|
-
children: /* @__PURE__ */ jsx59(CopyButton, {
|
|
12975
|
-
text: codeContent,
|
|
12976
|
-
className: "bg-background/80 backdrop-blur-sm border border-border/50 shadow-sm",
|
|
12977
|
-
size: "sm"
|
|
12978
|
-
})
|
|
12979
|
-
}),
|
|
12980
|
-
/* @__PURE__ */ jsx59("pre", {
|
|
12981
|
-
...props,
|
|
12982
|
-
className: "overflow-x-auto",
|
|
12983
|
-
children
|
|
12984
|
-
})
|
|
12985
|
-
]
|
|
12986
|
-
});
|
|
12987
|
-
},
|
|
12988
|
-
table: ({
|
|
12989
|
-
children,
|
|
12990
|
-
...props
|
|
12991
|
-
}) => /* @__PURE__ */ jsx59("div", {
|
|
12992
|
-
className: "overflow-x-auto max-w-full min-w-0 my-3",
|
|
12993
|
-
children: /* @__PURE__ */ jsx59("table", {
|
|
12994
|
-
...props,
|
|
12995
|
-
children
|
|
12996
|
-
})
|
|
12997
13135
|
})
|
|
12998
|
-
}
|
|
12999
|
-
|
|
13000
|
-
|
|
13001
|
-
}),
|
|
13002
|
-
content.length > 500 && /* @__PURE__ */ jsx59("div", {
|
|
13003
|
-
className: "absolute -bottom-1 right-0 opacity-0 group-hover:opacity-100 transition-opacity z-10",
|
|
13004
|
-
children: /* @__PURE__ */ jsx59(CopyButton, {
|
|
13005
|
-
text: content,
|
|
13006
|
-
className: "bg-background/80 backdrop-blur-sm border border-border/50 shadow-sm",
|
|
13007
|
-
size: "md"
|
|
13008
|
-
})
|
|
13136
|
+
})
|
|
13137
|
+
},
|
|
13138
|
+
children: content
|
|
13009
13139
|
})
|
|
13010
|
-
|
|
13140
|
+
})
|
|
13011
13141
|
});
|
|
13012
13142
|
}
|
|
13013
13143
|
if (part.type === "error") {
|
|
@@ -14059,7 +14189,7 @@ function ActionToolBox({ part, showLine, compact }) {
|
|
|
14059
14189
|
},
|
|
14060
14190
|
children: /* @__PURE__ */ jsx61("pre", {
|
|
14061
14191
|
ref: contentMeasureRef,
|
|
14062
|
-
className: "px-1 pt-2.5 pb-1 text-[12px] leading-relaxed text-foreground/60 font-mono whitespace-pre-wrap break-
|
|
14192
|
+
className: "px-1 pt-2.5 pb-1 text-[12px] leading-relaxed text-foreground/60 font-mono whitespace-pre-wrap break-words",
|
|
14063
14193
|
children: displayContent
|
|
14064
14194
|
})
|
|
14065
14195
|
})
|
|
@@ -14123,20 +14253,10 @@ function extractJsonStringField(raw, field) {
|
|
|
14123
14253
|
let result = "";
|
|
14124
14254
|
let i = start;
|
|
14125
14255
|
while (i < raw.length) {
|
|
14126
|
-
|
|
14127
|
-
|
|
14128
|
-
|
|
14129
|
-
|
|
14130
|
-
`;
|
|
14131
|
-
else if (next === "t")
|
|
14132
|
-
result += "\t";
|
|
14133
|
-
else if (next === '"')
|
|
14134
|
-
result += '"';
|
|
14135
|
-
else if (next === "\\")
|
|
14136
|
-
result += "\\";
|
|
14137
|
-
else
|
|
14138
|
-
result += next;
|
|
14139
|
-
i += 2;
|
|
14256
|
+
const decoded = decodeJsonStringChar(raw, i);
|
|
14257
|
+
if (decoded) {
|
|
14258
|
+
result += decoded.value;
|
|
14259
|
+
i = decoded.nextIndex;
|
|
14140
14260
|
} else if (raw[i] === '"') {
|
|
14141
14261
|
break;
|
|
14142
14262
|
} else {
|
|
@@ -14146,6 +14266,38 @@ function extractJsonStringField(raw, field) {
|
|
|
14146
14266
|
}
|
|
14147
14267
|
return result;
|
|
14148
14268
|
}
|
|
14269
|
+
function decodeJsonStringChar(raw, index) {
|
|
14270
|
+
if (raw[index] !== "\\" || index + 1 >= raw.length)
|
|
14271
|
+
return null;
|
|
14272
|
+
const next = raw[index + 1];
|
|
14273
|
+
if (next === "n")
|
|
14274
|
+
return { value: `
|
|
14275
|
+
`, nextIndex: index + 2 };
|
|
14276
|
+
if (next === "t")
|
|
14277
|
+
return { value: "\t", nextIndex: index + 2 };
|
|
14278
|
+
if (next === "r")
|
|
14279
|
+
return { value: "\r", nextIndex: index + 2 };
|
|
14280
|
+
if (next === "b")
|
|
14281
|
+
return { value: "\b", nextIndex: index + 2 };
|
|
14282
|
+
if (next === "f")
|
|
14283
|
+
return { value: "\f", nextIndex: index + 2 };
|
|
14284
|
+
if (next === '"')
|
|
14285
|
+
return { value: '"', nextIndex: index + 2 };
|
|
14286
|
+
if (next === "\\")
|
|
14287
|
+
return { value: "\\", nextIndex: index + 2 };
|
|
14288
|
+
if (next === "/")
|
|
14289
|
+
return { value: "/", nextIndex: index + 2 };
|
|
14290
|
+
if (next === "u" && index + 5 < raw.length) {
|
|
14291
|
+
const hex = raw.slice(index + 2, index + 6);
|
|
14292
|
+
if (/^[0-9a-fA-F]{4}$/.test(hex)) {
|
|
14293
|
+
return {
|
|
14294
|
+
value: String.fromCharCode(Number.parseInt(hex, 16)),
|
|
14295
|
+
nextIndex: index + 6
|
|
14296
|
+
};
|
|
14297
|
+
}
|
|
14298
|
+
}
|
|
14299
|
+
return { value: next, nextIndex: index + 2 };
|
|
14300
|
+
}
|
|
14149
14301
|
function extractJsonStringFieldPreview(raw, field) {
|
|
14150
14302
|
const pattern = new RegExp(`"${field}"\\s*:\\s*"`);
|
|
14151
14303
|
const m = pattern.exec(raw);
|
|
@@ -14155,8 +14307,25 @@ function extractJsonStringFieldPreview(raw, field) {
|
|
|
14155
14307
|
if (raw.length - start <= LIVE_TOOL_CONTENT_PREVIEW_CHARS) {
|
|
14156
14308
|
return extractJsonStringField(raw, field);
|
|
14157
14309
|
}
|
|
14310
|
+
let result = "";
|
|
14311
|
+
let i = start;
|
|
14312
|
+
while (i < raw.length) {
|
|
14313
|
+
const decoded = decodeJsonStringChar(raw, i);
|
|
14314
|
+
if (decoded) {
|
|
14315
|
+
result += decoded.value;
|
|
14316
|
+
i = decoded.nextIndex;
|
|
14317
|
+
} else if (raw[i] === '"') {
|
|
14318
|
+
break;
|
|
14319
|
+
} else {
|
|
14320
|
+
result += raw[i];
|
|
14321
|
+
i += 1;
|
|
14322
|
+
}
|
|
14323
|
+
if (result.length > LIVE_TOOL_CONTENT_PREVIEW_CHARS) {
|
|
14324
|
+
result = result.slice(-LIVE_TOOL_CONTENT_PREVIEW_CHARS);
|
|
14325
|
+
}
|
|
14326
|
+
}
|
|
14158
14327
|
return `… showing latest streamed content only …
|
|
14159
|
-
${
|
|
14328
|
+
${result}`;
|
|
14160
14329
|
}
|
|
14161
14330
|
function getLiveToolContentPreview(toolName, content) {
|
|
14162
14331
|
if (toolName !== "write" && toolName !== "apply_patch" && content.length <= LIVE_TOOL_CONTENT_PREVIEW_CHARS) {
|
|
@@ -15837,21 +16006,23 @@ var UsageModal = memo14(function UsageModal2() {
|
|
|
15837
16006
|
// src/hooks/useProviderUsage.ts
|
|
15838
16007
|
import { useEffect as useEffect23, useCallback as useCallback15, useRef as useRef15 } from "react";
|
|
15839
16008
|
var POLL_INTERVAL = 60000;
|
|
15840
|
-
var STALE_THRESHOLD =
|
|
16009
|
+
var STALE_THRESHOLD = 60000;
|
|
15841
16010
|
var inflight = new Set;
|
|
15842
16011
|
function useProviderUsage(provider, authType) {
|
|
15843
16012
|
const setUsage = useUsageStore((s) => s.setUsage);
|
|
15844
16013
|
const setLoading = useUsageStore((s) => s.setLoading);
|
|
15845
16014
|
const setLastFetched = useUsageStore((s) => s.setLastFetched);
|
|
16015
|
+
const isModalOpen = useUsageStore((s) => s.isModalOpen);
|
|
16016
|
+
const modalProvider = useUsageStore((s) => s.modalProvider);
|
|
15846
16017
|
const usage = useUsageStore((s) => provider ? s.usage[provider] : undefined);
|
|
15847
16018
|
const isOAuthProvider = authType === "oauth" && (provider === "anthropic" || provider === "openai");
|
|
15848
|
-
const fetchUsage = useCallback15(async () => {
|
|
16019
|
+
const fetchUsage = useCallback15(async (force = false) => {
|
|
15849
16020
|
if (!provider || !isOAuthProvider)
|
|
15850
16021
|
return;
|
|
15851
16022
|
if (inflight.has(provider))
|
|
15852
16023
|
return;
|
|
15853
16024
|
const last = useUsageStore.getState().lastFetched[provider] ?? 0;
|
|
15854
|
-
if (last && Date.now() - last < STALE_THRESHOLD)
|
|
16025
|
+
if (!force && last && Date.now() - last < STALE_THRESHOLD)
|
|
15855
16026
|
return;
|
|
15856
16027
|
inflight.add(provider);
|
|
15857
16028
|
setLoading(provider, true);
|
|
@@ -15870,9 +16041,15 @@ function useProviderUsage(provider, authType) {
|
|
|
15870
16041
|
if (!provider || !isOAuthProvider)
|
|
15871
16042
|
return;
|
|
15872
16043
|
fetchRef.current();
|
|
16044
|
+
}, [isOAuthProvider, provider]);
|
|
16045
|
+
useEffect23(() => {
|
|
16046
|
+
if (!provider || !isOAuthProvider || !isModalOpen || modalProvider !== provider) {
|
|
16047
|
+
return;
|
|
16048
|
+
}
|
|
16049
|
+
fetchRef.current(true);
|
|
15873
16050
|
const interval = setInterval(() => fetchRef.current(), POLL_INTERVAL);
|
|
15874
16051
|
return () => clearInterval(interval);
|
|
15875
|
-
}, [isOAuthProvider, provider]);
|
|
16052
|
+
}, [isModalOpen, isOAuthProvider, modalProvider, provider]);
|
|
15876
16053
|
return {
|
|
15877
16054
|
usage,
|
|
15878
16055
|
fetchUsage,
|
|
@@ -16585,7 +16762,7 @@ var MessageThread = memo16(function MessageThread2({
|
|
|
16585
16762
|
}
|
|
16586
16763
|
};
|
|
16587
16764
|
const filteredMessages = useMemo17(() => {
|
|
16588
|
-
const visibleMessages = messages.filter((message) => message.role !== "system");
|
|
16765
|
+
const visibleMessages = messages.filter((message) => message.role !== "system" && !(message.role === "assistant" && message.status === "complete" && (message.parts?.length ?? 0) === 0));
|
|
16589
16766
|
const queueBusy = Boolean(queueState.currentMessageId) || queueState.queueLength > 0;
|
|
16590
16767
|
if (!queueBusy)
|
|
16591
16768
|
return visibleMessages;
|
|
@@ -16756,7 +16933,8 @@ var MessageThread = memo16(function MessageThread2({
|
|
|
16756
16933
|
});
|
|
16757
16934
|
});
|
|
16758
16935
|
// src/components/messages/MessageThreadContainer.tsx
|
|
16759
|
-
import { memo as memo19, useMemo as useMemo18 } from "react";
|
|
16936
|
+
import { memo as memo19, useEffect as useEffect29, useMemo as useMemo18 } from "react";
|
|
16937
|
+
import { useQueryClient as useQueryClient12 } from "@tanstack/react-query";
|
|
16760
16938
|
|
|
16761
16939
|
// src/hooks/useSessionStream.ts
|
|
16762
16940
|
import { useEffect as useEffect26, useRef as useRef18 } from "react";
|
|
@@ -17163,22 +17341,30 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
|
|
|
17163
17341
|
return;
|
|
17164
17342
|
let changeLines = 0;
|
|
17165
17343
|
let stableChangeLength = 0;
|
|
17344
|
+
let lineDirectiveCount = 0;
|
|
17166
17345
|
for (const line of stablePatch.split(`
|
|
17167
17346
|
`)) {
|
|
17168
17347
|
if (line.startsWith("+") && !line.startsWith("+++") || line.startsWith("-") && !line.startsWith("---")) {
|
|
17169
17348
|
changeLines += 1;
|
|
17170
17349
|
stableChangeLength += line.length;
|
|
17350
|
+
} else if (/^\*\*\* (?:Delete Lines in|Replace Lines in|Insert Before in|Insert After in): /.test(line) || line.startsWith("*** Lines:") || line.startsWith("*** Line:") || line.startsWith("*** With:")) {
|
|
17351
|
+
lineDirectiveCount += 1;
|
|
17171
17352
|
}
|
|
17172
17353
|
}
|
|
17173
|
-
|
|
17354
|
+
if (changeLines > 0)
|
|
17355
|
+
return `${changeLines}:${stableChangeLength}`;
|
|
17356
|
+
return lineDirectiveCount > 0 ? `lines:${lineDirectiveCount}:${stablePatch.length}` : undefined;
|
|
17174
17357
|
};
|
|
17175
17358
|
const extractPathsFromPatch = (patch) => {
|
|
17176
17359
|
const paths = new Set;
|
|
17177
17360
|
for (const line of patch.split(`
|
|
17178
17361
|
`)) {
|
|
17179
17362
|
const directive = line.match(/^\*\*\* (?:Update|Add|Delete) File: (.+)$/);
|
|
17180
|
-
|
|
17181
|
-
|
|
17363
|
+
const replaceDirective = line.match(/^\*\*\* Replace in: (.+)$/);
|
|
17364
|
+
const lineDirective = line.match(/^\*\*\* (?:Delete Lines in|Replace Lines in|Insert Before in|Insert After in): (.+)$/);
|
|
17365
|
+
const path = directive?.[1] ?? replaceDirective?.[1] ?? lineDirective?.[1];
|
|
17366
|
+
if (path) {
|
|
17367
|
+
paths.add(path.trim());
|
|
17182
17368
|
continue;
|
|
17183
17369
|
}
|
|
17184
17370
|
const unified = line.match(/^\+\+\+ (?:b\/)?(.+)$/);
|
|
@@ -17188,6 +17374,47 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
|
|
|
17188
17374
|
}
|
|
17189
17375
|
return [...paths];
|
|
17190
17376
|
};
|
|
17377
|
+
const getExtension = (path) => path.split(".").pop()?.toLowerCase() ?? "";
|
|
17378
|
+
const updateFileContentCache = (path, content) => {
|
|
17379
|
+
queryClient.setQueryData(["files", "read", path], {
|
|
17380
|
+
content,
|
|
17381
|
+
path,
|
|
17382
|
+
extension: getExtension(path),
|
|
17383
|
+
lineCount: content.split(`
|
|
17384
|
+
`).length
|
|
17385
|
+
});
|
|
17386
|
+
};
|
|
17387
|
+
const mergeReadResultIntoFileCache = (path, result, startLine, endLine) => {
|
|
17388
|
+
if (typeof result?.content !== "string")
|
|
17389
|
+
return;
|
|
17390
|
+
const readContent = result.content;
|
|
17391
|
+
if (!startLine || !endLine) {
|
|
17392
|
+
updateFileContentCache(path, readContent);
|
|
17393
|
+
return;
|
|
17394
|
+
}
|
|
17395
|
+
queryClient.setQueryData(["files", "read", path], (current) => {
|
|
17396
|
+
if (!current?.content)
|
|
17397
|
+
return current;
|
|
17398
|
+
const lines = current.content.split(`
|
|
17399
|
+
`);
|
|
17400
|
+
if (lines.at(-1) === "")
|
|
17401
|
+
lines.pop();
|
|
17402
|
+
const readLines = readContent.split(`
|
|
17403
|
+
`);
|
|
17404
|
+
lines.splice(startLine - 1, endLine - startLine + 1, ...readLines);
|
|
17405
|
+
const content = `${lines.join(`
|
|
17406
|
+
`)}
|
|
17407
|
+
`;
|
|
17408
|
+
return {
|
|
17409
|
+
...current,
|
|
17410
|
+
content,
|
|
17411
|
+
lineCount: typeof result.totalLines === "number" ? result.totalLines : lines.length
|
|
17412
|
+
};
|
|
17413
|
+
});
|
|
17414
|
+
};
|
|
17415
|
+
const invalidateFileContentCache = (path) => {
|
|
17416
|
+
queryClient.invalidateQueries({ queryKey: ["files", "read", path] });
|
|
17417
|
+
};
|
|
17191
17418
|
const getChangedLinesForPath = (result, path) => {
|
|
17192
17419
|
const changes = Array.isArray(result?.changes) ? result.changes : [];
|
|
17193
17420
|
const lines = new Set;
|
|
@@ -17217,9 +17444,6 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
|
|
|
17217
17444
|
return lines.size > 0 ? [...lines] : undefined;
|
|
17218
17445
|
};
|
|
17219
17446
|
const handleReadToolActivity = (eventType, payload, delta) => {
|
|
17220
|
-
const viewerStore = useViewerTabsStore.getState();
|
|
17221
|
-
if (!viewerStore.followToolActivity)
|
|
17222
|
-
return;
|
|
17223
17447
|
const name = getToolEventName(payload);
|
|
17224
17448
|
if (name !== "read")
|
|
17225
17449
|
return;
|
|
@@ -17232,6 +17456,12 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
|
|
|
17232
17456
|
const startLine = normalizeLineNumber(args.startLine) ?? normalizeLineNumber(args.start_line) ?? rangeFromResult.startLine;
|
|
17233
17457
|
const endLine = normalizeLineNumber(args.endLine) ?? normalizeLineNumber(args.end_line) ?? rangeFromResult.endLine ?? startLine;
|
|
17234
17458
|
const failed = result?.ok === false || eventType === "error";
|
|
17459
|
+
if (eventType === "tool.result" && !failed) {
|
|
17460
|
+
mergeReadResultIntoFileCache(path, result, startLine, endLine);
|
|
17461
|
+
}
|
|
17462
|
+
const viewerStore = useViewerTabsStore.getState();
|
|
17463
|
+
if (!viewerStore.followToolActivity)
|
|
17464
|
+
return;
|
|
17235
17465
|
viewerStore.openToolReadTab(path, {
|
|
17236
17466
|
startLine,
|
|
17237
17467
|
endLine,
|
|
@@ -17241,9 +17471,6 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
|
|
|
17241
17471
|
});
|
|
17242
17472
|
};
|
|
17243
17473
|
const handleWriteToolActivity = (eventType, payload, delta) => {
|
|
17244
|
-
const viewerStore = useViewerTabsStore.getState();
|
|
17245
|
-
if (!viewerStore.followToolActivity)
|
|
17246
|
-
return;
|
|
17247
17474
|
const name = getToolEventName(payload);
|
|
17248
17475
|
if (name !== "write")
|
|
17249
17476
|
return;
|
|
@@ -17257,6 +17484,15 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
|
|
|
17257
17484
|
const callId = getToolEventCallId(payload) ?? undefined;
|
|
17258
17485
|
const status = failed ? "error" : eventType === "tool.result" ? "success" : "streaming";
|
|
17259
17486
|
const content = status === "streaming" ? getStreamingWritePreviewContent(args, buffer) : getStringArg(args, buffer, "content");
|
|
17487
|
+
if (status === "success") {
|
|
17488
|
+
if (content !== undefined)
|
|
17489
|
+
updateFileContentCache(path, content);
|
|
17490
|
+
else
|
|
17491
|
+
invalidateFileContentCache(path);
|
|
17492
|
+
}
|
|
17493
|
+
const viewerStore = useViewerTabsStore.getState();
|
|
17494
|
+
if (!viewerStore.followToolActivity)
|
|
17495
|
+
return;
|
|
17260
17496
|
if (status === "streaming" && content !== undefined && content.length >= TOOL_PREVIEW_THROTTLE_MIN_CHARS) {
|
|
17261
17497
|
const previewKey = callId ?? path;
|
|
17262
17498
|
const now = Date.now();
|
|
@@ -17280,9 +17516,6 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
|
|
|
17280
17516
|
});
|
|
17281
17517
|
};
|
|
17282
17518
|
const handleApplyPatchToolActivity = (eventType, payload, delta) => {
|
|
17283
|
-
const viewerStore = useViewerTabsStore.getState();
|
|
17284
|
-
if (!viewerStore.followToolActivity)
|
|
17285
|
-
return;
|
|
17286
17519
|
const name = getToolEventName(payload);
|
|
17287
17520
|
if (name !== "apply_patch")
|
|
17288
17521
|
return;
|
|
@@ -17306,6 +17539,13 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
|
|
|
17306
17539
|
const patchPaths = extractPathsFromPatch(patch);
|
|
17307
17540
|
if (patchPaths.length === 0)
|
|
17308
17541
|
return;
|
|
17542
|
+
if (status === "success") {
|
|
17543
|
+
for (const path of patchPaths)
|
|
17544
|
+
invalidateFileContentCache(path);
|
|
17545
|
+
}
|
|
17546
|
+
const viewerStore = useViewerTabsStore.getState();
|
|
17547
|
+
if (!viewerStore.followToolActivity)
|
|
17548
|
+
return;
|
|
17309
17549
|
const matchingFileTabs = viewerStore.tabs.filter((tab) => tab.type === "file" && patchPaths.some((path) => patchPathMayReferToTarget(path, tab.path)));
|
|
17310
17550
|
const activeMatchingFileTab = matchingFileTabs.find((tab) => tab.id === viewerStore.activeTabId);
|
|
17311
17551
|
const fallbackPath = patchPaths.find(isLikelyCompletePatchPath);
|
|
@@ -17411,6 +17651,11 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
|
|
|
17411
17651
|
const applyMessageDelta = (payload) => {
|
|
17412
17652
|
const messageId = typeof payload?.messageId === "string" ? payload.messageId : null;
|
|
17413
17653
|
const partId = typeof payload?.partId === "string" ? payload.partId : null;
|
|
17654
|
+
const payloadType = typeof payload?.type === "string" ? payload.type : undefined;
|
|
17655
|
+
if (payloadType === "error") {
|
|
17656
|
+
upsertErrorPart(payload);
|
|
17657
|
+
return;
|
|
17658
|
+
}
|
|
17414
17659
|
const delta = typeof payload?.delta === "string" ? payload.delta : null;
|
|
17415
17660
|
if (!messageId || !partId || delta === null)
|
|
17416
17661
|
return;
|
|
@@ -17461,6 +17706,90 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
|
|
|
17461
17706
|
return nextMessages;
|
|
17462
17707
|
});
|
|
17463
17708
|
};
|
|
17709
|
+
const toRecord = (value) => {
|
|
17710
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
17711
|
+
return value;
|
|
17712
|
+
}
|
|
17713
|
+
return null;
|
|
17714
|
+
};
|
|
17715
|
+
const parseErrorContent = (payload) => {
|
|
17716
|
+
const contentRecord = toRecord(payload.content);
|
|
17717
|
+
if (contentRecord)
|
|
17718
|
+
return contentRecord;
|
|
17719
|
+
if (typeof payload.content === "string") {
|
|
17720
|
+
try {
|
|
17721
|
+
const parsed = JSON.parse(payload.content);
|
|
17722
|
+
const parsedRecord = toRecord(parsed);
|
|
17723
|
+
if (parsedRecord)
|
|
17724
|
+
return parsedRecord;
|
|
17725
|
+
} catch {}
|
|
17726
|
+
}
|
|
17727
|
+
const message = typeof payload.error === "string" ? payload.error : typeof payload.message === "string" ? payload.message : "Assistant run failed";
|
|
17728
|
+
return {
|
|
17729
|
+
message,
|
|
17730
|
+
type: typeof payload.errorType === "string" ? payload.errorType : "error",
|
|
17731
|
+
details: toRecord(payload.details) ?? undefined,
|
|
17732
|
+
isAborted: payload.isAborted === true,
|
|
17733
|
+
autoCompacted: payload.autoCompacted === true
|
|
17734
|
+
};
|
|
17735
|
+
};
|
|
17736
|
+
const upsertErrorPart = (payload) => {
|
|
17737
|
+
const messageId = typeof payload?.messageId === "string" ? payload.messageId : null;
|
|
17738
|
+
if (!payload || !messageId)
|
|
17739
|
+
return;
|
|
17740
|
+
const contentJson = parseErrorContent(payload);
|
|
17741
|
+
const content = JSON.stringify(contentJson);
|
|
17742
|
+
const errorMessage = typeof contentJson.message === "string" ? contentJson.message : typeof payload.error === "string" ? payload.error : "Assistant run failed";
|
|
17743
|
+
const stepIndex = typeof payload.stepIndex === "number" ? payload.stepIndex : null;
|
|
17744
|
+
const partId = typeof payload.partId === "string" ? payload.partId : `error-${messageId}`;
|
|
17745
|
+
queryClient.setQueryData(["messages", sessionId], (oldMessages) => {
|
|
17746
|
+
if (!oldMessages)
|
|
17747
|
+
return oldMessages;
|
|
17748
|
+
const nextMessages = [...oldMessages];
|
|
17749
|
+
const messageIndex = nextMessages.findIndex((message) => message.id === messageId);
|
|
17750
|
+
if (messageIndex === -1)
|
|
17751
|
+
return oldMessages;
|
|
17752
|
+
const targetMessage = nextMessages[messageIndex];
|
|
17753
|
+
const parts = targetMessage.parts ? [...targetMessage.parts] : [];
|
|
17754
|
+
const partIndex = parts.findIndex((part) => part.id === partId);
|
|
17755
|
+
if (partIndex === -1) {
|
|
17756
|
+
const newPart = {
|
|
17757
|
+
id: partId,
|
|
17758
|
+
messageId,
|
|
17759
|
+
index: getOptimisticPartIndex(parts, stepIndex),
|
|
17760
|
+
stepIndex,
|
|
17761
|
+
type: "error",
|
|
17762
|
+
content,
|
|
17763
|
+
contentJson,
|
|
17764
|
+
agent: targetMessage.agent,
|
|
17765
|
+
provider: targetMessage.provider,
|
|
17766
|
+
model: targetMessage.model,
|
|
17767
|
+
startedAt: Date.now(),
|
|
17768
|
+
completedAt: Date.now(),
|
|
17769
|
+
toolName: null,
|
|
17770
|
+
toolCallId: null,
|
|
17771
|
+
toolDurationMs: null
|
|
17772
|
+
};
|
|
17773
|
+
parts.push(newPart);
|
|
17774
|
+
} else {
|
|
17775
|
+
parts[partIndex] = {
|
|
17776
|
+
...parts[partIndex],
|
|
17777
|
+
content,
|
|
17778
|
+
contentJson,
|
|
17779
|
+
stepIndex: stepIndex ?? parts[partIndex].stepIndex ?? null,
|
|
17780
|
+
completedAt: Date.now()
|
|
17781
|
+
};
|
|
17782
|
+
}
|
|
17783
|
+
nextMessages[messageIndex] = {
|
|
17784
|
+
...targetMessage,
|
|
17785
|
+
status: "error",
|
|
17786
|
+
completedAt: targetMessage.completedAt ?? Date.now(),
|
|
17787
|
+
error: errorMessage,
|
|
17788
|
+
parts
|
|
17789
|
+
};
|
|
17790
|
+
return nextMessages;
|
|
17791
|
+
});
|
|
17792
|
+
};
|
|
17464
17793
|
const upsertEphemeralToolCall = (payload) => {
|
|
17465
17794
|
if (!payload)
|
|
17466
17795
|
return;
|
|
@@ -17890,6 +18219,17 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
|
|
|
17890
18219
|
}
|
|
17891
18220
|
markMessageCompleted(payload);
|
|
17892
18221
|
clearEphemeralForMessage(id);
|
|
18222
|
+
if (id) {
|
|
18223
|
+
queryClient.setQueryData(["queueState", sessionId], (current) => {
|
|
18224
|
+
if (!current || current.currentMessageId !== id)
|
|
18225
|
+
return current;
|
|
18226
|
+
return normalizeQueueState({
|
|
18227
|
+
currentMessageId: null,
|
|
18228
|
+
queuedMessages: [],
|
|
18229
|
+
isRunning: false
|
|
18230
|
+
});
|
|
18231
|
+
});
|
|
18232
|
+
}
|
|
17893
18233
|
queryClient.invalidateQueries({ queryKey: ["messages", sessionId] });
|
|
17894
18234
|
queryClient.invalidateQueries({ queryKey: sessionsQueryKey });
|
|
17895
18235
|
break;
|
|
@@ -17963,22 +18303,7 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
|
|
|
17963
18303
|
assistantMessageIdRef.current = null;
|
|
17964
18304
|
}
|
|
17965
18305
|
clearEphemeralForMessage(messageId);
|
|
17966
|
-
|
|
17967
|
-
queryClient.setQueryData(["messages", sessionId], (oldMessages) => {
|
|
17968
|
-
if (!oldMessages)
|
|
17969
|
-
return oldMessages;
|
|
17970
|
-
const idx = oldMessages.findIndex((m) => m.id === messageId);
|
|
17971
|
-
if (idx === -1)
|
|
17972
|
-
return oldMessages;
|
|
17973
|
-
const next = [...oldMessages];
|
|
17974
|
-
next[idx] = {
|
|
17975
|
-
...next[idx],
|
|
17976
|
-
status: "error",
|
|
17977
|
-
completedAt: next[idx].completedAt ?? Date.now(),
|
|
17978
|
-
error: errorMessage
|
|
17979
|
-
};
|
|
17980
|
-
return next;
|
|
17981
|
-
});
|
|
18306
|
+
upsertErrorPart(payload);
|
|
17982
18307
|
}
|
|
17983
18308
|
queryClient.invalidateQueries({ queryKey: ["messages", sessionId] });
|
|
17984
18309
|
break;
|
|
@@ -18013,11 +18338,11 @@ ${bestEffortUnescapeJsonString(rawTail)}`;
|
|
|
18013
18338
|
break;
|
|
18014
18339
|
}
|
|
18015
18340
|
case "queue.updated": {
|
|
18016
|
-
const queueState = {
|
|
18341
|
+
const queueState = normalizeQueueState({
|
|
18017
18342
|
currentMessageId: payload?.currentMessageId,
|
|
18018
18343
|
queuedMessages: payload?.queuedMessages ?? [],
|
|
18019
|
-
|
|
18020
|
-
};
|
|
18344
|
+
isRunning: typeof payload?.isRunning === "boolean" ? payload.isRunning : undefined
|
|
18345
|
+
});
|
|
18021
18346
|
queryClient.setQueryData(["queueState", sessionId], queueState);
|
|
18022
18347
|
break;
|
|
18023
18348
|
}
|
|
@@ -18962,10 +19287,16 @@ var MessageThreadContainer = memo19(function MessageThreadContainer2({
|
|
|
18962
19287
|
sessionId,
|
|
18963
19288
|
onSelectSession
|
|
18964
19289
|
}) {
|
|
19290
|
+
const queryClient = useQueryClient12();
|
|
18965
19291
|
const { data: messages = [], isLoading } = useMessages(sessionId);
|
|
18966
19292
|
const { data: sessions = [] } = useSessions();
|
|
18967
19293
|
const { preferences: preferences2 } = usePreferences();
|
|
18968
19294
|
useSessionStream(sessionId);
|
|
19295
|
+
useEffect29(() => {
|
|
19296
|
+
queryClient.invalidateQueries({ queryKey: ["messages", sessionId] });
|
|
19297
|
+
queryClient.invalidateQueries({ queryKey: ["queueState", sessionId] });
|
|
19298
|
+
queryClient.invalidateQueries({ queryKey: sessionsQueryKey });
|
|
19299
|
+
}, [queryClient, sessionId]);
|
|
18969
19300
|
useToolApprovalShortcuts(sessionId);
|
|
18970
19301
|
const session = useMemo18(() => sessions.find((s) => s.id === sessionId), [sessions, sessionId]);
|
|
18971
19302
|
const isGenerating = useMemo18(() => messages.some((m) => m.role === "assistant" && m.status === "pending"), [messages]);
|
|
@@ -19110,7 +19441,7 @@ var SessionItem = memo20(function SessionItem2({
|
|
|
19110
19441
|
});
|
|
19111
19442
|
});
|
|
19112
19443
|
// src/components/sessions/SessionListContainer.tsx
|
|
19113
|
-
import { memo as memo21, useMemo as useMemo19, useCallback as useCallback20, useEffect as
|
|
19444
|
+
import { memo as memo21, useMemo as useMemo19, useCallback as useCallback20, useEffect as useEffect30, useRef as useRef20 } from "react";
|
|
19114
19445
|
|
|
19115
19446
|
// src/stores/focusStore.ts
|
|
19116
19447
|
import { create as create20 } from "zustand";
|
|
@@ -19206,7 +19537,7 @@ var SessionListContainer = memo21(function SessionListContainer2({
|
|
|
19206
19537
|
sessions: groupedSessions
|
|
19207
19538
|
}));
|
|
19208
19539
|
}, [sessionSnapshot, statusSessionIds]);
|
|
19209
|
-
|
|
19540
|
+
useEffect30(() => {
|
|
19210
19541
|
if (currentFocus === "sessions") {
|
|
19211
19542
|
const session = sessionSnapshot[sessionIndex];
|
|
19212
19543
|
if (session) {
|
|
@@ -19229,14 +19560,14 @@ var SessionListContainer = memo21(function SessionListContainer2({
|
|
|
19229
19560
|
onError: () => markedViewedRef.current.delete(session.id)
|
|
19230
19561
|
});
|
|
19231
19562
|
}, [markSessionViewed, sessionSnapshot]);
|
|
19232
|
-
|
|
19563
|
+
useEffect30(() => {
|
|
19233
19564
|
const previousId = previousActiveSessionId.current;
|
|
19234
19565
|
if (previousId && previousId !== activeSessionId) {
|
|
19235
19566
|
markViewedIfReady(previousId);
|
|
19236
19567
|
}
|
|
19237
19568
|
previousActiveSessionId.current = activeSessionId;
|
|
19238
19569
|
}, [activeSessionId, markViewedIfReady]);
|
|
19239
|
-
|
|
19570
|
+
useEffect30(() => {
|
|
19240
19571
|
if (!activeSessionId || lastScrolledSessionId.current === activeSessionId || sessions.length === 0)
|
|
19241
19572
|
return;
|
|
19242
19573
|
const activeIndex = sessions.findIndex((s) => s.id === activeSessionId);
|
|
@@ -19252,7 +19583,7 @@ var SessionListContainer = memo21(function SessionListContainer2({
|
|
|
19252
19583
|
});
|
|
19253
19584
|
}
|
|
19254
19585
|
}, [activeSessionId, sessions, hasNextPage, fetchNextPage]);
|
|
19255
|
-
|
|
19586
|
+
useEffect30(() => {
|
|
19256
19587
|
const container = scrollContainerRef.current;
|
|
19257
19588
|
if (!container)
|
|
19258
19589
|
return;
|
|
@@ -19273,7 +19604,7 @@ var SessionListContainer = memo21(function SessionListContainer2({
|
|
|
19273
19604
|
container.addEventListener("scroll", handleScroll, { passive: true });
|
|
19274
19605
|
return () => container.removeEventListener("scroll", handleScroll);
|
|
19275
19606
|
}, [hasNextPage, isFetchingNextPage, fetchNextPage]);
|
|
19276
|
-
|
|
19607
|
+
useEffect30(() => {
|
|
19277
19608
|
const container = scrollContainerRef.current;
|
|
19278
19609
|
const sentinel = paginationSentinelRef.current;
|
|
19279
19610
|
if (!container || !sentinel || typeof IntersectionObserver === "undefined") {
|
|
@@ -19422,7 +19753,7 @@ import {
|
|
|
19422
19753
|
lineNumbers
|
|
19423
19754
|
} from "@codemirror/view";
|
|
19424
19755
|
import { tags } from "@lezer/highlight";
|
|
19425
|
-
import { useCallback as useCallback21, useEffect as
|
|
19756
|
+
import { useCallback as useCallback21, useEffect as useEffect31, useMemo as useMemo20, useRef as useRef21 } from "react";
|
|
19426
19757
|
import { jsx as jsx78 } from "react/jsx-runtime";
|
|
19427
19758
|
var viewerTheme = EditorView.theme({
|
|
19428
19759
|
"&": {
|
|
@@ -19579,7 +19910,7 @@ var syntaxTheme = HighlightStyle.define([
|
|
|
19579
19910
|
{ tag: tags.invalid, color: "var(--otto-cm-invalid)" }
|
|
19580
19911
|
]);
|
|
19581
19912
|
function lineDecorationsExtension(highlightedLines, highlightTone = "primary", lineTones) {
|
|
19582
|
-
return EditorView.decorations.compute([], (state) => {
|
|
19913
|
+
return EditorView.decorations.compute(["doc"], (state) => {
|
|
19583
19914
|
const decorations = [];
|
|
19584
19915
|
for (const [line, tone] of lineTones ?? []) {
|
|
19585
19916
|
if (line > 0)
|
|
@@ -19600,7 +19931,7 @@ function lineDecorationsExtension(highlightedLines, highlightTone = "primary", l
|
|
|
19600
19931
|
return builder.finish();
|
|
19601
19932
|
});
|
|
19602
19933
|
}
|
|
19603
|
-
function getLanguageExtension(path) {
|
|
19934
|
+
function getLanguageExtension(path, disableMarkdownSyntax = false) {
|
|
19604
19935
|
const ext = path?.split(".").pop()?.toLowerCase() ?? "";
|
|
19605
19936
|
switch (ext) {
|
|
19606
19937
|
case "js":
|
|
@@ -19632,6 +19963,8 @@ function getLanguageExtension(path) {
|
|
|
19632
19963
|
case "md":
|
|
19633
19964
|
case "markdown":
|
|
19634
19965
|
case "mdx":
|
|
19966
|
+
if (disableMarkdownSyntax)
|
|
19967
|
+
return [];
|
|
19635
19968
|
return markdown();
|
|
19636
19969
|
case "sql":
|
|
19637
19970
|
return sql();
|
|
@@ -19658,7 +19991,8 @@ function CodeMirrorViewer({
|
|
|
19658
19991
|
highlightTone = "primary",
|
|
19659
19992
|
lineTones,
|
|
19660
19993
|
scrollToLine,
|
|
19661
|
-
scrollToEndSignal
|
|
19994
|
+
scrollToEndSignal,
|
|
19995
|
+
disableMarkdownSyntax = false
|
|
19662
19996
|
}) {
|
|
19663
19997
|
const hostRef = useRef21(null);
|
|
19664
19998
|
const viewRef = useRef21(null);
|
|
@@ -19667,7 +20001,7 @@ function CodeMirrorViewer({
|
|
|
19667
20001
|
const decorationsCompartmentRef = useRef21(new Compartment);
|
|
19668
20002
|
const languageExtensionRef = useRef21([]);
|
|
19669
20003
|
const decorationsExtensionRef = useRef21([]);
|
|
19670
|
-
const languageExtension = useMemo20(() => getLanguageExtension(path), [path]);
|
|
20004
|
+
const languageExtension = useMemo20(() => getLanguageExtension(path, disableMarkdownSyntax), [path, disableMarkdownSyntax]);
|
|
19671
20005
|
const decorationsExtension = useMemo20(() => lineDecorationsExtension(highlightedLines, highlightTone, lineTones), [highlightedLines, highlightTone, lineTones]);
|
|
19672
20006
|
languageExtensionRef.current = languageExtension;
|
|
19673
20007
|
decorationsExtensionRef.current = decorationsExtension;
|
|
@@ -19683,7 +20017,7 @@ function CodeMirrorViewer({
|
|
|
19683
20017
|
decorationsCompartmentRef.current.of(decorationsExtension)
|
|
19684
20018
|
]
|
|
19685
20019
|
}), [languageExtension, decorationsExtension]);
|
|
19686
|
-
|
|
20020
|
+
useEffect31(() => {
|
|
19687
20021
|
const host = hostRef.current;
|
|
19688
20022
|
if (!host)
|
|
19689
20023
|
return;
|
|
@@ -19710,7 +20044,7 @@ function CodeMirrorViewer({
|
|
|
19710
20044
|
viewRef.current = null;
|
|
19711
20045
|
};
|
|
19712
20046
|
}, []);
|
|
19713
|
-
|
|
20047
|
+
useEffect31(() => {
|
|
19714
20048
|
const view = viewRef.current;
|
|
19715
20049
|
if (!view)
|
|
19716
20050
|
return;
|
|
@@ -19722,7 +20056,7 @@ function CodeMirrorViewer({
|
|
|
19722
20056
|
view.setState(createEditorState(contentRef.current));
|
|
19723
20057
|
}
|
|
19724
20058
|
}, [languageExtension, createEditorState]);
|
|
19725
|
-
|
|
20059
|
+
useEffect31(() => {
|
|
19726
20060
|
const view = viewRef.current;
|
|
19727
20061
|
if (!view)
|
|
19728
20062
|
return;
|
|
@@ -19734,7 +20068,7 @@ function CodeMirrorViewer({
|
|
|
19734
20068
|
view.setState(createEditorState(contentRef.current));
|
|
19735
20069
|
}
|
|
19736
20070
|
}, [decorationsExtension, createEditorState]);
|
|
19737
|
-
|
|
20071
|
+
useEffect31(() => {
|
|
19738
20072
|
const view = viewRef.current;
|
|
19739
20073
|
if (!view)
|
|
19740
20074
|
return;
|
|
@@ -19750,7 +20084,7 @@ function CodeMirrorViewer({
|
|
|
19750
20084
|
}
|
|
19751
20085
|
contentRef.current = content;
|
|
19752
20086
|
}, [content, createEditorState]);
|
|
19753
|
-
|
|
20087
|
+
useEffect31(() => {
|
|
19754
20088
|
const view = viewRef.current;
|
|
19755
20089
|
if (!view || !scrollToLine || scrollToLine < 1)
|
|
19756
20090
|
return;
|
|
@@ -19763,7 +20097,7 @@ function CodeMirrorViewer({
|
|
|
19763
20097
|
view.setState(createEditorState(contentRef.current));
|
|
19764
20098
|
}
|
|
19765
20099
|
}, [scrollToLine, createEditorState]);
|
|
19766
|
-
|
|
20100
|
+
useEffect31(() => {
|
|
19767
20101
|
const view = viewRef.current;
|
|
19768
20102
|
if (!view || scrollToEndSignal === undefined)
|
|
19769
20103
|
return;
|
|
@@ -19839,7 +20173,8 @@ function GitDiffViewer({ diff: diff2 }) {
|
|
|
19839
20173
|
className: "flex-1 min-h-0",
|
|
19840
20174
|
children: /* @__PURE__ */ jsx79(CodeMirrorViewer, {
|
|
19841
20175
|
content: diff2.content,
|
|
19842
|
-
path: diff2.file
|
|
20176
|
+
path: diff2.file,
|
|
20177
|
+
disableMarkdownSyntax: true
|
|
19843
20178
|
})
|
|
19844
20179
|
})
|
|
19845
20180
|
]
|
|
@@ -19882,8 +20217,9 @@ function GitDiffViewer({ diff: diff2 }) {
|
|
|
19882
20217
|
children: "No changes to display"
|
|
19883
20218
|
}) : /* @__PURE__ */ jsx79(CodeMirrorViewer, {
|
|
19884
20219
|
content: diff2.diff,
|
|
19885
|
-
path:
|
|
19886
|
-
lineTones: getDiffLineTones(diff2.diff)
|
|
20220
|
+
path: diff2.file,
|
|
20221
|
+
lineTones: getDiffLineTones(diff2.diff),
|
|
20222
|
+
disableMarkdownSyntax: true
|
|
19887
20223
|
})
|
|
19888
20224
|
})
|
|
19889
20225
|
});
|
|
@@ -20143,7 +20479,7 @@ ${file.absPath}`,
|
|
|
20143
20479
|
}
|
|
20144
20480
|
|
|
20145
20481
|
// src/components/git/GitFileList.tsx
|
|
20146
|
-
import { useEffect as
|
|
20482
|
+
import { useEffect as useEffect32, useRef as useRef22, useMemo as useMemo21 } from "react";
|
|
20147
20483
|
import { jsx as jsx81, jsxs as jsxs70 } from "react/jsx-runtime";
|
|
20148
20484
|
function GitFileList({ status }) {
|
|
20149
20485
|
const { openCommitModal, openDiff } = useGitStore();
|
|
@@ -20177,7 +20513,7 @@ function GitFileList({ status }) {
|
|
|
20177
20513
|
}
|
|
20178
20514
|
};
|
|
20179
20515
|
const conflictedLength = status.conflicted?.length ?? 0;
|
|
20180
|
-
|
|
20516
|
+
useEffect32(() => {
|
|
20181
20517
|
if (currentFocus === "git" && gitFileIndex >= 0) {
|
|
20182
20518
|
const element = itemRefs.current.get(gitFileIndex);
|
|
20183
20519
|
element?.scrollIntoView({ block: "nearest", behavior: "smooth" });
|
|
@@ -20381,7 +20717,7 @@ function GitFileList({ status }) {
|
|
|
20381
20717
|
});
|
|
20382
20718
|
}
|
|
20383
20719
|
// src/components/git/GitSidebar.tsx
|
|
20384
|
-
import { memo as memo22, useCallback as useCallback22, useEffect as
|
|
20720
|
+
import { memo as memo22, useCallback as useCallback22, useEffect as useEffect33, useState as useState36 } from "react";
|
|
20385
20721
|
import {
|
|
20386
20722
|
FolderGit2,
|
|
20387
20723
|
ChevronRight as ChevronRight11,
|
|
@@ -20396,7 +20732,7 @@ import {
|
|
|
20396
20732
|
Upload,
|
|
20397
20733
|
X as X12
|
|
20398
20734
|
} from "lucide-react";
|
|
20399
|
-
import { useQueryClient as
|
|
20735
|
+
import { useQueryClient as useQueryClient13 } from "@tanstack/react-query";
|
|
20400
20736
|
import { jsx as jsx82, jsxs as jsxs71, Fragment as Fragment33 } from "react/jsx-runtime";
|
|
20401
20737
|
var PANEL_KEY = "git";
|
|
20402
20738
|
var DEFAULT_WIDTH = 320;
|
|
@@ -20410,7 +20746,7 @@ var GitSidebar = memo22(function GitSidebar2({
|
|
|
20410
20746
|
const panelWidth = usePanelWidthStore((s) => s.widths[PANEL_KEY] ?? DEFAULT_WIDTH);
|
|
20411
20747
|
const { data: status, isLoading, error, refetch } = useGitStatus();
|
|
20412
20748
|
const { data: remotes } = useGitRemotes();
|
|
20413
|
-
const queryClient =
|
|
20749
|
+
const queryClient = useQueryClient13();
|
|
20414
20750
|
const pushMutation = usePushCommits();
|
|
20415
20751
|
const pullMutation = usePullChanges();
|
|
20416
20752
|
const initMutation = useGitInit();
|
|
@@ -20423,7 +20759,7 @@ var GitSidebar = memo22(function GitSidebar2({
|
|
|
20423
20759
|
const [remoteName, setRemoteName] = useState36("origin");
|
|
20424
20760
|
const [remoteUrl, setRemoteUrl] = useState36("");
|
|
20425
20761
|
const [confirmRemoveRemote, setConfirmRemoveRemote] = useState36(null);
|
|
20426
|
-
|
|
20762
|
+
useEffect33(() => {
|
|
20427
20763
|
if (isExpanded) {
|
|
20428
20764
|
queryClient.invalidateQueries({ queryKey: ["git", "status"] });
|
|
20429
20765
|
}
|
|
@@ -20938,11 +21274,11 @@ import { GitBranch as GitBranch9 } from "lucide-react";
|
|
|
20938
21274
|
import { memo as memo23 } from "react";
|
|
20939
21275
|
|
|
20940
21276
|
// src/hooks/useShortcutHintsVisible.ts
|
|
20941
|
-
import { useEffect as
|
|
21277
|
+
import { useEffect as useEffect34, useState as useState37 } from "react";
|
|
20942
21278
|
var SHORTCUT_HINT_MODIFIERS = new Set(["Control", "Meta"]);
|
|
20943
21279
|
function useShortcutHintsVisible() {
|
|
20944
21280
|
const [isVisible, setIsVisible] = useState37(false);
|
|
20945
|
-
|
|
21281
|
+
useEffect34(() => {
|
|
20946
21282
|
const handleKeyDown = (event) => {
|
|
20947
21283
|
if (SHORTCUT_HINT_MODIFIERS.has(event.key) || event.ctrlKey || event.metaKey) {
|
|
20948
21284
|
setIsVisible(true);
|
|
@@ -21008,7 +21344,7 @@ var GitSidebarToggle = memo24(function GitSidebarToggle2() {
|
|
|
21008
21344
|
});
|
|
21009
21345
|
});
|
|
21010
21346
|
// src/components/git/GitDiffPanel.tsx
|
|
21011
|
-
import { useEffect as
|
|
21347
|
+
import { useEffect as useEffect35, memo as memo25, useState as useState38 } from "react";
|
|
21012
21348
|
import { X as X13, Maximize2, Minimize2 as Minimize22 } from "lucide-react";
|
|
21013
21349
|
|
|
21014
21350
|
// src/hooks/useFileBrowser.ts
|
|
@@ -21063,11 +21399,11 @@ var GitDiffPanel = memo25(function GitDiffPanel2({
|
|
|
21063
21399
|
const { data: fullFileDiff, isLoading: fullFileLoading } = useGitDiffFullFile(selectedFile, selectedFileStaged, showFullFile);
|
|
21064
21400
|
const activeDiff = showFullFile && fullFileDiff ? fullFileDiff : diff2;
|
|
21065
21401
|
const activeLoading = showFullFile ? fullFileLoading : isLoading;
|
|
21066
|
-
|
|
21402
|
+
useEffect35(() => {
|
|
21067
21403
|
if (!isDiffOpen)
|
|
21068
21404
|
setShowFullFile(false);
|
|
21069
21405
|
}, [isDiffOpen]);
|
|
21070
|
-
|
|
21406
|
+
useEffect35(() => {
|
|
21071
21407
|
const handleEscape = (e) => {
|
|
21072
21408
|
const target = e.target;
|
|
21073
21409
|
const isInInput = target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable;
|
|
@@ -21162,7 +21498,7 @@ ${activeDiff?.absPath || ""}`,
|
|
|
21162
21498
|
});
|
|
21163
21499
|
});
|
|
21164
21500
|
// src/components/git/GitCommitModal.tsx
|
|
21165
|
-
import { useState as useState39, useId as useId2, useEffect as
|
|
21501
|
+
import { useState as useState39, useId as useId2, useEffect as useEffect36, useCallback as useCallback23 } from "react";
|
|
21166
21502
|
import { GitCommit as GitCommit4, Sparkles as Sparkles5 } from "lucide-react";
|
|
21167
21503
|
import { jsx as jsx86, jsxs as jsxs74, Fragment as Fragment34 } from "react/jsx-runtime";
|
|
21168
21504
|
function GitCommitModal() {
|
|
@@ -21195,7 +21531,7 @@ function GitCommitModal() {
|
|
|
21195
21531
|
console.error("Failed to generate commit message:", error);
|
|
21196
21532
|
}
|
|
21197
21533
|
}, [generateMessage]);
|
|
21198
|
-
|
|
21534
|
+
useEffect36(() => {
|
|
21199
21535
|
if (!isCommitModalOpen)
|
|
21200
21536
|
return;
|
|
21201
21537
|
const handleKeyDown = (e) => {
|
|
@@ -21334,7 +21670,7 @@ function GitCommitModal() {
|
|
|
21334
21670
|
});
|
|
21335
21671
|
}
|
|
21336
21672
|
// src/components/terminals/TerminalsPanel.tsx
|
|
21337
|
-
import { memo as memo27, useCallback as useCallback25, useRef as useRef24, useEffect as
|
|
21673
|
+
import { memo as memo27, useCallback as useCallback25, useRef as useRef24, useEffect as useEffect38 } from "react";
|
|
21338
21674
|
import {
|
|
21339
21675
|
Terminal as TerminalIcon,
|
|
21340
21676
|
Maximize2 as Maximize22,
|
|
@@ -21376,7 +21712,7 @@ var useTerminalStore = create21((set) => ({
|
|
|
21376
21712
|
}));
|
|
21377
21713
|
|
|
21378
21714
|
// src/hooks/useTerminals.ts
|
|
21379
|
-
import { useQuery as useQuery9, useMutation as useMutation6, useQueryClient as
|
|
21715
|
+
import { useQuery as useQuery9, useMutation as useMutation6, useQueryClient as useQueryClient14 } from "@tanstack/react-query";
|
|
21380
21716
|
import {
|
|
21381
21717
|
getTerminals,
|
|
21382
21718
|
postTerminals,
|
|
@@ -21397,7 +21733,7 @@ function useTerminals() {
|
|
|
21397
21733
|
});
|
|
21398
21734
|
}
|
|
21399
21735
|
function useCreateTerminal() {
|
|
21400
|
-
const queryClient =
|
|
21736
|
+
const queryClient = useQueryClient14();
|
|
21401
21737
|
return useMutation6({
|
|
21402
21738
|
mutationFn: async (params) => {
|
|
21403
21739
|
const response = await postTerminals({
|
|
@@ -21414,7 +21750,7 @@ function useCreateTerminal() {
|
|
|
21414
21750
|
});
|
|
21415
21751
|
}
|
|
21416
21752
|
function useKillTerminal() {
|
|
21417
|
-
const queryClient =
|
|
21753
|
+
const queryClient = useQueryClient14();
|
|
21418
21754
|
return useMutation6({
|
|
21419
21755
|
mutationFn: async (terminalId) => {
|
|
21420
21756
|
const response = await deleteTerminalsById({
|
|
@@ -21504,7 +21840,7 @@ var TerminalTabBar = memo26(function TerminalTabBar2({
|
|
|
21504
21840
|
});
|
|
21505
21841
|
|
|
21506
21842
|
// src/components/terminals/TerminalViewer.tsx
|
|
21507
|
-
import { useEffect as
|
|
21843
|
+
import { useEffect as useEffect37, useRef as useRef23, useState as useState40, useCallback as useCallback24 } from "react";
|
|
21508
21844
|
import { init, Terminal as Terminal7, FitAddon } from "ghostty-web";
|
|
21509
21845
|
import { client as client3 } from "@ottocode/api";
|
|
21510
21846
|
import { jsx as jsx88, jsxs as jsxs76 } from "react/jsx-runtime";
|
|
@@ -21669,7 +22005,7 @@ function TerminalViewer({
|
|
|
21669
22005
|
}
|
|
21670
22006
|
};
|
|
21671
22007
|
}, [terminalId]);
|
|
21672
|
-
|
|
22008
|
+
useEffect37(() => {
|
|
21673
22009
|
if (!containerRef.current || !terminalId)
|
|
21674
22010
|
return;
|
|
21675
22011
|
let disposed = false;
|
|
@@ -21839,7 +22175,7 @@ function TerminalViewer({
|
|
|
21839
22175
|
fitAddonRef.current = null;
|
|
21840
22176
|
};
|
|
21841
22177
|
}, [terminalId, connectWebSocket]);
|
|
21842
|
-
|
|
22178
|
+
useEffect37(() => {
|
|
21843
22179
|
const term = termRef.current;
|
|
21844
22180
|
if (!term)
|
|
21845
22181
|
return;
|
|
@@ -21857,7 +22193,7 @@ function TerminalViewer({
|
|
|
21857
22193
|
}
|
|
21858
22194
|
}
|
|
21859
22195
|
}, [isActive, fitTerminal]);
|
|
21860
|
-
|
|
22196
|
+
useEffect37(() => {
|
|
21861
22197
|
fitTerminal();
|
|
21862
22198
|
}, [fitTerminal]);
|
|
21863
22199
|
return /* @__PURE__ */ jsx88("div", {
|
|
@@ -21914,12 +22250,12 @@ var TerminalsPanel = memo27(function TerminalsPanel2() {
|
|
|
21914
22250
|
const autoCreatingRef = useRef24(false);
|
|
21915
22251
|
const terminalsListRef = useRef24(terminalsList);
|
|
21916
22252
|
terminalsListRef.current = terminalsList;
|
|
21917
|
-
|
|
22253
|
+
useEffect38(() => {
|
|
21918
22254
|
if (isOpen && terminalsListRef.current.length > 0 && (!activeTabId || !terminalsListRef.current.find((t) => t.id === activeTabId))) {
|
|
21919
22255
|
selectTab(terminalsListRef.current[0].id);
|
|
21920
22256
|
}
|
|
21921
22257
|
}, [isOpen, terminalsList.length, activeTabId, selectTab]);
|
|
21922
|
-
|
|
22258
|
+
useEffect38(() => {
|
|
21923
22259
|
if (isOpen && terminals && terminalsList.length === 0 && !autoCreatingRef.current && !createTerminal.isPending) {
|
|
21924
22260
|
autoCreatingRef.current = true;
|
|
21925
22261
|
createTerminal.mutateAsync({
|
|
@@ -21955,7 +22291,7 @@ var TerminalsPanel = memo27(function TerminalsPanel2() {
|
|
|
21955
22291
|
}
|
|
21956
22292
|
} catch {}
|
|
21957
22293
|
}, [killTerminal, activeTabId, selectTab, closePanel]);
|
|
21958
|
-
|
|
22294
|
+
useEffect38(() => {
|
|
21959
22295
|
const handleKeyDown = (e) => {
|
|
21960
22296
|
if (e.key === "`" && e.ctrlKey) {
|
|
21961
22297
|
e.preventDefault();
|
|
@@ -22401,7 +22737,7 @@ var SessionFilesSidebarToggle = memo30(function SessionFilesSidebarToggle2({
|
|
|
22401
22737
|
});
|
|
22402
22738
|
});
|
|
22403
22739
|
// src/components/session-files/SessionFilesDiffPanel.tsx
|
|
22404
|
-
import { useEffect as
|
|
22740
|
+
import { useEffect as useEffect39, useMemo as useMemo23, memo as memo31 } from "react";
|
|
22405
22741
|
import { X as X15, ChevronLeft, ChevronRight as ChevronRight12 } from "lucide-react";
|
|
22406
22742
|
import { jsx as jsx93, jsxs as jsxs81 } from "react/jsx-runtime";
|
|
22407
22743
|
function transformToUnifiedDiff(patch) {
|
|
@@ -22482,13 +22818,17 @@ function getPatchLineTones(patch) {
|
|
|
22482
22818
|
}
|
|
22483
22819
|
return tones;
|
|
22484
22820
|
}
|
|
22485
|
-
function FullHeightDiffView({
|
|
22821
|
+
function FullHeightDiffView({
|
|
22822
|
+
patch,
|
|
22823
|
+
filePath
|
|
22824
|
+
}) {
|
|
22486
22825
|
return /* @__PURE__ */ jsx93("div", {
|
|
22487
22826
|
className: "bg-card/60 border border-border rounded-lg overflow-hidden h-full",
|
|
22488
22827
|
children: /* @__PURE__ */ jsx93(CodeMirrorViewer, {
|
|
22489
22828
|
content: patch,
|
|
22490
|
-
path:
|
|
22491
|
-
lineTones: getPatchLineTones(patch)
|
|
22829
|
+
path: filePath,
|
|
22830
|
+
lineTones: getPatchLineTones(patch),
|
|
22831
|
+
disableMarkdownSyntax: true
|
|
22492
22832
|
})
|
|
22493
22833
|
});
|
|
22494
22834
|
}
|
|
@@ -22541,7 +22881,7 @@ ${contentLines.map((line) => `+${line}`).join(`
|
|
|
22541
22881
|
}
|
|
22542
22882
|
return rawPatch;
|
|
22543
22883
|
}, [selectedOperation, selectedFile]);
|
|
22544
|
-
|
|
22884
|
+
useEffect39(() => {
|
|
22545
22885
|
const handleKeyDown = (e) => {
|
|
22546
22886
|
const target = e.target;
|
|
22547
22887
|
const isInInput = target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable;
|
|
@@ -22686,7 +23026,8 @@ ${contentLines.map((line) => `+${line}`).join(`
|
|
|
22686
23026
|
/* @__PURE__ */ jsx93("div", {
|
|
22687
23027
|
className: "flex-1 overflow-hidden p-4",
|
|
22688
23028
|
children: patchContent ? /* @__PURE__ */ jsx93(FullHeightDiffView, {
|
|
22689
|
-
patch: patchContent
|
|
23029
|
+
patch: patchContent,
|
|
23030
|
+
filePath: selectedFile
|
|
22690
23031
|
}) : /* @__PURE__ */ jsx93("div", {
|
|
22691
23032
|
className: "h-full flex items-center justify-center text-muted-foreground",
|
|
22692
23033
|
children: "No diff content available"
|
|
@@ -22696,7 +23037,7 @@ ${contentLines.map((line) => `+${line}`).join(`
|
|
|
22696
23037
|
});
|
|
22697
23038
|
});
|
|
22698
23039
|
// src/components/research/ResearchSidebar.tsx
|
|
22699
|
-
import { memo as memo32, useState as useState41, useEffect as
|
|
23040
|
+
import { memo as memo32, useState as useState41, useEffect as useEffect40, useCallback as useCallback26, useRef as useRef25, useMemo as useMemo24 } from "react";
|
|
22700
23041
|
import {
|
|
22701
23042
|
FlaskConical as FlaskConical3,
|
|
22702
23043
|
Plus as Plus5,
|
|
@@ -22710,7 +23051,7 @@ import {
|
|
|
22710
23051
|
} from "lucide-react";
|
|
22711
23052
|
|
|
22712
23053
|
// src/hooks/useResearch.ts
|
|
22713
|
-
import { useQuery as useQuery11, useMutation as useMutation7, useQueryClient as
|
|
23054
|
+
import { useQuery as useQuery11, useMutation as useMutation7, useQueryClient as useQueryClient15 } from "@tanstack/react-query";
|
|
22714
23055
|
import {
|
|
22715
23056
|
createResearchSession as apiCreateResearchSession,
|
|
22716
23057
|
deleteResearchSession as apiDeleteResearchSession,
|
|
@@ -22773,7 +23114,7 @@ function useResearchSessions(parentSessionId, enabled = true) {
|
|
|
22773
23114
|
});
|
|
22774
23115
|
}
|
|
22775
23116
|
function useCreateResearchSession() {
|
|
22776
|
-
const queryClient =
|
|
23117
|
+
const queryClient = useQueryClient15();
|
|
22777
23118
|
return useMutation7({
|
|
22778
23119
|
mutationFn: ({
|
|
22779
23120
|
parentSessionId,
|
|
@@ -22787,7 +23128,7 @@ function useCreateResearchSession() {
|
|
|
22787
23128
|
});
|
|
22788
23129
|
}
|
|
22789
23130
|
function useDeleteResearchSession() {
|
|
22790
|
-
const queryClient =
|
|
23131
|
+
const queryClient = useQueryClient15();
|
|
22791
23132
|
return useMutation7({
|
|
22792
23133
|
mutationFn: (researchId) => researchApi.deleteResearchSession(researchId),
|
|
22793
23134
|
onSuccess: () => {
|
|
@@ -22814,7 +23155,7 @@ function useInjectContext() {
|
|
|
22814
23155
|
});
|
|
22815
23156
|
}
|
|
22816
23157
|
function useExportToSession() {
|
|
22817
|
-
const queryClient =
|
|
23158
|
+
const queryClient = useQueryClient15();
|
|
22818
23159
|
return useMutation7({
|
|
22819
23160
|
mutationFn: ({
|
|
22820
23161
|
researchId,
|
|
@@ -22827,7 +23168,7 @@ function useExportToSession() {
|
|
|
22827
23168
|
}
|
|
22828
23169
|
|
|
22829
23170
|
// src/components/research/ResearchSidebar.tsx
|
|
22830
|
-
import { useMutation as useMutation8, useQueryClient as
|
|
23171
|
+
import { useMutation as useMutation8, useQueryClient as useQueryClient16 } from "@tanstack/react-query";
|
|
22831
23172
|
import { jsx as jsx94, jsxs as jsxs82, Fragment as Fragment36 } from "react/jsx-runtime";
|
|
22832
23173
|
var PANEL_KEY3 = "research";
|
|
22833
23174
|
var DEFAULT_WIDTH3 = 384;
|
|
@@ -22861,7 +23202,7 @@ var ResearchSidebar = memo32(function ResearchSidebar2({
|
|
|
22861
23202
|
const { data: parentMessagesData } = useMessages(parentSessionId ?? undefined, { enabled: isExpanded });
|
|
22862
23203
|
useSessionStream(activeResearchSessionId ?? undefined, isExpanded);
|
|
22863
23204
|
const updateSession = useUpdateSession(activeResearchSessionId ?? "");
|
|
22864
|
-
const queryClient =
|
|
23205
|
+
const queryClient = useQueryClient16();
|
|
22865
23206
|
const sendMessage = useMutation8({
|
|
22866
23207
|
mutationFn: async ({
|
|
22867
23208
|
sessionId,
|
|
@@ -22871,12 +23212,12 @@ var ResearchSidebar = memo32(function ResearchSidebar2({
|
|
|
22871
23212
|
queryClient.invalidateQueries({ queryKey: ["messages", sessionId] });
|
|
22872
23213
|
}
|
|
22873
23214
|
});
|
|
22874
|
-
|
|
23215
|
+
useEffect40(() => {
|
|
22875
23216
|
if (parentSessionId) {
|
|
22876
23217
|
useResearchStore.getState().setParentSessionId(parentSessionId);
|
|
22877
23218
|
}
|
|
22878
23219
|
}, [parentSessionId]);
|
|
22879
|
-
|
|
23220
|
+
useEffect40(() => {
|
|
22880
23221
|
if (researchData?.sessions?.length) {
|
|
22881
23222
|
const currentIsValid = researchData.sessions.some((s) => s.id === activeResearchSessionId);
|
|
22882
23223
|
if (!currentIsValid) {
|
|
@@ -22886,7 +23227,7 @@ var ResearchSidebar = memo32(function ResearchSidebar2({
|
|
|
22886
23227
|
selectResearchSession(null);
|
|
22887
23228
|
}
|
|
22888
23229
|
}, [researchData, activeResearchSessionId, selectResearchSession]);
|
|
22889
|
-
|
|
23230
|
+
useEffect40(() => {
|
|
22890
23231
|
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
22891
23232
|
}, []);
|
|
22892
23233
|
const adjustTextareaHeight = useCallback26(() => {
|
|
@@ -22896,7 +23237,7 @@ var ResearchSidebar = memo32(function ResearchSidebar2({
|
|
|
22896
23237
|
textarea.style.height = "auto";
|
|
22897
23238
|
textarea.style.height = `${Math.min(textarea.scrollHeight, 120)}px`;
|
|
22898
23239
|
}, []);
|
|
22899
|
-
|
|
23240
|
+
useEffect40(() => {
|
|
22900
23241
|
adjustTextareaHeight();
|
|
22901
23242
|
}, [adjustTextareaHeight]);
|
|
22902
23243
|
const handleCreateNew = useCallback26(async () => {
|
|
@@ -23390,7 +23731,7 @@ var ResearchSidebarToggle = memo33(function ResearchSidebarToggle2({
|
|
|
23390
23731
|
});
|
|
23391
23732
|
});
|
|
23392
23733
|
// src/components/settings/SettingsSidebar.tsx
|
|
23393
|
-
import { memo as memo34, useState as useState43, useMemo as useMemo25, useCallback as useCallback28, useEffect as
|
|
23734
|
+
import { memo as memo34, useState as useState43, useMemo as useMemo25, useCallback as useCallback28, useEffect as useEffect43, useRef as useRef28 } from "react";
|
|
23394
23735
|
import { createPortal } from "react-dom";
|
|
23395
23736
|
import {
|
|
23396
23737
|
Settings as Settings2,
|
|
@@ -23451,8 +23792,8 @@ var useOnboardingStore = create22((set, get) => ({
|
|
|
23451
23792
|
}));
|
|
23452
23793
|
|
|
23453
23794
|
// src/hooks/useAuthStatus.ts
|
|
23454
|
-
import { useEffect as
|
|
23455
|
-
import { useQueryClient as
|
|
23795
|
+
import { useEffect as useEffect41, useCallback as useCallback27, useState as useState42, useRef as useRef26 } from "react";
|
|
23796
|
+
import { useQueryClient as useQueryClient17 } from "@tanstack/react-query";
|
|
23456
23797
|
var isInIframe = typeof window !== "undefined" && window.self !== window.top;
|
|
23457
23798
|
function useAuthStatus() {
|
|
23458
23799
|
const setAuthStatus = useOnboardingStore((s) => s.setAuthStatus);
|
|
@@ -23461,7 +23802,7 @@ function useAuthStatus() {
|
|
|
23461
23802
|
const setError = useOnboardingStore((s) => s.setError);
|
|
23462
23803
|
const authStatus = useOnboardingStore((s) => s.authStatus);
|
|
23463
23804
|
const isOpen = useOnboardingStore((s) => s.isOpen);
|
|
23464
|
-
const queryClient =
|
|
23805
|
+
const queryClient = useQueryClient17();
|
|
23465
23806
|
const [initialized, setInitialized] = useState42(false);
|
|
23466
23807
|
const [oauthPolling, setOauthPolling] = useState42(false);
|
|
23467
23808
|
const oauthPollingRef = useRef26(null);
|
|
@@ -23655,7 +23996,7 @@ function useAuthStatus() {
|
|
|
23655
23996
|
setLoading(false);
|
|
23656
23997
|
}
|
|
23657
23998
|
}, [fetchAuthStatus, setLoading, setError]);
|
|
23658
|
-
|
|
23999
|
+
useEffect41(() => {
|
|
23659
24000
|
if (!oauthPolling || !isInIframe)
|
|
23660
24001
|
return;
|
|
23661
24002
|
oauthPollingRef.current = setInterval(() => {
|
|
@@ -23669,7 +24010,7 @@ function useAuthStatus() {
|
|
|
23669
24010
|
clearTimeout(timeout);
|
|
23670
24011
|
};
|
|
23671
24012
|
}, [oauthPolling, fetchAuthStatus]);
|
|
23672
|
-
|
|
24013
|
+
useEffect41(() => {
|
|
23673
24014
|
if (!oauthPolling || !authStatus)
|
|
23674
24015
|
return;
|
|
23675
24016
|
const currentConfigured = Object.entries(authStatus.providers).filter(([, p]) => p.configured);
|
|
@@ -23678,7 +24019,7 @@ function useAuthStatus() {
|
|
|
23678
24019
|
setOauthPolling(false);
|
|
23679
24020
|
}
|
|
23680
24021
|
}, [authStatus, oauthPolling]);
|
|
23681
|
-
|
|
24022
|
+
useEffect41(() => {
|
|
23682
24023
|
const handleOAuthMessage = (event) => {
|
|
23683
24024
|
if (event.data?.type === "oauth-success") {
|
|
23684
24025
|
fetchAuthStatus();
|
|
@@ -23749,14 +24090,14 @@ function useAuthStatus() {
|
|
|
23749
24090
|
}
|
|
23750
24091
|
|
|
23751
24092
|
// src/hooks/useTopupCallback.ts
|
|
23752
|
-
import { useEffect as
|
|
24093
|
+
import { useEffect as useEffect42, useRef as useRef27 } from "react";
|
|
23753
24094
|
var STORAGE_KEY2 = "pendingPolarCheckout";
|
|
23754
24095
|
function useTopupCallback() {
|
|
23755
24096
|
const hasHandled = useRef27(false);
|
|
23756
24097
|
const loadingToastId = useRef27(null);
|
|
23757
24098
|
const setBalance = useOttoRouterStore((s) => s.setBalance);
|
|
23758
24099
|
const removeToast = useToastStore((s) => s.removeToast);
|
|
23759
|
-
|
|
24100
|
+
useEffect42(() => {
|
|
23760
24101
|
if (hasHandled.current)
|
|
23761
24102
|
return;
|
|
23762
24103
|
const params = new URLSearchParams(window.location.search);
|
|
@@ -23950,7 +24291,7 @@ var SelectRow = memo34(function SelectRow2({
|
|
|
23950
24291
|
const [menuStyle, setMenuStyle] = useState43(null);
|
|
23951
24292
|
const buttonRef = useRef28(null);
|
|
23952
24293
|
const selectedOption = options.find((o) => o.id === value);
|
|
23953
|
-
|
|
24294
|
+
useEffect43(() => {
|
|
23954
24295
|
if (!isOpen || !buttonRef.current)
|
|
23955
24296
|
return;
|
|
23956
24297
|
const update = () => {
|
|
@@ -24167,7 +24508,7 @@ var NumberInputRow = memo34(function NumberInputRow2({
|
|
|
24167
24508
|
disabled
|
|
24168
24509
|
}) {
|
|
24169
24510
|
const [draft, setDraft] = useState43(value !== null && value !== undefined ? String(value) : "");
|
|
24170
|
-
|
|
24511
|
+
useEffect43(() => {
|
|
24171
24512
|
setDraft(value !== null && value !== undefined ? String(value) : "");
|
|
24172
24513
|
}, [value]);
|
|
24173
24514
|
const persistedValue = value !== null && value !== undefined ? String(value) : "";
|
|
@@ -24898,8 +25239,8 @@ import {
|
|
|
24898
25239
|
import { QRCodeSVG as QRCodeSVG2 } from "qrcode.react";
|
|
24899
25240
|
|
|
24900
25241
|
// src/hooks/useTunnel.ts
|
|
24901
|
-
import { useQuery as useQuery12, useMutation as useMutation9, useQueryClient as
|
|
24902
|
-
import { useEffect as
|
|
25242
|
+
import { useQuery as useQuery12, useMutation as useMutation9, useQueryClient as useQueryClient18 } from "@tanstack/react-query";
|
|
25243
|
+
import { useEffect as useEffect44, useCallback as useCallback29, useRef as useRef29 } from "react";
|
|
24903
25244
|
import {
|
|
24904
25245
|
client as client4,
|
|
24905
25246
|
getTunnelQr,
|
|
@@ -24942,7 +25283,7 @@ function useTunnelStatus() {
|
|
|
24942
25283
|
queryFn: fetchTunnelStatus,
|
|
24943
25284
|
refetchInterval: 3000
|
|
24944
25285
|
});
|
|
24945
|
-
|
|
25286
|
+
useEffect44(() => {
|
|
24946
25287
|
if (query.data) {
|
|
24947
25288
|
setStatus(query.data.status);
|
|
24948
25289
|
setUrl(query.data.url);
|
|
@@ -24952,7 +25293,7 @@ function useTunnelStatus() {
|
|
|
24952
25293
|
return query;
|
|
24953
25294
|
}
|
|
24954
25295
|
function useStartTunnel() {
|
|
24955
|
-
const queryClient =
|
|
25296
|
+
const queryClient = useQueryClient18();
|
|
24956
25297
|
const setStatus = useTunnelStore((s) => s.setStatus);
|
|
24957
25298
|
const setUrl = useTunnelStore((s) => s.setUrl);
|
|
24958
25299
|
const setError = useTunnelStore((s) => s.setError);
|
|
@@ -24984,7 +25325,7 @@ function useStartTunnel() {
|
|
|
24984
25325
|
});
|
|
24985
25326
|
}
|
|
24986
25327
|
function useStopTunnel() {
|
|
24987
|
-
const queryClient =
|
|
25328
|
+
const queryClient = useQueryClient18();
|
|
24988
25329
|
const reset = useTunnelStore((s) => s.reset);
|
|
24989
25330
|
return useMutation9({
|
|
24990
25331
|
mutationFn: stopTunnel,
|
|
@@ -25002,7 +25343,7 @@ function useTunnelQr() {
|
|
|
25002
25343
|
queryFn: fetchTunnelQr,
|
|
25003
25344
|
enabled: !!url
|
|
25004
25345
|
});
|
|
25005
|
-
|
|
25346
|
+
useEffect44(() => {
|
|
25006
25347
|
if (query.data?.ok && query.data.qrCode) {
|
|
25007
25348
|
setQrCode(query.data.qrCode);
|
|
25008
25349
|
}
|
|
@@ -25042,7 +25383,7 @@ function useTunnelStream() {
|
|
|
25042
25383
|
eventSourceRef.current = null;
|
|
25043
25384
|
};
|
|
25044
25385
|
}, [setStatus, setUrl, setError, setProgress]);
|
|
25045
|
-
|
|
25386
|
+
useEffect44(() => {
|
|
25046
25387
|
if (isExpanded) {
|
|
25047
25388
|
const cleanup = connect();
|
|
25048
25389
|
return cleanup;
|
|
@@ -25301,7 +25642,7 @@ var TunnelSidebarToggle = memo37(function TunnelSidebarToggle2() {
|
|
|
25301
25642
|
});
|
|
25302
25643
|
});
|
|
25303
25644
|
// src/components/mcp/MCPSidebar.tsx
|
|
25304
|
-
import { memo as memo40, useState as useState46, useCallback as useCallback32, useMemo as useMemo26, useEffect as
|
|
25645
|
+
import { memo as memo40, useState as useState46, useCallback as useCallback32, useMemo as useMemo26, useEffect as useEffect47, useRef as useRef32 } from "react";
|
|
25305
25646
|
import {
|
|
25306
25647
|
ChevronDown as ChevronDown12,
|
|
25307
25648
|
ChevronRight as ChevronRight14,
|
|
@@ -25318,11 +25659,11 @@ import {
|
|
|
25318
25659
|
Wrench,
|
|
25319
25660
|
X as X17
|
|
25320
25661
|
} from "lucide-react";
|
|
25321
|
-
import { useQueryClient as
|
|
25662
|
+
import { useQueryClient as useQueryClient20 } from "@tanstack/react-query";
|
|
25322
25663
|
|
|
25323
25664
|
// src/hooks/useMCP.ts
|
|
25324
|
-
import { useQuery as useQuery13, useMutation as useMutation10, useQueryClient as
|
|
25325
|
-
import { useEffect as
|
|
25665
|
+
import { useQuery as useQuery13, useMutation as useMutation10, useQueryClient as useQueryClient19 } from "@tanstack/react-query";
|
|
25666
|
+
import { useEffect as useEffect45, useRef as useRef30, useCallback as useCallback30 } from "react";
|
|
25326
25667
|
import {
|
|
25327
25668
|
listMcpServers,
|
|
25328
25669
|
startMcpServer,
|
|
@@ -25344,7 +25685,7 @@ function useMCPServers() {
|
|
|
25344
25685
|
},
|
|
25345
25686
|
refetchInterval: 1e4
|
|
25346
25687
|
});
|
|
25347
|
-
|
|
25688
|
+
useEffect45(() => {
|
|
25348
25689
|
if (query.data?.servers) {
|
|
25349
25690
|
setServers(query.data.servers);
|
|
25350
25691
|
}
|
|
@@ -25352,7 +25693,7 @@ function useMCPServers() {
|
|
|
25352
25693
|
return query;
|
|
25353
25694
|
}
|
|
25354
25695
|
function useStartMCPServer() {
|
|
25355
|
-
const queryClient =
|
|
25696
|
+
const queryClient = useQueryClient19();
|
|
25356
25697
|
return useMutation10({
|
|
25357
25698
|
mutationFn: async (name) => {
|
|
25358
25699
|
const { data, error } = await startMcpServer({
|
|
@@ -25371,7 +25712,7 @@ function useStartMCPServer() {
|
|
|
25371
25712
|
});
|
|
25372
25713
|
}
|
|
25373
25714
|
function useStopMCPServer() {
|
|
25374
|
-
const queryClient =
|
|
25715
|
+
const queryClient = useQueryClient19();
|
|
25375
25716
|
const setLoading = useMCPStore((s) => s.setLoading);
|
|
25376
25717
|
return useMutation10({
|
|
25377
25718
|
mutationFn: async (name) => {
|
|
@@ -25393,7 +25734,7 @@ function useStopMCPServer() {
|
|
|
25393
25734
|
});
|
|
25394
25735
|
}
|
|
25395
25736
|
function useAddMCPServer() {
|
|
25396
|
-
const queryClient =
|
|
25737
|
+
const queryClient = useQueryClient19();
|
|
25397
25738
|
return useMutation10({
|
|
25398
25739
|
mutationFn: async (params) => {
|
|
25399
25740
|
const { data, error } = await addMcpServer({
|
|
@@ -25412,7 +25753,7 @@ function useAddMCPServer() {
|
|
|
25412
25753
|
});
|
|
25413
25754
|
}
|
|
25414
25755
|
function useRemoveMCPServer() {
|
|
25415
|
-
const queryClient =
|
|
25756
|
+
const queryClient = useQueryClient19();
|
|
25416
25757
|
return useMutation10({
|
|
25417
25758
|
mutationFn: async (name) => {
|
|
25418
25759
|
const { data, error } = await removeMcpServer({
|
|
@@ -25431,7 +25772,7 @@ function useRemoveMCPServer() {
|
|
|
25431
25772
|
});
|
|
25432
25773
|
}
|
|
25433
25774
|
function useAuthenticateMCPServer() {
|
|
25434
|
-
const queryClient =
|
|
25775
|
+
const queryClient = useQueryClient19();
|
|
25435
25776
|
return useMutation10({
|
|
25436
25777
|
mutationFn: async (name) => {
|
|
25437
25778
|
const { data, error } = await initiateMcpAuth({
|
|
@@ -25450,7 +25791,7 @@ function useAuthenticateMCPServer() {
|
|
|
25450
25791
|
});
|
|
25451
25792
|
}
|
|
25452
25793
|
function useRevokeMCPAuth() {
|
|
25453
|
-
const queryClient =
|
|
25794
|
+
const queryClient = useQueryClient19();
|
|
25454
25795
|
return useMutation10({
|
|
25455
25796
|
mutationFn: async (name) => {
|
|
25456
25797
|
const { data, error } = await revokeMcpAuth({
|
|
@@ -25487,7 +25828,7 @@ function useCopilotDevicePoller() {
|
|
|
25487
25828
|
const copilotDevice = useMCPStore((s) => s.copilotDevice);
|
|
25488
25829
|
const setCopilotDevice = useMCPStore((s) => s.setCopilotDevice);
|
|
25489
25830
|
const setLoading = useMCPStore((s) => s.setLoading);
|
|
25490
|
-
const queryClient =
|
|
25831
|
+
const queryClient = useQueryClient19();
|
|
25491
25832
|
const timerRef = useRef30(null);
|
|
25492
25833
|
const stopPolling = useCallback30(() => {
|
|
25493
25834
|
if (timerRef.current) {
|
|
@@ -25495,7 +25836,7 @@ function useCopilotDevicePoller() {
|
|
|
25495
25836
|
timerRef.current = null;
|
|
25496
25837
|
}
|
|
25497
25838
|
}, []);
|
|
25498
|
-
|
|
25839
|
+
useEffect45(() => {
|
|
25499
25840
|
if (!copilotDevice) {
|
|
25500
25841
|
stopPolling();
|
|
25501
25842
|
return;
|
|
@@ -25531,7 +25872,7 @@ function useCopilotDevicePoller() {
|
|
|
25531
25872
|
}
|
|
25532
25873
|
|
|
25533
25874
|
// src/components/mcp/AddMCPServerModal.tsx
|
|
25534
|
-
import { memo as memo38, useState as useState45, useCallback as useCallback31, useRef as useRef31, useEffect as
|
|
25875
|
+
import { memo as memo38, useState as useState45, useCallback as useCallback31, useRef as useRef31, useEffect as useEffect46 } from "react";
|
|
25535
25876
|
import { Globe as Globe5, Laptop, FolderDot, Terminal as Terminal9 } from "lucide-react";
|
|
25536
25877
|
import { jsx as jsx100, jsxs as jsxs88, Fragment as Fragment39 } from "react/jsx-runtime";
|
|
25537
25878
|
function parseCommandString(input) {
|
|
@@ -25654,7 +25995,7 @@ var AddMCPServerModal = memo38(function AddMCPServerModal2({
|
|
|
25654
25995
|
]);
|
|
25655
25996
|
const contentRef = useRef31(null);
|
|
25656
25997
|
const [contentHeight, setContentHeight] = useState45(undefined);
|
|
25657
|
-
|
|
25998
|
+
useEffect46(() => {
|
|
25658
25999
|
const el = contentRef.current;
|
|
25659
26000
|
if (!el)
|
|
25660
26001
|
return;
|
|
@@ -26198,7 +26539,7 @@ var MCPServerCard = memo40(function MCPServerCard2({
|
|
|
26198
26539
|
function useAuthPoller(name, onAuthenticated) {
|
|
26199
26540
|
const { data } = useMCPAuthStatus(name);
|
|
26200
26541
|
const prevAuth = useRef32(false);
|
|
26201
|
-
|
|
26542
|
+
useEffect47(() => {
|
|
26202
26543
|
if (data?.authenticated && !prevAuth.current) {
|
|
26203
26544
|
onAuthenticated();
|
|
26204
26545
|
}
|
|
@@ -26224,7 +26565,7 @@ var MCPSidebar = memo40(function MCPSidebar2() {
|
|
|
26224
26565
|
const [pollingServer, setPollingServer] = useState46(null);
|
|
26225
26566
|
const [deleteTarget, setDeleteTarget] = useState46(null);
|
|
26226
26567
|
const [searchQuery, setSearchQuery] = useState46("");
|
|
26227
|
-
const queryClient =
|
|
26568
|
+
const queryClient = useQueryClient20();
|
|
26228
26569
|
const handleAuthCompleted = useCallback32(() => {
|
|
26229
26570
|
if (pollingServer) {
|
|
26230
26571
|
setAuthUrl(pollingServer, null);
|
|
@@ -26233,7 +26574,7 @@ var MCPSidebar = memo40(function MCPSidebar2() {
|
|
|
26233
26574
|
}
|
|
26234
26575
|
}, [pollingServer, setAuthUrl, queryClient]);
|
|
26235
26576
|
useAuthPoller(pollingServer, handleAuthCompleted);
|
|
26236
|
-
|
|
26577
|
+
useEffect47(() => {
|
|
26237
26578
|
for (const name of loading) {
|
|
26238
26579
|
const server = servers.find((s) => s.name === name);
|
|
26239
26580
|
if (server?.connected) {
|
|
@@ -26530,8 +26871,8 @@ import {
|
|
|
26530
26871
|
} from "lucide-react";
|
|
26531
26872
|
|
|
26532
26873
|
// src/hooks/useSkills.ts
|
|
26533
|
-
import { useMutation as useMutation11, useQuery as useQuery14, useQueryClient as
|
|
26534
|
-
import { useEffect as
|
|
26874
|
+
import { useMutation as useMutation11, useQuery as useQuery14, useQueryClient as useQueryClient21 } from "@tanstack/react-query";
|
|
26875
|
+
import { useEffect as useEffect48 } from "react";
|
|
26535
26876
|
function useSkills() {
|
|
26536
26877
|
const setSkillsConfig = useSkillsStore((s) => s.setSkillsConfig);
|
|
26537
26878
|
const query = useQuery14({
|
|
@@ -26541,7 +26882,7 @@ function useSkills() {
|
|
|
26541
26882
|
},
|
|
26542
26883
|
refetchInterval: 30000
|
|
26543
26884
|
});
|
|
26544
|
-
|
|
26885
|
+
useEffect48(() => {
|
|
26545
26886
|
if (query.data?.items) {
|
|
26546
26887
|
setSkillsConfig({
|
|
26547
26888
|
skills: query.data.items,
|
|
@@ -26554,7 +26895,7 @@ function useSkills() {
|
|
|
26554
26895
|
return query;
|
|
26555
26896
|
}
|
|
26556
26897
|
function useUpdateSkillsConfig() {
|
|
26557
|
-
const queryClient =
|
|
26898
|
+
const queryClient = useQueryClient21();
|
|
26558
26899
|
const setSkillsConfig = useSkillsStore((s) => s.setSkillsConfig);
|
|
26559
26900
|
return useMutation11({
|
|
26560
26901
|
mutationFn: (input) => apiClient.updateSkillsConfig(input),
|
|
@@ -26997,7 +27338,7 @@ var SkillsSidebarToggle = memo43(function SkillsSidebarToggle2() {
|
|
|
26997
27338
|
});
|
|
26998
27339
|
});
|
|
26999
27340
|
// src/components/skills/SkillViewerPanel.tsx
|
|
27000
|
-
import { memo as memo44, useEffect as
|
|
27341
|
+
import { memo as memo44, useEffect as useEffect49 } from "react";
|
|
27001
27342
|
import { X as X19 } from "lucide-react";
|
|
27002
27343
|
import { jsx as jsx106, jsxs as jsxs93 } from "react/jsx-runtime";
|
|
27003
27344
|
var SkillViewerPanel = memo44(function SkillViewerPanel2({
|
|
@@ -27021,7 +27362,7 @@ var SkillViewerPanel = memo44(function SkillViewerPanel2({
|
|
|
27021
27362
|
const content = isMainFile ? skillDetail?.content : fileData?.content;
|
|
27022
27363
|
const isLoading = isMainFile ? !skillDetail : fileLoading;
|
|
27023
27364
|
const displayPath = isMainFile ? "SKILL.md" : viewingFile ?? "";
|
|
27024
|
-
|
|
27365
|
+
useEffect49(() => {
|
|
27025
27366
|
const handleEscape = (e) => {
|
|
27026
27367
|
const target = e.target;
|
|
27027
27368
|
const isInInput = target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable;
|
|
@@ -27091,7 +27432,7 @@ var SkillViewerPanel = memo44(function SkillViewerPanel2({
|
|
|
27091
27432
|
});
|
|
27092
27433
|
});
|
|
27093
27434
|
// src/components/file-browser/FileBrowserSidebar.tsx
|
|
27094
|
-
import { memo as memo45, useCallback as useCallback33, useEffect as
|
|
27435
|
+
import { memo as memo45, useCallback as useCallback33, useEffect as useEffect50, useRef as useRef33 } from "react";
|
|
27095
27436
|
import {
|
|
27096
27437
|
ChevronRight as ChevronRight15,
|
|
27097
27438
|
ChevronDown as ChevronDown13,
|
|
@@ -27160,7 +27501,7 @@ function TreeItem({
|
|
|
27160
27501
|
const activeViewerTabPath = getViewerTabPath3(activeViewerTab);
|
|
27161
27502
|
const isSelected = selectedFile === path || activeViewerTabPath === path;
|
|
27162
27503
|
const itemRef = useRef33(null);
|
|
27163
|
-
|
|
27504
|
+
useEffect50(() => {
|
|
27164
27505
|
if (isSelected) {
|
|
27165
27506
|
itemRef.current?.scrollIntoView({ block: "nearest" });
|
|
27166
27507
|
}
|
|
@@ -27225,7 +27566,7 @@ var FileBrowserSidebar = memo45(function FileBrowserSidebar2() {
|
|
|
27225
27566
|
});
|
|
27226
27567
|
const panelWidth = usePanelWidthStore((s) => s.widths[PANEL_KEY4] ?? DEFAULT_WIDTH4);
|
|
27227
27568
|
const { data: rootData, isLoading, refetch } = useFileTree(".");
|
|
27228
|
-
|
|
27569
|
+
useEffect50(() => {
|
|
27229
27570
|
if (isExpanded && activeFileTabPath) {
|
|
27230
27571
|
revealFile(activeFileTabPath);
|
|
27231
27572
|
}
|
|
@@ -27330,7 +27671,7 @@ var FileBrowserSidebarToggle = memo46(function FileBrowserSidebarToggle2() {
|
|
|
27330
27671
|
// src/components/file-browser/FileViewerPanel.tsx
|
|
27331
27672
|
import {
|
|
27332
27673
|
memo as memo47,
|
|
27333
|
-
useEffect as
|
|
27674
|
+
useEffect as useEffect52,
|
|
27334
27675
|
useMemo as useMemo29,
|
|
27335
27676
|
useRef as useRef35
|
|
27336
27677
|
} from "react";
|
|
@@ -27340,7 +27681,7 @@ import remarkGfm3 from "remark-gfm";
|
|
|
27340
27681
|
|
|
27341
27682
|
// src/components/workspace/ToolPreviewPanel.tsx
|
|
27342
27683
|
import { CheckCircle2 as CheckCircle22, XCircle as XCircle4 } from "lucide-react";
|
|
27343
|
-
import { useEffect as
|
|
27684
|
+
import { useEffect as useEffect51, useMemo as useMemo28, useRef as useRef34 } from "react";
|
|
27344
27685
|
import { jsx as jsx109, jsxs as jsxs96 } from "react/jsx-runtime";
|
|
27345
27686
|
var LARGE_WRITE_PREVIEW_CHARS = 24000;
|
|
27346
27687
|
var LARGE_WRITE_PREVIEW_LINES = 500;
|
|
@@ -27412,6 +27753,35 @@ function getStablePatchLines(patch) {
|
|
|
27412
27753
|
lines.pop();
|
|
27413
27754
|
return lines;
|
|
27414
27755
|
}
|
|
27756
|
+
function getEnvelopedPatchPath(line) {
|
|
27757
|
+
const directive = line.match(/^\*\*\* (?:Update|Add|Delete) File: (.+)$/);
|
|
27758
|
+
const replaceDirective = line.match(/^\*\*\* Replace in: (.+)$/);
|
|
27759
|
+
const lineDirective = line.match(/^\*\*\* (?:Delete Lines in|Replace Lines in|Insert Before in|Insert After in): (.+)$/);
|
|
27760
|
+
return directive?.[1] ?? replaceDirective?.[1] ?? lineDirective?.[1];
|
|
27761
|
+
}
|
|
27762
|
+
function parsePatchLineNumber(value) {
|
|
27763
|
+
const trimmed = value.trim();
|
|
27764
|
+
if (!/^\d+$/.test(trimmed))
|
|
27765
|
+
return;
|
|
27766
|
+
const line = Number.parseInt(trimmed, 10);
|
|
27767
|
+
return line > 0 ? line : undefined;
|
|
27768
|
+
}
|
|
27769
|
+
function parsePatchLineRange(value) {
|
|
27770
|
+
const match = /^(\d+)(?:\s*-\s*(\d+|end|eof|\$))?$/i.exec(value.trim());
|
|
27771
|
+
if (!match)
|
|
27772
|
+
return;
|
|
27773
|
+
const startLine = parsePatchLineNumber(match[1]);
|
|
27774
|
+
if (!startLine)
|
|
27775
|
+
return;
|
|
27776
|
+
if (!match[2])
|
|
27777
|
+
return { startLine, endLine: startLine };
|
|
27778
|
+
const endLine = /^(end|eof|\$)$/i.test(match[2]) ? "end" : parsePatchLineNumber(match[2]);
|
|
27779
|
+
if (!endLine)
|
|
27780
|
+
return;
|
|
27781
|
+
if (typeof endLine === "number" && endLine < startLine)
|
|
27782
|
+
return;
|
|
27783
|
+
return { startLine, endLine };
|
|
27784
|
+
}
|
|
27415
27785
|
function getPatchLineHighlights(patch, targetPath, fallbackLines) {
|
|
27416
27786
|
const highlighted = new Set(fallbackLines ?? []);
|
|
27417
27787
|
if (!patch)
|
|
@@ -27427,9 +27797,9 @@ function getPatchLineHighlights(patch, targetPath, fallbackLines) {
|
|
|
27427
27797
|
let inHunk = false;
|
|
27428
27798
|
let newLine = 0;
|
|
27429
27799
|
for (const line of getStablePatchLines(patch)) {
|
|
27430
|
-
const
|
|
27431
|
-
if (
|
|
27432
|
-
activeFile = patchPathMatches(
|
|
27800
|
+
const directivePath = getEnvelopedPatchPath(line);
|
|
27801
|
+
if (directivePath) {
|
|
27802
|
+
activeFile = patchPathMatches(directivePath, targetPath);
|
|
27433
27803
|
sawFileDirective = true;
|
|
27434
27804
|
inHunk = false;
|
|
27435
27805
|
newLine = 0;
|
|
@@ -27523,10 +27893,10 @@ function collectEnvelopedPatchHunks(patch, targetPath) {
|
|
|
27523
27893
|
current = [];
|
|
27524
27894
|
};
|
|
27525
27895
|
for (const line of getStablePatchLines(patch)) {
|
|
27526
|
-
const
|
|
27527
|
-
if (
|
|
27896
|
+
const directivePath = getEnvelopedPatchPath(line);
|
|
27897
|
+
if (directivePath) {
|
|
27528
27898
|
flush();
|
|
27529
|
-
activeFile = patchPathMatches(
|
|
27899
|
+
activeFile = patchPathMatches(directivePath, targetPath);
|
|
27530
27900
|
sawFileDirective = true;
|
|
27531
27901
|
inHunk = activeFile;
|
|
27532
27902
|
continue;
|
|
@@ -27615,9 +27985,152 @@ function buildEnvelopedPatchPreview(content, patch, targetPath) {
|
|
|
27615
27985
|
latestLine: changedLines.length > 0 ? Math.max(...changedLines) : undefined
|
|
27616
27986
|
};
|
|
27617
27987
|
}
|
|
27988
|
+
function collectLineNumberPatchOperations(patch, targetPath) {
|
|
27989
|
+
const operations = [];
|
|
27990
|
+
let current = null;
|
|
27991
|
+
let activeFile = false;
|
|
27992
|
+
let phase = "directives";
|
|
27993
|
+
const flush = () => {
|
|
27994
|
+
if (current && activeFile)
|
|
27995
|
+
operations.push(current);
|
|
27996
|
+
current = null;
|
|
27997
|
+
phase = "directives";
|
|
27998
|
+
};
|
|
27999
|
+
for (const line of getStablePatchLines(patch)) {
|
|
28000
|
+
const directive = line.match(/^\*\*\* (Delete Lines in|Replace Lines in|Insert Before in|Insert After in): (.+)$/);
|
|
28001
|
+
if (directive?.[1] && directive[2]) {
|
|
28002
|
+
flush();
|
|
28003
|
+
activeFile = patchPathMatches(directive[2], targetPath);
|
|
28004
|
+
if (directive[1] === "Delete Lines in") {
|
|
28005
|
+
current = { kind: "delete", filePath: directive[2], lines: [] };
|
|
28006
|
+
} else if (directive[1] === "Replace Lines in") {
|
|
28007
|
+
current = { kind: "replace", filePath: directive[2], lines: [] };
|
|
28008
|
+
} else {
|
|
28009
|
+
current = {
|
|
28010
|
+
kind: "insert",
|
|
28011
|
+
filePath: directive[2],
|
|
28012
|
+
position: directive[1] === "Insert Before in" ? "before" : "after",
|
|
28013
|
+
lines: []
|
|
28014
|
+
};
|
|
28015
|
+
}
|
|
28016
|
+
continue;
|
|
28017
|
+
}
|
|
28018
|
+
if (!current)
|
|
28019
|
+
continue;
|
|
28020
|
+
if (line.startsWith("*** End Patch")) {
|
|
28021
|
+
flush();
|
|
28022
|
+
continue;
|
|
28023
|
+
}
|
|
28024
|
+
if (line.startsWith("*** Begin Patch"))
|
|
28025
|
+
continue;
|
|
28026
|
+
if (phase === "with") {
|
|
28027
|
+
current.lines.push(line);
|
|
28028
|
+
continue;
|
|
28029
|
+
}
|
|
28030
|
+
if (line.startsWith("*** Lines:") && current.kind !== "insert") {
|
|
28031
|
+
const range = parsePatchLineRange(line.slice("*** Lines:".length));
|
|
28032
|
+
if (range) {
|
|
28033
|
+
current.startLine = range.startLine;
|
|
28034
|
+
current.endLine = range.endLine;
|
|
28035
|
+
}
|
|
28036
|
+
continue;
|
|
28037
|
+
}
|
|
28038
|
+
if (line.startsWith("*** Line:") && current.kind === "insert") {
|
|
28039
|
+
current.line = parsePatchLineNumber(line.slice("*** Line:".length));
|
|
28040
|
+
continue;
|
|
28041
|
+
}
|
|
28042
|
+
if (line.startsWith("*** With:")) {
|
|
28043
|
+
phase = "with";
|
|
28044
|
+
}
|
|
28045
|
+
}
|
|
28046
|
+
flush();
|
|
28047
|
+
return operations;
|
|
28048
|
+
}
|
|
28049
|
+
function getCurrentRecordPosition(records, currentIndex) {
|
|
28050
|
+
let seen = 0;
|
|
28051
|
+
for (let index = 0;index < records.length; index += 1) {
|
|
28052
|
+
if (records[index].removed)
|
|
28053
|
+
continue;
|
|
28054
|
+
if (seen === currentIndex)
|
|
28055
|
+
return index;
|
|
28056
|
+
seen += 1;
|
|
28057
|
+
}
|
|
28058
|
+
return records.length;
|
|
28059
|
+
}
|
|
28060
|
+
function buildLineNumberPatchPreview(content, patch, targetPath) {
|
|
28061
|
+
const operations = collectLineNumberPatchOperations(patch, targetPath);
|
|
28062
|
+
if (operations.length === 0)
|
|
28063
|
+
return null;
|
|
28064
|
+
const contentLines = content.split(`
|
|
28065
|
+
`);
|
|
28066
|
+
if (contentLines.at(-1) === "")
|
|
28067
|
+
contentLines.pop();
|
|
28068
|
+
const records = contentLines.map((line) => ({
|
|
28069
|
+
text: line
|
|
28070
|
+
}));
|
|
28071
|
+
for (const operation of operations) {
|
|
28072
|
+
const currentLines = records.filter((record) => !record.removed);
|
|
28073
|
+
if (operation.kind === "insert") {
|
|
28074
|
+
if (!operation.line)
|
|
28075
|
+
continue;
|
|
28076
|
+
const insertIndex = operation.position === "before" ? operation.line - 1 : operation.line;
|
|
28077
|
+
if (insertIndex < 0 || insertIndex > currentLines.length)
|
|
28078
|
+
continue;
|
|
28079
|
+
const recordIndex2 = getCurrentRecordPosition(records, insertIndex);
|
|
28080
|
+
records.splice(recordIndex2, 0, ...operation.lines.map((line) => ({
|
|
28081
|
+
text: line,
|
|
28082
|
+
tone: "add"
|
|
28083
|
+
})));
|
|
28084
|
+
continue;
|
|
28085
|
+
}
|
|
28086
|
+
if (!operation.startLine || !operation.endLine)
|
|
28087
|
+
continue;
|
|
28088
|
+
const endLine = operation.endLine === "end" ? currentLines.length : operation.endLine;
|
|
28089
|
+
if (operation.startLine > currentLines.length || endLine > currentLines.length)
|
|
28090
|
+
continue;
|
|
28091
|
+
const startIndex = operation.startLine - 1;
|
|
28092
|
+
const endIndex = endLine - 1;
|
|
28093
|
+
const recordIndex = getCurrentRecordPosition(records, startIndex);
|
|
28094
|
+
for (let index = startIndex;index <= endIndex; index += 1) {
|
|
28095
|
+
const position = getCurrentRecordPosition(records, startIndex);
|
|
28096
|
+
if (!records[position])
|
|
28097
|
+
continue;
|
|
28098
|
+
records[position].tone = "remove";
|
|
28099
|
+
records[position].removed = true;
|
|
28100
|
+
}
|
|
28101
|
+
if (operation.kind === "replace") {
|
|
28102
|
+
records.splice(recordIndex, 0, ...operation.lines.map((line) => ({
|
|
28103
|
+
text: line,
|
|
28104
|
+
tone: "add"
|
|
28105
|
+
})));
|
|
28106
|
+
}
|
|
28107
|
+
}
|
|
28108
|
+
const lineTones = new Map;
|
|
28109
|
+
const renderedLines = records.map((record, index) => {
|
|
28110
|
+
if (record.tone)
|
|
28111
|
+
lineTones.set(index + 1, record.tone);
|
|
28112
|
+
return record.text;
|
|
28113
|
+
});
|
|
28114
|
+
if (lineTones.size === 0)
|
|
28115
|
+
return null;
|
|
28116
|
+
const resultLines = records.filter((record) => !record.removed).map((record) => record.text);
|
|
28117
|
+
const changedLines = [...lineTones.keys()];
|
|
28118
|
+
return {
|
|
28119
|
+
content: renderedLines.join(`
|
|
28120
|
+
`),
|
|
28121
|
+
resultContent: resultLines.join(`
|
|
28122
|
+
`),
|
|
28123
|
+
lineTones,
|
|
28124
|
+
firstLine: Math.min(...changedLines),
|
|
28125
|
+
latestLine: Math.max(...changedLines)
|
|
28126
|
+
};
|
|
28127
|
+
}
|
|
27618
28128
|
function buildLivePatchPreview(content, patch, targetPath) {
|
|
27619
28129
|
if (!patch)
|
|
27620
28130
|
return null;
|
|
28131
|
+
const lineNumberPreview = buildLineNumberPatchPreview(content, patch, targetPath);
|
|
28132
|
+
if (lineNumberPreview)
|
|
28133
|
+
return lineNumberPreview;
|
|
27621
28134
|
const insertions = new Map;
|
|
27622
28135
|
const removals = new Set;
|
|
27623
28136
|
let activeFile = false;
|
|
@@ -27747,7 +28260,8 @@ function PlainSourceViewer({
|
|
|
27747
28260
|
}),
|
|
27748
28261
|
/* @__PURE__ */ jsx109(CodeMirrorViewer, {
|
|
27749
28262
|
content,
|
|
27750
|
-
path
|
|
28263
|
+
path,
|
|
28264
|
+
disableMarkdownSyntax: true
|
|
27751
28265
|
})
|
|
27752
28266
|
]
|
|
27753
28267
|
});
|
|
@@ -27768,7 +28282,8 @@ function SourceViewer({
|
|
|
27768
28282
|
highlightTone,
|
|
27769
28283
|
lineTones,
|
|
27770
28284
|
scrollToLine,
|
|
27771
|
-
scrollToEndSignal
|
|
28285
|
+
scrollToEndSignal,
|
|
28286
|
+
disableMarkdownSyntax: true
|
|
27772
28287
|
});
|
|
27773
28288
|
}
|
|
27774
28289
|
function ToolPreviewPanel({ tab }) {
|
|
@@ -27822,7 +28337,7 @@ function ToolPreviewPanel({ tab }) {
|
|
|
27822
28337
|
};
|
|
27823
28338
|
}
|
|
27824
28339
|
const stablePatchPreview = lastPatchPreviewRef.current?.key === patchPreviewKey ? livePatchPreview ?? lastPatchPreviewRef.current.preview : livePatchPreview ?? persistedPatchPreview;
|
|
27825
|
-
|
|
28340
|
+
useEffect51(() => {
|
|
27826
28341
|
if (tab.toolName !== "apply_patch" || !livePatchPreview)
|
|
27827
28342
|
return;
|
|
27828
28343
|
const baseContent = tab.baseContent ?? appliedFile?.content;
|
|
@@ -27847,11 +28362,11 @@ function ToolPreviewPanel({ tab }) {
|
|
|
27847
28362
|
error: tab.error
|
|
27848
28363
|
});
|
|
27849
28364
|
}, [tab, appliedFile?.content, livePatchPreview]);
|
|
27850
|
-
|
|
28365
|
+
useEffect51(() => {
|
|
27851
28366
|
if (shouldLoadAppliedFile)
|
|
27852
28367
|
refetchAppliedFile();
|
|
27853
28368
|
}, [shouldLoadAppliedFile, refetchAppliedFile]);
|
|
27854
|
-
|
|
28369
|
+
useEffect51(() => {
|
|
27855
28370
|
if (scrollSignal.length === 0)
|
|
27856
28371
|
return;
|
|
27857
28372
|
const frame = window.requestAnimationFrame(() => {
|
|
@@ -27885,26 +28400,6 @@ function ToolPreviewPanel({ tab }) {
|
|
|
27885
28400
|
return /* @__PURE__ */ jsxs96("div", {
|
|
27886
28401
|
className: "h-full w-full bg-transparent flex flex-col",
|
|
27887
28402
|
children: [
|
|
27888
|
-
/* @__PURE__ */ jsxs96("div", {
|
|
27889
|
-
className: "shrink-0 border-b border-sidebar-border bg-sidebar-accent/30 px-3 py-1.5 text-[12px] text-muted-foreground flex items-center gap-2",
|
|
27890
|
-
children: [
|
|
27891
|
-
/* @__PURE__ */ jsx109(StatusIcon, {
|
|
27892
|
-
status: tab.status
|
|
27893
|
-
}),
|
|
27894
|
-
/* @__PURE__ */ jsx109("span", {
|
|
27895
|
-
children: statusLabel
|
|
27896
|
-
}),
|
|
27897
|
-
/* @__PURE__ */ jsx109("span", {
|
|
27898
|
-
className: "text-muted-foreground/60",
|
|
27899
|
-
children: "·"
|
|
27900
|
-
}),
|
|
27901
|
-
/* @__PURE__ */ jsx109("span", {
|
|
27902
|
-
className: "font-mono truncate",
|
|
27903
|
-
title: tab.path,
|
|
27904
|
-
children: tab.path
|
|
27905
|
-
})
|
|
27906
|
-
]
|
|
27907
|
-
}),
|
|
27908
28403
|
tab.error && /* @__PURE__ */ jsx109("div", {
|
|
27909
28404
|
className: "shrink-0 border-b border-red-500/20 bg-red-500/10 px-3 py-2 text-[12px] text-red-700 dark:text-red-300",
|
|
27910
28405
|
children: tab.error
|
|
@@ -27952,6 +28447,26 @@ function ToolPreviewPanel({ tab }) {
|
|
|
27952
28447
|
className: "h-full flex items-center justify-center text-sm text-muted-foreground",
|
|
27953
28448
|
children: "Waiting for write content..."
|
|
27954
28449
|
})
|
|
28450
|
+
}),
|
|
28451
|
+
/* @__PURE__ */ jsxs96("div", {
|
|
28452
|
+
className: "shrink-0 border-t border-sidebar-border bg-sidebar-accent/30 px-3 py-1.5 text-[12px] text-muted-foreground flex items-center gap-2",
|
|
28453
|
+
children: [
|
|
28454
|
+
/* @__PURE__ */ jsx109(StatusIcon, {
|
|
28455
|
+
status: tab.status
|
|
28456
|
+
}),
|
|
28457
|
+
/* @__PURE__ */ jsx109("span", {
|
|
28458
|
+
children: statusLabel
|
|
28459
|
+
}),
|
|
28460
|
+
/* @__PURE__ */ jsx109("span", {
|
|
28461
|
+
className: "text-muted-foreground/60",
|
|
28462
|
+
children: "·"
|
|
28463
|
+
}),
|
|
28464
|
+
/* @__PURE__ */ jsx109("span", {
|
|
28465
|
+
className: "font-mono truncate",
|
|
28466
|
+
title: tab.path,
|
|
28467
|
+
children: tab.path
|
|
28468
|
+
})
|
|
28469
|
+
]
|
|
27955
28470
|
})
|
|
27956
28471
|
]
|
|
27957
28472
|
});
|
|
@@ -28061,6 +28576,7 @@ var FileViewerPanel = memo47(function FileViewerPanel2({
|
|
|
28061
28576
|
open,
|
|
28062
28577
|
file,
|
|
28063
28578
|
highlight,
|
|
28579
|
+
annotations,
|
|
28064
28580
|
patchPreview,
|
|
28065
28581
|
writePreview,
|
|
28066
28582
|
onClose
|
|
@@ -28073,7 +28589,7 @@ var FileViewerPanel = memo47(function FileViewerPanel2({
|
|
|
28073
28589
|
const selectedFile = file ?? storeSelectedFile;
|
|
28074
28590
|
const closeViewer = onClose ?? storeCloseViewer;
|
|
28075
28591
|
const { data, isLoading } = useFileContent(selectedFile);
|
|
28076
|
-
|
|
28592
|
+
useEffect52(() => {
|
|
28077
28593
|
const handleEscape = (e) => {
|
|
28078
28594
|
const target = e.target;
|
|
28079
28595
|
const isInInput = target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable;
|
|
@@ -28100,7 +28616,7 @@ var FileViewerPanel = memo47(function FileViewerPanel2({
|
|
|
28100
28616
|
const patchBaseContent = patchPreview ? patchPreview.baseContent ?? data?.content ?? "" : undefined;
|
|
28101
28617
|
const livePatchPreview = useMemo29(() => selectedFile && patchPreview?.patch && patchBaseContent !== undefined ? buildLivePatchPreview(patchBaseContent, patchPreview.patch, selectedFile) : null, [selectedFile, patchPreview?.patch, patchBaseContent]);
|
|
28102
28618
|
const activePatchPreview = patchPreview?.status === "success" ? persistedPatchPreview ?? livePatchPreview : livePatchPreview ?? persistedPatchPreview;
|
|
28103
|
-
|
|
28619
|
+
useEffect52(() => {
|
|
28104
28620
|
if (!selectedFile || !patchPreview || !livePatchPreview)
|
|
28105
28621
|
return;
|
|
28106
28622
|
const baseContent = patchPreview.baseContent ?? data?.content;
|
|
@@ -28125,7 +28641,7 @@ var FileViewerPanel = memo47(function FileViewerPanel2({
|
|
|
28125
28641
|
error: patchPreview.error
|
|
28126
28642
|
});
|
|
28127
28643
|
}, [selectedFile, data?.content, patchPreview, livePatchPreview]);
|
|
28128
|
-
|
|
28644
|
+
useEffect52(() => {
|
|
28129
28645
|
if (!data || !effectiveHighlight?.startLine)
|
|
28130
28646
|
return;
|
|
28131
28647
|
const frame = window.requestAnimationFrame(() => {
|
|
@@ -28139,6 +28655,28 @@ var FileViewerPanel = memo47(function FileViewerPanel2({
|
|
|
28139
28655
|
const highlightStart = effectiveHighlight?.startLine;
|
|
28140
28656
|
const highlightEnd = effectiveHighlight?.endLine ?? highlightStart;
|
|
28141
28657
|
const patchChangedLines = patchPreview?.changedLines;
|
|
28658
|
+
const persistentLineTones = useMemo29(() => {
|
|
28659
|
+
if (!annotations?.length)
|
|
28660
|
+
return;
|
|
28661
|
+
const tones = new Map;
|
|
28662
|
+
for (const annotation of annotations) {
|
|
28663
|
+
for (const [line, tone] of annotation.lineTones) {
|
|
28664
|
+
if (line > 0)
|
|
28665
|
+
tones.set(line, tone);
|
|
28666
|
+
}
|
|
28667
|
+
}
|
|
28668
|
+
return tones.size > 0 ? tones : undefined;
|
|
28669
|
+
}, [annotations]);
|
|
28670
|
+
const writePreviewLineTones = useMemo29(() => {
|
|
28671
|
+
if (writePreview?.content === undefined)
|
|
28672
|
+
return;
|
|
28673
|
+
const tones = new Map;
|
|
28674
|
+
const lineCount = writePreview.content.length === 0 ? 1 : writePreview.content.split(`
|
|
28675
|
+
`).length;
|
|
28676
|
+
for (let line = 1;line <= lineCount; line += 1)
|
|
28677
|
+
tones.set(line, "add");
|
|
28678
|
+
return tones;
|
|
28679
|
+
}, [writePreview?.content]);
|
|
28142
28680
|
const highlightedLines = useMemo29(() => {
|
|
28143
28681
|
if (highlightStart && highlightEnd) {
|
|
28144
28682
|
return new Set(Array.from({ length: highlightEnd - highlightStart + 1 }, (_, index) => highlightStart + index));
|
|
@@ -28152,18 +28690,21 @@ var FileViewerPanel = memo47(function FileViewerPanel2({
|
|
|
28152
28690
|
const scrollToHighlightLine = highlightStart ?? fallbackPatchHighlightStart;
|
|
28153
28691
|
const activePatchLineTones = useMemo29(() => {
|
|
28154
28692
|
if (!activePatchPreview)
|
|
28155
|
-
return;
|
|
28156
|
-
const tones = new Map(
|
|
28693
|
+
return persistentLineTones;
|
|
28694
|
+
const tones = new Map(persistentLineTones);
|
|
28695
|
+
for (const [line, tone] of activePatchPreview.lineTones) {
|
|
28696
|
+
tones.set(line, tone);
|
|
28697
|
+
}
|
|
28157
28698
|
for (const line of patchChangedLines ?? []) {
|
|
28158
28699
|
if (!tones.has(line))
|
|
28159
28700
|
tones.set(line, "add");
|
|
28160
28701
|
}
|
|
28161
28702
|
return tones;
|
|
28162
|
-
}, [activePatchPreview, patchChangedLines]);
|
|
28703
|
+
}, [activePatchPreview, patchChangedLines, persistentLineTones]);
|
|
28163
28704
|
if (!isViewerOpen || !selectedFile)
|
|
28164
28705
|
return null;
|
|
28165
28706
|
const language = inferLanguage(selectedFile);
|
|
28166
|
-
const renderMarkdown = isMarkdownFile(selectedFile) && !effectiveHighlight && !activePatchPreview && !writePreview?.content;
|
|
28707
|
+
const renderMarkdown = isMarkdownFile(selectedFile) && !effectiveHighlight && !persistentLineTones && !activePatchPreview && !writePreview?.content;
|
|
28167
28708
|
return /* @__PURE__ */ jsxs97("div", {
|
|
28168
28709
|
className: mode === "pane" ? "h-full w-full bg-transparent flex flex-col" : "absolute inset-0 bg-background z-50 flex flex-col animate-in slide-in-from-left duration-300",
|
|
28169
28710
|
children: [
|
|
@@ -28208,12 +28749,15 @@ var FileViewerPanel = memo47(function FileViewerPanel2({
|
|
|
28208
28749
|
className: "flex-1 overflow-auto",
|
|
28209
28750
|
children: writePreview?.content !== undefined ? /* @__PURE__ */ jsx110(CodeMirrorViewer, {
|
|
28210
28751
|
content: writePreview.content,
|
|
28211
|
-
path: selectedFile
|
|
28752
|
+
path: selectedFile,
|
|
28753
|
+
lineTones: writePreviewLineTones,
|
|
28754
|
+
disableMarkdownSyntax: true
|
|
28212
28755
|
}) : activePatchPreview ? /* @__PURE__ */ jsx110(CodeMirrorViewer, {
|
|
28213
28756
|
content: activePatchPreview.content,
|
|
28214
28757
|
path: selectedFile,
|
|
28215
28758
|
lineTones: activePatchLineTones,
|
|
28216
|
-
scrollToLine: activePatchPreview.latestLine
|
|
28759
|
+
scrollToLine: activePatchPreview.latestLine,
|
|
28760
|
+
disableMarkdownSyntax: true
|
|
28217
28761
|
}) : isLoading ? /* @__PURE__ */ jsx110("div", {
|
|
28218
28762
|
className: "h-full flex items-center justify-center text-muted-foreground",
|
|
28219
28763
|
children: "Loading file..."
|
|
@@ -28259,7 +28803,9 @@ var FileViewerPanel = memo47(function FileViewerPanel2({
|
|
|
28259
28803
|
content: data.content,
|
|
28260
28804
|
path: selectedFile,
|
|
28261
28805
|
highlightedLines,
|
|
28262
|
-
|
|
28806
|
+
lineTones: persistentLineTones,
|
|
28807
|
+
scrollToLine: scrollToHighlightLine,
|
|
28808
|
+
disableMarkdownSyntax: isMarkdownFile(selectedFile)
|
|
28263
28809
|
}) : /* @__PURE__ */ jsx110("div", {
|
|
28264
28810
|
className: "h-full flex items-center justify-center text-muted-foreground",
|
|
28265
28811
|
children: "Unable to load file"
|
|
@@ -28294,7 +28840,7 @@ var FileViewerPanel = memo47(function FileViewerPanel2({
|
|
|
28294
28840
|
});
|
|
28295
28841
|
});
|
|
28296
28842
|
// src/components/file-browser/QuickFilePicker.tsx
|
|
28297
|
-
import { memo as memo48, useState as useState48, useEffect as
|
|
28843
|
+
import { memo as memo48, useState as useState48, useEffect as useEffect53, useRef as useRef36, useCallback as useCallback34, useMemo as useMemo30 } from "react";
|
|
28298
28844
|
import { FileCode as FileCode4, Search as Search9 } from "lucide-react";
|
|
28299
28845
|
|
|
28300
28846
|
// src/stores/filePickerStore.ts
|
|
@@ -28349,14 +28895,14 @@ var QuickFilePicker = memo48(function QuickFilePicker2() {
|
|
|
28349
28895
|
const results = filesData.files.map((file) => ({ file, ...fuzzyMatch(query, file) })).filter((r) => r.match).sort((a, b) => b.score - a.score).slice(0, 50);
|
|
28350
28896
|
return results.map((r) => r.file);
|
|
28351
28897
|
}, [filesData?.files, query]);
|
|
28352
|
-
|
|
28898
|
+
useEffect53(() => {
|
|
28353
28899
|
if (isOpen) {
|
|
28354
28900
|
setQuery("");
|
|
28355
28901
|
setSelectedIndex(0);
|
|
28356
28902
|
setTimeout(() => inputRef.current?.focus(), 0);
|
|
28357
28903
|
}
|
|
28358
28904
|
}, [isOpen]);
|
|
28359
|
-
|
|
28905
|
+
useEffect53(() => {
|
|
28360
28906
|
const item = listRef.current?.children[selectedIndex];
|
|
28361
28907
|
item?.scrollIntoView({ block: "nearest" });
|
|
28362
28908
|
}, [selectedIndex]);
|
|
@@ -28514,20 +29060,170 @@ function HighlightedPath({ path, query }) {
|
|
|
28514
29060
|
});
|
|
28515
29061
|
}
|
|
28516
29062
|
// src/components/workspace/ViewerTabs.tsx
|
|
28517
|
-
import {
|
|
28518
|
-
import {
|
|
28519
|
-
|
|
28520
|
-
|
|
28521
|
-
FileCode as FileCode5,
|
|
28522
|
-
FileJson as FileJson2,
|
|
28523
|
-
FileText as FileText8,
|
|
28524
|
-
FileType as FileType2,
|
|
28525
|
-
GitCommit as GitCommit5,
|
|
28526
|
-
Image as Image2,
|
|
28527
|
-
Settings as Settings4,
|
|
28528
|
-
X as X21
|
|
28529
|
-
} from "lucide-react";
|
|
29063
|
+
import { Icon, addCollection } from "@iconify/react";
|
|
29064
|
+
import { icons as materialIconTheme } from "@iconify-json/material-icon-theme";
|
|
29065
|
+
import { memo as memo49, useEffect as useEffect54 } from "react";
|
|
29066
|
+
import { GitCommit as GitCommit5, X as X21 } from "lucide-react";
|
|
28530
29067
|
import { jsx as jsx112, jsxs as jsxs99 } from "react/jsx-runtime";
|
|
29068
|
+
addCollection(materialIconTheme);
|
|
29069
|
+
var ICON_CLASS = "h-3.5 w-3.5 shrink-0";
|
|
29070
|
+
var FILENAME_ICON_MAP = {
|
|
29071
|
+
".dockerignore": "docker",
|
|
29072
|
+
".editorconfig": "editorconfig",
|
|
29073
|
+
".env": "settings",
|
|
29074
|
+
".env.example": "settings",
|
|
29075
|
+
".env.local": "settings",
|
|
29076
|
+
".eslintignore": "eslint",
|
|
29077
|
+
".eslintrc": "eslint",
|
|
29078
|
+
".gitattributes": "git",
|
|
29079
|
+
".gitignore": "git",
|
|
29080
|
+
".prettierrc": "prettier",
|
|
29081
|
+
"astro.config.mjs": "astro-config",
|
|
29082
|
+
"astro.config.ts": "astro-config",
|
|
29083
|
+
"biome.json": "biome",
|
|
29084
|
+
"bun.lock": "bun",
|
|
29085
|
+
"bun.lockb": "bun",
|
|
29086
|
+
"bunfig.toml": "bun",
|
|
29087
|
+
"cargo.lock": "lock",
|
|
29088
|
+
"cargo.toml": "rust",
|
|
29089
|
+
"compose.yaml": "docker",
|
|
29090
|
+
"compose.yml": "docker",
|
|
29091
|
+
"docker-compose.yaml": "docker",
|
|
29092
|
+
"docker-compose.yml": "docker",
|
|
29093
|
+
dockerfile: "docker",
|
|
29094
|
+
"eslint.config.js": "eslint",
|
|
29095
|
+
"eslint.config.mjs": "eslint",
|
|
29096
|
+
"eslint.config.ts": "eslint",
|
|
29097
|
+
gemfile: "gemfile",
|
|
29098
|
+
"go.mod": "go-mod",
|
|
29099
|
+
"go.sum": "go-mod",
|
|
29100
|
+
"jsconfig.json": "jsconfig",
|
|
29101
|
+
license: "license",
|
|
29102
|
+
makefile: "makefile",
|
|
29103
|
+
"next.config.js": "next",
|
|
29104
|
+
"next.config.mjs": "next",
|
|
29105
|
+
"next.config.ts": "next",
|
|
29106
|
+
"package-lock.json": "npm",
|
|
29107
|
+
"package.json": "npm",
|
|
29108
|
+
"pnpm-lock.yaml": "pnpm",
|
|
29109
|
+
"postcss.config.js": "postcss",
|
|
29110
|
+
"postcss.config.mjs": "postcss",
|
|
29111
|
+
"postcss.config.ts": "postcss",
|
|
29112
|
+
"prettier.config.js": "prettier",
|
|
29113
|
+
"prettier.config.mjs": "prettier",
|
|
29114
|
+
"prettier.config.ts": "prettier",
|
|
29115
|
+
"readme.md": "readme",
|
|
29116
|
+
"readme.mdx": "readme",
|
|
29117
|
+
"rollup.config.js": "rollup",
|
|
29118
|
+
"rollup.config.mjs": "rollup",
|
|
29119
|
+
"rollup.config.ts": "rollup",
|
|
29120
|
+
"svelte.config.js": "svelte",
|
|
29121
|
+
"svelte.config.ts": "svelte",
|
|
29122
|
+
"tailwind.config.js": "tailwindcss",
|
|
29123
|
+
"tailwind.config.ts": "tailwindcss",
|
|
29124
|
+
"tauri.conf.json": "tauri",
|
|
29125
|
+
"tsconfig.json": "tsconfig",
|
|
29126
|
+
"vite.config.js": "vite",
|
|
29127
|
+
"vite.config.mjs": "vite",
|
|
29128
|
+
"vite.config.ts": "vite",
|
|
29129
|
+
"vitest.config.js": "vitest",
|
|
29130
|
+
"vitest.config.mjs": "vitest",
|
|
29131
|
+
"vitest.config.ts": "vitest",
|
|
29132
|
+
"vue.config.js": "vue-config",
|
|
29133
|
+
"vue.config.ts": "vue-config",
|
|
29134
|
+
"yarn.lock": "lock"
|
|
29135
|
+
};
|
|
29136
|
+
var EXTENSION_ICON_MAP = {
|
|
29137
|
+
ai: "image",
|
|
29138
|
+
astro: "astro",
|
|
29139
|
+
avif: "image",
|
|
29140
|
+
bash: "console",
|
|
29141
|
+
bmp: "image",
|
|
29142
|
+
c: "c",
|
|
29143
|
+
cc: "cpp",
|
|
29144
|
+
clj: "clojure",
|
|
29145
|
+
cljc: "clojure",
|
|
29146
|
+
cljs: "clojure",
|
|
29147
|
+
cpp: "cpp",
|
|
29148
|
+
cs: "csharp",
|
|
29149
|
+
css: "css",
|
|
29150
|
+
cxx: "cpp",
|
|
29151
|
+
dart: "dart",
|
|
29152
|
+
dockerfile: "docker",
|
|
29153
|
+
ex: "elixir",
|
|
29154
|
+
exs: "elixir",
|
|
29155
|
+
erl: "erlang",
|
|
29156
|
+
fish: "console",
|
|
29157
|
+
gif: "image",
|
|
29158
|
+
go: "go",
|
|
29159
|
+
graphql: "graphql",
|
|
29160
|
+
gql: "graphql",
|
|
29161
|
+
groovy: "groovy",
|
|
29162
|
+
h: "c",
|
|
29163
|
+
hpp: "cpp",
|
|
29164
|
+
hrl: "erlang",
|
|
29165
|
+
hs: "haskell",
|
|
29166
|
+
htm: "html",
|
|
29167
|
+
html: "html",
|
|
29168
|
+
hxx: "cpp",
|
|
29169
|
+
ico: "favicon",
|
|
29170
|
+
java: "java",
|
|
29171
|
+
jpeg: "image",
|
|
29172
|
+
jpg: "image",
|
|
29173
|
+
js: "javascript",
|
|
29174
|
+
json: "json",
|
|
29175
|
+
jsonc: "json",
|
|
29176
|
+
jsx: "react",
|
|
29177
|
+
jl: "julia",
|
|
29178
|
+
kt: "kotlin",
|
|
29179
|
+
kts: "kotlin",
|
|
29180
|
+
less: "less",
|
|
29181
|
+
log: "log",
|
|
29182
|
+
lua: "lua",
|
|
29183
|
+
luau: "luau",
|
|
29184
|
+
mjs: "javascript",
|
|
29185
|
+
ml: "ocaml",
|
|
29186
|
+
mli: "ocaml",
|
|
29187
|
+
mov: "video",
|
|
29188
|
+
mp3: "audio",
|
|
29189
|
+
mp4: "video",
|
|
29190
|
+
md: "markdown",
|
|
29191
|
+
mdx: "markdown",
|
|
29192
|
+
nim: "nim",
|
|
29193
|
+
pdf: "pdf",
|
|
29194
|
+
php: "php-elephant",
|
|
29195
|
+
png: "image",
|
|
29196
|
+
prisma: "prisma",
|
|
29197
|
+
proto: "proto",
|
|
29198
|
+
ps1: "powershell",
|
|
29199
|
+
py: "python",
|
|
29200
|
+
pyw: "python",
|
|
29201
|
+
r: "r",
|
|
29202
|
+
rb: "ruby",
|
|
29203
|
+
rs: "rust",
|
|
29204
|
+
sass: "sass",
|
|
29205
|
+
scala: "scala",
|
|
29206
|
+
scss: "sass",
|
|
29207
|
+
sh: "console",
|
|
29208
|
+
sql: "database",
|
|
29209
|
+
svg: "svg",
|
|
29210
|
+
svelte: "svelte",
|
|
29211
|
+
swift: "swift",
|
|
29212
|
+
toml: "toml",
|
|
29213
|
+
ts: "typescript",
|
|
29214
|
+
tsx: "react-ts",
|
|
29215
|
+
txt: "document",
|
|
29216
|
+
vue: "vue",
|
|
29217
|
+
wav: "audio",
|
|
29218
|
+
webm: "video",
|
|
29219
|
+
webp: "image",
|
|
29220
|
+
xml: "xml",
|
|
29221
|
+
yaml: "yaml",
|
|
29222
|
+
yml: "yaml",
|
|
29223
|
+
zig: "zig",
|
|
29224
|
+
zip: "zip",
|
|
29225
|
+
zsh: "console"
|
|
29226
|
+
};
|
|
28531
29227
|
function tabKindLabel(tab) {
|
|
28532
29228
|
switch (tab.type) {
|
|
28533
29229
|
case "git-diff":
|
|
@@ -28557,86 +29253,34 @@ function getFileExtension2(path) {
|
|
|
28557
29253
|
const extension = path.split(".").pop()?.toLowerCase() ?? "";
|
|
28558
29254
|
return extension && extension !== path.toLowerCase() ? extension : "";
|
|
28559
29255
|
}
|
|
28560
|
-
function
|
|
28561
|
-
|
|
28562
|
-
|
|
28563
|
-
|
|
28564
|
-
|
|
28565
|
-
|
|
28566
|
-
|
|
28567
|
-
|
|
28568
|
-
|
|
28569
|
-
|
|
28570
|
-
|
|
28571
|
-
|
|
28572
|
-
|
|
28573
|
-
|
|
28574
|
-
|
|
28575
|
-
});
|
|
28576
|
-
case "py":
|
|
28577
|
-
return /* @__PURE__ */ jsx112("span", {
|
|
28578
|
-
className: "inline-flex h-3.5 w-3.5 shrink-0 items-center justify-center rounded-[3px] bg-gradient-to-br from-[#3776ab] to-[#ffd43b] text-[7px] font-bold leading-none text-white",
|
|
28579
|
-
children: "Py"
|
|
28580
|
-
});
|
|
28581
|
-
case "go":
|
|
28582
|
-
return /* @__PURE__ */ jsx112("span", {
|
|
28583
|
-
className: "inline-flex h-3.5 w-3.5 shrink-0 items-center justify-center rounded-full bg-[#00add8] text-[7px] font-bold leading-none text-white",
|
|
28584
|
-
children: "Go"
|
|
28585
|
-
});
|
|
28586
|
-
case "rs":
|
|
28587
|
-
return /* @__PURE__ */ jsx112("span", {
|
|
28588
|
-
className: "inline-flex h-3.5 w-3.5 shrink-0 items-center justify-center rounded-full bg-[#ce422b] text-[8px] font-bold leading-none text-white",
|
|
28589
|
-
children: "R"
|
|
28590
|
-
});
|
|
28591
|
-
case "json":
|
|
28592
|
-
return /* @__PURE__ */ jsx112(FileJson2, {
|
|
28593
|
-
className: "h-3.5 w-3.5 shrink-0 text-yellow-500"
|
|
28594
|
-
});
|
|
28595
|
-
case "md":
|
|
28596
|
-
case "mdx":
|
|
28597
|
-
return /* @__PURE__ */ jsx112(FileText8, {
|
|
28598
|
-
className: "h-3.5 w-3.5 shrink-0 text-sky-500"
|
|
28599
|
-
});
|
|
28600
|
-
case "env":
|
|
28601
|
-
case "toml":
|
|
28602
|
-
case "yaml":
|
|
28603
|
-
case "yml":
|
|
28604
|
-
return /* @__PURE__ */ jsx112(Settings4, {
|
|
28605
|
-
className: "h-3.5 w-3.5 shrink-0 text-violet-500"
|
|
28606
|
-
});
|
|
28607
|
-
case "css":
|
|
28608
|
-
case "scss":
|
|
28609
|
-
case "sass":
|
|
28610
|
-
case "less":
|
|
28611
|
-
return /* @__PURE__ */ jsx112(Braces2, {
|
|
28612
|
-
className: "h-3.5 w-3.5 shrink-0 text-blue-500"
|
|
28613
|
-
});
|
|
28614
|
-
case "html":
|
|
28615
|
-
case "xml":
|
|
28616
|
-
return /* @__PURE__ */ jsx112(FileType2, {
|
|
28617
|
-
className: "h-3.5 w-3.5 shrink-0 text-orange-500"
|
|
28618
|
-
});
|
|
28619
|
-
case "png":
|
|
28620
|
-
case "jpg":
|
|
28621
|
-
case "jpeg":
|
|
28622
|
-
case "gif":
|
|
28623
|
-
case "svg":
|
|
28624
|
-
case "webp":
|
|
28625
|
-
return /* @__PURE__ */ jsx112(Image2, {
|
|
28626
|
-
className: "h-3.5 w-3.5 shrink-0 text-pink-500"
|
|
28627
|
-
});
|
|
28628
|
-
case "txt":
|
|
28629
|
-
case "log":
|
|
28630
|
-
return /* @__PURE__ */ jsx112(FileText8, {
|
|
28631
|
-
className: "h-3.5 w-3.5 shrink-0 text-muted-foreground"
|
|
28632
|
-
});
|
|
28633
|
-
default:
|
|
28634
|
-
return extension ? /* @__PURE__ */ jsx112(FileCode5, {
|
|
28635
|
-
className: "h-3.5 w-3.5 shrink-0 text-muted-foreground/80"
|
|
28636
|
-
}) : /* @__PURE__ */ jsx112(File3, {
|
|
28637
|
-
className: "h-3.5 w-3.5 shrink-0 text-muted-foreground/80"
|
|
28638
|
-
});
|
|
29256
|
+
function getFileName3(path) {
|
|
29257
|
+
return path.split(/[\\/]/).pop()?.toLowerCase() ?? path.toLowerCase();
|
|
29258
|
+
}
|
|
29259
|
+
function getIconNameForPath(path) {
|
|
29260
|
+
const fileName = getFileName3(path);
|
|
29261
|
+
const fileIcon = FILENAME_ICON_MAP[fileName];
|
|
29262
|
+
if (fileIcon)
|
|
29263
|
+
return fileIcon;
|
|
29264
|
+
if (fileName.endsWith(".d.ts"))
|
|
29265
|
+
return "typescript-def";
|
|
29266
|
+
if (fileName.endsWith(".test.ts") || fileName.endsWith(".spec.ts")) {
|
|
29267
|
+
return "test-ts";
|
|
29268
|
+
}
|
|
29269
|
+
if (fileName.endsWith(".test.js") || fileName.endsWith(".spec.js")) {
|
|
29270
|
+
return "test-js";
|
|
28639
29271
|
}
|
|
29272
|
+
if (fileName.endsWith(".test.jsx") || fileName.endsWith(".spec.jsx") || fileName.endsWith(".test.tsx") || fileName.endsWith(".spec.tsx")) {
|
|
29273
|
+
return "test-jsx";
|
|
29274
|
+
}
|
|
29275
|
+
const extension = getFileExtension2(fileName);
|
|
29276
|
+
return EXTENSION_ICON_MAP[extension] ?? "document";
|
|
29277
|
+
}
|
|
29278
|
+
function renderFileIcon(path) {
|
|
29279
|
+
return /* @__PURE__ */ jsx112(Icon, {
|
|
29280
|
+
"aria-hidden": "true",
|
|
29281
|
+
className: ICON_CLASS,
|
|
29282
|
+
icon: `material-icon-theme:${getIconNameForPath(path)}`
|
|
29283
|
+
});
|
|
28640
29284
|
}
|
|
28641
29285
|
function renderTabIcon(tab) {
|
|
28642
29286
|
if (tab.type === "git-diff") {
|
|
@@ -28654,10 +29298,10 @@ function renderTabIcon(tab) {
|
|
|
28654
29298
|
className: `h-3.5 w-3.5 shrink-0 ${tab.status === "error" ? "text-red-500" : tab.status === "success" ? "text-emerald-500" : "text-blue-500"}`
|
|
28655
29299
|
});
|
|
28656
29300
|
}
|
|
28657
|
-
const
|
|
29301
|
+
const path = getTabPath(tab);
|
|
28658
29302
|
return /* @__PURE__ */ jsx112("span", {
|
|
28659
29303
|
className: "shrink-0 inline-flex items-center text-muted-foreground/80",
|
|
28660
|
-
children:
|
|
29304
|
+
children: renderFileIcon(path)
|
|
28661
29305
|
});
|
|
28662
29306
|
}
|
|
28663
29307
|
function renderTabContent(tab, closeTab, updateSessionFileOperationIndex) {
|
|
@@ -28686,6 +29330,7 @@ function renderTabContent(tab, closeTab, updateSessionFileOperationIndex) {
|
|
|
28686
29330
|
open: true,
|
|
28687
29331
|
file: tab.path,
|
|
28688
29332
|
highlight: tab.highlight,
|
|
29333
|
+
annotations: tab.annotations,
|
|
28689
29334
|
patchPreview: tab.patchPreview,
|
|
28690
29335
|
writePreview: tab.writePreview,
|
|
28691
29336
|
onClose: () => closeTab(tab.id)
|
|
@@ -28710,7 +29355,7 @@ var ViewerTabs = memo49(function ViewerTabs2() {
|
|
|
28710
29355
|
const setActiveTab = useViewerTabsStore((state) => state.setActiveTab);
|
|
28711
29356
|
const closeTab = useViewerTabsStore((state) => state.closeTab);
|
|
28712
29357
|
const updateSessionFileOperationIndex = useViewerTabsStore((state) => state.updateSessionFileOperationIndex);
|
|
28713
|
-
|
|
29358
|
+
useEffect54(() => {
|
|
28714
29359
|
const handleKeyDown = (event) => {
|
|
28715
29360
|
const target = event.target;
|
|
28716
29361
|
const isInInput = target?.tagName === "INPUT" || target?.tagName === "TEXTAREA" || target?.isContentEditable;
|
|
@@ -28734,12 +29379,12 @@ var ViewerTabs = memo49(function ViewerTabs2() {
|
|
|
28734
29379
|
className: "h-full w-full min-w-0 bg-sidebar flex flex-col",
|
|
28735
29380
|
children: [
|
|
28736
29381
|
/* @__PURE__ */ jsxs99("div", {
|
|
28737
|
-
className: "h-12 shrink-0 bg-background flex overflow-x-auto overflow-y-hidden",
|
|
29382
|
+
className: "h-12 shrink-0 bg-background flex overflow-x-auto overflow-y-hidden overscroll-x-contain scrollbar-hide",
|
|
28738
29383
|
children: [
|
|
28739
29384
|
tabs.map((tab) => {
|
|
28740
29385
|
const isActive = tab.id === activeTab.id;
|
|
28741
29386
|
return /* @__PURE__ */ jsxs99("div", {
|
|
28742
|
-
className: `group h-12 max-w-56
|
|
29387
|
+
className: `group h-12 w-44 max-w-56 shrink-0 px-3 border-r border-sidebar-border flex items-center gap-2 text-left transition-colors ${isActive ? "bg-sidebar text-sidebar-foreground" : "border-b bg-background text-muted-foreground/70 hover:text-foreground hover:bg-sidebar-accent/40"}`,
|
|
28743
29388
|
title: `${tab.title}
|
|
28744
29389
|
${tabKindLabel(tab)}`,
|
|
28745
29390
|
children: [
|
|
@@ -28783,10 +29428,10 @@ ${tabKindLabel(tab)}`,
|
|
|
28783
29428
|
});
|
|
28784
29429
|
});
|
|
28785
29430
|
// src/components/onboarding/OnboardingModal.tsx
|
|
28786
|
-
import { memo as memo52, useEffect as
|
|
29431
|
+
import { memo as memo52, useEffect as useEffect57 } from "react";
|
|
28787
29432
|
|
|
28788
29433
|
// src/components/onboarding/steps/ProviderSetupStep.tsx
|
|
28789
|
-
import { memo as memo50, useEffect as
|
|
29434
|
+
import { memo as memo50, useEffect as useEffect55, useState as useState49, useRef as useRef37 } from "react";
|
|
28790
29435
|
import {
|
|
28791
29436
|
Copy as Copy5,
|
|
28792
29437
|
Check as Check13,
|
|
@@ -28893,34 +29538,34 @@ var ProviderSetupStep = memo50(function ProviderSetupStep2({
|
|
|
28893
29538
|
const { fetchBalance } = useOttoRouterBalance("ottorouter");
|
|
28894
29539
|
const effectivePayg = payg?.effectiveSpendableUsd ?? balance ?? 0;
|
|
28895
29540
|
const setuStatusLabel = subscription?.active ? `GO ${(subscription.creditsRemaining ?? 0).toFixed(1)} credits` : `$${effectivePayg.toFixed(2)}`;
|
|
28896
|
-
|
|
29541
|
+
useEffect55(() => {
|
|
28897
29542
|
if (prevTopupModalOpen.current && !isTopupModalOpen) {
|
|
28898
29543
|
fetchBalance();
|
|
28899
29544
|
}
|
|
28900
29545
|
prevTopupModalOpen.current = isTopupModalOpen;
|
|
28901
29546
|
}, [isTopupModalOpen, fetchBalance]);
|
|
28902
|
-
|
|
29547
|
+
useEffect55(() => {
|
|
28903
29548
|
if (!authStatus.ottorouter.configured && !isSettingUp) {
|
|
28904
29549
|
setIsSettingUp(true);
|
|
28905
29550
|
onSetupWallet().finally(() => setIsSettingUp(false));
|
|
28906
29551
|
}
|
|
28907
29552
|
}, [authStatus.ottorouter.configured, onSetupWallet, isSettingUp]);
|
|
28908
|
-
|
|
29553
|
+
useEffect55(() => {
|
|
28909
29554
|
if (addingProvider && apiKeyInputRef.current) {
|
|
28910
29555
|
apiKeyInputRef.current.focus();
|
|
28911
29556
|
}
|
|
28912
29557
|
}, [addingProvider]);
|
|
28913
|
-
|
|
29558
|
+
useEffect55(() => {
|
|
28914
29559
|
if (oauthSession && oauthCodeInputRef.current) {
|
|
28915
29560
|
oauthCodeInputRef.current.focus();
|
|
28916
29561
|
}
|
|
28917
29562
|
}, [oauthSession]);
|
|
28918
|
-
|
|
29563
|
+
useEffect55(() => {
|
|
28919
29564
|
if (isImportModalOpen && importPrivateKeyRef.current) {
|
|
28920
29565
|
importPrivateKeyRef.current.focus();
|
|
28921
29566
|
}
|
|
28922
29567
|
}, [isImportModalOpen]);
|
|
28923
|
-
|
|
29568
|
+
useEffect55(() => {
|
|
28924
29569
|
if (!copilotPolling || !copilotDevice || !copilotPollFnRef.current)
|
|
28925
29570
|
return;
|
|
28926
29571
|
copilotCancelledRef.current = false;
|
|
@@ -29218,7 +29863,7 @@ var ProviderSetupStep = memo50(function ProviderSetupStep2({
|
|
|
29218
29863
|
setImportWalletError(null);
|
|
29219
29864
|
setImportPrivateKey("");
|
|
29220
29865
|
};
|
|
29221
|
-
|
|
29866
|
+
useEffect55(() => {
|
|
29222
29867
|
const handleNativeBack = (event) => {
|
|
29223
29868
|
const customEvent = event;
|
|
29224
29869
|
if (!customEvent.detail || customEvent.detail.handled)
|
|
@@ -30408,7 +31053,7 @@ var ProviderSetupStep = memo50(function ProviderSetupStep2({
|
|
|
30408
31053
|
});
|
|
30409
31054
|
|
|
30410
31055
|
// src/components/onboarding/steps/DefaultsStep.tsx
|
|
30411
|
-
import { memo as memo51, useState as useState50, useEffect as
|
|
31056
|
+
import { memo as memo51, useState as useState50, useEffect as useEffect56, useId as useId3, useRef as useRef38 } from "react";
|
|
30412
31057
|
import { ArrowLeft, Sparkles as Sparkles9, ChevronDown as ChevronDown14 } from "lucide-react";
|
|
30413
31058
|
import { jsx as jsx114, jsxs as jsxs101, Fragment as Fragment43 } from "react/jsx-runtime";
|
|
30414
31059
|
var DefaultsStep = memo51(function DefaultsStep2({
|
|
@@ -30431,7 +31076,7 @@ var DefaultsStep = memo51(function DefaultsStep2({
|
|
|
30431
31076
|
const modelId = useId3();
|
|
30432
31077
|
const agentId = useId3();
|
|
30433
31078
|
const approvalId = useId3();
|
|
30434
|
-
|
|
31079
|
+
useEffect56(() => {
|
|
30435
31080
|
const loadConfig = async () => {
|
|
30436
31081
|
try {
|
|
30437
31082
|
const [configData, modelsData] = await Promise.all([
|
|
@@ -30462,7 +31107,7 @@ var DefaultsStep = memo51(function DefaultsStep2({
|
|
|
30462
31107
|
};
|
|
30463
31108
|
loadConfig();
|
|
30464
31109
|
}, []);
|
|
30465
|
-
|
|
31110
|
+
useEffect56(() => {
|
|
30466
31111
|
if (config2?.agents?.length) {
|
|
30467
31112
|
const agents = config2.agents;
|
|
30468
31113
|
if (!selectedAgent || !agents.includes(selectedAgent)) {
|
|
@@ -30470,7 +31115,7 @@ var DefaultsStep = memo51(function DefaultsStep2({
|
|
|
30470
31115
|
}
|
|
30471
31116
|
}
|
|
30472
31117
|
}, [config2, selectedAgent]);
|
|
30473
|
-
|
|
31118
|
+
useEffect56(() => {
|
|
30474
31119
|
if (allModels?.[selectedProvider] && hasUserChangedProvider.current) {
|
|
30475
31120
|
const providerModels = allModels[selectedProvider];
|
|
30476
31121
|
if (!providerModels.models.some((m) => m.id === selectedModel)) {
|
|
@@ -30799,7 +31444,7 @@ var OnboardingModal = memo52(function OnboardingModal2({
|
|
|
30799
31444
|
importCopilotTokenFromGh,
|
|
30800
31445
|
getCopilotDiagnostics
|
|
30801
31446
|
} = useAuthStatus();
|
|
30802
|
-
|
|
31447
|
+
useEffect57(() => {
|
|
30803
31448
|
if (!isOpen)
|
|
30804
31449
|
return;
|
|
30805
31450
|
const handleNativeBack = (event) => {
|
|
@@ -30928,4 +31573,4 @@ export {
|
|
|
30928
31573
|
AssistantMessageGroup
|
|
30929
31574
|
};
|
|
30930
31575
|
|
|
30931
|
-
//# debugId=
|
|
31576
|
+
//# debugId=83646DAB6C1728A064756E2164756E21
|