@alivault/pico 0.10.0 → 0.10.1
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/.output/nitro.json +1 -1
- package/.output/public/assets/{index-Cv9CWbsI.js → index-7ls3Zqfs.js} +8 -8
- package/.output/public/assets/routes-CNpFhMfH.js +2161 -0
- package/.output/public/assets/styles-oRWMaOB0.css +2 -0
- package/.output/server/_libs/@pierre/diffs+[...].mjs +3 -34
- package/.output/server/_libs/lucide-react.mjs +27 -1
- package/.output/server/_ssr/{router-BfWi4RfZ.mjs → router-DhVJ7gcL.mjs} +166 -54
- package/.output/server/_ssr/{routes-D6yf6dMU.mjs → routes-DbGwM-bj.mjs} +9 -4
- package/.output/server/_ssr/{routes-CSvcOSyF.mjs → routes-NB2wmfpS.mjs} +710 -189
- package/.output/server/_ssr/ssr.mjs +2 -2
- package/.output/server/{_tanstack-start-manifest_v-Am6Tm4xr.mjs → _tanstack-start-manifest_v-DrOsJYxt.mjs} +4 -4
- package/.output/server/index.mjs +470 -470
- package/package.json +1 -1
- package/.output/public/assets/routes-FmISceu0.js +0 -2160
- package/.output/public/assets/styles-DgbW000h.css +0 -2
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { i as __toESM } from "../_runtime.mjs";
|
|
2
2
|
import { $ as require_react, A as TabsTab, B as Input, C as MenuPositioner, D as MenuGroupLabel, E as MenuItem, F as DialogPopup, H as useRender, I as DialogDescription$1, L as DialogClose, M as DialogTitle$1, N as DialogRoot, O as MenuGroup, P as DialogPortal$1, Q as require_jsx_runtime, R as DialogBackdrop, S as MenuRoot, T as MenuPopup, V as Button, Y as mergeProps, _ as AccordionItem$1, a as ContextMenuRoot, b as MenuTrigger, c as CollapsibleRoot, d as PopoverPortal, f as PopoverTrigger$1, g as AccordionHeader, h as AccordionTrigger$1, i as ContextMenuTrigger$1, j as TabsRoot, k as TabsList$1, l as PopoverPopup, m as AccordionPanel, n as ToggleGroup, o as CollapsiblePanel, p as PopoverRoot, r as Toggle, s as CollapsibleTrigger$1, t as AlertDialogRoot, u as PopoverPositioner, v as AccordionRoot, w as MenuPortal, x as MenuSubmenuRoot, y as MenuSubmenuTrigger, z as Separator } from "../_libs/@base-ui/react+[...].mjs";
|
|
3
3
|
import { t as cva } from "../_libs/class-variance-authority+clsx.mjs";
|
|
4
|
-
import { A as
|
|
5
|
-
import { $ as
|
|
4
|
+
import { A as ExternalLink, B as ChevronRight, C as ImagePlus, D as Folder, E as GitCommitHorizontal, F as Command, G as ArrowUpRight, H as Check, J as ArrowDown, L as ChevronsUpDown, M as EllipsisVertical, N as Download, O as FolderPlus, P as Copy, R as ChevronsDownUp, T as GitBranch, U as ArrowUp, V as ChevronDown, W as ArrowUpToLine, _ as OctagonX, a as TriangleAlert, b as ListStart, c as SquarePen, d as Plus, f as PanelRight, h as PanelLeftClose, i as Undo2, j as Ellipsis, k as FileDiff, l as Settings2, m as PanelLeftOpen, n as WandSparkles, o as Tag, p as PanelLeft, q as ArrowLeft, r as Upload, s as Square, t as X, u as Search, v as Minimize2, w as GitPullRequestArrow, x as ListEnd, y as Maximize2 } from "../_libs/lucide-react.mjs";
|
|
5
|
+
import { $ as promptDraftKeyMatchesOwner, C as THEME_COLOR_MODES, D as TitleTooltip, E as THEME_STORAGE_KEY, F as buildItemsFromSync, I as cn, J as normalizeStoredDirectoryList, K as normalizePromptImage, M as VIEWER_CONTEXT_STORAGE_KEY, N as appliedThemeClass, O as Tooltip$1, Q as promptDraftKey, R as createContextId, S as Spinner, T as THEME_FAMILIES, U as flattenTree, W as getSessionTitle, X as normalizeThemeFamily, Y as normalizeThemeColorMode, Z as previewUrlForImage, _ as RIGHT_SIDEBAR_WIDTHS_STORAGE_KEY, _t as sameContextUsage, a as COLLAPSED_DIRECTORIES_STORAGE_KEY, at as readStoredPinnedSessionKeys, b as SESSION_DONE_SOUND_ENABLED_STORAGE_KEY, bt as themeFamilyLabel, c as Kbd, ct as readStoredRightSidebarOpen, d as RECENT_DIRECTORIES_STORAGE_KEY, dt as readStoredSidebarDirectories, et as readStoredAutoScrollEnabled, f as RIGHT_SIDEBAR_ACTIVE_TAB_STORAGE_KEY, ft as readStoredTheme, g as RIGHT_SIDEBAR_OPEN_STORAGE_KEY, gt as safeLocalStorageSetItem, h as RIGHT_SIDEBAR_HISTORY_TAB_STORAGE_KEY, ht as safeLocalStorageGetItem, i as CENTER_MESSAGES_STORAGE_KEY, it as readStoredHideToolBlocks, j as TooltipTrigger, k as TooltipContent, l as KeyboardShortcutContent, lt as readStoredSessionDoneDesktopNotificationsEnabled, m as RIGHT_SIDEBAR_HISTORY_HEIGHT_STORAGE_KEY, mt as rememberStoredPromptDraft, n as APPLIED_THEME_STORAGE_KEY, nt as readStoredCollapsedDirectories, o as DRAFT_DIRECTORY_STORAGE_KEY, ot as readStoredPromptDraft, p as RIGHT_SIDEBAR_FILE_TREE_WIDTH_STORAGE_KEY, pt as readStoredThemeColorMode, q as normalizeSessionSelectionKeys, r as AUTO_SCROLL_ENABLED_STORAGE_KEY, rt as readStoredDraftDirectory, s as HIDE_TOOL_BLOCKS_STORAGE_KEY, st as readStoredRecentDirectories, tt as readStoredCenterMessages, u as PINNED_SESSIONS_STORAGE_KEY, ut as readStoredSessionDoneSoundEnabled, v as Route, vt as sessionListEntryKey, w as THEME_COLOR_MODE_STORAGE_KEY, x as SIDEBAR_DIRECTORIES_STORAGE_KEY, xt as thinkingSummaryText, y as SESSION_DONE_DESKTOP_NOTIFICATIONS_ENABLED_STORAGE_KEY, yt as themeColorModeLabel, z as createInitialSessionState } from "./routes-DbGwM-bj.mjs";
|
|
6
6
|
import { i as useQuery, n as useIsMutating, o as useQueryClient, r as useIsFetching, t as useMutation } from "../_libs/tanstack__react-query.mjs";
|
|
7
7
|
import { t as useHotkeys } from "../_libs/tanstack__react-hotkeys.mjs";
|
|
8
8
|
import { a as matchesKeyboardEvent, i as batch, o as formatForDisplay, r as createStore } from "../_libs/@tanstack/hotkeys+[...].mjs";
|
|
@@ -22,7 +22,7 @@ import { t as remarkGfm } from "../_libs/remark-gfm.mjs";
|
|
|
22
22
|
import { a as getBuiltInSpriteSheet, i as getBuiltInFileIconColor, n as FileTree, r as createFileTreeIconResolver, t as useFileTree } from "../_libs/@pierre/trees+[...].mjs";
|
|
23
23
|
import { a as closestCenter, c as useDraggable, d as useSensors, f as CSS$1, i as PointerSensor, n as DragOverlay, t as DndContext, u as useSensor } from "../_libs/@dnd-kit/core+[...].mjs";
|
|
24
24
|
import { a as verticalListSortingStrategy, i as useSortable, n as arrayMove, r as horizontalListSortingStrategy, t as SortableContext } from "../_libs/dnd-kit__sortable.mjs";
|
|
25
|
-
//#region node_modules/.nitro/vite/services/ssr/assets/routes-
|
|
25
|
+
//#region node_modules/.nitro/vite/services/ssr/assets/routes-NB2wmfpS.js
|
|
26
26
|
var import_react = /* @__PURE__ */ __toESM(require_react());
|
|
27
27
|
var import_jsx_runtime = require_jsx_runtime();
|
|
28
28
|
var MOBILE_BREAKPOINT = 768;
|
|
@@ -5286,8 +5286,8 @@ function AppShellTreeDialogController({ ref, openStateRef, viewerContextId, sess
|
|
|
5286
5286
|
})
|
|
5287
5287
|
});
|
|
5288
5288
|
},
|
|
5289
|
-
onSuccess:
|
|
5290
|
-
|
|
5289
|
+
onSuccess: () => {
|
|
5290
|
+
queryClient.invalidateQueries({
|
|
5291
5291
|
queryKey,
|
|
5292
5292
|
exact: true,
|
|
5293
5293
|
refetchType: "active"
|
|
@@ -5318,6 +5318,7 @@ function AppShellTreeDialogController({ ref, openStateRef, viewerContextId, sess
|
|
|
5318
5318
|
};
|
|
5319
5319
|
const navigateTreeNode = async (targetId, options) => {
|
|
5320
5320
|
if (!viewerContextId) return;
|
|
5321
|
+
setOpenState(false);
|
|
5321
5322
|
try {
|
|
5322
5323
|
const response = await navigateTreeNodeMutation.mutateAsync({
|
|
5323
5324
|
targetId,
|
|
@@ -5332,7 +5333,6 @@ function AppShellTreeDialogController({ ref, openStateRef, viewerContextId, sess
|
|
|
5332
5333
|
toast.info("Tree navigation cancelled");
|
|
5333
5334
|
return;
|
|
5334
5335
|
}
|
|
5335
|
-
setOpenState(false);
|
|
5336
5336
|
toast.success(options?.summarize ? "Continued from summarized branch" : "Moved session tree cursor");
|
|
5337
5337
|
} catch (error) {
|
|
5338
5338
|
toast.error(error instanceof Error ? error.message : "Failed to navigate tree");
|
|
@@ -9409,6 +9409,24 @@ function formatComposerSkillName(skillName = "") {
|
|
|
9409
9409
|
return [`${part.charAt(0).toUpperCase()}${part.slice(1)}`];
|
|
9410
9410
|
}).join(" ");
|
|
9411
9411
|
}
|
|
9412
|
+
function formatComposerDiffLineCommentReference(comment) {
|
|
9413
|
+
const sideLabel = comment.side === "deletions" ? "old" : "new";
|
|
9414
|
+
return `${comment.path}:L${comment.lineNumber} (${sideLabel})`;
|
|
9415
|
+
}
|
|
9416
|
+
function formatComposerDiffLineCommentForPrompt(comment) {
|
|
9417
|
+
const sourceLabel = comment.commit === "working-tree" ? "working tree changes" : comment.shortHash;
|
|
9418
|
+
return `- ${formatComposerDiffLineCommentReference(comment)} in ${sourceLabel}: ${comment.text}`;
|
|
9419
|
+
}
|
|
9420
|
+
function buildComposerPromptMessage({ diffLineComments, skillName, text }) {
|
|
9421
|
+
const baseMessage = serializeComposerDraft({
|
|
9422
|
+
text,
|
|
9423
|
+
skillName
|
|
9424
|
+
}).trim();
|
|
9425
|
+
const comments = diffLineComments?.filter((comment) => comment.text.trim().length > 0);
|
|
9426
|
+
if (!comments || comments.length === 0) return baseMessage;
|
|
9427
|
+
const commentBlock = `Diff comments:\n${comments.map(formatComposerDiffLineCommentForPrompt).join("\n")}`;
|
|
9428
|
+
return baseMessage ? `${baseMessage}\n\n${commentBlock}` : commentBlock;
|
|
9429
|
+
}
|
|
9412
9430
|
function parseSlashCommandInput(value = "") {
|
|
9413
9431
|
const rawValue = typeof value === "string" ? value : "";
|
|
9414
9432
|
const trimmedStart = rawValue.trimStart();
|
|
@@ -12074,7 +12092,7 @@ function getClipboardImageFiles(data) {
|
|
|
12074
12092
|
if (itemFiles.length > 0) return itemFiles;
|
|
12075
12093
|
return Array.from(data.files).filter((file) => file.type.startsWith("image/"));
|
|
12076
12094
|
}
|
|
12077
|
-
function ComposerPanel({ activeSessionId, currentPendingMessages, composerImages, composerText, composerSkill, composerSyncNonce, centerMessages, contextUsageStore, displaySettingsStore, sessionStore, isSubmitting, isStreaming, awaitingFirstTurn, disabled = false, flush = false, topContent, viewerContextId, fileInputRef, onComposerTextChange, onPickImages, onRemoveComposerImage, onSubmitPrompt, onAbort, onEditPendingMessage, onRemovePendingMessage, onReorderPending, onRunBuiltinSlashCommand, onSelectModel, onSelectThinkingLevel, requestPathCompletions, requestFileCompletions, ref }) {
|
|
12095
|
+
function ComposerPanel({ activeSessionId, currentPendingMessages, composerDiffLineComments, composerImages, composerText, composerSkill, composerSyncNonce, centerMessages, contextUsageStore, displaySettingsStore, sessionStore, isSubmitting, isStreaming, awaitingFirstTurn, disabled = false, flush = false, topContent, viewerContextId, fileInputRef, onComposerTextChange, onPickImages, onRemoveComposerDiffLineComment, onRemoveComposerImage, onSubmitPrompt, onAbort, onEditPendingMessage, onRemovePendingMessage, onReorderPending, onRunBuiltinSlashCommand, onSelectModel, onSelectThinkingLevel, requestPathCompletions, requestFileCompletions, ref }) {
|
|
12078
12096
|
const promptRef = import_react.useRef(null);
|
|
12079
12097
|
const [pickerState, dispatchPickerState] = import_react.useReducer(composerPickerReducer, INITIAL_COMPOSER_PICKER_STATE);
|
|
12080
12098
|
const { modelPickerOpen, thinkingPickerOpen, modelQuery } = pickerState;
|
|
@@ -12108,6 +12126,7 @@ function ComposerPanel({ activeSessionId, currentPendingMessages, composerImages
|
|
|
12108
12126
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
12109
12127
|
className: "overflow-visible rounded-[18px] border bg-card",
|
|
12110
12128
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ComposerPromptEditor, {
|
|
12129
|
+
composerDiffLineComments,
|
|
12111
12130
|
composerImages,
|
|
12112
12131
|
composerText,
|
|
12113
12132
|
composerSkill,
|
|
@@ -12122,6 +12141,7 @@ function ComposerPanel({ activeSessionId, currentPendingMessages, composerImages
|
|
|
12122
12141
|
sessionStore,
|
|
12123
12142
|
onComposerTextChange,
|
|
12124
12143
|
onPickImages,
|
|
12144
|
+
onRemoveComposerDiffLineComment,
|
|
12125
12145
|
onRemoveComposerImage,
|
|
12126
12146
|
onSubmitPrompt,
|
|
12127
12147
|
onAbort,
|
|
@@ -12195,7 +12215,7 @@ var ComposerAttachments = import_react.memo(function ComposerAttachments({ image
|
|
|
12195
12215
|
}, promptImageKey(image)))
|
|
12196
12216
|
});
|
|
12197
12217
|
});
|
|
12198
|
-
var ComposerPromptEditor = import_react.memo(function ComposerPromptEditor({ composerImages, composerText, composerSkill, composerSyncNonce, isSubmitting, isStreaming, awaitingFirstTurn, disabled = false, fileInputRef, promptRef, displaySettingsStore, sessionStore, onComposerTextChange, onPickImages, onRemoveComposerImage, onSubmitPrompt, onAbort, onRunBuiltinSlashCommand, requestPathCompletions, requestFileCompletions }) {
|
|
12218
|
+
var ComposerPromptEditor = import_react.memo(function ComposerPromptEditor({ composerDiffLineComments, composerImages, composerText, composerSkill, composerSyncNonce, isSubmitting, isStreaming, awaitingFirstTurn, disabled = false, fileInputRef, promptRef, displaySettingsStore, sessionStore, onComposerTextChange, onPickImages, onRemoveComposerDiffLineComment, onRemoveComposerImage, onSubmitPrompt, onAbort, onRunBuiltinSlashCommand, requestPathCompletions, requestFileCompletions }) {
|
|
12199
12219
|
const slashCommands = useComposerSlashCommands({
|
|
12200
12220
|
displaySettingsStore,
|
|
12201
12221
|
sessionStore
|
|
@@ -12282,8 +12302,9 @@ var ComposerPromptEditor = import_react.memo(function ComposerPromptEditor({ com
|
|
|
12282
12302
|
dismissMenus,
|
|
12283
12303
|
promptRef
|
|
12284
12304
|
]);
|
|
12285
|
-
const hasSubmittableContent = hasDraftText || composerImages.length > 0;
|
|
12286
|
-
const
|
|
12305
|
+
const hasSubmittableContent = hasDraftText || composerDiffLineComments.length > 0 || composerImages.length > 0;
|
|
12306
|
+
const responseInFlight = isStreaming || awaitingFirstTurn || isSubmitting;
|
|
12307
|
+
const acceptFollowUps = responseInFlight;
|
|
12287
12308
|
const setAssistPointerSelectionSuppressedValue = (next) => {
|
|
12288
12309
|
assistPointerSelectionSuppressedRef.current = next;
|
|
12289
12310
|
setAssistPointerSelectionSuppressed(next);
|
|
@@ -12358,6 +12379,11 @@ var ComposerPromptEditor = import_react.memo(function ComposerPromptEditor({ com
|
|
|
12358
12379
|
applyDraft("", void 0, { immediate: true });
|
|
12359
12380
|
return;
|
|
12360
12381
|
}
|
|
12382
|
+
if (event.key === "Backspace" && !draftText && !currentDraftSkill && composerDiffLineComments.length > 0) {
|
|
12383
|
+
const lastComment = composerDiffLineComments.at(-1);
|
|
12384
|
+
if (lastComment) onRemoveComposerDiffLineComment(lastComment.id);
|
|
12385
|
+
return;
|
|
12386
|
+
}
|
|
12361
12387
|
if (visibleCompletion && (event.key === "ArrowDown" || event.key === "ArrowUp")) {
|
|
12362
12388
|
event.preventDefault();
|
|
12363
12389
|
setAssistPointerSelectionSuppressedValue(true);
|
|
@@ -12416,7 +12442,7 @@ var ComposerPromptEditor = import_react.memo(function ComposerPromptEditor({ com
|
|
|
12416
12442
|
dismissMenus();
|
|
12417
12443
|
return;
|
|
12418
12444
|
}
|
|
12419
|
-
if (
|
|
12445
|
+
if (responseInFlight && !event.repeat) {
|
|
12420
12446
|
event.preventDefault();
|
|
12421
12447
|
event.stopPropagation();
|
|
12422
12448
|
onAbort();
|
|
@@ -12463,39 +12489,62 @@ var ComposerPromptEditor = import_react.memo(function ComposerPromptEditor({ com
|
|
|
12463
12489
|
className: "min-w-0",
|
|
12464
12490
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
12465
12491
|
className: "flex min-w-0 flex-wrap items-start gap-2",
|
|
12466
|
-
children: [
|
|
12467
|
-
|
|
12468
|
-
|
|
12469
|
-
|
|
12470
|
-
|
|
12471
|
-
|
|
12472
|
-
|
|
12473
|
-
|
|
12474
|
-
|
|
12475
|
-
|
|
12492
|
+
children: [
|
|
12493
|
+
draftSkill ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
12494
|
+
className: "inline-flex h-7 max-w-[45%] shrink-0 items-center gap-0 overflow-hidden rounded-full bg-primary/10 pr-0.5 pl-2 text-sm font-medium text-primary",
|
|
12495
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
12496
|
+
className: "truncate",
|
|
12497
|
+
children: ["Skill: ", formatComposerSkillName(draftSkill)]
|
|
12498
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button$1, {
|
|
12499
|
+
size: "icon-sm",
|
|
12500
|
+
variant: "ghost",
|
|
12501
|
+
className: "ml-1 rounded-full text-primary hover:bg-primary/10 hover:text-primary",
|
|
12502
|
+
"aria-label": `Remove skill ${formatComposerSkillName(draftSkill)}`,
|
|
12503
|
+
disabled,
|
|
12504
|
+
onClick: () => applyDraft(draftTextRef.current, void 0, { immediate: true }),
|
|
12505
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(X, { className: "size-3.5" })
|
|
12506
|
+
})]
|
|
12507
|
+
}) : null,
|
|
12508
|
+
composerDiffLineComments.map((comment) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
12509
|
+
title: `${formatComposerDiffLineCommentReference(comment)}: ${comment.text}`,
|
|
12510
|
+
className: "inline-flex h-7 max-w-[45%] shrink-0 items-center gap-1 overflow-hidden rounded-full bg-amber-500/10 pr-0.5 pl-2 text-sm font-medium text-amber-700 dark:text-amber-300",
|
|
12511
|
+
children: [
|
|
12512
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitPullRequestArrow, { className: "size-3.5 shrink-0" }),
|
|
12513
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
12514
|
+
className: "truncate",
|
|
12515
|
+
children: ["Diff: ", formatComposerDiffLineCommentReference(comment)]
|
|
12516
|
+
}),
|
|
12517
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button$1, {
|
|
12518
|
+
size: "icon-sm",
|
|
12519
|
+
variant: "ghost",
|
|
12520
|
+
className: "ml-1 rounded-full text-amber-700 hover:bg-amber-500/10 hover:text-amber-700 dark:text-amber-300 dark:hover:text-amber-300",
|
|
12521
|
+
"aria-label": `Remove diff comment for ${formatComposerDiffLineCommentReference(comment)}`,
|
|
12522
|
+
disabled,
|
|
12523
|
+
onClick: () => onRemoveComposerDiffLineComment(comment.id),
|
|
12524
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(X, { className: "size-3.5" })
|
|
12525
|
+
})
|
|
12526
|
+
]
|
|
12527
|
+
}, comment.id)),
|
|
12528
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Textarea, {
|
|
12529
|
+
ref: promptRef,
|
|
12530
|
+
name: "prompt",
|
|
12531
|
+
rows: 1,
|
|
12532
|
+
autoComplete: "off",
|
|
12533
|
+
"data-1p-ignore": "true",
|
|
12534
|
+
"data-form-type": "other",
|
|
12535
|
+
"data-lpignore": "true",
|
|
12536
|
+
defaultValue: composerText,
|
|
12537
|
+
onChange: handleTextChange,
|
|
12538
|
+
onClick: syncSelection,
|
|
12539
|
+
onKeyUp: syncSelection,
|
|
12540
|
+
onSelect: syncSelection,
|
|
12541
|
+
onKeyDown: handleKeyDown,
|
|
12542
|
+
onPaste: handlePaste,
|
|
12476
12543
|
disabled,
|
|
12477
|
-
|
|
12478
|
-
|
|
12479
|
-
})
|
|
12480
|
-
|
|
12481
|
-
ref: promptRef,
|
|
12482
|
-
name: "prompt",
|
|
12483
|
-
rows: 1,
|
|
12484
|
-
autoComplete: "off",
|
|
12485
|
-
"data-1p-ignore": "true",
|
|
12486
|
-
"data-form-type": "other",
|
|
12487
|
-
"data-lpignore": "true",
|
|
12488
|
-
defaultValue: composerText,
|
|
12489
|
-
onChange: handleTextChange,
|
|
12490
|
-
onClick: syncSelection,
|
|
12491
|
-
onKeyUp: syncSelection,
|
|
12492
|
-
onSelect: syncSelection,
|
|
12493
|
-
onKeyDown: handleKeyDown,
|
|
12494
|
-
onPaste: handlePaste,
|
|
12495
|
-
disabled,
|
|
12496
|
-
placeholder: acceptFollowUps ? "Add a message to the queue..." : draftSkill ? `Ask with ${formatComposerSkillName(draftSkill)}…` : "Ask anything…",
|
|
12497
|
-
className: "max-h-[min(40dvh,18rem)] min-h-[22px] max-w-full min-w-0 flex-1 basis-[min(240px,100%)] resize-none overflow-y-auto rounded-none border-0 bg-transparent p-0 text-base shadow-none ring-0 focus-visible:border-transparent focus-visible:ring-0 disabled:cursor-text disabled:bg-transparent disabled:opacity-60 md:text-sm dark:bg-transparent dark:disabled:bg-transparent"
|
|
12498
|
-
})]
|
|
12544
|
+
placeholder: acceptFollowUps ? "Add a message to the queue..." : draftSkill ? `Ask with ${formatComposerSkillName(draftSkill)}…` : "Ask anything…",
|
|
12545
|
+
className: "max-h-[min(40dvh,18rem)] min-h-[22px] max-w-full min-w-0 flex-1 basis-[min(240px,100%)] resize-none overflow-y-auto rounded-none border-0 bg-transparent p-0 text-base shadow-none ring-0 focus-visible:border-transparent focus-visible:ring-0 disabled:cursor-text disabled:bg-transparent disabled:opacity-60 md:text-sm dark:bg-transparent dark:disabled:bg-transparent"
|
|
12546
|
+
})
|
|
12547
|
+
]
|
|
12499
12548
|
})
|
|
12500
12549
|
})]
|
|
12501
12550
|
}),
|
|
@@ -12550,7 +12599,7 @@ var ComposerPromptEditor = import_react.memo(function ComposerPromptEditor({ com
|
|
|
12550
12599
|
onClick: () => runPrimaryComposerAction("steer"),
|
|
12551
12600
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ListStart, { "data-icon": "inline-start" }), "Steer"]
|
|
12552
12601
|
}),
|
|
12553
|
-
|
|
12602
|
+
responseInFlight ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleTooltip, {
|
|
12554
12603
|
title: "Abort",
|
|
12555
12604
|
kbd: "Esc",
|
|
12556
12605
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button$1, {
|
|
@@ -12929,6 +12978,7 @@ var AppShellComposerController = import_react.memo(function AppShellComposerCont
|
|
|
12929
12978
|
ref: composerPanelRef,
|
|
12930
12979
|
activeSessionId: snapshot.activeSessionId,
|
|
12931
12980
|
currentPendingMessages: snapshot.currentPendingMessages,
|
|
12981
|
+
composerDiffLineComments: snapshot.composerDiffLineComments,
|
|
12932
12982
|
composerImages: snapshot.composerImages,
|
|
12933
12983
|
composerText: snapshot.composerText,
|
|
12934
12984
|
composerSkill: snapshot.composerSkill,
|
|
@@ -12947,6 +12997,7 @@ var AppShellComposerController = import_react.memo(function AppShellComposerCont
|
|
|
12947
12997
|
fileInputRef,
|
|
12948
12998
|
onComposerTextChange,
|
|
12949
12999
|
onPickImages,
|
|
13000
|
+
onRemoveComposerDiffLineComment: actionsRef.current.removeDiffLineComment,
|
|
12950
13001
|
onRemoveComposerImage,
|
|
12951
13002
|
onSubmitPrompt,
|
|
12952
13003
|
onAbort,
|
|
@@ -13973,9 +14024,11 @@ function AppShellConversationFrame({ autoScrollEnabled, children, conversationIt
|
|
|
13973
14024
|
}
|
|
13974
14025
|
function AppShellWorkingIndicatorLabel({ fallbackLabel, hiddenThinkingPreviewStore, useHiddenThinkingPreview }) {
|
|
13975
14026
|
const hiddenThinkingPreview = useSelector(hiddenThinkingPreviewStore);
|
|
14027
|
+
const visibleLabel = useHiddenThinkingPreview && hiddenThinkingPreview ? hiddenThinkingPreview : fallbackLabel;
|
|
14028
|
+
if (!visibleLabel.trim()) return null;
|
|
13976
14029
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
13977
14030
|
className: "font-medium text-foreground",
|
|
13978
|
-
children:
|
|
14031
|
+
children: visibleLabel
|
|
13979
14032
|
});
|
|
13980
14033
|
}
|
|
13981
14034
|
function AppShellMessagesWorkingIndicator({ hiddenThinkingPreviewStore, onCancel, state, useHiddenThinkingPreview }) {
|
|
@@ -14113,7 +14166,7 @@ function AppShellConversationEmptyState({ awaitingFirstTurn, conversationItemsSt
|
|
|
14113
14166
|
const conversationLoadingLabel = isSessionViewLoading ? "Loading session…" : displayedWorkingState && !displayedWorkingState.done ? displayedWorkingState.label : "Loading…";
|
|
14114
14167
|
if (showConversationLoadingState) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
14115
14168
|
className: "flex flex-1 flex-col items-center justify-center gap-3 py-10 text-sm text-muted-foreground",
|
|
14116
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: conversationLoadingLabel })]
|
|
14169
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Spinner, {}), conversationLoadingLabel ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { children: conversationLoadingLabel }) : null]
|
|
14117
14170
|
});
|
|
14118
14171
|
if (hasMessages) return null;
|
|
14119
14172
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Empty, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(EmptyHeader, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(EmptyTitle, { children: draft ? "New session" : "Start a new conversation" }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EmptyDescription, { children: draft ? void 0 : "This is the native Pico session view backed by the new TypeScript runtime." })] }), draft ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(EmptyContent, {
|
|
@@ -16327,7 +16380,7 @@ var GIT_GRAPH_LANE_COLORS = [
|
|
|
16327
16380
|
];
|
|
16328
16381
|
var GIT_GRAPH_NULL_VERTEX_ID = -1;
|
|
16329
16382
|
var GIT_GRAPH_ROW_HEIGHT = 32;
|
|
16330
|
-
var GIT_GRAPH_COMMIT_DETAILS_HEIGHT =
|
|
16383
|
+
var GIT_GRAPH_COMMIT_DETAILS_HEIGHT = 200;
|
|
16331
16384
|
var GIT_GRAPH_LANE_WIDTH = 14;
|
|
16332
16385
|
var GIT_GRAPH_OFFSET_X = 12;
|
|
16333
16386
|
var initialGitCommitRowState = {
|
|
@@ -17361,7 +17414,7 @@ function useGitCommitRowView({ viewerContextId, cwd, graphWidth, line, value, on
|
|
|
17361
17414
|
}, contextMenuKey)
|
|
17362
17415
|
}),
|
|
17363
17416
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(AccordionContent, {
|
|
17364
|
-
className: "relative h-[
|
|
17417
|
+
className: "relative h-[200px] border-b border-border/70 bg-muted/50 p-0",
|
|
17365
17418
|
children: [
|
|
17366
17419
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
17367
17420
|
ref: commitBodyScrollRef,
|
|
@@ -17767,6 +17820,124 @@ function GitFileDiff({ file }) {
|
|
|
17767
17820
|
}) : null]
|
|
17768
17821
|
});
|
|
17769
17822
|
}
|
|
17823
|
+
function reviewDiffCommentSideLabel(side) {
|
|
17824
|
+
return side === "deletions" ? "old" : "new";
|
|
17825
|
+
}
|
|
17826
|
+
function reviewDiffCommentLineFromRange(range) {
|
|
17827
|
+
return Math.min(range.start, range.end);
|
|
17828
|
+
}
|
|
17829
|
+
function reviewDiffCommentSideFromRange(range) {
|
|
17830
|
+
return range.side || range.endSide || "additions";
|
|
17831
|
+
}
|
|
17832
|
+
function reviewDiffCommentPath(file, side) {
|
|
17833
|
+
return side === "deletions" ? file.previousPath || file.path : file.path;
|
|
17834
|
+
}
|
|
17835
|
+
function reviewDiffCommentTabKey(file) {
|
|
17836
|
+
return `changes:${reviewFileValue(file)}`;
|
|
17837
|
+
}
|
|
17838
|
+
function reviewDiffLineCommentAnnotations({ comments, pendingComment }) {
|
|
17839
|
+
const annotations = comments.map((comment) => ({
|
|
17840
|
+
lineNumber: comment.lineNumber,
|
|
17841
|
+
metadata: comment,
|
|
17842
|
+
side: comment.side
|
|
17843
|
+
}));
|
|
17844
|
+
if (pendingComment) annotations.push({
|
|
17845
|
+
lineNumber: pendingComment.lineNumber,
|
|
17846
|
+
metadata: pendingComment,
|
|
17847
|
+
side: pendingComment.side
|
|
17848
|
+
});
|
|
17849
|
+
return annotations;
|
|
17850
|
+
}
|
|
17851
|
+
function ReviewDiffPendingLineComment({ comment }) {
|
|
17852
|
+
const [text, setText] = import_react.useState("");
|
|
17853
|
+
const textareaRef = import_react.useRef(null);
|
|
17854
|
+
import_react.useEffect(() => {
|
|
17855
|
+
textareaRef.current?.focus();
|
|
17856
|
+
}, []);
|
|
17857
|
+
const submit = () => {
|
|
17858
|
+
const normalizedText = text.trim();
|
|
17859
|
+
if (!normalizedText) return;
|
|
17860
|
+
comment.onSubmit(normalizedText);
|
|
17861
|
+
};
|
|
17862
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("form", {
|
|
17863
|
+
className: "m-2 max-w-[min(38rem,calc(100%-1rem))] rounded-lg border border-border/70 bg-background p-2 shadow-sm",
|
|
17864
|
+
onPointerDown: (event) => event.stopPropagation(),
|
|
17865
|
+
onSubmit: (event) => {
|
|
17866
|
+
event.preventDefault();
|
|
17867
|
+
submit();
|
|
17868
|
+
},
|
|
17869
|
+
children: [
|
|
17870
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
17871
|
+
className: "mb-2 flex min-w-0 items-center justify-between gap-2 text-xs text-muted-foreground",
|
|
17872
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
17873
|
+
className: "min-w-0 truncate",
|
|
17874
|
+
children: [
|
|
17875
|
+
"Comment on ",
|
|
17876
|
+
comment.path,
|
|
17877
|
+
":L",
|
|
17878
|
+
comment.lineNumber,
|
|
17879
|
+
" (",
|
|
17880
|
+
reviewDiffCommentSideLabel(comment.side),
|
|
17881
|
+
")"
|
|
17882
|
+
]
|
|
17883
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button$1, {
|
|
17884
|
+
type: "button",
|
|
17885
|
+
variant: "ghost",
|
|
17886
|
+
size: "icon-sm",
|
|
17887
|
+
"aria-label": "Cancel line comment",
|
|
17888
|
+
onClick: comment.onCancel,
|
|
17889
|
+
children: "×"
|
|
17890
|
+
})]
|
|
17891
|
+
}),
|
|
17892
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Textarea, {
|
|
17893
|
+
ref: textareaRef,
|
|
17894
|
+
value: text,
|
|
17895
|
+
rows: 2,
|
|
17896
|
+
placeholder: "Add a note for the prompt…",
|
|
17897
|
+
className: "min-h-16 resize-none text-sm",
|
|
17898
|
+
onChange: (event) => setText(event.target.value),
|
|
17899
|
+
onKeyDown: (event) => {
|
|
17900
|
+
if (event.key === "Enter" && (event.metaKey || event.ctrlKey)) {
|
|
17901
|
+
event.preventDefault();
|
|
17902
|
+
submit();
|
|
17903
|
+
}
|
|
17904
|
+
if (event.key === "Escape") {
|
|
17905
|
+
event.preventDefault();
|
|
17906
|
+
comment.onCancel();
|
|
17907
|
+
}
|
|
17908
|
+
}
|
|
17909
|
+
}),
|
|
17910
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
17911
|
+
className: "mt-2 flex justify-end gap-2",
|
|
17912
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button$1, {
|
|
17913
|
+
type: "button",
|
|
17914
|
+
variant: "ghost",
|
|
17915
|
+
onClick: comment.onCancel,
|
|
17916
|
+
children: "Cancel"
|
|
17917
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Button$1, {
|
|
17918
|
+
type: "submit",
|
|
17919
|
+
disabled: !text.trim(),
|
|
17920
|
+
children: "Add to prompt"
|
|
17921
|
+
})]
|
|
17922
|
+
})
|
|
17923
|
+
]
|
|
17924
|
+
});
|
|
17925
|
+
}
|
|
17926
|
+
function ReviewDiffLineAnnotation({ annotation }) {
|
|
17927
|
+
const comment = annotation.metadata;
|
|
17928
|
+
if (!comment) return null;
|
|
17929
|
+
if (comment.kind === "pending") return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ReviewDiffPendingLineComment, { comment });
|
|
17930
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
17931
|
+
className: "my-1 ml-2 inline-flex max-w-[min(32rem,90%)] items-center gap-1 rounded-full border border-amber-500/20 bg-amber-500/10 px-2 py-1 text-[11px] text-amber-800 dark:text-amber-200",
|
|
17932
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
17933
|
+
className: "shrink-0",
|
|
17934
|
+
children: "💬"
|
|
17935
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
17936
|
+
className: "truncate",
|
|
17937
|
+
children: comment.text
|
|
17938
|
+
})]
|
|
17939
|
+
});
|
|
17940
|
+
}
|
|
17770
17941
|
var GIT_HISTORY_PANEL_MIN_HEIGHT = 160;
|
|
17771
17942
|
var GIT_HISTORY_PANEL_MAX_STORED_HEIGHT = 1600;
|
|
17772
17943
|
function clampStoredGitHistoryPanelHeight(height) {
|
|
@@ -17866,7 +18037,7 @@ function gitFileShouldPreviewPatch(file) {
|
|
|
17866
18037
|
function FileReviewContent(props) {
|
|
17867
18038
|
return useFileReviewContentView(props);
|
|
17868
18039
|
}
|
|
17869
|
-
function useFileReviewContentView({ viewerContextId, cwd, active, onMaximizeHistory, onOpenCommitDiff, onOpenFile, showEmbeddedHistory = true }) {
|
|
18040
|
+
function useFileReviewContentView({ viewerContextId, cwd, active, diffLineComments = [], onAddDiffLineComment, onMaximizeHistory, onOpenCommitDiff, onOpenFile, showEmbeddedHistory = true }) {
|
|
17870
18041
|
const normalizedCwd = normalizeCwd(cwd);
|
|
17871
18042
|
const isMobile = useIsMobile();
|
|
17872
18043
|
const [state, dispatch] = import_react.useReducer(fileReviewReducer, initialFileReviewState, (initialState) => ({
|
|
@@ -18102,10 +18273,12 @@ function useFileReviewContentView({ viewerContextId, cwd, active, onMaximizeHist
|
|
|
18102
18273
|
viewerContextId,
|
|
18103
18274
|
cwd: normalizedCwd,
|
|
18104
18275
|
active,
|
|
18276
|
+
diffLineComments,
|
|
18105
18277
|
diffStyle,
|
|
18106
18278
|
file,
|
|
18107
18279
|
open: openFiles.includes(reviewFileValue(file)),
|
|
18108
18280
|
stuck: stickyReviewFileValue === reviewFileValue(file),
|
|
18281
|
+
onAddDiffLineComment,
|
|
18109
18282
|
onOpenFile
|
|
18110
18283
|
}, reviewFileValue(file)))
|
|
18111
18284
|
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitSectionNote, {
|
|
@@ -18174,10 +18347,12 @@ function useFileReviewContentView({ viewerContextId, cwd, active, onMaximizeHist
|
|
|
18174
18347
|
]
|
|
18175
18348
|
});
|
|
18176
18349
|
}
|
|
18177
|
-
function ReviewFileAccordionItem({ viewerContextId, cwd, active, diffStyle, file, open, stuck, onOpenFile }) {
|
|
18350
|
+
function ReviewFileAccordionItem({ viewerContextId, cwd, active, diffLineComments = [], diffStyle, file, open, stuck, onAddDiffLineComment, onOpenFile }) {
|
|
18178
18351
|
const normalizedCwd = normalizeCwd(cwd);
|
|
18179
18352
|
const queryClient = useQueryClient();
|
|
18180
18353
|
const value = reviewFileValue(file);
|
|
18354
|
+
const commentTabKey = reviewDiffCommentTabKey(file);
|
|
18355
|
+
const [commentTarget, setCommentTarget] = import_react.useState(null);
|
|
18181
18356
|
const [fullContextRequested, setFullContextRequested] = import_react.useState(false);
|
|
18182
18357
|
const previewPatch = gitFileShouldPreviewPatch(file) && !fullContextRequested;
|
|
18183
18358
|
const diffQuery = useQuery({
|
|
@@ -18210,6 +18385,40 @@ function ReviewFileAccordionItem({ viewerContextId, cwd, active, diffStyle, file
|
|
|
18210
18385
|
const oldContent = reviewQuery.data?.oldContent ?? "";
|
|
18211
18386
|
const newContent = reviewQuery.data?.newContent ?? "";
|
|
18212
18387
|
const patch = diffQuery.data?.patch ?? "";
|
|
18388
|
+
const commentsForFile = diffLineComments.filter((comment) => comment.cwd === normalizedCwd && comment.tabKey === commentTabKey);
|
|
18389
|
+
const startLineComment = (range) => {
|
|
18390
|
+
if (!onAddDiffLineComment) return;
|
|
18391
|
+
const side = reviewDiffCommentSideFromRange(range);
|
|
18392
|
+
setCommentTarget({
|
|
18393
|
+
commit: "working-tree",
|
|
18394
|
+
lineNumber: reviewDiffCommentLineFromRange(range),
|
|
18395
|
+
mode: "head",
|
|
18396
|
+
path: reviewDiffCommentPath(file, side),
|
|
18397
|
+
shortHash: "working tree",
|
|
18398
|
+
side,
|
|
18399
|
+
tabKey: commentTabKey,
|
|
18400
|
+
tabTitle: "Working tree changes"
|
|
18401
|
+
});
|
|
18402
|
+
};
|
|
18403
|
+
const lineAnnotations = reviewDiffLineCommentAnnotations({
|
|
18404
|
+
comments: commentsForFile,
|
|
18405
|
+
pendingComment: commentTarget ? {
|
|
18406
|
+
...commentTarget,
|
|
18407
|
+
kind: "pending",
|
|
18408
|
+
onCancel: () => setCommentTarget(null),
|
|
18409
|
+
onSubmit: (text) => {
|
|
18410
|
+
onAddDiffLineComment?.({
|
|
18411
|
+
...commentTarget,
|
|
18412
|
+
text
|
|
18413
|
+
});
|
|
18414
|
+
setCommentTarget(null);
|
|
18415
|
+
}
|
|
18416
|
+
} : null
|
|
18417
|
+
});
|
|
18418
|
+
const commentableOptions = onAddDiffLineComment ? {
|
|
18419
|
+
enableGutterUtility: true,
|
|
18420
|
+
onGutterUtilityClick: startLineComment
|
|
18421
|
+
} : {};
|
|
18213
18422
|
const [indexStatus, worktreeStatus] = gitFileStatusCharacters(file.status);
|
|
18214
18423
|
const canStage = worktreeStatus !== " " || indexStatus === "?";
|
|
18215
18424
|
const invalidateChangedFileQueries = async () => {
|
|
@@ -18267,6 +18476,15 @@ function ReviewFileAccordionItem({ viewerContextId, cwd, active, diffStyle, file
|
|
|
18267
18476
|
}
|
|
18268
18477
|
});
|
|
18269
18478
|
const actionPending = stageMutation.isPending || discardMutation.isPending;
|
|
18479
|
+
import_react.useEffect(() => {
|
|
18480
|
+
setCommentTarget(null);
|
|
18481
|
+
}, [
|
|
18482
|
+
value,
|
|
18483
|
+
previewPatch,
|
|
18484
|
+
patch,
|
|
18485
|
+
oldContent,
|
|
18486
|
+
newContent
|
|
18487
|
+
]);
|
|
18270
18488
|
const openFile = (event) => {
|
|
18271
18489
|
event?.stopPropagation();
|
|
18272
18490
|
onOpenFile?.(file.path, { pin: true });
|
|
@@ -18375,9 +18593,12 @@ function ReviewFileAccordionItem({ viewerContextId, cwd, active, diffStyle, file
|
|
|
18375
18593
|
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PatchDiff, {
|
|
18376
18594
|
patch,
|
|
18377
18595
|
disableWorkerPool: true,
|
|
18596
|
+
lineAnnotations,
|
|
18597
|
+
renderAnnotation: (annotation) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ReviewDiffLineAnnotation, { annotation }),
|
|
18378
18598
|
options: {
|
|
18379
18599
|
diffStyle,
|
|
18380
18600
|
disableFileHeader: true,
|
|
18601
|
+
...commentableOptions,
|
|
18381
18602
|
overflow: "wrap"
|
|
18382
18603
|
}
|
|
18383
18604
|
})] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
@@ -18402,9 +18623,12 @@ function ReviewFileAccordionItem({ viewerContextId, cwd, active, diffStyle, file
|
|
|
18402
18623
|
contents: newContent
|
|
18403
18624
|
},
|
|
18404
18625
|
disableWorkerPool: true,
|
|
18626
|
+
lineAnnotations,
|
|
18627
|
+
renderAnnotation: (annotation) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ReviewDiffLineAnnotation, { annotation }),
|
|
18405
18628
|
options: {
|
|
18406
18629
|
diffStyle,
|
|
18407
18630
|
disableFileHeader: true,
|
|
18631
|
+
...commentableOptions,
|
|
18408
18632
|
overflow: "wrap"
|
|
18409
18633
|
}
|
|
18410
18634
|
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
@@ -18414,6 +18638,7 @@ function ReviewFileAccordionItem({ viewerContextId, cwd, active, diffStyle, file
|
|
|
18414
18638
|
})]
|
|
18415
18639
|
});
|
|
18416
18640
|
}
|
|
18641
|
+
var EMPTY_RIGHT_SIDEBAR_DIFF_LINE_COMMENTS = [];
|
|
18417
18642
|
var EMPTY_RIGHT_SIDEBAR_FILE_TABS = [];
|
|
18418
18643
|
function readStoredHistoryAsTab() {
|
|
18419
18644
|
return safeLocalStorageGetItem(RIGHT_SIDEBAR_HISTORY_TAB_STORAGE_KEY) === "1";
|
|
@@ -18535,7 +18760,159 @@ function commitFileDiffLineCounts(fileDiff) {
|
|
|
18535
18760
|
deletions: 0
|
|
18536
18761
|
});
|
|
18537
18762
|
}
|
|
18538
|
-
function
|
|
18763
|
+
function commitDiffCommentSideLabel(side) {
|
|
18764
|
+
return side === "deletions" ? "old" : "new";
|
|
18765
|
+
}
|
|
18766
|
+
function commitDiffLineCommentAnnotations({ comments, pendingComment }) {
|
|
18767
|
+
const annotations = comments.map((comment) => ({
|
|
18768
|
+
lineNumber: comment.lineNumber,
|
|
18769
|
+
metadata: comment,
|
|
18770
|
+
side: comment.side
|
|
18771
|
+
}));
|
|
18772
|
+
if (pendingComment) annotations.push({
|
|
18773
|
+
lineNumber: pendingComment.lineNumber,
|
|
18774
|
+
metadata: pendingComment,
|
|
18775
|
+
side: pendingComment.side
|
|
18776
|
+
});
|
|
18777
|
+
return annotations;
|
|
18778
|
+
}
|
|
18779
|
+
function assignClassName(element, className) {
|
|
18780
|
+
for (const classItem of className.split(/\s+/)) if (classItem) element.classList.add(classItem);
|
|
18781
|
+
}
|
|
18782
|
+
function renderPendingCommitDiffLineComment(pendingComment) {
|
|
18783
|
+
const form = document.createElement("form");
|
|
18784
|
+
assignClassName(form, "m-2 max-w-[min(38rem,calc(100%-1rem))] rounded-lg border border-border/70 bg-background p-2 shadow-sm");
|
|
18785
|
+
const header = document.createElement("div");
|
|
18786
|
+
assignClassName(header, "mb-2 flex min-w-0 items-center justify-between gap-2 text-xs text-muted-foreground");
|
|
18787
|
+
const label = document.createElement("span");
|
|
18788
|
+
label.textContent = `Comment on ${pendingComment.path}:L${pendingComment.lineNumber} (${commitDiffCommentSideLabel(pendingComment.side)})`;
|
|
18789
|
+
assignClassName(label, "min-w-0 truncate");
|
|
18790
|
+
const cancelButton = document.createElement("button");
|
|
18791
|
+
cancelButton.type = "button";
|
|
18792
|
+
cancelButton.textContent = "×";
|
|
18793
|
+
cancelButton.setAttribute("aria-label", "Cancel line comment");
|
|
18794
|
+
assignClassName(cancelButton, "inline-flex size-7 shrink-0 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground");
|
|
18795
|
+
cancelButton.addEventListener("click", () => pendingComment.onCancel());
|
|
18796
|
+
header.append(label, cancelButton);
|
|
18797
|
+
const textarea = document.createElement("textarea");
|
|
18798
|
+
textarea.rows = 2;
|
|
18799
|
+
textarea.placeholder = "Add a note for the prompt…";
|
|
18800
|
+
assignClassName(textarea, "flex min-h-16 w-full resize-none rounded-lg border border-input bg-transparent px-2.5 py-2 text-sm outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50");
|
|
18801
|
+
textarea.addEventListener("keydown", (event) => {
|
|
18802
|
+
if (event.key === "Enter" && (event.metaKey || event.ctrlKey)) {
|
|
18803
|
+
event.preventDefault();
|
|
18804
|
+
submit();
|
|
18805
|
+
}
|
|
18806
|
+
if (event.key === "Escape") {
|
|
18807
|
+
event.preventDefault();
|
|
18808
|
+
pendingComment.onCancel();
|
|
18809
|
+
}
|
|
18810
|
+
});
|
|
18811
|
+
const footer = document.createElement("div");
|
|
18812
|
+
assignClassName(footer, "mt-2 flex justify-end gap-2");
|
|
18813
|
+
const secondaryCancelButton = document.createElement("button");
|
|
18814
|
+
secondaryCancelButton.type = "button";
|
|
18815
|
+
secondaryCancelButton.textContent = "Cancel";
|
|
18816
|
+
assignClassName(secondaryCancelButton, "inline-flex h-8 items-center rounded-md px-3 text-sm hover:bg-muted");
|
|
18817
|
+
secondaryCancelButton.addEventListener("click", () => pendingComment.onCancel());
|
|
18818
|
+
const submitButton = document.createElement("button");
|
|
18819
|
+
submitButton.type = "submit";
|
|
18820
|
+
submitButton.textContent = "Add to prompt";
|
|
18821
|
+
assignClassName(submitButton, "inline-flex h-8 items-center rounded-md bg-primary px-3 text-sm font-medium text-primary-foreground disabled:pointer-events-none disabled:opacity-50");
|
|
18822
|
+
function syncSubmitDisabled() {
|
|
18823
|
+
submitButton.disabled = textarea.value.trim().length === 0;
|
|
18824
|
+
}
|
|
18825
|
+
function submit() {
|
|
18826
|
+
const text = textarea.value.trim();
|
|
18827
|
+
if (!text) return;
|
|
18828
|
+
pendingComment.onSubmit(text);
|
|
18829
|
+
}
|
|
18830
|
+
textarea.addEventListener("input", syncSubmitDisabled);
|
|
18831
|
+
form.addEventListener("submit", (event) => {
|
|
18832
|
+
event.preventDefault();
|
|
18833
|
+
submit();
|
|
18834
|
+
});
|
|
18835
|
+
footer.append(secondaryCancelButton, submitButton);
|
|
18836
|
+
form.append(header, textarea, footer);
|
|
18837
|
+
syncSubmitDisabled();
|
|
18838
|
+
window.setTimeout(() => textarea.focus(), 0);
|
|
18839
|
+
return form;
|
|
18840
|
+
}
|
|
18841
|
+
function renderCommitDiffLineAnnotation(annotation) {
|
|
18842
|
+
const comment = annotation.metadata;
|
|
18843
|
+
if (!comment) return void 0;
|
|
18844
|
+
if (comment.kind === "pending") return renderPendingCommitDiffLineComment(comment);
|
|
18845
|
+
const savedComment = comment;
|
|
18846
|
+
const wrapper = document.createElement("div");
|
|
18847
|
+
assignClassName(wrapper, "my-1 ml-2 inline-flex max-w-[min(32rem,90%)] items-center gap-1 rounded-full border border-amber-500/20 bg-amber-500/10 px-2 py-1 text-[11px] text-amber-800 dark:text-amber-200");
|
|
18848
|
+
const icon = document.createElement("span");
|
|
18849
|
+
icon.textContent = "💬";
|
|
18850
|
+
assignClassName(icon, "shrink-0");
|
|
18851
|
+
const text = document.createElement("span");
|
|
18852
|
+
text.textContent = savedComment.text;
|
|
18853
|
+
assignClassName(text, "truncate");
|
|
18854
|
+
wrapper.append(icon, text);
|
|
18855
|
+
return wrapper;
|
|
18856
|
+
}
|
|
18857
|
+
function CommitDiffFileRenderer({ comments, diffStyle, disableFileHeader = false, fileDiff, onStartComment, pendingComment }) {
|
|
18858
|
+
const [container, setContainer] = import_react.useState(null);
|
|
18859
|
+
const instanceRef = import_react.useRef(null);
|
|
18860
|
+
const lineAnnotations = commitDiffLineCommentAnnotations({
|
|
18861
|
+
comments,
|
|
18862
|
+
pendingComment
|
|
18863
|
+
});
|
|
18864
|
+
const options = {
|
|
18865
|
+
diffStyle,
|
|
18866
|
+
disableFileHeader,
|
|
18867
|
+
enableGutterUtility: true,
|
|
18868
|
+
lineDiffType: "word-alt",
|
|
18869
|
+
lineHoverHighlight: "both",
|
|
18870
|
+
maxLineDiffLength: 1e3,
|
|
18871
|
+
onGutterUtilityClick: (range) => {
|
|
18872
|
+
onStartComment({
|
|
18873
|
+
lineNumber: Math.min(range.start, range.end),
|
|
18874
|
+
path: fileDiff.name,
|
|
18875
|
+
side: range.side || range.endSide || "additions"
|
|
18876
|
+
});
|
|
18877
|
+
},
|
|
18878
|
+
onLineNumberClick: (props) => {
|
|
18879
|
+
onStartComment({
|
|
18880
|
+
lineNumber: props.lineNumber,
|
|
18881
|
+
path: fileDiff.name,
|
|
18882
|
+
side: props.annotationSide
|
|
18883
|
+
});
|
|
18884
|
+
},
|
|
18885
|
+
overflow: "wrap",
|
|
18886
|
+
renderAnnotation: renderCommitDiffLineAnnotation
|
|
18887
|
+
};
|
|
18888
|
+
import_react.useLayoutEffect(() => {
|
|
18889
|
+
if (!container) return;
|
|
18890
|
+
const existing = instanceRef.current;
|
|
18891
|
+
if (existing) {
|
|
18892
|
+
existing.setOptions(options);
|
|
18893
|
+
existing.render({
|
|
18894
|
+
containerWrapper: container,
|
|
18895
|
+
fileDiff,
|
|
18896
|
+
forceRender: true,
|
|
18897
|
+
lineAnnotations
|
|
18898
|
+
});
|
|
18899
|
+
return;
|
|
18900
|
+
}
|
|
18901
|
+
const instance = new FileDiff$1(options, void 0, false);
|
|
18902
|
+
instanceRef.current = instance;
|
|
18903
|
+
instance.render({
|
|
18904
|
+
containerWrapper: container,
|
|
18905
|
+
fileDiff,
|
|
18906
|
+
lineAnnotations
|
|
18907
|
+
});
|
|
18908
|
+
});
|
|
18909
|
+
import_react.useLayoutEffect(() => () => {
|
|
18910
|
+
instanceRef.current?.cleanUp();
|
|
18911
|
+
instanceRef.current = null;
|
|
18912
|
+
}, []);
|
|
18913
|
+
return import_react.createElement("div", { ref: setContainer });
|
|
18914
|
+
}
|
|
18915
|
+
function CommitFileDiffAccordionItem({ comments, diffStyle, fileDiff, index, onStartComment, pendingComment, stuck }) {
|
|
18539
18916
|
const value = commitFileDiffValue(fileDiff, index);
|
|
18540
18917
|
const counts = commitFileDiffLineCounts(fileDiff);
|
|
18541
18918
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(AccordionItem, {
|
|
@@ -18586,21 +18963,18 @@ function CommitFileDiffAccordionItem({ diffStyle, fileDiff, index, stuck }) {
|
|
|
18586
18963
|
})
|
|
18587
18964
|
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AccordionContent, {
|
|
18588
18965
|
className: "bg-background p-0",
|
|
18589
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
18966
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommitDiffFileRenderer, {
|
|
18967
|
+
comments,
|
|
18968
|
+
diffStyle,
|
|
18969
|
+
disableFileHeader: true,
|
|
18590
18970
|
fileDiff,
|
|
18591
|
-
|
|
18592
|
-
|
|
18593
|
-
diffStyle,
|
|
18594
|
-
disableFileHeader: true,
|
|
18595
|
-
lineDiffType: "word-alt",
|
|
18596
|
-
maxLineDiffLength: 1e3,
|
|
18597
|
-
overflow: "wrap"
|
|
18598
|
-
}
|
|
18971
|
+
onStartComment,
|
|
18972
|
+
pendingComment
|
|
18599
18973
|
})
|
|
18600
18974
|
})]
|
|
18601
18975
|
});
|
|
18602
18976
|
}
|
|
18603
|
-
function CommitSingleFileDiff({ diffStyle, patch }) {
|
|
18977
|
+
function CommitSingleFileDiff({ comments, diffStyle, onStartComment, patch, pendingComment }) {
|
|
18604
18978
|
const fileDiff = parsePatchFiles(patch).flatMap((parsed) => parsed.files)[0];
|
|
18605
18979
|
if (!fileDiff) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
18606
18980
|
className: "p-4",
|
|
@@ -18609,19 +18983,16 @@ function CommitSingleFileDiff({ diffStyle, patch }) {
|
|
|
18609
18983
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
18610
18984
|
className: "min-h-full text-xs",
|
|
18611
18985
|
style: { "--diffs-font-family": "var(--font-mono, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace)" },
|
|
18612
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
18986
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommitDiffFileRenderer, {
|
|
18987
|
+
comments,
|
|
18988
|
+
diffStyle,
|
|
18613
18989
|
fileDiff,
|
|
18614
|
-
|
|
18615
|
-
|
|
18616
|
-
diffStyle,
|
|
18617
|
-
lineDiffType: "word-alt",
|
|
18618
|
-
maxLineDiffLength: 1e3,
|
|
18619
|
-
overflow: "wrap"
|
|
18620
|
-
}
|
|
18990
|
+
onStartComment,
|
|
18991
|
+
pendingComment
|
|
18621
18992
|
})
|
|
18622
18993
|
});
|
|
18623
18994
|
}
|
|
18624
|
-
function CommitPatchDiffs({ diffStyle, patch, stuckFileValue }) {
|
|
18995
|
+
function CommitPatchDiffs({ comments, diffStyle, onStartComment, patch, pendingComment, stuckFileValue }) {
|
|
18625
18996
|
const fileDiffs = parsePatchFiles(patch).flatMap((parsed) => parsed.files);
|
|
18626
18997
|
const firstValue = fileDiffs[0] ? commitFileDiffValue(fileDiffs[0], 0) : void 0;
|
|
18627
18998
|
if (fileDiffs.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
@@ -18636,9 +19007,12 @@ function CommitPatchDiffs({ diffStyle, patch, stuckFileValue }) {
|
|
|
18636
19007
|
defaultValue: firstValue ? [firstValue] : [],
|
|
18637
19008
|
className: "border-b border-border/80",
|
|
18638
19009
|
children: fileDiffs.map((fileDiff, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommitFileDiffAccordionItem, {
|
|
19010
|
+
comments: comments.filter((comment) => comment.path === fileDiff.name),
|
|
18639
19011
|
diffStyle,
|
|
18640
19012
|
fileDiff,
|
|
18641
19013
|
index,
|
|
19014
|
+
onStartComment,
|
|
19015
|
+
pendingComment: pendingComment?.path === fileDiff.name ? pendingComment : null,
|
|
18642
19016
|
stuck: stuckFileValue === commitFileDiffValue(fileDiff, index)
|
|
18643
19017
|
}, commitFileDiffValue(fileDiff, index)))
|
|
18644
19018
|
})
|
|
@@ -18684,9 +19058,10 @@ function CommitDiffHeaderTitle({ tab }) {
|
|
|
18684
19058
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommitDiffPathBreadcrumb, { path: tab.path })
|
|
18685
19059
|
});
|
|
18686
19060
|
}
|
|
18687
|
-
function CommitDiffContent({ viewerContextId, cwd, active, tab }) {
|
|
19061
|
+
function CommitDiffContent({ viewerContextId, cwd, active, diffLineComments, onAddDiffLineComment, tab }) {
|
|
18688
19062
|
const [diffStyle, setDiffStyle] = import_react.useState("unified");
|
|
18689
19063
|
const [stickyCommitFileValue, setStickyCommitFileValue] = import_react.useState("");
|
|
19064
|
+
const [commentTarget, setCommentTarget] = import_react.useState(null);
|
|
18690
19065
|
const diffScrollRef = import_react.useRef(null);
|
|
18691
19066
|
const updateStickyCommitFileHeader = (scrollElement) => {
|
|
18692
19067
|
setDerivedScrollState(setStickyCommitFileValue, getStuckScrollTriggerValue({
|
|
@@ -18712,7 +19087,34 @@ function CommitDiffContent({ viewerContextId, cwd, active, tab }) {
|
|
|
18712
19087
|
"error"
|
|
18713
19088
|
]
|
|
18714
19089
|
});
|
|
19090
|
+
const commentsForTab = tab ? diffLineComments.filter((comment) => comment.tabKey === tab.key && comment.commit === tab.commit && comment.mode === tab.mode) : EMPTY_RIGHT_SIDEBAR_DIFF_LINE_COMMENTS;
|
|
19091
|
+
const startLineComment = (lineTarget) => {
|
|
19092
|
+
if (!tab || !onAddDiffLineComment) return;
|
|
19093
|
+
setCommentTarget({
|
|
19094
|
+
commit: tab.commit,
|
|
19095
|
+
lineNumber: lineTarget.lineNumber,
|
|
19096
|
+
mode: tab.mode,
|
|
19097
|
+
path: lineTarget.path,
|
|
19098
|
+
shortHash: tab.shortHash,
|
|
19099
|
+
side: lineTarget.side,
|
|
19100
|
+
tabKey: tab.key,
|
|
19101
|
+
tabTitle: tab.title
|
|
19102
|
+
});
|
|
19103
|
+
};
|
|
19104
|
+
const pendingComment = commentTarget ? {
|
|
19105
|
+
...commentTarget,
|
|
19106
|
+
kind: "pending",
|
|
19107
|
+
onCancel: () => setCommentTarget(null),
|
|
19108
|
+
onSubmit: (text) => {
|
|
19109
|
+
onAddDiffLineComment?.({
|
|
19110
|
+
...commentTarget,
|
|
19111
|
+
text
|
|
19112
|
+
});
|
|
19113
|
+
setCommentTarget(null);
|
|
19114
|
+
}
|
|
19115
|
+
} : null;
|
|
18715
19116
|
import_react.useEffect(() => {
|
|
19117
|
+
setCommentTarget(null);
|
|
18716
19118
|
setDerivedScrollState(setStickyCommitFileValue, "");
|
|
18717
19119
|
updateStickyCommitFileHeader(diffScrollRef.current);
|
|
18718
19120
|
}, [tab?.key, diffQuery.data?.patch]);
|
|
@@ -18755,11 +19157,20 @@ function CommitDiffContent({ viewerContextId, cwd, active, tab }) {
|
|
|
18755
19157
|
children: getErrorMessage(diffQuery.error, "Failed to load commit diff")
|
|
18756
19158
|
})
|
|
18757
19159
|
}) : diffQuery.data?.patch && tab.path ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommitSingleFileDiff, {
|
|
19160
|
+
comments: commentsForTab.filter((comment) => {
|
|
19161
|
+
if (!tab.path) return true;
|
|
19162
|
+
return comment.path === tab.path || comment.path === tab.previousPath;
|
|
19163
|
+
}),
|
|
18758
19164
|
diffStyle,
|
|
18759
|
-
|
|
19165
|
+
onStartComment: startLineComment,
|
|
19166
|
+
patch: diffQuery.data.patch,
|
|
19167
|
+
pendingComment
|
|
18760
19168
|
}) : diffQuery.data?.patch ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommitPatchDiffs, {
|
|
19169
|
+
comments: commentsForTab,
|
|
18761
19170
|
diffStyle,
|
|
19171
|
+
onStartComment: startLineComment,
|
|
18762
19172
|
patch: diffQuery.data.patch,
|
|
19173
|
+
pendingComment,
|
|
18763
19174
|
stuckFileValue: stickyCommitFileValue
|
|
18764
19175
|
}, `${diffQuery.data.commit}:${diffQuery.data.mode}`) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
18765
19176
|
className: "p-4",
|
|
@@ -18768,7 +19179,7 @@ function CommitDiffContent({ viewerContextId, cwd, active, tab }) {
|
|
|
18768
19179
|
})]
|
|
18769
19180
|
});
|
|
18770
19181
|
}
|
|
18771
|
-
function RightSidebar({ viewerContextId, cwd, active, activeFilePath = "", activeTab: controlledActiveTab, filePreviewPath = "", fileTabs = EMPTY_RIGHT_SIDEBAR_FILE_TABS, fileTreeCollapsed = false, onActiveFileChange, onActiveTabChange, onCloseAllFiles, onCloseFile, onCloseFilesToRight, onCloseOtherFiles, onFileTreeCollapsedChange, onOpenFile, onReorderFiles, showToolbar = true }) {
|
|
19182
|
+
function RightSidebar({ viewerContextId, cwd, active, activeFilePath = "", activeTab: controlledActiveTab, diffLineComments = EMPTY_RIGHT_SIDEBAR_DIFF_LINE_COMMENTS, filePreviewPath = "", fileTabs = EMPTY_RIGHT_SIDEBAR_FILE_TABS, fileTreeCollapsed = false, onActiveFileChange, onActiveTabChange, onAddDiffLineComment, onCloseAllFiles, onCloseFile, onCloseFilesToRight, onCloseOtherFiles, onFileTreeCollapsedChange, onOpenFile, onReorderFiles, showToolbar = true }) {
|
|
18772
19183
|
const normalizedCwd = normalizeCwd(cwd);
|
|
18773
19184
|
const isMobile = useIsMobile();
|
|
18774
19185
|
const [localState, dispatchLocal] = import_react.useReducer(rightSidebarLocalReducer, initialRightSidebarLocalState);
|
|
@@ -18912,96 +19323,88 @@ function RightSidebar({ viewerContextId, cwd, active, activeFilePath = "", activ
|
|
|
18912
19323
|
showHistory: historyAsTab,
|
|
18913
19324
|
showReview: true
|
|
18914
19325
|
}),
|
|
18915
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
18916
|
-
|
|
18917
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
18918
|
-
|
|
18919
|
-
|
|
18920
|
-
|
|
18921
|
-
|
|
18922
|
-
|
|
18923
|
-
|
|
18924
|
-
|
|
18925
|
-
|
|
18926
|
-
|
|
18927
|
-
|
|
18928
|
-
|
|
18929
|
-
|
|
18930
|
-
})
|
|
19326
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
19327
|
+
className: activeTab === "review" ? "min-h-0 flex-1 overflow-hidden" : "hidden",
|
|
19328
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FileReviewContent, {
|
|
19329
|
+
viewerContextId,
|
|
19330
|
+
cwd: normalizedCwd,
|
|
19331
|
+
active: active && activeTab === "review",
|
|
19332
|
+
diffLineComments,
|
|
19333
|
+
onMaximizeHistory: () => {
|
|
19334
|
+
setHistoryAsTab(true);
|
|
19335
|
+
setActiveTab("history");
|
|
19336
|
+
},
|
|
19337
|
+
onAddDiffLineComment,
|
|
19338
|
+
onOpenCommitDiff: openCommitDiff,
|
|
19339
|
+
onOpenFile: openFile,
|
|
19340
|
+
showEmbeddedHistory: !historyAsTab
|
|
18931
19341
|
})
|
|
18932
19342
|
}),
|
|
18933
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
18934
|
-
|
|
18935
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
18936
|
-
|
|
18937
|
-
|
|
18938
|
-
|
|
18939
|
-
|
|
18940
|
-
|
|
18941
|
-
|
|
18942
|
-
|
|
18943
|
-
|
|
18944
|
-
|
|
18945
|
-
setActiveTab("review");
|
|
18946
|
-
}
|
|
18947
|
-
})
|
|
19343
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
19344
|
+
className: activeTab === "history" ? "min-h-0 flex-1 overflow-hidden" : "hidden",
|
|
19345
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(GitCommitsSection, {
|
|
19346
|
+
viewerContextId,
|
|
19347
|
+
cwd: normalizedCwd,
|
|
19348
|
+
active: active && activeTab === "history",
|
|
19349
|
+
flush: true,
|
|
19350
|
+
onOpenCommitDiff: openCommitDiff,
|
|
19351
|
+
onRestoreEmbedded: () => {
|
|
19352
|
+
setHistoryAsTab(false);
|
|
19353
|
+
setActiveTab("review");
|
|
19354
|
+
}
|
|
18948
19355
|
})
|
|
18949
19356
|
}),
|
|
18950
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
18951
|
-
|
|
18952
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
18953
|
-
|
|
18954
|
-
|
|
18955
|
-
|
|
18956
|
-
|
|
18957
|
-
|
|
18958
|
-
|
|
18959
|
-
})
|
|
19357
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
19358
|
+
className: activeTab === "commit-diff" ? "min-h-0 flex-1 overflow-hidden" : "hidden",
|
|
19359
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommitDiffContent, {
|
|
19360
|
+
viewerContextId,
|
|
19361
|
+
cwd: normalizedCwd,
|
|
19362
|
+
active: active && activeTab === "commit-diff",
|
|
19363
|
+
diffLineComments,
|
|
19364
|
+
onAddDiffLineComment,
|
|
19365
|
+
tab: activeCommitDiffTab
|
|
18960
19366
|
})
|
|
18961
19367
|
}),
|
|
18962
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
18963
|
-
|
|
18964
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.
|
|
18965
|
-
className: "min-h-0 flex-
|
|
18966
|
-
children:
|
|
18967
|
-
|
|
18968
|
-
|
|
18969
|
-
|
|
18970
|
-
|
|
18971
|
-
|
|
18972
|
-
|
|
18973
|
-
|
|
18974
|
-
|
|
19368
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
19369
|
+
className: activeTab === "files" ? "min-h-0 flex-1 overflow-hidden" : "hidden",
|
|
19370
|
+
children: previewMode === "external" && hasOpenFileTabs ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
19371
|
+
className: "flex h-full min-h-0 min-w-0 flex-col overflow-hidden",
|
|
19372
|
+
children: [currentFilePath ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FilePathBreadcrumb, {
|
|
19373
|
+
path: currentFilePath,
|
|
19374
|
+
fileTreeCollapsed,
|
|
19375
|
+
onFileTreeCollapsedChange
|
|
19376
|
+
}) : null, /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
19377
|
+
className: "flex min-h-0 flex-1 overflow-hidden",
|
|
19378
|
+
children: [fileTreeCollapsed ? null : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ProjectFileTreePane, {
|
|
19379
|
+
viewerContextId,
|
|
19380
|
+
cwd: normalizedCwd,
|
|
19381
|
+
active: active && activeTab === "files",
|
|
19382
|
+
activeFilePath: currentFilePath,
|
|
19383
|
+
onOpenFile: openFile,
|
|
19384
|
+
previewMode
|
|
19385
|
+
}), currentFilePath ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
19386
|
+
className: "min-h-0 min-w-0 flex-1 overflow-hidden",
|
|
19387
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ProjectFileContent, {
|
|
18975
19388
|
viewerContextId,
|
|
18976
19389
|
cwd: normalizedCwd,
|
|
18977
19390
|
active: active && activeTab === "files",
|
|
18978
|
-
|
|
18979
|
-
|
|
18980
|
-
|
|
18981
|
-
|
|
18982
|
-
|
|
18983
|
-
|
|
18984
|
-
|
|
18985
|
-
|
|
18986
|
-
|
|
18987
|
-
|
|
18988
|
-
|
|
18989
|
-
|
|
18990
|
-
|
|
18991
|
-
|
|
18992
|
-
|
|
18993
|
-
|
|
18994
|
-
|
|
18995
|
-
activeFilePath: currentFilePath,
|
|
18996
|
-
onCloseFile: () => {
|
|
18997
|
-
dispatchLocal({
|
|
18998
|
-
type: "set-inline-active-file",
|
|
18999
|
-
path: ""
|
|
19000
|
-
});
|
|
19001
|
-
},
|
|
19002
|
-
onOpenFile: openFile,
|
|
19003
|
-
previewMode
|
|
19004
|
-
})
|
|
19391
|
+
path: currentFilePath
|
|
19392
|
+
})
|
|
19393
|
+
}) : null]
|
|
19394
|
+
})]
|
|
19395
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ProjectFilesWorkspace, {
|
|
19396
|
+
viewerContextId,
|
|
19397
|
+
cwd: normalizedCwd,
|
|
19398
|
+
active: active && activeTab === "files",
|
|
19399
|
+
activeFilePath: currentFilePath,
|
|
19400
|
+
onCloseFile: () => {
|
|
19401
|
+
dispatchLocal({
|
|
19402
|
+
type: "set-inline-active-file",
|
|
19403
|
+
path: ""
|
|
19404
|
+
});
|
|
19405
|
+
},
|
|
19406
|
+
onOpenFile: openFile,
|
|
19407
|
+
previewMode
|
|
19005
19408
|
})
|
|
19006
19409
|
}),
|
|
19007
19410
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ProjectOpenFileDialog, {
|
|
@@ -19151,13 +19554,14 @@ function AppShellTabsList({ sessionStore, viewerContextId }) {
|
|
|
19151
19554
|
})]
|
|
19152
19555
|
});
|
|
19153
19556
|
}
|
|
19154
|
-
var AppShellGitPanelController = import_react.memo(function AppShellGitPanelController({ active, onCloseAllFiles, onCloseFile, onCloseFilesToRight, onCloseOtherFiles, onOpenFile, onReorderFiles, rightSidebarStore, sessionStore, viewerContextId }) {
|
|
19557
|
+
var AppShellGitPanelController = import_react.memo(function AppShellGitPanelController({ active, composerDiffLineComments, onAddDiffLineComment, onCloseAllFiles, onCloseFile, onCloseFilesToRight, onCloseOtherFiles, onOpenFile, onReorderFiles, rightSidebarStore, sessionStore, viewerContextId }) {
|
|
19155
19558
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RightSidebar, {
|
|
19156
19559
|
viewerContextId,
|
|
19157
19560
|
cwd: useSelector(sessionStore, (sessionState) => sessionState.cwd),
|
|
19158
19561
|
active,
|
|
19159
19562
|
activeFilePath: useSelector(rightSidebarStore, (state) => state.fileActivePath),
|
|
19160
19563
|
activeTab: useSelector(rightSidebarStore, (state) => state.activeTab),
|
|
19564
|
+
diffLineComments: composerDiffLineComments,
|
|
19161
19565
|
filePreviewPath: useSelector(rightSidebarStore, (state) => state.filePreviewPath),
|
|
19162
19566
|
fileTabs: useSelector(rightSidebarStore, selectRightSidebarVisibleFileTabs, { compare: sameStringArray$3 }),
|
|
19163
19567
|
fileTreeCollapsed: useSelector(rightSidebarStore, (state) => state.fileTreeCollapsed),
|
|
@@ -19167,6 +19571,7 @@ var AppShellGitPanelController = import_react.memo(function AppShellGitPanelCont
|
|
|
19167
19571
|
onActiveTabChange: (tab) => {
|
|
19168
19572
|
setRightSidebarActiveTab(rightSidebarStore, tab);
|
|
19169
19573
|
},
|
|
19574
|
+
onAddDiffLineComment,
|
|
19170
19575
|
onCloseAllFiles,
|
|
19171
19576
|
onCloseFile,
|
|
19172
19577
|
onCloseFilesToRight,
|
|
@@ -19178,7 +19583,7 @@ var AppShellGitPanelController = import_react.memo(function AppShellGitPanelCont
|
|
|
19178
19583
|
onReorderFiles
|
|
19179
19584
|
});
|
|
19180
19585
|
});
|
|
19181
|
-
function AppShellDesktopGitPanel({ active, onCloseAllFiles, onCloseFile, onCloseFilesToRight, onCloseOtherFiles, onOpenFile, onReorderFiles, rightSidebarStore, sessionStore, viewerContextId }) {
|
|
19586
|
+
function AppShellDesktopGitPanel({ active, composerDiffLineComments, onAddDiffLineComment, onCloseAllFiles, onCloseFile, onCloseFilesToRight, onCloseOtherFiles, onOpenFile, onReorderFiles, rightSidebarStore, sessionStore, viewerContextId }) {
|
|
19182
19587
|
const cwd = useSelector(sessionStore, (sessionState) => sessionState.cwd);
|
|
19183
19588
|
const activeFilePath = useSelector(rightSidebarStore, (state) => state.fileActivePath);
|
|
19184
19589
|
const activeTab = useSelector(rightSidebarStore, (state) => state.activeTab);
|
|
@@ -19196,6 +19601,7 @@ function AppShellDesktopGitPanel({ active, onCloseAllFiles, onCloseFile, onClose
|
|
|
19196
19601
|
active,
|
|
19197
19602
|
activeFilePath,
|
|
19198
19603
|
activeTab,
|
|
19604
|
+
diffLineComments: composerDiffLineComments,
|
|
19199
19605
|
filePreviewPath,
|
|
19200
19606
|
fileTabs,
|
|
19201
19607
|
fileTreeCollapsed,
|
|
@@ -19205,6 +19611,7 @@ function AppShellDesktopGitPanel({ active, onCloseAllFiles, onCloseFile, onClose
|
|
|
19205
19611
|
onActiveTabChange: (tab) => {
|
|
19206
19612
|
setRightSidebarActiveTab(rightSidebarStore, tab);
|
|
19207
19613
|
},
|
|
19614
|
+
onAddDiffLineComment,
|
|
19208
19615
|
onCloseAllFiles,
|
|
19209
19616
|
onCloseFile,
|
|
19210
19617
|
onCloseFilesToRight,
|
|
@@ -19383,7 +19790,7 @@ function AppShellDesktopResizeHandle({ label, max, min, onResize, onResizeEnd, o
|
|
|
19383
19790
|
function AppShellTabsController(props) {
|
|
19384
19791
|
return useAppShellTabsControllerView(props);
|
|
19385
19792
|
}
|
|
19386
|
-
function useAppShellTabsControllerView({ actionsRef, appUiStore, awaitingFirstTurn, composerPanelRef, contextUsageStore, conversationFrameRef, conversationItemsStore, defaultNewSessionDirectory, displaySettingsStore, fileInputRef, gitPanelOpen, hiddenThinkingPreviewStore, isSessionViewLoading, isSubmitting, isMobile, newSessionDirectoryOptions, onCancelCompaction, onCreateSession, onOpenAddDirectoryDialog, onCloseAllFileViewTabs, onCloseFileViewTab, onCloseFileViewTabsToRight, onCloseOtherFileViewTabs, onOpenFileViewTab, onReorderFileViewTabs, onValueChange, rightSidebarStore, sessionStore, store, viewerContextId, workingStateStore }) {
|
|
19793
|
+
function useAppShellTabsControllerView({ actionsRef, appUiStore, awaitingFirstTurn, composerDiffLineComments, composerPanelRef, contextUsageStore, conversationFrameRef, conversationItemsStore, defaultNewSessionDirectory, displaySettingsStore, fileInputRef, gitPanelOpen, hiddenThinkingPreviewStore, isSessionViewLoading, isSubmitting, isMobile, newSessionDirectoryOptions, onCancelCompaction, onCreateSession, onOpenAddDirectoryDialog, onCloseAllFileViewTabs, onCloseFileViewTab, onCloseFileViewTabsToRight, onCloseOtherFileViewTabs, onAddDiffLineComment, onOpenFileViewTab, onReorderFileViewTabs, onValueChange, rightSidebarStore, sessionStore, store, viewerContextId, workingStateStore }) {
|
|
19387
19794
|
const currentTab = useSelector(appUiStore, (state) => state.currentTab);
|
|
19388
19795
|
const isDraftSession = useSelector(sessionStore, (sessionState) => sessionState.draft);
|
|
19389
19796
|
const showTabsList = isMobile || !isDraftSession || isSessionViewLoading;
|
|
@@ -19461,7 +19868,9 @@ function useAppShellTabsControllerView({ actionsRef, appUiStore, awaitingFirstTu
|
|
|
19461
19868
|
viewerContextId,
|
|
19462
19869
|
sessionStore,
|
|
19463
19870
|
active: currentTab === "git",
|
|
19871
|
+
composerDiffLineComments,
|
|
19464
19872
|
rightSidebarStore,
|
|
19873
|
+
onAddDiffLineComment,
|
|
19465
19874
|
onCloseAllFiles: onCloseAllFileViewTabs,
|
|
19466
19875
|
onCloseFile: onCloseFileViewTab,
|
|
19467
19876
|
onCloseFilesToRight: onCloseFileViewTabsToRight,
|
|
@@ -19564,7 +19973,9 @@ function useAppShellTabsControllerView({ actionsRef, appUiStore, awaitingFirstTu
|
|
|
19564
19973
|
viewerContextId,
|
|
19565
19974
|
sessionStore,
|
|
19566
19975
|
active: desktopGitPanelOpen,
|
|
19976
|
+
composerDiffLineComments,
|
|
19567
19977
|
rightSidebarStore,
|
|
19978
|
+
onAddDiffLineComment,
|
|
19568
19979
|
onCloseAllFiles: onCloseAllFileViewTabs,
|
|
19569
19980
|
onCloseFile: onCloseFileViewTab,
|
|
19570
19981
|
onCloseFilesToRight: onCloseFileViewTabsToRight,
|
|
@@ -21626,8 +22037,30 @@ function movePendingDraftFollowUpMessage(messages, pendingId, direction) {
|
|
|
21626
22037
|
next.splice(targetIndex, 0, movedItem);
|
|
21627
22038
|
return next;
|
|
21628
22039
|
}
|
|
22040
|
+
var EMPTY_COMPOSER_DIFF_LINE_COMMENTS = [];
|
|
21629
22041
|
var EMPTY_COMPOSER_IMAGES = [];
|
|
21630
22042
|
var EMPTY_COMPOSER_PENDING_MESSAGES = [];
|
|
22043
|
+
function sameComposerDiffLineComments(left, right) {
|
|
22044
|
+
if (left === right) return true;
|
|
22045
|
+
if (left.length !== right.length) return false;
|
|
22046
|
+
for (let index = 0; index < left.length; index += 1) {
|
|
22047
|
+
const leftComment = left[index];
|
|
22048
|
+
const rightComment = right[index];
|
|
22049
|
+
if (!leftComment || !rightComment) return false;
|
|
22050
|
+
if (leftComment.id !== rightComment.id) return false;
|
|
22051
|
+
if (leftComment.cwd !== rightComment.cwd) return false;
|
|
22052
|
+
if (leftComment.path !== rightComment.path) return false;
|
|
22053
|
+
if (leftComment.lineNumber !== rightComment.lineNumber) return false;
|
|
22054
|
+
if (leftComment.side !== rightComment.side) return false;
|
|
22055
|
+
if (leftComment.text !== rightComment.text) return false;
|
|
22056
|
+
if (leftComment.tabKey !== rightComment.tabKey) return false;
|
|
22057
|
+
if (leftComment.tabTitle !== rightComment.tabTitle) return false;
|
|
22058
|
+
if (leftComment.commit !== rightComment.commit) return false;
|
|
22059
|
+
if (leftComment.shortHash !== rightComment.shortHash) return false;
|
|
22060
|
+
if (leftComment.mode !== rightComment.mode) return false;
|
|
22061
|
+
}
|
|
22062
|
+
return true;
|
|
22063
|
+
}
|
|
21631
22064
|
function sameComposerPromptImages(left, right) {
|
|
21632
22065
|
if (left === right) return true;
|
|
21633
22066
|
if (left.length !== right.length) return false;
|
|
@@ -21656,13 +22089,14 @@ function sameComposerPendingMessages(left, right) {
|
|
|
21656
22089
|
return true;
|
|
21657
22090
|
}
|
|
21658
22091
|
function sameAppShellComposerSnapshot(left, right) {
|
|
21659
|
-
return left.activeSessionId === right.activeSessionId && left.awaitingFirstTurn === right.awaitingFirstTurn && left.centerMessages === right.centerMessages && left.composerSkill === right.composerSkill && left.composerSyncNonce === right.composerSyncNonce && left.composerText === right.composerText && left.disabled === right.disabled && left.isStreaming === right.isStreaming && left.isSubmitting === right.isSubmitting && left.viewerContextId === right.viewerContextId && sameComposerPromptImages(left.composerImages, right.composerImages) && sameComposerPendingMessages(left.currentPendingMessages, right.currentPendingMessages);
|
|
22092
|
+
return left.activeSessionId === right.activeSessionId && left.awaitingFirstTurn === right.awaitingFirstTurn && left.centerMessages === right.centerMessages && sameComposerDiffLineComments(left.composerDiffLineComments, right.composerDiffLineComments) && left.composerSkill === right.composerSkill && left.composerSyncNonce === right.composerSyncNonce && left.composerText === right.composerText && left.disabled === right.disabled && left.isStreaming === right.isStreaming && left.isSubmitting === right.isSubmitting && left.viewerContextId === right.viewerContextId && sameComposerPromptImages(left.composerImages, right.composerImages) && sameComposerPendingMessages(left.currentPendingMessages, right.currentPendingMessages);
|
|
21660
22093
|
}
|
|
21661
22094
|
function createInitialAppShellComposerSnapshot(viewerContextId) {
|
|
21662
22095
|
return {
|
|
21663
22096
|
activeSessionId: void 0,
|
|
21664
22097
|
awaitingFirstTurn: false,
|
|
21665
22098
|
centerMessages: false,
|
|
22099
|
+
composerDiffLineComments: EMPTY_COMPOSER_DIFF_LINE_COMMENTS,
|
|
21666
22100
|
composerImages: EMPTY_COMPOSER_IMAGES,
|
|
21667
22101
|
composerSkill: void 0,
|
|
21668
22102
|
composerSyncNonce: 0,
|
|
@@ -21732,10 +22166,23 @@ function createPicoLatestThrottler(options) {
|
|
|
21732
22166
|
};
|
|
21733
22167
|
}
|
|
21734
22168
|
function samePromptMutationSessionSnapshot(left, right) {
|
|
21735
|
-
return left.cwd === right.cwd && left.draft === right.draft && left.sessionFile === right.sessionFile && left.sessionId === right.sessionId && left.sessionKey === right.sessionKey && left.streaming === right.streaming;
|
|
22169
|
+
return left.assistantOutputSignature === right.assistantOutputSignature && left.cwd === right.cwd && left.draft === right.draft && left.sessionFile === right.sessionFile && left.sessionId === right.sessionId && left.sessionKey === right.sessionKey && left.streaming === right.streaming;
|
|
22170
|
+
}
|
|
22171
|
+
function sessionAssistantOutputSignature(items) {
|
|
22172
|
+
let outputCount = 0;
|
|
22173
|
+
let lastOutputKey = "";
|
|
22174
|
+
for (let index = 0; index < items.length; index += 1) {
|
|
22175
|
+
const item = items[index];
|
|
22176
|
+
if (!item || item.kind !== "assistant") continue;
|
|
22177
|
+
if (!item.blocks.some((block) => block.type === "text" && block.text.trim())) continue;
|
|
22178
|
+
outputCount += 1;
|
|
22179
|
+
lastOutputKey = item.itemKey || item.renderKey || `index:${index}`;
|
|
22180
|
+
}
|
|
22181
|
+
return `${outputCount}:${lastOutputKey}`;
|
|
21736
22182
|
}
|
|
21737
22183
|
function usePromptMutationSessionSnapshot(store) {
|
|
21738
22184
|
return useSelector(store, (sessionState) => ({
|
|
22185
|
+
assistantOutputSignature: sessionAssistantOutputSignature(sessionState.items),
|
|
21739
22186
|
cwd: sessionState.cwd,
|
|
21740
22187
|
draft: sessionState.draft,
|
|
21741
22188
|
sessionFile: sessionState.sessionFile,
|
|
@@ -21753,7 +22200,8 @@ function createLocalPendingId() {
|
|
|
21753
22200
|
}
|
|
21754
22201
|
function buildCurrentSessionRequestUrl(path, { contextId, sessionState, fallbackSessionId }) {
|
|
21755
22202
|
const sessionKey = sessionState.sessionKey && !sessionState.sessionKey.startsWith("optimistic:") ? sessionState.sessionKey : void 0;
|
|
21756
|
-
const
|
|
22203
|
+
const hasFallbackSession = Boolean(fallbackSessionId && fallbackSessionId !== sessionState.sessionId);
|
|
22204
|
+
const shouldUseSessionKey = Boolean(sessionKey && !hasFallbackSession && (sessionState.draft || !sessionState.sessionId));
|
|
21757
22205
|
return buildRequestUrl(path, {
|
|
21758
22206
|
contextId,
|
|
21759
22207
|
sessionId: shouldUseSessionKey ? void 0 : sessionState.sessionId ?? fallbackSessionId,
|
|
@@ -21809,13 +22257,14 @@ function movePendingComposerMessage(messages, pendingId, direction) {
|
|
|
21809
22257
|
next.splice(targetIndex, 0, movedItem);
|
|
21810
22258
|
return next;
|
|
21811
22259
|
}
|
|
21812
|
-
function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultNewSessionDirectory, sessionStore, sessionStateRef, draftSessionLoadingOwnerKey, pendingDraftPrompt, pendingDraftFollowUps, awaitingFirstTurn, pendingMessages, composerImagesRef, composerTextRef, composerSkillRef, replaceComposerDraft, lastSyncedEditorTextRef, rememberRecentDirectory, prefetchDirectorySessionsIndex, addOptimisticUserMessage, removeOptimisticUserMessage, setSidebarDirectories, setStoredDraftDirectory, setDraftSessionLoadingOwnerKey, setPendingDraftPrompt, setPendingDraftFollowUps, setPendingMessages, setAwaitingFirstTurn, setIsSubmitting, setComposerImages }) {
|
|
22260
|
+
function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultNewSessionDirectory, sessionStore, sessionStateRef, draftSessionLoadingOwnerKey, pendingDraftPrompt, pendingDraftFollowUps, awaitingFirstTurn, pendingMessages, composerDiffLineCommentsRef, composerImagesRef, composerTextRef, composerSkillRef, replaceComposerDraft, lastSyncedEditorTextRef, rememberRecentDirectory, prefetchDirectorySessionsIndex, addOptimisticUserMessage, removeOptimisticUserMessage, setSidebarDirectories, setStoredDraftDirectory, setDraftSessionLoadingOwnerKey, setPendingDraftPrompt, setPendingDraftFollowUps, setPendingMessages, setAwaitingFirstTurn, setIsSubmitting, setComposerDiffLineComments, setComposerImages }) {
|
|
21813
22261
|
const queryClient = useQueryClient();
|
|
21814
22262
|
const draftSessionLoadingOwnerKeyRef = import_react.useRef(draftSessionLoadingOwnerKey);
|
|
21815
22263
|
const pendingDraftPromptRef = import_react.useRef(pendingDraftPrompt);
|
|
21816
22264
|
const pendingDraftFollowUpsRef = import_react.useRef(pendingDraftFollowUps);
|
|
21817
22265
|
const pendingMessagesRef = import_react.useRef(pendingMessages);
|
|
21818
22266
|
const awaitingFirstTurnRef = import_react.useRef(awaitingFirstTurn);
|
|
22267
|
+
const awaitingFirstTurnAssistantOutputSignatureRef = import_react.useRef(null);
|
|
21819
22268
|
const sessionSnapshot = usePromptMutationSessionSnapshot(sessionStore);
|
|
21820
22269
|
const sessionStreamingRef = import_react.useRef(sessionSnapshot.streaming);
|
|
21821
22270
|
import_react.useEffect(() => {
|
|
@@ -21893,6 +22342,7 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
21893
22342
|
pendingDraftFollowUpsRef.current = [];
|
|
21894
22343
|
setPendingDraftPrompt(null);
|
|
21895
22344
|
setPendingDraftFollowUps([]);
|
|
22345
|
+
awaitingFirstTurnAssistantOutputSignatureRef.current = null;
|
|
21896
22346
|
awaitingFirstTurnRef.current = false;
|
|
21897
22347
|
setAwaitingFirstTurn(false);
|
|
21898
22348
|
return applyPendingDraftPromptToComposer(nextPrompt);
|
|
@@ -21977,9 +22427,10 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
21977
22427
|
const queuePendingDraftPrompt = import_react.useCallback((streamingBehavior) => {
|
|
21978
22428
|
const ownerKey = draftSessionLoadingOwnerKeyRef.current;
|
|
21979
22429
|
if (!ownerKey) return false;
|
|
21980
|
-
const message =
|
|
22430
|
+
const message = buildComposerPromptMessage({
|
|
21981
22431
|
text: composerTextRef.current,
|
|
21982
|
-
skillName: composerSkillRef.current
|
|
22432
|
+
skillName: composerSkillRef.current,
|
|
22433
|
+
diffLineComments: composerDiffLineCommentsRef.current
|
|
21983
22434
|
}).trim();
|
|
21984
22435
|
const images = composerImagesRef.current.map((image) => ({ ...image }));
|
|
21985
22436
|
if (!message && images.length === 0) return false;
|
|
@@ -22012,17 +22463,20 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
22012
22463
|
setPendingDraftFollowUps(nextFollowUps);
|
|
22013
22464
|
}
|
|
22014
22465
|
replaceComposerDraft("", void 0, { forceSync: true });
|
|
22466
|
+
setComposerDiffLineComments([]);
|
|
22015
22467
|
setComposerImages([]);
|
|
22016
22468
|
lastSyncedEditorTextRef.current = "";
|
|
22017
22469
|
return true;
|
|
22018
22470
|
}, [
|
|
22019
22471
|
addOptimisticUserMessage,
|
|
22472
|
+
composerDiffLineCommentsRef,
|
|
22020
22473
|
composerImagesRef,
|
|
22021
22474
|
composerSkillRef,
|
|
22022
22475
|
composerTextRef,
|
|
22023
22476
|
lastSyncedEditorTextRef,
|
|
22024
22477
|
replaceComposerDraft,
|
|
22025
22478
|
setAwaitingFirstTurn,
|
|
22479
|
+
setComposerDiffLineComments,
|
|
22026
22480
|
setComposerImages,
|
|
22027
22481
|
setPendingDraftFollowUps,
|
|
22028
22482
|
setPendingDraftPrompt
|
|
@@ -22056,15 +22510,22 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
22056
22510
|
const submitPrompt = import_react.useCallback(async (streamingBehavior, options) => {
|
|
22057
22511
|
if (!viewerContextId) return false;
|
|
22058
22512
|
if (draftSessionLoadingOwnerKeyRef.current) return queuePendingDraftPrompt(streamingBehavior);
|
|
22059
|
-
const
|
|
22513
|
+
const submittedDiffLineComments = composerDiffLineCommentsRef.current.map((comment) => ({ ...comment }));
|
|
22514
|
+
const message = buildComposerPromptMessage({
|
|
22060
22515
|
text: composerTextRef.current,
|
|
22061
|
-
skillName: composerSkillRef.current
|
|
22516
|
+
skillName: composerSkillRef.current,
|
|
22517
|
+
diffLineComments: submittedDiffLineComments
|
|
22062
22518
|
}).trim();
|
|
22063
22519
|
if (!message && composerImagesRef.current.length === 0) return false;
|
|
22064
22520
|
const treatAsQueuedPrompt = options?.forceFirstPrompt ? false : Boolean(sessionStreamingRef.current || awaitingFirstTurnRef.current);
|
|
22065
22521
|
const normalizedStreamingBehavior = treatAsQueuedPrompt ? normalizeQueuedStreamingBehavior(streamingBehavior) : void 0;
|
|
22066
22522
|
const submittedImages = composerImagesRef.current.map((image) => ({ ...image }));
|
|
22067
22523
|
const queuedPendingId = treatAsQueuedPrompt ? createLocalPendingId() : void 0;
|
|
22524
|
+
if (!treatAsQueuedPrompt) {
|
|
22525
|
+
awaitingFirstTurnAssistantOutputSignatureRef.current = sessionAssistantOutputSignature(sessionStateRef.current.items);
|
|
22526
|
+
awaitingFirstTurnRef.current = true;
|
|
22527
|
+
setAwaitingFirstTurn(true);
|
|
22528
|
+
}
|
|
22068
22529
|
const optimisticId = options?.optimisticId ?? (treatAsQueuedPrompt ? void 0 : addOptimisticUserMessage({
|
|
22069
22530
|
message,
|
|
22070
22531
|
images: submittedImages,
|
|
@@ -22076,12 +22537,9 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
22076
22537
|
images: submittedImages.map((image) => ({ ...image })),
|
|
22077
22538
|
streamingBehavior: normalizedStreamingBehavior
|
|
22078
22539
|
});
|
|
22079
|
-
if (!treatAsQueuedPrompt) {
|
|
22080
|
-
awaitingFirstTurnRef.current = true;
|
|
22081
|
-
setAwaitingFirstTurn(true);
|
|
22082
|
-
}
|
|
22083
22540
|
setIsSubmitting(true);
|
|
22084
22541
|
replaceComposerDraft("", void 0, { forceSync: true });
|
|
22542
|
+
setComposerDiffLineComments([]);
|
|
22085
22543
|
setComposerImages([]);
|
|
22086
22544
|
lastSyncedEditorTextRef.current = "";
|
|
22087
22545
|
try {
|
|
@@ -22098,14 +22556,16 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
22098
22556
|
if (queuedPendingId) removeOptimisticPendingMessage(queuedPendingId);
|
|
22099
22557
|
removeOptimisticUserMessage(optimisticId);
|
|
22100
22558
|
if (!treatAsQueuedPrompt) {
|
|
22559
|
+
awaitingFirstTurnAssistantOutputSignatureRef.current = null;
|
|
22101
22560
|
awaitingFirstTurnRef.current = false;
|
|
22102
22561
|
setAwaitingFirstTurn(false);
|
|
22103
22562
|
}
|
|
22104
22563
|
if (!serializeComposerDraft({
|
|
22105
22564
|
text: composerTextRef.current,
|
|
22106
22565
|
skillName: composerSkillRef.current
|
|
22107
|
-
}).trim()) {
|
|
22566
|
+
}).trim() && composerDiffLineCommentsRef.current.length === 0) {
|
|
22108
22567
|
replaceComposerDraft(message);
|
|
22568
|
+
setComposerDiffLineComments((current) => current.length === 0 ? submittedDiffLineComments.map((comment) => ({ ...comment })) : current);
|
|
22109
22569
|
setComposerImages((current) => current.length === 0 ? submittedImages.map((image) => ({ ...image })) : current);
|
|
22110
22570
|
}
|
|
22111
22571
|
toast.error(error instanceof Error ? error.message : "Failed to submit prompt");
|
|
@@ -22116,6 +22576,7 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
22116
22576
|
}, [
|
|
22117
22577
|
addOptimisticPendingMessage,
|
|
22118
22578
|
addOptimisticUserMessage,
|
|
22579
|
+
composerDiffLineCommentsRef,
|
|
22119
22580
|
composerImagesRef,
|
|
22120
22581
|
composerSkillRef,
|
|
22121
22582
|
composerTextRef,
|
|
@@ -22127,6 +22588,7 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
22127
22588
|
removeOptimisticUserMessage,
|
|
22128
22589
|
replaceComposerDraft,
|
|
22129
22590
|
setAwaitingFirstTurn,
|
|
22591
|
+
setComposerDiffLineComments,
|
|
22130
22592
|
setComposerImages,
|
|
22131
22593
|
setIsSubmitting,
|
|
22132
22594
|
viewerContextId
|
|
@@ -22205,7 +22667,7 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
22205
22667
|
const currentSessionState = sessionStateRef.current;
|
|
22206
22668
|
if (currentSessionState.sessionKey?.startsWith("optimistic:")) return;
|
|
22207
22669
|
const currentOwnerKey = promptDraftKey(currentSessionState);
|
|
22208
|
-
if (!currentSessionState.draft || currentOwnerKey
|
|
22670
|
+
if (!currentSessionState.draft || !promptDraftKeyMatchesOwner(currentOwnerKey, draftSessionLoadingOwnerKey)) return;
|
|
22209
22671
|
draftSessionLoadingOwnerKeyRef.current = null;
|
|
22210
22672
|
setDraftSessionLoadingOwnerKey(null);
|
|
22211
22673
|
if (pendingDraftPromptRef.current?.ownerKey === draftSessionLoadingOwnerKey) flushPendingDraftPrompt(draftSessionLoadingOwnerKey);
|
|
@@ -22218,15 +22680,17 @@ function useAppShellPromptMutations({ viewerContextId, activeSessionId, defaultN
|
|
|
22218
22680
|
]);
|
|
22219
22681
|
import_react.useEffect(() => {
|
|
22220
22682
|
if (!awaitingFirstTurn) return;
|
|
22221
|
-
const
|
|
22222
|
-
const
|
|
22223
|
-
if (
|
|
22683
|
+
const baselineAssistantOutputSignature = awaitingFirstTurnAssistantOutputSignatureRef.current;
|
|
22684
|
+
const assistantOutputStarted = baselineAssistantOutputSignature !== null && sessionSnapshot.assistantOutputSignature !== baselineAssistantOutputSignature;
|
|
22685
|
+
if (sessionStateRef.current.streaming || assistantOutputStarted || pendingMessages.length > 0) {
|
|
22686
|
+
awaitingFirstTurnAssistantOutputSignatureRef.current = null;
|
|
22224
22687
|
awaitingFirstTurnRef.current = false;
|
|
22225
22688
|
setAwaitingFirstTurn(false);
|
|
22226
22689
|
}
|
|
22227
22690
|
}, [
|
|
22228
22691
|
awaitingFirstTurn,
|
|
22229
22692
|
pendingMessages.length,
|
|
22693
|
+
sessionSnapshot.assistantOutputSignature,
|
|
22230
22694
|
sessionSnapshot.streaming,
|
|
22231
22695
|
sessionStateRef,
|
|
22232
22696
|
setAwaitingFirstTurn
|
|
@@ -23169,20 +23633,28 @@ function shouldPublishSessionState(previous, next) {
|
|
|
23169
23633
|
if (previous === next) return false;
|
|
23170
23634
|
return !sameSessionStateExceptConversation(previous, next) || !samePublishableUiState(previous.uiState, next.uiState) || previous.items.length === 0 !== (next.items.length === 0);
|
|
23171
23635
|
}
|
|
23172
|
-
function
|
|
23173
|
-
if (!ownerKey || payload.draft !== true) return false;
|
|
23636
|
+
function stateSyncPayloadDraftKey(payload) {
|
|
23174
23637
|
return promptDraftKey({
|
|
23175
23638
|
cwd: typeof payload.cwd === "string" ? payload.cwd : void 0,
|
|
23176
23639
|
sessionFile: typeof payload.sessionFile === "string" ? payload.sessionFile : void 0,
|
|
23177
23640
|
sessionId: typeof payload.sessionId === "string" ? payload.sessionId : void 0
|
|
23178
|
-
})
|
|
23641
|
+
});
|
|
23642
|
+
}
|
|
23643
|
+
function stateSyncPayloadConfirmsPendingDraft(payload, ownerKey) {
|
|
23644
|
+
if (!ownerKey || payload.draft !== true) return false;
|
|
23645
|
+
return promptDraftKeyMatchesOwner(stateSyncPayloadDraftKey(payload), ownerKey);
|
|
23646
|
+
}
|
|
23647
|
+
function stateSyncPayloadConfirmsOptimisticDraft(payload, previousState) {
|
|
23648
|
+
if (payload.draft !== true) return false;
|
|
23649
|
+
return promptDraftKeyMatchesOwner(stateSyncPayloadDraftKey(payload), promptDraftKey(previousState));
|
|
23179
23650
|
}
|
|
23180
23651
|
function shouldIgnoreOptimisticDraftStateSync(options) {
|
|
23181
23652
|
const previousSessionKey = options.previousState.sessionKey || "";
|
|
23182
23653
|
const payloadSessionKey = typeof options.payload.sessionKey === "string" ? options.payload.sessionKey : "";
|
|
23183
23654
|
if (!previousSessionKey.startsWith("optimistic:")) return false;
|
|
23184
23655
|
if (!payloadSessionKey || payloadSessionKey === previousSessionKey) return false;
|
|
23185
|
-
|
|
23656
|
+
if (stateSyncPayloadConfirmsPendingDraft(options.payload, options.ownerKey) || stateSyncPayloadConfirmsOptimisticDraft(options.payload, options.previousState)) return false;
|
|
23657
|
+
return true;
|
|
23186
23658
|
}
|
|
23187
23659
|
function useAppShellSessionSync({ viewerContextId, sessionId, draftSessionLoadingOwnerKey, bootstrapSidebarDirectories, hideToolBlocksRef, sessionStore, sessionStateRef, composerTextRef, composerSkillRef, replaceComposerDraftRef, handleSelectSessionRef, pendingRouteSessionIdRef, pendingRouteSessionPathRef, setSessionState, setConversationItems, setHiddenThinkingPreview, setWorkingState, setCompactRunningState, setComposerContextUsage, setComposerStreaming, setSessionsEvent, setSessionDoneEvents, applySidebarSessionStatusRef, setComposerImages, setPendingMessages, pendingUiRequestHandlerRef, lastSyncedEditorTextRef }) {
|
|
23188
23660
|
const queryClient = useQueryClient();
|
|
@@ -23191,6 +23663,7 @@ function useAppShellSessionSync({ viewerContextId, sessionId, draftSessionLoadin
|
|
|
23191
23663
|
const draftSessionLoadingOwnerKeyRef = import_react.useRef(draftSessionLoadingOwnerKey);
|
|
23192
23664
|
const currentSourceRef = import_react.useRef(null);
|
|
23193
23665
|
const hasReceivedStateSyncRef = import_react.useRef(false);
|
|
23666
|
+
const [hasReceivedStateSync, setHasReceivedStateSync] = import_react.useState(false);
|
|
23194
23667
|
const backgroundedAtRef = import_react.useRef(null);
|
|
23195
23668
|
const wasBackgroundedRef = import_react.useRef(false);
|
|
23196
23669
|
const [eventsReconnectNonce, setEventsReconnectNonce] = import_react.useState(0);
|
|
@@ -23205,8 +23678,8 @@ function useAppShellSessionSync({ viewerContextId, sessionId, draftSessionLoadin
|
|
|
23205
23678
|
initialEventsSessionIdRef.current = sessionId;
|
|
23206
23679
|
}, [sessionId]);
|
|
23207
23680
|
const syncedSessionId = useSelector(sessionStore, (sessionState) => sessionState.sessionId);
|
|
23208
|
-
const syncedSessionIdRef = import_react.useRef(syncedSessionId);
|
|
23209
23681
|
const latestActivationRevisionRef = import_react.useRef(0);
|
|
23682
|
+
const sessionSelectNonceRef = import_react.useRef(Date.now() * 1e3);
|
|
23210
23683
|
const observedRouteSessionIdRef = import_react.useRef(void 0);
|
|
23211
23684
|
const syncedSessionDraft = useSelector(sessionStore, (sessionState) => sessionState.draft);
|
|
23212
23685
|
import_react.useEffect(() => {
|
|
@@ -23320,7 +23793,10 @@ function useAppShellSessionSync({ viewerContextId, sessionId, draftSessionLoadin
|
|
|
23320
23793
|
const activationRevision = payload.activationRevision;
|
|
23321
23794
|
if (typeof activationRevision === "number" && activationRevision < latestActivationRevisionRef.current) return;
|
|
23322
23795
|
if (typeof activationRevision === "number") latestActivationRevisionRef.current = activationRevision;
|
|
23323
|
-
hasReceivedStateSyncRef.current
|
|
23796
|
+
if (!hasReceivedStateSyncRef.current) {
|
|
23797
|
+
hasReceivedStateSyncRef.current = true;
|
|
23798
|
+
setHasReceivedStateSync(true);
|
|
23799
|
+
}
|
|
23324
23800
|
const previousState = sessionStateRef.current;
|
|
23325
23801
|
if (shouldIgnoreOptimisticDraftStateSync({
|
|
23326
23802
|
ownerKey: draftSessionLoadingOwnerKeyRef.current,
|
|
@@ -23339,7 +23815,7 @@ function useAppShellSessionSync({ viewerContextId, sessionId, draftSessionLoadin
|
|
|
23339
23815
|
const currentDraftOwnerKey = draftSessionLoadingOwnerKeyRef.current;
|
|
23340
23816
|
const confirmedDraft = nextState.draft && !nextState.sessionKey?.startsWith("optimistic:");
|
|
23341
23817
|
const previousWasOptimisticDraft = previousState.draft && previousState.sessionKey?.startsWith("optimistic:");
|
|
23342
|
-
const draftMatchesPendingOwner =
|
|
23818
|
+
const draftMatchesPendingOwner = promptDraftKeyMatchesOwner(promptDraftKey(nextState), currentDraftOwnerKey);
|
|
23343
23819
|
const shouldClearDraftRoute = Boolean(currentRouteSessionId && !pendingRouteSessionIdRef.current && confirmedDraft && (draftMatchesPendingOwner || previousWasOptimisticDraft));
|
|
23344
23820
|
const preserveLocalPrompt = !sessionChanged && localPromptText !== previousEditorText;
|
|
23345
23821
|
const nextPromptText = preserveLocalPrompt ? localPromptText : readStoredPromptDraft(nextState) ?? nextState.uiState.editorText ?? "";
|
|
@@ -23455,6 +23931,8 @@ function useAppShellSessionSync({ viewerContextId, sessionId, draftSessionLoadin
|
|
|
23455
23931
|
import_react.useEffect(() => {
|
|
23456
23932
|
if (!viewerContextId) return;
|
|
23457
23933
|
hasReceivedStateSyncRef.current = false;
|
|
23934
|
+
setHasReceivedStateSync(false);
|
|
23935
|
+
latestActivationRevisionRef.current = 0;
|
|
23458
23936
|
const gitInvalidationBatcher = new Batcher((items) => {
|
|
23459
23937
|
const scopesByCwd = /* @__PURE__ */ new Map();
|
|
23460
23938
|
for (const item of items) {
|
|
@@ -23528,21 +24006,23 @@ function useAppShellSessionSync({ viewerContextId, sessionId, draftSessionLoadin
|
|
|
23528
24006
|
queryClient,
|
|
23529
24007
|
viewerContextId
|
|
23530
24008
|
]);
|
|
23531
|
-
import_react.useEffect(() => {
|
|
23532
|
-
syncedSessionIdRef.current = syncedSessionId;
|
|
23533
|
-
}, [syncedSessionId]);
|
|
23534
24009
|
import_react.useEffect(() => {
|
|
23535
24010
|
if (!viewerContextId || !sessionId) return;
|
|
23536
24011
|
if (draftSessionLoadingOwnerKey) return;
|
|
23537
|
-
if (!
|
|
23538
|
-
if (sessionId ===
|
|
24012
|
+
if (!hasReceivedStateSync) return;
|
|
24013
|
+
if (sessionId === syncedSessionId) return;
|
|
23539
24014
|
if (pendingRouteSessionIdRef.current !== sessionId) return;
|
|
23540
24015
|
const abortController = new AbortController();
|
|
23541
24016
|
const sessionPath = pendingRouteSessionPathRef.current;
|
|
24017
|
+
const selectionNonce = Math.max(sessionSelectNonceRef.current + 1, Date.now() * 1e3);
|
|
24018
|
+
sessionSelectNonceRef.current = selectionNonce;
|
|
23542
24019
|
fetchJson(buildRequestUrl("/api/session/select", {
|
|
23543
24020
|
contextId: viewerContextId,
|
|
23544
24021
|
sessionId,
|
|
23545
|
-
searchParams: {
|
|
24022
|
+
searchParams: {
|
|
24023
|
+
selectionNonce,
|
|
24024
|
+
sessionPath
|
|
24025
|
+
}
|
|
23546
24026
|
}), {
|
|
23547
24027
|
method: "POST",
|
|
23548
24028
|
signal: abortController.signal
|
|
@@ -23555,8 +24035,10 @@ function useAppShellSessionSync({ viewerContextId, sessionId, draftSessionLoadin
|
|
|
23555
24035
|
};
|
|
23556
24036
|
}, [
|
|
23557
24037
|
draftSessionLoadingOwnerKey,
|
|
24038
|
+
hasReceivedStateSync,
|
|
23558
24039
|
pendingRouteSessionIdRef,
|
|
23559
24040
|
pendingRouteSessionPathRef,
|
|
24041
|
+
syncedSessionId,
|
|
23560
24042
|
viewerContextId,
|
|
23561
24043
|
sessionId
|
|
23562
24044
|
]);
|
|
@@ -23965,6 +24447,8 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
23965
24447
|
if (!composerImagesStoreRef.current) composerImagesStoreRef.current = createPicoStore([]);
|
|
23966
24448
|
const composerImagesStore = composerImagesStoreRef.current;
|
|
23967
24449
|
const composerImagesRef = import_react.useRef([]);
|
|
24450
|
+
const composerDiffLineCommentsRef = import_react.useRef([]);
|
|
24451
|
+
const [composerDiffLineComments, setComposerDiffLineCommentsState] = import_react.useState([]);
|
|
23968
24452
|
const displaySettingsStoreRef = import_react.useRef(null);
|
|
23969
24453
|
if (!displaySettingsStoreRef.current) displaySettingsStoreRef.current = createPicoStore({
|
|
23970
24454
|
autoScrollEnabled: true,
|
|
@@ -24070,6 +24554,18 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
24070
24554
|
const composerStoreRef = import_react.useRef(null);
|
|
24071
24555
|
if (!composerStoreRef.current) composerStoreRef.current = createPicoStore(createInitialAppShellComposerSnapshot(viewerContextId), sameAppShellComposerSnapshot);
|
|
24072
24556
|
const composerStore = composerStoreRef.current;
|
|
24557
|
+
const setComposerDiffLineComments = import_react.useCallback((action) => {
|
|
24558
|
+
const current = composerDiffLineCommentsRef.current;
|
|
24559
|
+
const next = applyStoreAction(current, action);
|
|
24560
|
+
if (next === current) return;
|
|
24561
|
+
composerDiffLineCommentsRef.current = next;
|
|
24562
|
+
setComposerDiffLineCommentsState(next);
|
|
24563
|
+
const currentComposerSnapshot = composerStore.state;
|
|
24564
|
+
setStoreState(composerStore, {
|
|
24565
|
+
...currentComposerSnapshot,
|
|
24566
|
+
composerDiffLineComments: currentComposerSnapshot.disabled ? [] : next
|
|
24567
|
+
});
|
|
24568
|
+
}, [composerStore]);
|
|
24073
24569
|
const contextUsageStoreRef = import_react.useRef(null);
|
|
24074
24570
|
if (!contextUsageStoreRef.current) contextUsageStoreRef.current = createPicoStore(void 0);
|
|
24075
24571
|
const contextUsageStore = contextUsageStoreRef.current;
|
|
@@ -24217,8 +24713,8 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
24217
24713
|
...currentComposerSnapshot,
|
|
24218
24714
|
awaitingFirstTurn: currentComposerSnapshot.disabled ? false : next
|
|
24219
24715
|
});
|
|
24220
|
-
if (next && !sessionStateRef.current.streaming) setStoreState(workingStateStore, { label: "
|
|
24221
|
-
else if (!next && workingStateStore.state?.label === "
|
|
24716
|
+
if (next && !sessionStateRef.current.streaming) setStoreState(workingStateStore, { label: "" });
|
|
24717
|
+
else if (!next && workingStateStore.state?.label === "") setStoreState(workingStateStore, null);
|
|
24222
24718
|
});
|
|
24223
24719
|
}, [
|
|
24224
24720
|
awaitingFirstTurnStore,
|
|
@@ -24999,6 +25495,7 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
24999
25495
|
pendingDraftFollowUps,
|
|
25000
25496
|
awaitingFirstTurn,
|
|
25001
25497
|
pendingMessages,
|
|
25498
|
+
composerDiffLineCommentsRef,
|
|
25002
25499
|
composerImagesRef,
|
|
25003
25500
|
composerTextRef,
|
|
25004
25501
|
composerSkillRef,
|
|
@@ -25016,6 +25513,7 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
25016
25513
|
setPendingMessages,
|
|
25017
25514
|
setAwaitingFirstTurn,
|
|
25018
25515
|
setIsSubmitting,
|
|
25516
|
+
setComposerDiffLineComments,
|
|
25019
25517
|
setComposerImages
|
|
25020
25518
|
});
|
|
25021
25519
|
const switchEmptyDraftDirectory = import_react.useCallback((directory) => {
|
|
@@ -25096,6 +25594,22 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
25096
25594
|
setPendingMessages,
|
|
25097
25595
|
setSessionState
|
|
25098
25596
|
]);
|
|
25597
|
+
const createDiffLineCommentId = () => {
|
|
25598
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") return `diff-comment:${crypto.randomUUID()}`;
|
|
25599
|
+
return `diff-comment:${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
25600
|
+
};
|
|
25601
|
+
const addComposerDiffLineComment = (comment) => {
|
|
25602
|
+
const text = comment.text.trim();
|
|
25603
|
+
const cwd = sessionStateRef.current.cwd?.trim() || "";
|
|
25604
|
+
if (!text || !cwd) return;
|
|
25605
|
+
setComposerDiffLineComments((current) => [...current, {
|
|
25606
|
+
...comment,
|
|
25607
|
+
id: createDiffLineCommentId(),
|
|
25608
|
+
cwd,
|
|
25609
|
+
text
|
|
25610
|
+
}]);
|
|
25611
|
+
composerPanelRef.current?.focusPrompt({ preventScroll: true });
|
|
25612
|
+
};
|
|
25099
25613
|
const onPickImages = async (files) => {
|
|
25100
25614
|
if (!files || files.length === 0) return;
|
|
25101
25615
|
const imageFiles = Array.from(files).filter((file) => file.type.startsWith("image/"));
|
|
@@ -25113,6 +25627,7 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
25113
25627
|
}));
|
|
25114
25628
|
const currentPendingMessages = pendingDraftFollowUpMessages.length > 0 || pendingMessages.length > 0 ? [...pendingDraftFollowUpMessages, ...pendingMessages] : EMPTY_COMPOSER_PENDING_MESSAGES;
|
|
25115
25629
|
const composerDisabled = isSessionViewLoading;
|
|
25630
|
+
const displayedDiffLineComments = composerDisabled ? EMPTY_COMPOSER_DIFF_LINE_COMMENTS : composerDiffLineComments;
|
|
25116
25631
|
const displayedPendingMessages = composerDisabled ? EMPTY_COMPOSER_PENDING_MESSAGES : currentPendingMessages;
|
|
25117
25632
|
const displayedComposerImages = composerDisabled ? EMPTY_COMPOSER_IMAGES : composerImages;
|
|
25118
25633
|
const displayedComposerText = composerDisabled ? "" : composerDraftSeed.text;
|
|
@@ -25405,6 +25920,7 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
25405
25920
|
activeSessionId,
|
|
25406
25921
|
awaitingFirstTurn: composerDisabled ? false : awaitingFirstTurn,
|
|
25407
25922
|
centerMessages: displaySettingsRef.current.centerMessages,
|
|
25923
|
+
composerDiffLineComments: displayedDiffLineComments,
|
|
25408
25924
|
composerImages: displayedComposerImages,
|
|
25409
25925
|
composerSkill: displayedComposerSkill,
|
|
25410
25926
|
composerSyncNonce: composerDraftSeed.syncNonce,
|
|
@@ -25421,6 +25937,9 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
25421
25937
|
const composerActionsRef = useLatestRef({
|
|
25422
25938
|
abortSession,
|
|
25423
25939
|
onPickImages,
|
|
25940
|
+
removeDiffLineComment: (id) => {
|
|
25941
|
+
setComposerDiffLineComments((current) => current.filter((comment) => comment.id !== id));
|
|
25942
|
+
},
|
|
25424
25943
|
onRemoveComposerImage: (index) => {
|
|
25425
25944
|
setComposerImages((current) => current.filter((_, imageIndex) => imageIndex !== index));
|
|
25426
25945
|
},
|
|
@@ -26012,6 +26531,7 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
26012
26531
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(AppShellTabsController, {
|
|
26013
26532
|
actionsRef: composerActionsRef,
|
|
26014
26533
|
appUiStore,
|
|
26534
|
+
composerDiffLineComments: displayedDiffLineComments,
|
|
26015
26535
|
composerPanelRef,
|
|
26016
26536
|
contextUsageStore,
|
|
26017
26537
|
conversationFrameRef,
|
|
@@ -26034,6 +26554,7 @@ function useAppShellSessionWorkspaceView({ viewerContextId, sessionId, onSelectS
|
|
|
26034
26554
|
onCloseFileViewTab: closeFileViewTab,
|
|
26035
26555
|
onCloseFileViewTabsToRight: closeFileViewTabsToRight,
|
|
26036
26556
|
onCloseOtherFileViewTabs: closeOtherFileViewTabs,
|
|
26557
|
+
onAddDiffLineComment: addComposerDiffLineComment,
|
|
26037
26558
|
onOpenFileViewTab: openFileViewTab,
|
|
26038
26559
|
onReorderFileViewTabs: reorderFileViewTabs,
|
|
26039
26560
|
rightSidebarStore,
|