@percena/weft 0.4.0-next.0 → 0.4.0-next.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/action-bridge.cjs +323 -0
- package/dist/action-bridge.d.cts +8 -0
- package/dist/action-bridge.d.ts +8 -0
- package/dist/action-bridge.js +291 -0
- package/dist/chat.cjs +3851 -36
- package/dist/chat.d.cts +1 -874
- package/dist/chat.d.ts +1 -874
- package/dist/chat.js +3870 -36
- package/dist/index.cjs +12085 -1488
- package/dist/index.d.cts +553 -240
- package/dist/index.d.ts +553 -240
- package/dist/index.js +12118 -1447
- package/dist/providers-flitro.cjs +50 -307
- package/dist/providers-flitro.d.cts +75 -52
- package/dist/providers-flitro.d.ts +75 -52
- package/dist/providers-flitro.js +45 -287
- package/dist/styles/fonts/KaTeX_AMS-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_AMS-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Bold.woff +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Main-Bold.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Main-Bold.woff +0 -0
- package/dist/styles/fonts/KaTeX_Main-Bold.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Main-BoldItalic.woff +0 -0
- package/dist/styles/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Main-Italic.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Main-Italic.woff +0 -0
- package/dist/styles/fonts/KaTeX_Main-Italic.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Main-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Main-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Main-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Math-BoldItalic.woff +0 -0
- package/dist/styles/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Math-Italic.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Math-Italic.woff +0 -0
- package/dist/styles/fonts/KaTeX_Math-Italic.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Bold.woff +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Italic.woff +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Script-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Script-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Script-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Size1-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Size1-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Size2-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Size2-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Size3-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Size3-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Size3-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Size4-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Size4-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Size4-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Typewriter-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
- package/dist/styles/index.css +2 -212
- package/package.json +23 -49
- package/dist/auth.cjs +0 -241
- package/dist/auth.d.cts +0 -21
- package/dist/auth.d.ts +0 -21
- package/dist/auth.js +0 -208
- package/dist/automations.cjs +0 -3044
- package/dist/automations.d.cts +0 -4774
- package/dist/automations.d.ts +0 -4774
- package/dist/automations.js +0 -2965
- package/dist/factory.cjs +0 -5057
- package/dist/factory.d.cts +0 -7909
- package/dist/factory.d.ts +0 -7909
- package/dist/factory.js +0 -5008
- package/dist/local-runtime.cjs +0 -1387
- package/dist/local-runtime.d.cts +0 -3314
- package/dist/local-runtime.d.ts +0 -3314
- package/dist/local-runtime.js +0 -1345
- package/dist/providers.cjs +0 -6154
- package/dist/providers.d.cts +0 -6024
- package/dist/providers.d.ts +0 -6024
- package/dist/providers.js +0 -6110
- package/dist/server.cjs +0 -9137
- package/dist/server.d.cts +0 -9868
- package/dist/server.d.ts +0 -9868
- package/dist/server.js +0 -9118
- package/dist/skills-browser.cjs +0 -118
- package/dist/skills-browser.d.cts +0 -105
- package/dist/skills-browser.d.ts +0 -105
- package/dist/skills-browser.js +0 -88
- package/dist/skills.cjs +0 -505
- package/dist/skills.d.cts +0 -218
- package/dist/skills.d.ts +0 -218
- package/dist/skills.js +0 -458
- package/dist/sources.cjs +0 -1710
- package/dist/sources.d.cts +0 -3978
- package/dist/sources.d.ts +0 -3978
- package/dist/sources.js +0 -1675
package/dist/chat.cjs
CHANGED
|
@@ -88,6 +88,7 @@ __export(chat_exports, {
|
|
|
88
88
|
toStoredSession: () => toStoredSession,
|
|
89
89
|
updateMessageAt: () => updateMessageAt,
|
|
90
90
|
useAgentChatSession: () => useAgentChatSession,
|
|
91
|
+
useAgentSession: () => useAgentSession,
|
|
91
92
|
useEventProcessor: () => useEventProcessor,
|
|
92
93
|
useTimelineAgentChatSession: () => useTimelineAgentChatSession
|
|
93
94
|
});
|
|
@@ -907,7 +908,7 @@ function TurnCardActionsMenu({
|
|
|
907
908
|
hasEditOrWriteActivities,
|
|
908
909
|
className
|
|
909
910
|
}) {
|
|
910
|
-
const { t:
|
|
911
|
+
const { t: t22 } = (0, import_react_i18next.useTranslation)();
|
|
911
912
|
const [isOpen, setIsOpen] = React2.useState(false);
|
|
912
913
|
if (!onOpenDetails && !onOpenMultiFileDiff) {
|
|
913
914
|
return null;
|
|
@@ -945,7 +946,7 @@ function TurnCardActionsMenu({
|
|
|
945
946
|
{
|
|
946
947
|
onClick: onOpenMultiFileDiff,
|
|
947
948
|
icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.FileDiff, {}),
|
|
948
|
-
children:
|
|
949
|
+
children: t22("chat.viewFileChanges")
|
|
949
950
|
}
|
|
950
951
|
),
|
|
951
952
|
onOpenDetails && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
@@ -953,7 +954,7 @@ function TurnCardActionsMenu({
|
|
|
953
954
|
{
|
|
954
955
|
onClick: onOpenDetails,
|
|
955
956
|
icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react2.ArrowUpRight, {}),
|
|
956
|
-
children:
|
|
957
|
+
children: t22("chat.viewTurnDetails")
|
|
957
958
|
}
|
|
958
959
|
)
|
|
959
960
|
]
|
|
@@ -2707,9 +2708,9 @@ function AcceptPlanDropdown({
|
|
|
2707
2708
|
acceptOptionLabel,
|
|
2708
2709
|
className
|
|
2709
2710
|
}) {
|
|
2710
|
-
const { t:
|
|
2711
|
-
const effectiveAcceptLabel = acceptLabel ??
|
|
2712
|
-
const effectiveAcceptOptionLabel = acceptOptionLabel ??
|
|
2711
|
+
const { t: t22 } = (0, import_react_i18next3.useTranslation)();
|
|
2712
|
+
const effectiveAcceptLabel = acceptLabel ?? t22("plan.acceptPlan");
|
|
2713
|
+
const effectiveAcceptOptionLabel = acceptOptionLabel ?? t22("plan.accept");
|
|
2713
2714
|
const [isOpen, setIsOpen] = (0, import_react9.useState)(false);
|
|
2714
2715
|
const [position, setPosition] = (0, import_react9.useState)(null);
|
|
2715
2716
|
const triggerRef = (0, import_react9.useRef)(null);
|
|
@@ -2839,7 +2840,7 @@ function AcceptPlanDropdown({
|
|
|
2839
2840
|
),
|
|
2840
2841
|
children: [
|
|
2841
2842
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[13px] font-medium", children: effectiveAcceptOptionLabel }),
|
|
2842
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-xs text-muted-foreground", children:
|
|
2843
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-xs text-muted-foreground", children: t22("plan.executeImmediately") })
|
|
2843
2844
|
]
|
|
2844
2845
|
}
|
|
2845
2846
|
),
|
|
@@ -2854,8 +2855,8 @@ function AcceptPlanDropdown({
|
|
|
2854
2855
|
"transition-colors"
|
|
2855
2856
|
),
|
|
2856
2857
|
children: [
|
|
2857
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[13px] font-medium", children:
|
|
2858
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-xs text-muted-foreground", children:
|
|
2858
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-[13px] font-medium", children: t22("plan.acceptAndCompact") }),
|
|
2859
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-xs text-muted-foreground", children: t22("plan.worksForComplex") })
|
|
2859
2860
|
]
|
|
2860
2861
|
}
|
|
2861
2862
|
)
|
|
@@ -2905,7 +2906,7 @@ function StyledDropdownMenuItem({
|
|
|
2905
2906
|
);
|
|
2906
2907
|
}
|
|
2907
2908
|
function BranchDropdown({ onBranch }) {
|
|
2908
|
-
const { t:
|
|
2909
|
+
const { t: t22 } = (0, import_react_i18next2.useTranslation)();
|
|
2909
2910
|
const handleBranchClick = () => {
|
|
2910
2911
|
onBranch({ newPanel: true });
|
|
2911
2912
|
};
|
|
@@ -2914,8 +2915,8 @@ function BranchDropdown({ onBranch }) {
|
|
|
2914
2915
|
"button",
|
|
2915
2916
|
{
|
|
2916
2917
|
type: "button",
|
|
2917
|
-
"aria-label":
|
|
2918
|
-
title:
|
|
2918
|
+
"aria-label": t22("chat.branchOptions"),
|
|
2919
|
+
title: t22("chat.branch"),
|
|
2919
2920
|
className: cn(
|
|
2920
2921
|
"p-1 rounded-[4px] transition-colors select-none",
|
|
2921
2922
|
"text-muted-foreground hover:text-foreground hover:bg-foreground/5",
|
|
@@ -2926,8 +2927,8 @@ function BranchDropdown({ onBranch }) {
|
|
|
2926
2927
|
}
|
|
2927
2928
|
) }),
|
|
2928
2929
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(StyledDropdownMenuContent, { align: "end", minWidth: "min-w-64", sideOffset: 6, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(StyledDropdownMenuItem, { onClick: handleBranchClick, className: "items-start py-2", children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "flex flex-col gap-0.5", children: [
|
|
2929
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[13px] leading-tight", children:
|
|
2930
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "max-w-[220px] whitespace-normal text-xs leading-tight text-muted-foreground", children:
|
|
2930
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "text-[13px] leading-tight", children: t22("chat.branchFromThisMessage") }),
|
|
2931
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "max-w-[220px] whitespace-normal text-xs leading-tight text-muted-foreground", children: t22("chat.branchFromThisMessageDescription") })
|
|
2931
2932
|
] }) }) })
|
|
2932
2933
|
] });
|
|
2933
2934
|
}
|
|
@@ -2975,7 +2976,7 @@ function ResponseCard({
|
|
|
2975
2976
|
openAnnotationRequest,
|
|
2976
2977
|
annotationInteractionMode = "interactive"
|
|
2977
2978
|
}) {
|
|
2978
|
-
const { t:
|
|
2979
|
+
const { t: t22 } = (0, import_react_i18next2.useTranslation)();
|
|
2979
2980
|
const [displayedText, setDisplayedText] = (0, import_react5.useState)(text);
|
|
2980
2981
|
const lastUpdateRef = (0, import_react5.useRef)(Date.now());
|
|
2981
2982
|
const [copied, setCopied] = (0, import_react5.useState)(false);
|
|
@@ -3575,7 +3576,7 @@ function ResponseCard({
|
|
|
3575
3576
|
"text-muted-foreground/50 hover:text-foreground",
|
|
3576
3577
|
"focus:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:opacity-100"
|
|
3577
3578
|
),
|
|
3578
|
-
title:
|
|
3579
|
+
title: t22("common.viewFullscreen"),
|
|
3579
3580
|
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react4.Maximize2, { className: "w-3.5 h-3.5" })
|
|
3580
3581
|
}
|
|
3581
3582
|
),
|
|
@@ -3638,10 +3639,10 @@ function ResponseCard({
|
|
|
3638
3639
|
),
|
|
3639
3640
|
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
3640
3641
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react4.Check, { className: SIZE_CONFIG.iconSize }),
|
|
3641
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children:
|
|
3642
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: t22("common.copied") })
|
|
3642
3643
|
] }) : /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
3643
3644
|
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_lucide_react4.Copy, { className: SIZE_CONFIG.iconSize }),
|
|
3644
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children:
|
|
3645
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: t22("common.copy") })
|
|
3645
3646
|
] })
|
|
3646
3647
|
}
|
|
3647
3648
|
),
|
|
@@ -3674,8 +3675,8 @@ function ResponseCard({
|
|
|
3674
3675
|
{
|
|
3675
3676
|
onAccept,
|
|
3676
3677
|
onAcceptWithCompact,
|
|
3677
|
-
acceptLabel: hasActiveFollowUpAnnotations ?
|
|
3678
|
-
acceptOptionLabel: hasActiveFollowUpAnnotations ?
|
|
3678
|
+
acceptLabel: hasActiveFollowUpAnnotations ? t22("plan.acceptAndSendFollowups") : t22("plan.acceptPlan"),
|
|
3679
|
+
acceptOptionLabel: hasActiveFollowUpAnnotations ? t22("plan.acceptAndSendFollowups") : t22("plan.accept")
|
|
3679
3680
|
}
|
|
3680
3681
|
)
|
|
3681
3682
|
}
|
|
@@ -4221,12 +4222,12 @@ function InlineExecution({
|
|
|
4221
4222
|
onRetry,
|
|
4222
4223
|
className
|
|
4223
4224
|
}) {
|
|
4224
|
-
const { t:
|
|
4225
|
+
const { t: t22 } = (0, import_react_i18next4.useTranslation)();
|
|
4225
4226
|
if (status === "executing") {
|
|
4226
4227
|
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: cn("space-y-3", className), children: [
|
|
4227
4228
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
4228
4229
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(LoadingIndicator, { animated: true, showElapsed: true }),
|
|
4229
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: cn("text-foreground/80", SIZE_CONFIG.fontSize), children:
|
|
4230
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: cn("text-foreground/80", SIZE_CONFIG.fontSize), children: t22("common.editing") })
|
|
4230
4231
|
] }),
|
|
4231
4232
|
activities.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "space-y-0.5 pl-1", children: activities.slice(-3).map((activity) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(InlineActivityRow, { activity }, activity.id)) }),
|
|
4232
4233
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex items-center justify-start pt-1 border-t border-border/30", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
@@ -4238,7 +4239,7 @@ function InlineExecution({
|
|
|
4238
4239
|
"text-muted-foreground hover:text-foreground transition-colors",
|
|
4239
4240
|
SIZE_CONFIG.fontSize
|
|
4240
4241
|
),
|
|
4241
|
-
children:
|
|
4242
|
+
children: t22("common.cancel")
|
|
4242
4243
|
}
|
|
4243
4244
|
) })
|
|
4244
4245
|
] });
|
|
@@ -4247,7 +4248,7 @@ function InlineExecution({
|
|
|
4247
4248
|
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: cn("space-y-3", className), children: [
|
|
4248
4249
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
4249
4250
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react8.CheckCircle2, { className: "w-4 h-4 text-success" }),
|
|
4250
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: cn("text-foreground font-medium", SIZE_CONFIG.fontSize), children:
|
|
4251
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: cn("text-foreground font-medium", SIZE_CONFIG.fontSize), children: t22("common.done") })
|
|
4251
4252
|
] }),
|
|
4252
4253
|
result && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cn("text-muted-foreground leading-relaxed prose-compact", SIZE_CONFIG.fontSize), children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Markdown, { children: result }) }),
|
|
4253
4254
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex items-center justify-end pt-1 border-t border-border/30", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
@@ -4261,7 +4262,7 @@ function InlineExecution({
|
|
|
4261
4262
|
),
|
|
4262
4263
|
children: [
|
|
4263
4264
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react8.CheckCircle2, { className: "w-3 h-3" }),
|
|
4264
|
-
|
|
4265
|
+
t22("common.done")
|
|
4265
4266
|
]
|
|
4266
4267
|
}
|
|
4267
4268
|
) })
|
|
@@ -4270,7 +4271,7 @@ function InlineExecution({
|
|
|
4270
4271
|
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: cn("space-y-3", className), children: [
|
|
4271
4272
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center gap-2", children: [
|
|
4272
4273
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react8.XCircle, { className: "w-4 h-4 text-destructive" }),
|
|
4273
|
-
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: cn("text-foreground font-medium", SIZE_CONFIG.fontSize), children:
|
|
4274
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: cn("text-foreground font-medium", SIZE_CONFIG.fontSize), children: t22("common.failed") })
|
|
4274
4275
|
] }),
|
|
4275
4276
|
error && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: cn("text-destructive/80 leading-relaxed prose-compact", SIZE_CONFIG.fontSize), children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Markdown, { children: error }) }),
|
|
4276
4277
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center justify-end gap-2 pt-1 border-t border-border/30", children: [
|
|
@@ -4285,7 +4286,7 @@ function InlineExecution({
|
|
|
4285
4286
|
),
|
|
4286
4287
|
children: [
|
|
4287
4288
|
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_lucide_react8.X, { className: "w-3 h-3" }),
|
|
4288
|
-
|
|
4289
|
+
t22("common.dismiss")
|
|
4289
4290
|
]
|
|
4290
4291
|
}
|
|
4291
4292
|
),
|
|
@@ -4298,7 +4299,7 @@ function InlineExecution({
|
|
|
4298
4299
|
"px-2 py-1 rounded-md bg-accent/10 text-accent hover:bg-accent/20 transition-colors",
|
|
4299
4300
|
SIZE_CONFIG.fontSize
|
|
4300
4301
|
),
|
|
4301
|
-
children:
|
|
4302
|
+
children: t22("common.retry")
|
|
4302
4303
|
}
|
|
4303
4304
|
)
|
|
4304
4305
|
] })
|
|
@@ -4525,14 +4526,14 @@ function CommandBadge({ badge }) {
|
|
|
4525
4526
|
);
|
|
4526
4527
|
}
|
|
4527
4528
|
function ContextBadge({ badge }) {
|
|
4528
|
-
const { t:
|
|
4529
|
+
const { t: t22 } = (0, import_react_i18next5.useTranslation)();
|
|
4529
4530
|
const displayLabel = badge.collapsedLabel || badge.label;
|
|
4530
4531
|
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
4531
4532
|
"span",
|
|
4532
4533
|
{
|
|
4533
4534
|
className: "inline-flex items-center gap-1 h-[22px] px-1.5 mr-1 rounded-[5px] bg-background shadow-minimal text-[12px] align-middle",
|
|
4534
4535
|
style: { verticalAlign: "middle", transform: "translateY(-1px)" },
|
|
4535
|
-
title:
|
|
4536
|
+
title: t22("chat.contextBadge"),
|
|
4536
4537
|
children: [
|
|
4537
4538
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "h-[12px] w-[12px] rounded-[2px] bg-foreground/5 flex items-center justify-center text-foreground/50 shrink-0 text-[8px]", children: CONTEXT_ICON_TEXT }),
|
|
4538
4539
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "truncate max-w-[200px] text-muted-foreground", children: displayLabel })
|
|
@@ -4696,7 +4697,7 @@ function UserMessageBubble({
|
|
|
4696
4697
|
isQueued,
|
|
4697
4698
|
compactMode
|
|
4698
4699
|
}) {
|
|
4699
|
-
const { t:
|
|
4700
|
+
const { t: t22 } = (0, import_react_i18next5.useTranslation)();
|
|
4700
4701
|
const hasAttachments = attachments && attachments.length > 0;
|
|
4701
4702
|
const [showQueued, setShowQueued] = (0, import_react12.useState)(isQueued ?? false);
|
|
4702
4703
|
const queuedShownAtRef = (0, import_react12.useRef)(isQueued ? Date.now() : null);
|
|
@@ -4753,7 +4754,7 @@ function UserMessageBubble({
|
|
|
4753
4754
|
{
|
|
4754
4755
|
className: "shrink-0 cursor-pointer hover:opacity-80 transition-opacity",
|
|
4755
4756
|
onClick: () => att.storedPath && onFileClick?.(att.storedPath),
|
|
4756
|
-
title:
|
|
4757
|
+
title: t22("chat.clickToOpen", { name: att.name }),
|
|
4757
4758
|
children: isImage ? (
|
|
4758
4759
|
/* IMAGE: Square thumbnail only */
|
|
4759
4760
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "h-14 w-14 rounded-[8px] overflow-hidden bg-background shadow-minimal", children: hasThumbnail ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
@@ -4802,7 +4803,7 @@ function UserMessageBubble({
|
|
|
4802
4803
|
"aria-live": "polite",
|
|
4803
4804
|
children: [
|
|
4804
4805
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react9.Clock, { className: "h-3 w-3 animate-pulse", "aria-hidden": "true" }),
|
|
4805
|
-
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-[11px] italic", children:
|
|
4806
|
+
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-[11px] italic", children: t22("chat.queuedBadge") })
|
|
4806
4807
|
]
|
|
4807
4808
|
}
|
|
4808
4809
|
),
|
|
@@ -5505,7 +5506,7 @@ function handleTextComplete(state, event) {
|
|
|
5505
5506
|
const existingMsg = session.messages[msgIndex];
|
|
5506
5507
|
const resolvedContent = event.text || streaming?.content || existingMsg?.content || "";
|
|
5507
5508
|
const isCompletingAccumulatedText = Boolean(event.text) && (event.text === existingMsg.content || event.text === streaming?.content);
|
|
5508
|
-
const completedTimestamp = isCompletingAccumulatedText ? existingMsg.timestamp : Math.max(event.timestamp ?? Date.now(), existingMsg.timestamp + 1);
|
|
5509
|
+
const completedTimestamp = event.isIntermediate ? existingMsg.timestamp : isCompletingAccumulatedText ? existingMsg.timestamp : Math.max(event.timestamp ?? Date.now(), existingMsg.timestamp + 1);
|
|
5509
5510
|
const updatedSession = updateMessageAt(session, msgIndex, {
|
|
5510
5511
|
// Replace temporary renderer-generated ID with authoritative main-process ID
|
|
5511
5512
|
// so branchFromMessageId always resolves against persisted session.jsonl.
|
|
@@ -7113,7 +7114,7 @@ var InProcessEventSource = class {
|
|
|
7113
7114
|
}
|
|
7114
7115
|
};
|
|
7115
7116
|
|
|
7116
|
-
// ../packages/
|
|
7117
|
+
// ../packages/chat/dist/index.js
|
|
7117
7118
|
var import_react18 = require("react");
|
|
7118
7119
|
var import_react19 = require("react");
|
|
7119
7120
|
|
|
@@ -7135,7 +7136,7 @@ function timelineKey(item) {
|
|
|
7135
7136
|
return `${item.epoch}:${item.seq}`;
|
|
7136
7137
|
}
|
|
7137
7138
|
|
|
7138
|
-
// ../packages/
|
|
7139
|
+
// ../packages/chat/dist/index.js
|
|
7139
7140
|
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
7140
7141
|
var import_react20 = require("react");
|
|
7141
7142
|
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
@@ -7172,6 +7173,7 @@ function createAgentChatPanelModelFromTimeline(args) {
|
|
|
7172
7173
|
};
|
|
7173
7174
|
}
|
|
7174
7175
|
function isChatTranscriptTimelineEnvelope(envelope) {
|
|
7176
|
+
if (!envelope.item) return false;
|
|
7175
7177
|
switch (envelope.item.type) {
|
|
7176
7178
|
case "user_message":
|
|
7177
7179
|
case "assistant_message_delta":
|
|
@@ -7897,6 +7899,3818 @@ function TimelineAgentChatPanel({
|
|
|
7897
7899
|
)
|
|
7898
7900
|
] });
|
|
7899
7901
|
}
|
|
7902
|
+
|
|
7903
|
+
// ../packages/react/dist/index.js
|
|
7904
|
+
var React102 = __toESM(require("react"), 1);
|
|
7905
|
+
var import_react21 = require("react");
|
|
7906
|
+
var import_i18next3 = __toESM(require("i18next"), 1);
|
|
7907
|
+
var import_react22 = require("motion/react");
|
|
7908
|
+
var import_lucide_react11 = require("lucide-react");
|
|
7909
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
7910
|
+
var React22 = __toESM(require("react"), 1);
|
|
7911
|
+
var import_react_i18next6 = require("react-i18next");
|
|
7912
|
+
var import_lucide_react12 = require("lucide-react");
|
|
7913
|
+
var React11 = __toESM(require("react"), 1);
|
|
7914
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
7915
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
7916
|
+
var import_i18next4 = __toESM(require("i18next"), 1);
|
|
7917
|
+
var import_react23 = require("react");
|
|
7918
|
+
var import_react24 = require("motion/react");
|
|
7919
|
+
var import_lucide_react13 = require("lucide-react");
|
|
7920
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
7921
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
7922
|
+
var import_react25 = require("react");
|
|
7923
|
+
var import_react_i18next7 = require("react-i18next");
|
|
7924
|
+
var import_lucide_react14 = require("lucide-react");
|
|
7925
|
+
var React62 = __toESM(require("react"), 1);
|
|
7926
|
+
var import_react_markdown2 = __toESM(require("react-markdown"), 1);
|
|
7927
|
+
var import_rehype_katex2 = __toESM(require("rehype-katex"), 1);
|
|
7928
|
+
var import_rehype_raw2 = __toESM(require("rehype-raw"), 1);
|
|
7929
|
+
var import_remark_gfm2 = __toESM(require("remark-gfm"), 1);
|
|
7930
|
+
var import_remark_math2 = __toESM(require("remark-math"), 1);
|
|
7931
|
+
var React32 = __toESM(require("react"), 1);
|
|
7932
|
+
var import_core4 = require("@shikijs/core");
|
|
7933
|
+
var import_engine_javascript2 = require("@shikijs/engine-javascript");
|
|
7934
|
+
var import_react26 = require("react");
|
|
7935
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
7936
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
7937
|
+
var React42 = __toESM(require("react"), 1);
|
|
7938
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
7939
|
+
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
7940
|
+
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
7941
|
+
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
7942
|
+
var import_jsx_runtime52 = require("react/jsx-runtime");
|
|
7943
|
+
var import_jsx_runtime53 = require("react/jsx-runtime");
|
|
7944
|
+
var import_jsx_runtime54 = require("react/jsx-runtime");
|
|
7945
|
+
var import_jsx_runtime55 = require("react/jsx-runtime");
|
|
7946
|
+
var import_jsx_runtime56 = require("react/jsx-runtime");
|
|
7947
|
+
var React52 = __toESM(require("react"), 1);
|
|
7948
|
+
var import_lucide_react15 = require("lucide-react");
|
|
7949
|
+
var import_react27 = require("motion/react");
|
|
7950
|
+
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
7951
|
+
var import_react28 = require("react");
|
|
7952
|
+
var import_jsx_runtime58 = require("react/jsx-runtime");
|
|
7953
|
+
var import_jsx_runtime59 = require("react/jsx-runtime");
|
|
7954
|
+
var React72 = __toESM(require("react"), 1);
|
|
7955
|
+
var import_jsx_runtime60 = require("react/jsx-runtime");
|
|
7956
|
+
var React82 = __toESM(require("react"), 1);
|
|
7957
|
+
var React92 = __toESM(require("react"), 1);
|
|
7958
|
+
var import_react29 = require("react");
|
|
7959
|
+
var import_react_i18next8 = require("react-i18next");
|
|
7960
|
+
var ReactDOM2 = __toESM(require("react-dom"), 1);
|
|
7961
|
+
var import_lucide_react16 = require("lucide-react");
|
|
7962
|
+
var import_jsx_runtime61 = require("react/jsx-runtime");
|
|
7963
|
+
var import_jsx_runtime62 = require("react/jsx-runtime");
|
|
7964
|
+
var import_jsx_runtime63 = require("react/jsx-runtime");
|
|
7965
|
+
var import_react30 = require("motion/react");
|
|
7966
|
+
var import_lucide_react17 = require("lucide-react");
|
|
7967
|
+
var import_jsx_runtime64 = require("react/jsx-runtime");
|
|
7968
|
+
var import_jsx_runtime65 = require("react/jsx-runtime");
|
|
7969
|
+
var import_react_i18next9 = require("react-i18next");
|
|
7970
|
+
var import_lucide_react18 = require("lucide-react");
|
|
7971
|
+
var import_jsx_runtime66 = require("react/jsx-runtime");
|
|
7972
|
+
var import_react31 = require("react");
|
|
7973
|
+
var import_react32 = require("react");
|
|
7974
|
+
var import_lucide_react19 = require("lucide-react");
|
|
7975
|
+
var import_lucide_react20 = require("lucide-react");
|
|
7976
|
+
var import_jsx_runtime67 = require("react/jsx-runtime");
|
|
7977
|
+
var import_react_i18next10 = require("react-i18next");
|
|
7978
|
+
var import_jsx_runtime68 = require("react/jsx-runtime");
|
|
7979
|
+
var import_jsx_runtime69 = require("react/jsx-runtime");
|
|
7980
|
+
var import_jsx_runtime70 = require("react/jsx-runtime");
|
|
7981
|
+
var import_jsx_runtime71 = require("react/jsx-runtime");
|
|
7982
|
+
var import_react33 = require("react");
|
|
7983
|
+
var import_react34 = require("react");
|
|
7984
|
+
var import_jsx_runtime72 = require("react/jsx-runtime");
|
|
7985
|
+
var import_jsx_runtime73 = require("react/jsx-runtime");
|
|
7986
|
+
var import_jsx_runtime74 = require("react/jsx-runtime");
|
|
7987
|
+
var import_react35 = require("react");
|
|
7988
|
+
var import_jsx_runtime75 = require("react/jsx-runtime");
|
|
7989
|
+
var import_jsx_runtime76 = require("react/jsx-runtime");
|
|
7990
|
+
var import_react36 = require("react");
|
|
7991
|
+
var import_jsx_runtime77 = require("react/jsx-runtime");
|
|
7992
|
+
var import_jsx_runtime78 = require("react/jsx-runtime");
|
|
7993
|
+
var import_react37 = require("react");
|
|
7994
|
+
var import_react38 = require("react");
|
|
7995
|
+
var import_react39 = require("react");
|
|
7996
|
+
var import_jsx_runtime79 = require("react/jsx-runtime");
|
|
7997
|
+
var import_react40 = require("react");
|
|
7998
|
+
var import_jsx_runtime80 = require("react/jsx-runtime");
|
|
7999
|
+
var import_react41 = require("react");
|
|
8000
|
+
var EN_FALLBACK2 = {
|
|
8001
|
+
// TurnCard
|
|
8002
|
+
"turnCard.processing": "Processing",
|
|
8003
|
+
"turnCard.responding": "Responding",
|
|
8004
|
+
"turnCard.stepsCompleted": "Steps completed",
|
|
8005
|
+
"turnCard.starting": "Starting",
|
|
8006
|
+
"turnCard.errorCount": "{{count}} errors",
|
|
8007
|
+
// Common
|
|
8008
|
+
"common.error": "Error",
|
|
8009
|
+
"common.viewFullscreen": "View fullscreen",
|
|
8010
|
+
"common.copy": "Copy",
|
|
8011
|
+
"common.copied": "Copied",
|
|
8012
|
+
"common.editing": "Editing",
|
|
8013
|
+
"common.cancel": "Cancel",
|
|
8014
|
+
"common.done": "Done",
|
|
8015
|
+
"common.failed": "Failed",
|
|
8016
|
+
"common.dismiss": "Dismiss",
|
|
8017
|
+
"common.retry": "Retry",
|
|
8018
|
+
// Chat
|
|
8019
|
+
"chat.branchOptions": "Branch options",
|
|
8020
|
+
"chat.branch": "Branch",
|
|
8021
|
+
"chat.branchFromThisMessage": "Branch from this message",
|
|
8022
|
+
"chat.branchFromThisMessageDescription": "Create a new conversation branch starting from this message",
|
|
8023
|
+
"chat.contextBadge": "Context",
|
|
8024
|
+
"chat.queuedBadge": "Queued",
|
|
8025
|
+
"chat.viewFileChanges": "View file changes",
|
|
8026
|
+
"chat.viewTurnDetails": "View turn details",
|
|
8027
|
+
// Plan
|
|
8028
|
+
"plan.acceptPlan": "Accept plan",
|
|
8029
|
+
"plan.accept": "Accept",
|
|
8030
|
+
"plan.executeImmediately": "Execute immediately",
|
|
8031
|
+
"plan.acceptAndCompact": "Accept & compact",
|
|
8032
|
+
"plan.worksForComplex": "Works well for complex multi-step plans",
|
|
8033
|
+
"plan.acceptAndSendFollowups": "Accept & send follow-ups"
|
|
8034
|
+
};
|
|
8035
|
+
function normalizePath2(path) {
|
|
8036
|
+
return path.replace(/\\/g, "/");
|
|
8037
|
+
}
|
|
8038
|
+
function pathStartsWith2(filePath, dirPath) {
|
|
8039
|
+
const normalizedFile = normalizePath2(filePath);
|
|
8040
|
+
const normalizedDir = normalizePath2(dirPath);
|
|
8041
|
+
return normalizedFile.startsWith(normalizedDir + "/") || normalizedFile === normalizedDir;
|
|
8042
|
+
}
|
|
8043
|
+
function stripPathPrefix2(filePath, prefix) {
|
|
8044
|
+
const normalizedFile = normalizePath2(filePath);
|
|
8045
|
+
const normalizedPrefix = normalizePath2(prefix);
|
|
8046
|
+
if (normalizedFile.startsWith(normalizedPrefix + "/")) {
|
|
8047
|
+
return normalizedFile.slice(normalizedPrefix.length + 1);
|
|
8048
|
+
}
|
|
8049
|
+
return filePath;
|
|
8050
|
+
}
|
|
8051
|
+
function deriveTurnPhase2(turn) {
|
|
8052
|
+
if (turn.isComplete) {
|
|
8053
|
+
return "complete";
|
|
8054
|
+
}
|
|
8055
|
+
if (turn.response && turn.response.isStreaming) {
|
|
8056
|
+
return "streaming";
|
|
8057
|
+
}
|
|
8058
|
+
const hasRunningTools = turn.activities.some((a) => a.type === "tool" && a.status === "running");
|
|
8059
|
+
if (hasRunningTools) {
|
|
8060
|
+
return "tool_active";
|
|
8061
|
+
}
|
|
8062
|
+
if (turn.activities.length > 0) {
|
|
8063
|
+
return "awaiting";
|
|
8064
|
+
}
|
|
8065
|
+
return "pending";
|
|
8066
|
+
}
|
|
8067
|
+
function shouldShowThinkingIndicator2(phase, isBuffering) {
|
|
8068
|
+
return phase === "pending" || phase === "awaiting" || phase === "streaming" && isBuffering;
|
|
8069
|
+
}
|
|
8070
|
+
function computeLastChildSet2(activities) {
|
|
8071
|
+
const lastByParent = /* @__PURE__ */ new Map();
|
|
8072
|
+
for (const activity of activities) {
|
|
8073
|
+
if (activity.depth && activity.depth > 0) {
|
|
8074
|
+
lastByParent.set(activity.parentId, activity.id);
|
|
8075
|
+
}
|
|
8076
|
+
}
|
|
8077
|
+
return new Set(lastByParent.values());
|
|
8078
|
+
}
|
|
8079
|
+
function formatDuration2(ms) {
|
|
8080
|
+
if (!Number.isFinite(ms) || ms < 0) {
|
|
8081
|
+
return "--";
|
|
8082
|
+
}
|
|
8083
|
+
const seconds = ms / 1e3;
|
|
8084
|
+
if (seconds < 60) {
|
|
8085
|
+
return `${seconds.toFixed(1)}s`;
|
|
8086
|
+
}
|
|
8087
|
+
const minutes = Math.floor(seconds / 60);
|
|
8088
|
+
const remainingSeconds = Math.round(seconds % 60);
|
|
8089
|
+
if (minutes >= 2) {
|
|
8090
|
+
return `${minutes}m+`;
|
|
8091
|
+
}
|
|
8092
|
+
return `${minutes}m ${remainingSeconds}s`;
|
|
8093
|
+
}
|
|
8094
|
+
function formatTokens2(count) {
|
|
8095
|
+
if (!Number.isFinite(count) || count < 0) {
|
|
8096
|
+
return "0";
|
|
8097
|
+
}
|
|
8098
|
+
count = Math.floor(count);
|
|
8099
|
+
if (count < 1e3) {
|
|
8100
|
+
return count.toString();
|
|
8101
|
+
}
|
|
8102
|
+
const k = count / 1e3;
|
|
8103
|
+
if (k < 10) {
|
|
8104
|
+
return `${k.toFixed(1)}k`;
|
|
8105
|
+
}
|
|
8106
|
+
return `${Math.round(k)}k`;
|
|
8107
|
+
}
|
|
8108
|
+
var PARENT_TASK_TOOL_NAMES3 = ["Task", "task"];
|
|
8109
|
+
function isParentTaskTool3(toolName) {
|
|
8110
|
+
return PARENT_TASK_TOOL_NAMES3.includes(toolName);
|
|
8111
|
+
}
|
|
8112
|
+
function isActivityGroup2(item) {
|
|
8113
|
+
return "type" in item && item.type === "group" && "parent" in item && "children" in item;
|
|
8114
|
+
}
|
|
8115
|
+
function extractTaskOutputData2(activity) {
|
|
8116
|
+
if (!activity.content) return void 0;
|
|
8117
|
+
try {
|
|
8118
|
+
const parsed = JSON.parse(activity.content);
|
|
8119
|
+
const data = {};
|
|
8120
|
+
if (typeof parsed.duration_ms === "number") {
|
|
8121
|
+
data.durationMs = parsed.duration_ms;
|
|
8122
|
+
}
|
|
8123
|
+
if (parsed.usage) {
|
|
8124
|
+
if (typeof parsed.usage.input_tokens === "number") {
|
|
8125
|
+
data.inputTokens = parsed.usage.input_tokens;
|
|
8126
|
+
}
|
|
8127
|
+
if (typeof parsed.usage.output_tokens === "number") {
|
|
8128
|
+
data.outputTokens = parsed.usage.output_tokens;
|
|
8129
|
+
}
|
|
8130
|
+
}
|
|
8131
|
+
if (data.durationMs !== void 0 || data.inputTokens !== void 0 || data.outputTokens !== void 0) {
|
|
8132
|
+
return data;
|
|
8133
|
+
}
|
|
8134
|
+
} catch {
|
|
8135
|
+
}
|
|
8136
|
+
return void 0;
|
|
8137
|
+
}
|
|
8138
|
+
function groupActivitiesByParent2(activities) {
|
|
8139
|
+
const taskToolUseIds = /* @__PURE__ */ new Set();
|
|
8140
|
+
for (const activity of activities) {
|
|
8141
|
+
if (isParentTaskTool3(activity.toolName ?? "") && activity.toolUseId) {
|
|
8142
|
+
taskToolUseIds.add(activity.toolUseId);
|
|
8143
|
+
}
|
|
8144
|
+
}
|
|
8145
|
+
const childrenByParent = /* @__PURE__ */ new Map();
|
|
8146
|
+
for (const activity of activities) {
|
|
8147
|
+
if (activity.parentId && taskToolUseIds.has(activity.parentId)) {
|
|
8148
|
+
const existing = childrenByParent.get(activity.parentId) || [];
|
|
8149
|
+
existing.push(activity);
|
|
8150
|
+
childrenByParent.set(activity.parentId, existing);
|
|
8151
|
+
}
|
|
8152
|
+
}
|
|
8153
|
+
const childIds = /* @__PURE__ */ new Set();
|
|
8154
|
+
for (const children of childrenByParent.values()) {
|
|
8155
|
+
for (const child of children) {
|
|
8156
|
+
childIds.add(child.id);
|
|
8157
|
+
}
|
|
8158
|
+
}
|
|
8159
|
+
const taskOutputByAgentId = /* @__PURE__ */ new Map();
|
|
8160
|
+
for (const activity of activities) {
|
|
8161
|
+
if (activity.toolName === "TaskOutput" && activity.status === "completed") {
|
|
8162
|
+
const taskId = activity.toolInput?.task_id;
|
|
8163
|
+
if (taskId) {
|
|
8164
|
+
const data = extractTaskOutputData2(activity);
|
|
8165
|
+
if (data) {
|
|
8166
|
+
taskOutputByAgentId.set(taskId, data);
|
|
8167
|
+
}
|
|
8168
|
+
}
|
|
8169
|
+
}
|
|
8170
|
+
}
|
|
8171
|
+
const taskToAgentId = /* @__PURE__ */ new Map();
|
|
8172
|
+
for (const activity of activities) {
|
|
8173
|
+
if (isParentTaskTool3(activity.toolName ?? "") && (activity.status === "completed" || activity.status === "backgrounded") && activity.content) {
|
|
8174
|
+
const agentIdMatch = activity.content.match(/agentId:\s*([a-zA-Z0-9_-]+)/);
|
|
8175
|
+
const capturedAgentId = agentIdMatch?.[1];
|
|
8176
|
+
if (capturedAgentId && activity.toolUseId) {
|
|
8177
|
+
taskToAgentId.set(activity.toolUseId, capturedAgentId);
|
|
8178
|
+
}
|
|
8179
|
+
}
|
|
8180
|
+
}
|
|
8181
|
+
const result = [];
|
|
8182
|
+
for (const activity of activities) {
|
|
8183
|
+
if (childIds.has(activity.id)) {
|
|
8184
|
+
continue;
|
|
8185
|
+
}
|
|
8186
|
+
if (activity.toolName === "TaskOutput") {
|
|
8187
|
+
continue;
|
|
8188
|
+
}
|
|
8189
|
+
if (isParentTaskTool3(activity.toolName ?? "")) {
|
|
8190
|
+
const children = activity.toolUseId ? childrenByParent.get(activity.toolUseId) || [] : [];
|
|
8191
|
+
let taskOutputData;
|
|
8192
|
+
if (activity.toolUseId) {
|
|
8193
|
+
const agentId = taskToAgentId.get(activity.toolUseId);
|
|
8194
|
+
if (agentId) {
|
|
8195
|
+
taskOutputData = taskOutputByAgentId.get(agentId);
|
|
8196
|
+
}
|
|
8197
|
+
}
|
|
8198
|
+
result.push({
|
|
8199
|
+
type: "group",
|
|
8200
|
+
parent: activity,
|
|
8201
|
+
children: children.sort((a, b) => a.timestamp - b.timestamp),
|
|
8202
|
+
taskOutputData
|
|
8203
|
+
});
|
|
8204
|
+
} else {
|
|
8205
|
+
result.push(activity);
|
|
8206
|
+
}
|
|
8207
|
+
}
|
|
8208
|
+
return result;
|
|
8209
|
+
}
|
|
8210
|
+
function asRecord2(value) {
|
|
8211
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
8212
|
+
}
|
|
8213
|
+
function normalizeFollowUpText2(text) {
|
|
8214
|
+
return text.replace(/\s+/g, " ").trim();
|
|
8215
|
+
}
|
|
8216
|
+
function getAnnotationNoteText2(annotation) {
|
|
8217
|
+
const noteBody = annotation.body.find((body) => body.type === "note");
|
|
8218
|
+
const bodyText = noteBody?.text?.trim() ?? "";
|
|
8219
|
+
if (bodyText.length > 0) return bodyText;
|
|
8220
|
+
const followUpMeta = asRecord2(asRecord2(annotation.meta)?.followUp);
|
|
8221
|
+
const metaText = typeof followUpMeta?.text === "string" ? followUpMeta.text.trim() : "";
|
|
8222
|
+
return metaText;
|
|
8223
|
+
}
|
|
8224
|
+
function formatAnnotationFollowUpTooltipText2(annotation, maxLength = 180) {
|
|
8225
|
+
const note = normalizeFollowUpText2(getAnnotationNoteText2(annotation));
|
|
8226
|
+
if (!note) return "";
|
|
8227
|
+
return note.length > maxLength ? `${note.slice(0, maxLength - 1).trimEnd()}\u2026` : note;
|
|
8228
|
+
}
|
|
8229
|
+
function extractAnnotationSelectedText2(annotation, messageContent) {
|
|
8230
|
+
const quoteSelector = annotation.target.selectors.find(
|
|
8231
|
+
(selector) => selector.type === "text-quote"
|
|
8232
|
+
);
|
|
8233
|
+
const quoteText = quoteSelector?.exact?.trim() ?? "";
|
|
8234
|
+
if (quoteText.length > 0) return quoteText;
|
|
8235
|
+
const positionSelector = annotation.target.selectors.find(
|
|
8236
|
+
(selector) => selector.type === "text-position"
|
|
8237
|
+
);
|
|
8238
|
+
if (positionSelector) {
|
|
8239
|
+
const start = Math.max(0, Math.min(positionSelector.start, messageContent.length));
|
|
8240
|
+
const end = Math.max(start, Math.min(positionSelector.end, messageContent.length));
|
|
8241
|
+
const slice = messageContent.slice(start, end).trim();
|
|
8242
|
+
if (slice.length > 0) return slice;
|
|
8243
|
+
}
|
|
8244
|
+
return "Selected text";
|
|
8245
|
+
}
|
|
8246
|
+
function cn2(...classes) {
|
|
8247
|
+
return classes.filter(Boolean).join(" ");
|
|
8248
|
+
}
|
|
8249
|
+
function Spinner2({ className }) {
|
|
8250
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
8251
|
+
"svg",
|
|
8252
|
+
{
|
|
8253
|
+
className: cn2("animate-spin h-4 w-4 text-muted-foreground", className),
|
|
8254
|
+
viewBox: "0 0 24 24",
|
|
8255
|
+
fill: "none",
|
|
8256
|
+
children: [
|
|
8257
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8258
|
+
"circle",
|
|
8259
|
+
{
|
|
8260
|
+
className: "opacity-25",
|
|
8261
|
+
cx: "12",
|
|
8262
|
+
cy: "12",
|
|
8263
|
+
r: "10",
|
|
8264
|
+
stroke: "currentColor",
|
|
8265
|
+
strokeWidth: "4"
|
|
8266
|
+
}
|
|
8267
|
+
),
|
|
8268
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8269
|
+
"path",
|
|
8270
|
+
{
|
|
8271
|
+
className: "opacity-75",
|
|
8272
|
+
fill: "currentColor",
|
|
8273
|
+
d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
8274
|
+
}
|
|
8275
|
+
)
|
|
8276
|
+
]
|
|
8277
|
+
}
|
|
8278
|
+
);
|
|
8279
|
+
}
|
|
8280
|
+
function SimpleDropdown2({
|
|
8281
|
+
align = "start",
|
|
8282
|
+
onOpenChange,
|
|
8283
|
+
trigger,
|
|
8284
|
+
children
|
|
8285
|
+
}) {
|
|
8286
|
+
const [isOpen, setIsOpen] = React11.useState(false);
|
|
8287
|
+
const handleToggle = () => {
|
|
8288
|
+
const next = !isOpen;
|
|
8289
|
+
setIsOpen(next);
|
|
8290
|
+
onOpenChange?.(next);
|
|
8291
|
+
};
|
|
8292
|
+
const handleClose = () => {
|
|
8293
|
+
setIsOpen(false);
|
|
8294
|
+
onOpenChange?.(false);
|
|
8295
|
+
};
|
|
8296
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "relative inline-flex", children: [
|
|
8297
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { onClick: handleToggle, children: trigger }),
|
|
8298
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
8299
|
+
"div",
|
|
8300
|
+
{
|
|
8301
|
+
className: cn2(
|
|
8302
|
+
"absolute z-50 min-w-[160px] p-1",
|
|
8303
|
+
"bg-background rounded-[8px] shadow-strong border border-border/50",
|
|
8304
|
+
align === "end" ? "right-0" : "left-0",
|
|
8305
|
+
"top-full mt-1"
|
|
8306
|
+
),
|
|
8307
|
+
onClick: handleClose,
|
|
8308
|
+
children
|
|
8309
|
+
}
|
|
8310
|
+
)
|
|
8311
|
+
] });
|
|
8312
|
+
}
|
|
8313
|
+
function SimpleDropdownItem2({
|
|
8314
|
+
onClick,
|
|
8315
|
+
icon,
|
|
8316
|
+
children,
|
|
8317
|
+
className
|
|
8318
|
+
}) {
|
|
8319
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
8320
|
+
"button",
|
|
8321
|
+
{
|
|
8322
|
+
type: "button",
|
|
8323
|
+
onClick,
|
|
8324
|
+
className: cn2(
|
|
8325
|
+
"flex items-center gap-2 w-full px-2 py-1.5 text-left rounded-[6px]",
|
|
8326
|
+
"hover:bg-foreground/[0.05] focus:bg-foreground/[0.05]",
|
|
8327
|
+
"text-sm transition-colors",
|
|
8328
|
+
className
|
|
8329
|
+
),
|
|
8330
|
+
children: [
|
|
8331
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "shrink-0", children: icon }),
|
|
8332
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { children })
|
|
8333
|
+
]
|
|
8334
|
+
}
|
|
8335
|
+
);
|
|
8336
|
+
}
|
|
8337
|
+
function TurnCardActionsMenu2({
|
|
8338
|
+
onOpenDetails,
|
|
8339
|
+
onOpenMultiFileDiff,
|
|
8340
|
+
hasEditOrWriteActivities,
|
|
8341
|
+
className
|
|
8342
|
+
}) {
|
|
8343
|
+
const { t: t22 } = (0, import_react_i18next6.useTranslation)();
|
|
8344
|
+
const [isOpen, setIsOpen] = React22.useState(false);
|
|
8345
|
+
if (!onOpenDetails && !onOpenMultiFileDiff) {
|
|
8346
|
+
return null;
|
|
8347
|
+
}
|
|
8348
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
8349
|
+
SimpleDropdown2,
|
|
8350
|
+
{
|
|
8351
|
+
align: "end",
|
|
8352
|
+
onOpenChange: setIsOpen,
|
|
8353
|
+
trigger: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8354
|
+
"div",
|
|
8355
|
+
{
|
|
8356
|
+
role: "button",
|
|
8357
|
+
tabIndex: 0,
|
|
8358
|
+
className: cn2(
|
|
8359
|
+
"p-1 rounded-[6px] transition-opacity shrink-0",
|
|
8360
|
+
"opacity-0 group-hover:opacity-100",
|
|
8361
|
+
"bg-background shadow-minimal",
|
|
8362
|
+
"text-muted-foreground/50 hover:text-foreground",
|
|
8363
|
+
"focus:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:opacity-100",
|
|
8364
|
+
isOpen && "opacity-100 text-foreground",
|
|
8365
|
+
className
|
|
8366
|
+
),
|
|
8367
|
+
onKeyDown: (e) => {
|
|
8368
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
8369
|
+
e.preventDefault();
|
|
8370
|
+
}
|
|
8371
|
+
},
|
|
8372
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react12.MoreHorizontal, { className: "w-3 h-3" })
|
|
8373
|
+
}
|
|
8374
|
+
),
|
|
8375
|
+
children: [
|
|
8376
|
+
onOpenMultiFileDiff && hasEditOrWriteActivities && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8377
|
+
SimpleDropdownItem2,
|
|
8378
|
+
{
|
|
8379
|
+
onClick: onOpenMultiFileDiff,
|
|
8380
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react12.FileDiff, {}),
|
|
8381
|
+
children: t22("chat.viewFileChanges")
|
|
8382
|
+
}
|
|
8383
|
+
),
|
|
8384
|
+
onOpenDetails && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
8385
|
+
SimpleDropdownItem2,
|
|
8386
|
+
{
|
|
8387
|
+
onClick: onOpenDetails,
|
|
8388
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react12.ArrowUpRight, {}),
|
|
8389
|
+
children: t22("chat.viewTurnDetails")
|
|
8390
|
+
}
|
|
8391
|
+
)
|
|
8392
|
+
]
|
|
8393
|
+
}
|
|
8394
|
+
);
|
|
8395
|
+
}
|
|
8396
|
+
function splitComparableLines2(value) {
|
|
8397
|
+
if (!value) return [];
|
|
8398
|
+
const lines = value.split(/\r?\n/);
|
|
8399
|
+
if (lines.length > 0 && lines[lines.length - 1] === "") {
|
|
8400
|
+
lines.pop();
|
|
8401
|
+
}
|
|
8402
|
+
return lines;
|
|
8403
|
+
}
|
|
8404
|
+
function lcsLength2(a, b) {
|
|
8405
|
+
if (a.length === 0 || b.length === 0) return 0;
|
|
8406
|
+
const previous = new Array(b.length + 1).fill(0);
|
|
8407
|
+
const current = new Array(b.length + 1).fill(0);
|
|
8408
|
+
for (let i = 1; i <= a.length; i += 1) {
|
|
8409
|
+
for (let j = 1; j <= b.length; j += 1) {
|
|
8410
|
+
current[j] = a[i - 1] === b[j - 1] ? previous[j - 1] + 1 : Math.max(previous[j], current[j - 1]);
|
|
8411
|
+
}
|
|
8412
|
+
previous.splice(0, previous.length, ...current);
|
|
8413
|
+
current.fill(0);
|
|
8414
|
+
}
|
|
8415
|
+
return previous[b.length] ?? 0;
|
|
8416
|
+
}
|
|
8417
|
+
function getTextDiffStats2(oldText, newText) {
|
|
8418
|
+
const oldLines = splitComparableLines2(oldText);
|
|
8419
|
+
const newLines = splitComparableLines2(newText);
|
|
8420
|
+
const common = lcsLength2(oldLines, newLines);
|
|
8421
|
+
return {
|
|
8422
|
+
additions: Math.max(0, newLines.length - common),
|
|
8423
|
+
deletions: Math.max(0, oldLines.length - common)
|
|
8424
|
+
};
|
|
8425
|
+
}
|
|
8426
|
+
function getUnifiedDiffStats2(_diff, _path) {
|
|
8427
|
+
let additions = 0;
|
|
8428
|
+
let deletions = 0;
|
|
8429
|
+
let files = 0;
|
|
8430
|
+
for (const line of _diff.split(/\r?\n/)) {
|
|
8431
|
+
if (line.startsWith("diff --git ") || line.startsWith("+++ ")) {
|
|
8432
|
+
files += 1;
|
|
8433
|
+
continue;
|
|
8434
|
+
}
|
|
8435
|
+
if (line.startsWith("+++") || line.startsWith("---") || line.startsWith("@@")) {
|
|
8436
|
+
continue;
|
|
8437
|
+
}
|
|
8438
|
+
if (line.startsWith("+")) additions += 1;
|
|
8439
|
+
if (line.startsWith("-")) deletions += 1;
|
|
8440
|
+
}
|
|
8441
|
+
return { added: additions, removed: deletions, additions, deletions, files };
|
|
8442
|
+
}
|
|
8443
|
+
function t2(key, options) {
|
|
8444
|
+
const result = import_i18next4.default.t(key, options);
|
|
8445
|
+
if (!result || result === key) {
|
|
8446
|
+
const fallback = EN_FALLBACK2[key];
|
|
8447
|
+
if (!fallback) return key;
|
|
8448
|
+
if (options) {
|
|
8449
|
+
return fallback.replace(/\{\{(\w+)\}\}/g, (_, k) => String(options[k] ?? ""));
|
|
8450
|
+
}
|
|
8451
|
+
return fallback;
|
|
8452
|
+
}
|
|
8453
|
+
return result;
|
|
8454
|
+
}
|
|
8455
|
+
function stripMarkdown2(text) {
|
|
8456
|
+
return text.replace(/```(?:\w+)?\n?([\s\S]*?)```/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/^#{1,6}\s+/gm, "").replace(/\*\*([^*]+)\*\*/g, "$1").replace(/\*([^*]+)\*/g, "$1").replace(/__([^_]+)__/g, "$1").replace(/_([^_]+)_/g, "$1").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/!\[[^\]]*\]\([^)]+\)/g, "").replace(/^>\s+/gm, "").replace(/^---+$/gm, "").replace(/\s+/g, " ").trim();
|
|
8457
|
+
}
|
|
8458
|
+
function computeEditWriteDiffStats2(toolName, toolInput) {
|
|
8459
|
+
if (!toolInput) return null;
|
|
8460
|
+
if (toolName === "Edit") {
|
|
8461
|
+
if (toolInput.changes && Array.isArray(toolInput.changes)) {
|
|
8462
|
+
let totalAdditions = 0;
|
|
8463
|
+
let totalDeletions = 0;
|
|
8464
|
+
for (const change of toolInput.changes) {
|
|
8465
|
+
if (change.diff) {
|
|
8466
|
+
const stats2 = getUnifiedDiffStats2(change.diff, change.path || "file");
|
|
8467
|
+
if (stats2) {
|
|
8468
|
+
totalAdditions += stats2.additions;
|
|
8469
|
+
totalDeletions += stats2.deletions;
|
|
8470
|
+
}
|
|
8471
|
+
}
|
|
8472
|
+
}
|
|
8473
|
+
if (totalAdditions === 0 && totalDeletions === 0) return null;
|
|
8474
|
+
return { additions: totalAdditions, deletions: totalDeletions };
|
|
8475
|
+
}
|
|
8476
|
+
const oldString = toolInput.old_string ?? "";
|
|
8477
|
+
const newString = toolInput.new_string ?? "";
|
|
8478
|
+
if (!oldString && !newString) return null;
|
|
8479
|
+
const stats = getTextDiffStats2(oldString, newString);
|
|
8480
|
+
if (stats.additions === 0 && stats.deletions === 0) return null;
|
|
8481
|
+
return stats;
|
|
8482
|
+
}
|
|
8483
|
+
if (toolName === "Write") {
|
|
8484
|
+
const content = toolInput.content ?? "";
|
|
8485
|
+
if (!content) return null;
|
|
8486
|
+
return getTextDiffStats2("", content);
|
|
8487
|
+
}
|
|
8488
|
+
return null;
|
|
8489
|
+
}
|
|
8490
|
+
var SIZE_CONFIG2 = {
|
|
8491
|
+
/** Base font size class for all text */
|
|
8492
|
+
fontSize: "text-[13px]",
|
|
8493
|
+
/** Icon size class (width and height) */
|
|
8494
|
+
iconSize: "w-3 h-3",
|
|
8495
|
+
/** Spinner text size class */
|
|
8496
|
+
spinnerSize: "text-[10px]",
|
|
8497
|
+
/** Small spinner for header */
|
|
8498
|
+
spinnerSizeSmall: "text-[8px]",
|
|
8499
|
+
/** Activity row height in pixels (approx for calculation) */
|
|
8500
|
+
activityRowHeight: 24,
|
|
8501
|
+
/** Max visible activities before scrolling (show ~15 items) */
|
|
8502
|
+
maxVisibleActivities: 15,
|
|
8503
|
+
/** Number of items before which we apply staggered animation */
|
|
8504
|
+
staggeredAnimationLimit: 10
|
|
8505
|
+
};
|
|
8506
|
+
var BUFFER_CONFIG2 = {
|
|
8507
|
+
MIN_WORDS_STANDARD: 1,
|
|
8508
|
+
// Base threshold for showing content
|
|
8509
|
+
MIN_WORDS_CODE: 15,
|
|
8510
|
+
// Code blocks show faster
|
|
8511
|
+
MIN_WORDS_LIST: 20,
|
|
8512
|
+
// Lists show faster
|
|
8513
|
+
MIN_WORDS_QUESTION: 8,
|
|
8514
|
+
// Questions from AI show faster
|
|
8515
|
+
MIN_WORDS_HEADER: 12,
|
|
8516
|
+
// Headers indicate structure
|
|
8517
|
+
MIN_BUFFER_MS: 0,
|
|
8518
|
+
// Show the first non-empty delta immediately
|
|
8519
|
+
MAX_BUFFER_MS: 800,
|
|
8520
|
+
// Keep fallback short if markdown structure is ambiguous
|
|
8521
|
+
TIMEOUT_MIN_WORDS: 1,
|
|
8522
|
+
// Show on timeout if at least this many words
|
|
8523
|
+
HIGH_WORD_COUNT: 60,
|
|
8524
|
+
// Show regardless of structure at this count
|
|
8525
|
+
CONTENT_THROTTLE_MS: 60
|
|
8526
|
+
// Light throttle while preserving live streaming feel
|
|
8527
|
+
};
|
|
8528
|
+
function countWords2(text) {
|
|
8529
|
+
return text.trim().split(/\s+/).filter((w) => w.length > 0).length;
|
|
8530
|
+
}
|
|
8531
|
+
function hasCodeBlock2(text) {
|
|
8532
|
+
return /```/.test(text);
|
|
8533
|
+
}
|
|
8534
|
+
function hasList2(text) {
|
|
8535
|
+
return /^\s*[-*•]\s/m.test(text) || /^\s*\d+\.\s/m.test(text);
|
|
8536
|
+
}
|
|
8537
|
+
function hasHeader2(text) {
|
|
8538
|
+
return /^#{1,4}\s/m.test(text);
|
|
8539
|
+
}
|
|
8540
|
+
function hasStructure2(text) {
|
|
8541
|
+
if (/[.!?:]\s*$/.test(text.trimEnd())) return true;
|
|
8542
|
+
if (/\n\s*\n/.test(text)) return true;
|
|
8543
|
+
if (/\n\s*#{1,4}\s/.test(text)) return true;
|
|
8544
|
+
if (hasCodeBlock2(text)) return true;
|
|
8545
|
+
return false;
|
|
8546
|
+
}
|
|
8547
|
+
function isQuestion2(text) {
|
|
8548
|
+
return /\?\s*$/.test(text.trim());
|
|
8549
|
+
}
|
|
8550
|
+
function shouldShowStreamingContent2(text, isStreaming, streamStartTime) {
|
|
8551
|
+
const wordCount = countWords2(text);
|
|
8552
|
+
if (!isStreaming) {
|
|
8553
|
+
return { shouldShow: true, reason: "complete", wordCount };
|
|
8554
|
+
}
|
|
8555
|
+
if (text.trim().length > 0) {
|
|
8556
|
+
return { shouldShow: true, reason: "threshold_met", wordCount };
|
|
8557
|
+
}
|
|
8558
|
+
const elapsed = streamStartTime ? Date.now() - streamStartTime : 0;
|
|
8559
|
+
if (elapsed < BUFFER_CONFIG2.MIN_BUFFER_MS) {
|
|
8560
|
+
return { shouldShow: false, reason: "min_time", wordCount };
|
|
8561
|
+
}
|
|
8562
|
+
if (elapsed > BUFFER_CONFIG2.MAX_BUFFER_MS && wordCount >= BUFFER_CONFIG2.TIMEOUT_MIN_WORDS) {
|
|
8563
|
+
return { shouldShow: true, reason: "timeout", wordCount };
|
|
8564
|
+
}
|
|
8565
|
+
if (hasCodeBlock2(text) && wordCount >= BUFFER_CONFIG2.MIN_WORDS_CODE) {
|
|
8566
|
+
return { shouldShow: true, reason: "code_block", wordCount };
|
|
8567
|
+
}
|
|
8568
|
+
if (hasHeader2(text) && wordCount >= BUFFER_CONFIG2.MIN_WORDS_HEADER) {
|
|
8569
|
+
return { shouldShow: true, reason: "header", wordCount };
|
|
8570
|
+
}
|
|
8571
|
+
if (hasList2(text) && wordCount >= BUFFER_CONFIG2.MIN_WORDS_LIST) {
|
|
8572
|
+
return { shouldShow: true, reason: "list", wordCount };
|
|
8573
|
+
}
|
|
8574
|
+
if (isQuestion2(text) && wordCount >= BUFFER_CONFIG2.MIN_WORDS_QUESTION) {
|
|
8575
|
+
return { shouldShow: true, reason: "question", wordCount };
|
|
8576
|
+
}
|
|
8577
|
+
if (wordCount >= BUFFER_CONFIG2.MIN_WORDS_STANDARD && hasStructure2(text)) {
|
|
8578
|
+
return { shouldShow: true, reason: "threshold_met", wordCount };
|
|
8579
|
+
}
|
|
8580
|
+
if (wordCount >= BUFFER_CONFIG2.HIGH_WORD_COUNT) {
|
|
8581
|
+
return { shouldShow: true, reason: "high_word_count", wordCount };
|
|
8582
|
+
}
|
|
8583
|
+
return { shouldShow: false, reason: "buffering", wordCount };
|
|
8584
|
+
}
|
|
8585
|
+
function isResponseBuffering2(response) {
|
|
8586
|
+
if (!response) return false;
|
|
8587
|
+
if (!response.isStreaming) return false;
|
|
8588
|
+
const decision = shouldShowStreamingContent2(response.text, response.isStreaming, response.streamStartTime);
|
|
8589
|
+
return !decision.shouldShow;
|
|
8590
|
+
}
|
|
8591
|
+
function getToolDisplayName2(name) {
|
|
8592
|
+
const stripped = name.replace(/^mcp__[^_]+__/, "");
|
|
8593
|
+
const displayNames = {
|
|
8594
|
+
"TodoWrite": "Todo List Updated",
|
|
8595
|
+
"set_session_labels": "Set Session Labels",
|
|
8596
|
+
"set_session_status": "Set Session Status",
|
|
8597
|
+
"get_session_info": "Get Session Info",
|
|
8598
|
+
"list_sessions": "List Sessions"
|
|
8599
|
+
};
|
|
8600
|
+
return displayNames[stripped] || stripped;
|
|
8601
|
+
}
|
|
8602
|
+
function stripSessionFolderPath2(filePath, sessionFolderPath) {
|
|
8603
|
+
if (!sessionFolderPath) return filePath;
|
|
8604
|
+
const workspacePath = normalizePath2(sessionFolderPath).replace(/\/sessions\/[^/]+$/, "");
|
|
8605
|
+
if (pathStartsWith2(filePath, sessionFolderPath)) {
|
|
8606
|
+
return stripPathPrefix2(filePath, sessionFolderPath);
|
|
8607
|
+
}
|
|
8608
|
+
if (pathStartsWith2(filePath, workspacePath)) {
|
|
8609
|
+
return stripPathPrefix2(filePath, workspacePath);
|
|
8610
|
+
}
|
|
8611
|
+
return filePath;
|
|
8612
|
+
}
|
|
8613
|
+
function formatToolInput2(input, toolName, sessionFolderPath) {
|
|
8614
|
+
if (!input || Object.keys(input).length === 0) return "";
|
|
8615
|
+
if (toolName === "mcp__session__call_llm") return "";
|
|
8616
|
+
const parts = [];
|
|
8617
|
+
const isEditOrWrite = toolName === "Edit" || toolName === "Write";
|
|
8618
|
+
if (isEditOrWrite && input.changes && Array.isArray(input.changes)) {
|
|
8619
|
+
const firstChange = input.changes[0];
|
|
8620
|
+
if (firstChange?.path) {
|
|
8621
|
+
const pathStr = stripSessionFolderPath2(firstChange.path, sessionFolderPath);
|
|
8622
|
+
parts.push(pathStr);
|
|
8623
|
+
}
|
|
8624
|
+
return parts.join(" ");
|
|
8625
|
+
}
|
|
8626
|
+
for (const [key, value] of Object.entries(input)) {
|
|
8627
|
+
if (key === "_intent" || key === "description" || value === void 0 || value === null) continue;
|
|
8628
|
+
if (isEditOrWrite && key !== "file_path") continue;
|
|
8629
|
+
let valStr = typeof value === "string" ? value.replace(/\s+/g, " ").trim() : JSON.stringify(value);
|
|
8630
|
+
if (isEditOrWrite && key === "file_path" && typeof value === "string") {
|
|
8631
|
+
valStr = stripSessionFolderPath2(valStr, sessionFolderPath);
|
|
8632
|
+
}
|
|
8633
|
+
parts.push(valStr);
|
|
8634
|
+
if (parts.length >= 2) break;
|
|
8635
|
+
}
|
|
8636
|
+
return parts.join(" ");
|
|
8637
|
+
}
|
|
8638
|
+
function extractActionFromDisplayName2(iconName, llmName) {
|
|
8639
|
+
if (llmName.toLowerCase().startsWith(iconName.toLowerCase() + " ")) {
|
|
8640
|
+
return llmName.slice(iconName.length + 1).trim();
|
|
8641
|
+
}
|
|
8642
|
+
return llmName;
|
|
8643
|
+
}
|
|
8644
|
+
function formatToolDisplay2(activity) {
|
|
8645
|
+
const { toolName, displayName, toolInput, toolDisplayMeta } = activity;
|
|
8646
|
+
if (toolDisplayMeta) {
|
|
8647
|
+
if (toolName?.startsWith("mcp__") && toolDisplayMeta.category === "source") {
|
|
8648
|
+
const parts = toolName.match(/^mcp__([^_]+)__(.+)$/);
|
|
8649
|
+
if (parts) {
|
|
8650
|
+
const toolSlug = parts[2];
|
|
8651
|
+
return {
|
|
8652
|
+
name: `${toolDisplayMeta.displayName}: ${toolSlug}`,
|
|
8653
|
+
icon: toolDisplayMeta.iconDataUrl,
|
|
8654
|
+
description: toolDisplayMeta.description
|
|
8655
|
+
};
|
|
8656
|
+
}
|
|
8657
|
+
}
|
|
8658
|
+
if (toolName === "Bash" && displayName) {
|
|
8659
|
+
const iconName = toolDisplayMeta.displayName;
|
|
8660
|
+
const action = extractActionFromDisplayName2(iconName, displayName);
|
|
8661
|
+
return {
|
|
8662
|
+
name: iconName.toLowerCase() === "terminal" ? action : `${iconName}: ${action}`,
|
|
8663
|
+
icon: toolDisplayMeta.iconDataUrl,
|
|
8664
|
+
description: toolDisplayMeta.description
|
|
8665
|
+
};
|
|
8666
|
+
}
|
|
8667
|
+
if (displayName && toolDisplayMeta.category === "native") {
|
|
8668
|
+
return {
|
|
8669
|
+
name: displayName,
|
|
8670
|
+
icon: toolDisplayMeta.iconDataUrl,
|
|
8671
|
+
description: toolDisplayMeta.description
|
|
8672
|
+
};
|
|
8673
|
+
}
|
|
8674
|
+
return {
|
|
8675
|
+
name: toolDisplayMeta.displayName,
|
|
8676
|
+
icon: toolDisplayMeta.iconDataUrl,
|
|
8677
|
+
description: toolDisplayMeta.description
|
|
8678
|
+
};
|
|
8679
|
+
}
|
|
8680
|
+
if (toolName === "Skill" && toolInput?.skill) {
|
|
8681
|
+
const skillId = String(toolInput.skill);
|
|
8682
|
+
const colonIdx = skillId.indexOf(":");
|
|
8683
|
+
const slug = colonIdx > 0 ? skillId.slice(colonIdx + 1) : skillId;
|
|
8684
|
+
return { name: slug };
|
|
8685
|
+
}
|
|
8686
|
+
const name = displayName || (toolName ? getToolDisplayName2(toolName) : t2("turnCard.processing"));
|
|
8687
|
+
return { name };
|
|
8688
|
+
}
|
|
8689
|
+
function getPreviewText2(activities, intent, isStreaming, hasResponse, isComplete) {
|
|
8690
|
+
if (intent) return intent;
|
|
8691
|
+
const activityWithIntent = activities.find((a) => a.intent);
|
|
8692
|
+
if (activityWithIntent?.intent) return activityWithIntent.intent;
|
|
8693
|
+
if (isStreaming && hasResponse) return t2("turnCard.responding");
|
|
8694
|
+
const runningTask = activities.find((a) => a.toolName === "Task" && a.status === "running");
|
|
8695
|
+
if (runningTask?.toolInput?.description) {
|
|
8696
|
+
return runningTask.toolInput.description;
|
|
8697
|
+
}
|
|
8698
|
+
if (isStreaming && !isComplete) {
|
|
8699
|
+
const latestIntermediate = [...activities].reverse().find((a) => a.type === "intermediate" && a.content);
|
|
8700
|
+
if (latestIntermediate?.content) {
|
|
8701
|
+
return latestIntermediate.content;
|
|
8702
|
+
}
|
|
8703
|
+
}
|
|
8704
|
+
const runningTools = activities.filter((a) => a.status === "running" && a.toolName);
|
|
8705
|
+
const errorCount = activities.filter((a) => a.status === "error").length;
|
|
8706
|
+
if (runningTools.length > 0) {
|
|
8707
|
+
const toolNames = runningTools.map((a) => getToolDisplayName2(a.toolName)).slice(0, 3);
|
|
8708
|
+
return `${toolNames.join(", ")}...`;
|
|
8709
|
+
}
|
|
8710
|
+
const firstTask = activities.find((a) => a.toolName === "Task");
|
|
8711
|
+
if (firstTask?.toolInput?.description) {
|
|
8712
|
+
const errorSuffix = errorCount > 0 ? t2("turnCard.errorCount", { count: errorCount }) : "";
|
|
8713
|
+
return `${firstTask.toolInput.description}${errorSuffix}`;
|
|
8714
|
+
}
|
|
8715
|
+
if (isComplete || !isStreaming && activities.length > 0) {
|
|
8716
|
+
const errorSuffix = errorCount > 0 ? t2("turnCard.errorCount", { count: errorCount }) : "";
|
|
8717
|
+
return `${t2("turnCard.stepsCompleted")}${errorSuffix}`;
|
|
8718
|
+
}
|
|
8719
|
+
return t2("turnCard.starting");
|
|
8720
|
+
}
|
|
8721
|
+
function Tooltip2({ children }) {
|
|
8722
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_jsx_runtime44.Fragment, { children });
|
|
8723
|
+
}
|
|
8724
|
+
function TooltipTrigger2({
|
|
8725
|
+
children,
|
|
8726
|
+
asChild = false
|
|
8727
|
+
}) {
|
|
8728
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_jsx_runtime44.Fragment, { children });
|
|
8729
|
+
}
|
|
8730
|
+
function TooltipContent2({
|
|
8731
|
+
children,
|
|
8732
|
+
side = "top",
|
|
8733
|
+
className
|
|
8734
|
+
}) {
|
|
8735
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: cn2(
|
|
8736
|
+
"px-2 py-1 text-xs rounded bg-foreground text-background",
|
|
8737
|
+
"max-w-xs whitespace-normal",
|
|
8738
|
+
className
|
|
8739
|
+
), children });
|
|
8740
|
+
}
|
|
8741
|
+
function ActivityStatusIcon2({
|
|
8742
|
+
status,
|
|
8743
|
+
toolName,
|
|
8744
|
+
customIcon
|
|
8745
|
+
}) {
|
|
8746
|
+
const renderIcon = () => {
|
|
8747
|
+
if (status === "completed" && customIcon) {
|
|
8748
|
+
const isLikelyEmoji = customIcon.length <= 8 && !/^(https?:\/\/|data:)/.test(customIcon);
|
|
8749
|
+
if (isLikelyEmoji) {
|
|
8750
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: cn2(SIZE_CONFIG2.iconSize, "shrink-0 flex items-center justify-center text-[10px] leading-none"), children: customIcon });
|
|
8751
|
+
}
|
|
8752
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
8753
|
+
"img",
|
|
8754
|
+
{
|
|
8755
|
+
src: customIcon,
|
|
8756
|
+
alt: "",
|
|
8757
|
+
className: cn2(SIZE_CONFIG2.iconSize, "shrink-0 rounded-sm object-contain")
|
|
8758
|
+
}
|
|
8759
|
+
);
|
|
8760
|
+
}
|
|
8761
|
+
switch (status) {
|
|
8762
|
+
case "pending":
|
|
8763
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react13.Circle, { className: cn2(SIZE_CONFIG2.iconSize, "shrink-0 text-muted-foreground/50") });
|
|
8764
|
+
case "running":
|
|
8765
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: cn2(SIZE_CONFIG2.iconSize, "flex items-center justify-center shrink-0"), children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Spinner2, { className: SIZE_CONFIG2.spinnerSize }) });
|
|
8766
|
+
case "backgrounded":
|
|
8767
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: cn2(SIZE_CONFIG2.iconSize, "flex items-center justify-center shrink-0"), children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Spinner2, { className: cn2(SIZE_CONFIG2.spinnerSize, "text-accent") }) });
|
|
8768
|
+
case "completed":
|
|
8769
|
+
if (toolName === "Edit") {
|
|
8770
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react13.Pencil, { className: cn2(SIZE_CONFIG2.iconSize, "shrink-0 text-accent") });
|
|
8771
|
+
}
|
|
8772
|
+
if (toolName === "Write") {
|
|
8773
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react13.FilePenLine, { className: cn2(SIZE_CONFIG2.iconSize, "shrink-0 text-accent") });
|
|
8774
|
+
}
|
|
8775
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react13.CheckCircle2, { className: cn2(SIZE_CONFIG2.iconSize, "shrink-0 text-success") });
|
|
8776
|
+
case "error":
|
|
8777
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react13.XCircle, { className: cn2(SIZE_CONFIG2.iconSize, "shrink-0 text-destructive") });
|
|
8778
|
+
}
|
|
8779
|
+
};
|
|
8780
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_react24.AnimatePresence, { mode: "wait", initial: false, children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
8781
|
+
import_react24.motion.div,
|
|
8782
|
+
{
|
|
8783
|
+
initial: { opacity: 0, scale: 0.8 },
|
|
8784
|
+
animate: { opacity: 1, scale: 1 },
|
|
8785
|
+
exit: { opacity: 0, scale: 0.8 },
|
|
8786
|
+
transition: { duration: 0.2, ease: "easeOut" },
|
|
8787
|
+
className: "shrink-0",
|
|
8788
|
+
children: renderIcon()
|
|
8789
|
+
},
|
|
8790
|
+
status
|
|
8791
|
+
) });
|
|
8792
|
+
}
|
|
8793
|
+
function TreeViewConnector2({ depth }) {
|
|
8794
|
+
if (depth === 0) return null;
|
|
8795
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "flex self-stretch", children: Array.from({ length: depth }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "w-4 shrink-0" }, i)) });
|
|
8796
|
+
}
|
|
8797
|
+
function ActivityRow2({ activity, onOpenDetails, isLastChild, sessionFolderPath, displayMode = "detailed" }) {
|
|
8798
|
+
const depth = activity.depth || 0;
|
|
8799
|
+
if (activity.type === "intermediate") {
|
|
8800
|
+
const isThinking = activity.status === "running";
|
|
8801
|
+
const displayContent = isThinking ? "Thinking..." : stripMarkdown2(activity.content || "");
|
|
8802
|
+
const isComplete2 = activity.status === "completed";
|
|
8803
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-stretch", children: [
|
|
8804
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(TreeViewConnector2, { depth, isLastChild }),
|
|
8805
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
8806
|
+
"div",
|
|
8807
|
+
{
|
|
8808
|
+
className: cn2(
|
|
8809
|
+
"group/row flex items-center gap-2 py-0.5 text-foreground/75 flex-1 min-w-0",
|
|
8810
|
+
SIZE_CONFIG2.fontSize
|
|
8811
|
+
),
|
|
8812
|
+
onClick: onOpenDetails && isComplete2 ? onOpenDetails : void 0,
|
|
8813
|
+
children: [
|
|
8814
|
+
isThinking ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: cn2(SIZE_CONFIG2.iconSize, "flex items-center justify-center shrink-0"), children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Spinner2, { className: SIZE_CONFIG2.spinnerSize }) }) : /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react13.MessageCircleDashed, { className: cn2(SIZE_CONFIG2.iconSize, "shrink-0") }),
|
|
8815
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: cn2("truncate flex-1", onOpenDetails && isComplete2 && "group-hover/row:underline"), children: displayContent }),
|
|
8816
|
+
onOpenDetails && isComplete2 && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
8817
|
+
"div",
|
|
8818
|
+
{
|
|
8819
|
+
role: "button",
|
|
8820
|
+
tabIndex: 0,
|
|
8821
|
+
onClick: (e) => {
|
|
8822
|
+
e.stopPropagation();
|
|
8823
|
+
onOpenDetails();
|
|
8824
|
+
},
|
|
8825
|
+
onKeyDown: (e) => {
|
|
8826
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
8827
|
+
e.stopPropagation();
|
|
8828
|
+
onOpenDetails();
|
|
8829
|
+
}
|
|
8830
|
+
},
|
|
8831
|
+
className: cn2(
|
|
8832
|
+
"p-0.5 rounded-[3px] opacity-0 group-hover/row:opacity-100 transition-opacity shrink-0",
|
|
8833
|
+
"hover:bg-muted/80 focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
8834
|
+
),
|
|
8835
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react13.ArrowUpRight, { className: SIZE_CONFIG2.iconSize })
|
|
8836
|
+
}
|
|
8837
|
+
)
|
|
8838
|
+
]
|
|
8839
|
+
}
|
|
8840
|
+
)
|
|
8841
|
+
] });
|
|
8842
|
+
}
|
|
8843
|
+
if (activity.type === "status") {
|
|
8844
|
+
const isRunning = activity.status === "running";
|
|
8845
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-stretch", children: [
|
|
8846
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(TreeViewConnector2, { depth, isLastChild }),
|
|
8847
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
8848
|
+
"div",
|
|
8849
|
+
{
|
|
8850
|
+
className: cn2(
|
|
8851
|
+
"flex items-center gap-2 py-0.5 text-muted-foreground flex-1 min-w-0",
|
|
8852
|
+
SIZE_CONFIG2.fontSize
|
|
8853
|
+
),
|
|
8854
|
+
children: [
|
|
8855
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: cn2(SIZE_CONFIG2.iconSize, "flex items-center justify-center shrink-0"), children: isRunning ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Spinner2, { className: SIZE_CONFIG2.spinnerSizeSmall }) : /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react13.CheckCircle2, { className: cn2(SIZE_CONFIG2.iconSize, "text-success") }) }),
|
|
8856
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "truncate", children: activity.content })
|
|
8857
|
+
]
|
|
8858
|
+
}
|
|
8859
|
+
)
|
|
8860
|
+
] });
|
|
8861
|
+
}
|
|
8862
|
+
const toolDisplay = formatToolDisplay2(activity);
|
|
8863
|
+
const fullDisplayName = toolDisplay.name || (activity.type === "thinking" ? "Thinking" : "Processing");
|
|
8864
|
+
const isMcpOrApiTool = activity.toolName?.startsWith("mcp__") ?? false;
|
|
8865
|
+
let sourceName = fullDisplayName;
|
|
8866
|
+
let toolSlug = void 0;
|
|
8867
|
+
if (isMcpOrApiTool) {
|
|
8868
|
+
const colonIndex = fullDisplayName.indexOf(":");
|
|
8869
|
+
if (colonIndex > 0) {
|
|
8870
|
+
sourceName = fullDisplayName.substring(0, colonIndex).trim();
|
|
8871
|
+
toolSlug = fullDisplayName.substring(colonIndex + 1).trim();
|
|
8872
|
+
}
|
|
8873
|
+
}
|
|
8874
|
+
const displayedName = isMcpOrApiTool ? sourceName : fullDisplayName;
|
|
8875
|
+
const intentOrDescription = activity.intent || activity.toolInput?.description;
|
|
8876
|
+
const inputSummary = formatToolInput2(activity.toolInput, activity.toolName, sessionFolderPath);
|
|
8877
|
+
const diffStats = computeEditWriteDiffStats2(activity.toolName, activity.toolInput);
|
|
8878
|
+
const isComplete = activity.status === "completed" || activity.status === "error";
|
|
8879
|
+
const isBackgrounded = activity.status === "backgrounded";
|
|
8880
|
+
const backgroundInfo = isBackgrounded ? activity.taskId ? `Task ID: ${activity.taskId}${activity.elapsedSeconds ? `, ${formatDuration2(activity.elapsedSeconds * 1e3)} elapsed` : ""}` : activity.shellId ? `Shell ID: ${activity.shellId}${activity.elapsedSeconds ? `, ${formatDuration2(activity.elapsedSeconds * 1e3)} elapsed` : ""}` : null : null;
|
|
8881
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex items-stretch", children: [
|
|
8882
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(TreeViewConnector2, { depth, isLastChild }),
|
|
8883
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
8884
|
+
"div",
|
|
8885
|
+
{
|
|
8886
|
+
className: cn2(
|
|
8887
|
+
"group/row flex items-center gap-2 py-0.5 text-muted-foreground flex-1 min-w-0",
|
|
8888
|
+
SIZE_CONFIG2.fontSize
|
|
8889
|
+
),
|
|
8890
|
+
onClick: onOpenDetails && isComplete ? onOpenDetails : void 0,
|
|
8891
|
+
children: [
|
|
8892
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(ActivityStatusIcon2, { status: activity.status, toolName: activity.toolName, customIcon: toolDisplay.icon }),
|
|
8893
|
+
isMcpOrApiTool && !isBackgrounded && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
|
|
8894
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "shrink-0", children: sourceName }),
|
|
8895
|
+
activity.status === "error" && activity.error && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(Tooltip2, { children: [
|
|
8896
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
8897
|
+
"span",
|
|
8898
|
+
{
|
|
8899
|
+
className: "px-1.5 py-0.5 bg-[color-mix(in_oklab,var(--destructive)_4%,var(--background))] shadow-tinted rounded-[4px] text-[10px] text-destructive font-medium cursor-default shrink-0",
|
|
8900
|
+
style: { "--shadow-color": "var(--destructive-rgb)" },
|
|
8901
|
+
children: t2("common.error")
|
|
8902
|
+
}
|
|
8903
|
+
) }),
|
|
8904
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(TooltipContent2, { side: "top", className: "max-w-[400px]", children: activity.error })
|
|
8905
|
+
] }),
|
|
8906
|
+
activity.toolName === "mcp__session__call_llm" && activity.toolInput?.model && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "px-1.5 py-0.5 bg-background shadow-minimal rounded-[4px] text-[10px] text-foreground/60 shrink-0", children: String(activity.toolInput.model) }),
|
|
8907
|
+
(intentOrDescription || displayMode === "detailed" && (toolSlug || inputSummary)) && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: cn2("truncate flex-1 min-w-0", onOpenDetails && isComplete && "group-hover/row:underline"), children: [
|
|
8908
|
+
intentOrDescription && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
|
|
8909
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "opacity-60", children: " \xB7 " }),
|
|
8910
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { children: intentOrDescription })
|
|
8911
|
+
] }),
|
|
8912
|
+
displayMode === "detailed" && toolSlug && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
|
|
8913
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "opacity-60", children: " \xB7 " }),
|
|
8914
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "opacity-70", children: toolSlug })
|
|
8915
|
+
] }),
|
|
8916
|
+
displayMode === "detailed" && inputSummary && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
|
|
8917
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "opacity-60", children: " \xB7 " }),
|
|
8918
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "opacity-50", children: inputSummary })
|
|
8919
|
+
] })
|
|
8920
|
+
] })
|
|
8921
|
+
] }),
|
|
8922
|
+
!isMcpOrApiTool && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: cn2("shrink-0", onOpenDetails && isComplete && "group-hover/row:underline"), children: displayedName }),
|
|
8923
|
+
!isMcpOrApiTool && !isBackgrounded && diffStats && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "flex items-center gap-1.5 text-[10px] shrink-0", children: [
|
|
8924
|
+
diffStats.deletions > 0 && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
8925
|
+
"span",
|
|
8926
|
+
{
|
|
8927
|
+
className: "px-1.5 py-0.5 bg-[color-mix(in_oklab,var(--destructive)_5%,var(--background))] shadow-tinted rounded-[4px] text-destructive",
|
|
8928
|
+
style: { "--shadow-color": "var(--destructive-rgb)" },
|
|
8929
|
+
children: diffStats.deletions
|
|
8930
|
+
}
|
|
8931
|
+
),
|
|
8932
|
+
diffStats.additions > 0 && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
8933
|
+
"span",
|
|
8934
|
+
{
|
|
8935
|
+
className: "px-1.5 py-0.5 bg-[color-mix(in_oklab,var(--success)_5%,var(--background))] shadow-tinted rounded-[4px] text-success",
|
|
8936
|
+
style: { "--shadow-color": "var(--success-rgb)" },
|
|
8937
|
+
children: diffStats.additions
|
|
8938
|
+
}
|
|
8939
|
+
),
|
|
8940
|
+
(() => {
|
|
8941
|
+
if (typeof activity.toolInput?.file_path === "string") {
|
|
8942
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "px-1.5 py-0.5 bg-background shadow-minimal rounded-[4px] text-[11px] text-foreground/70", children: normalizePath2(activity.toolInput.file_path).split("/").pop() });
|
|
8943
|
+
}
|
|
8944
|
+
if (Array.isArray(activity.toolInput?.changes)) {
|
|
8945
|
+
const firstChange = activity.toolInput.changes[0];
|
|
8946
|
+
if (firstChange?.path) {
|
|
8947
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "px-1.5 py-0.5 bg-background shadow-minimal rounded-[4px] text-[11px] text-foreground/70", children: normalizePath2(firstChange.path).split("/").pop() });
|
|
8948
|
+
}
|
|
8949
|
+
}
|
|
8950
|
+
return null;
|
|
8951
|
+
})()
|
|
8952
|
+
] }),
|
|
8953
|
+
!isMcpOrApiTool && !isBackgrounded && !diffStats && activity.toolName === "Read" && typeof activity.toolInput?.file_path === "string" && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "flex items-center gap-1.5 text-[10px] shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "px-1.5 py-0.5 bg-background shadow-minimal rounded-[4px] text-[11px] text-foreground/70", children: normalizePath2(activity.toolInput.file_path).split("/").pop() }) }),
|
|
8954
|
+
!isMcpOrApiTool && activity.status === "error" && activity.error && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(Tooltip2, { children: [
|
|
8955
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(TooltipTrigger2, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
8956
|
+
"span",
|
|
8957
|
+
{
|
|
8958
|
+
className: "px-1.5 py-0.5 bg-[color-mix(in_oklab,var(--destructive)_4%,var(--background))] shadow-tinted rounded-[4px] text-[10px] text-destructive font-medium cursor-default shrink-0",
|
|
8959
|
+
style: { "--shadow-color": "var(--destructive-rgb)" },
|
|
8960
|
+
children: "Error"
|
|
8961
|
+
}
|
|
8962
|
+
) }),
|
|
8963
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(TooltipContent2, { side: "top", className: "max-w-[400px]", children: activity.error })
|
|
8964
|
+
] }),
|
|
8965
|
+
!isMcpOrApiTool && !isBackgrounded && (intentOrDescription || displayMode === "detailed" && inputSummary) && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: cn2("truncate flex-1 min-w-0", onOpenDetails && isComplete && "group-hover/row:underline"), children: [
|
|
8966
|
+
intentOrDescription && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
|
|
8967
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "opacity-60", children: " \xB7 " }),
|
|
8968
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { children: intentOrDescription })
|
|
8969
|
+
] }),
|
|
8970
|
+
displayMode === "detailed" && inputSummary && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
|
|
8971
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "opacity-60", children: " \xB7 " }),
|
|
8972
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "opacity-50", children: inputSummary })
|
|
8973
|
+
] })
|
|
8974
|
+
] }),
|
|
8975
|
+
backgroundInfo && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_jsx_runtime45.Fragment, { children: [
|
|
8976
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "opacity-60 shrink-0", children: "\xB7" }),
|
|
8977
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "truncate min-w-0 max-w-[300px] text-accent", children: backgroundInfo })
|
|
8978
|
+
] }),
|
|
8979
|
+
onOpenDetails && isComplete && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
8980
|
+
"div",
|
|
8981
|
+
{
|
|
8982
|
+
role: "button",
|
|
8983
|
+
tabIndex: 0,
|
|
8984
|
+
onClick: (e) => {
|
|
8985
|
+
e.stopPropagation();
|
|
8986
|
+
onOpenDetails();
|
|
8987
|
+
},
|
|
8988
|
+
onKeyDown: (e) => {
|
|
8989
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
8990
|
+
e.stopPropagation();
|
|
8991
|
+
onOpenDetails();
|
|
8992
|
+
}
|
|
8993
|
+
},
|
|
8994
|
+
className: cn2(
|
|
8995
|
+
"p-0.5 rounded-[3px] opacity-0 group-hover/row:opacity-100 transition-opacity shrink-0",
|
|
8996
|
+
"hover:bg-muted/80 focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
8997
|
+
),
|
|
8998
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react13.ArrowUpRight, { className: SIZE_CONFIG2.iconSize })
|
|
8999
|
+
}
|
|
9000
|
+
)
|
|
9001
|
+
]
|
|
9002
|
+
}
|
|
9003
|
+
)
|
|
9004
|
+
] });
|
|
9005
|
+
}
|
|
9006
|
+
function ActivityGroupRow2({ group, expandedGroups: externalExpandedGroups, onExpandedGroupsChange, onOpenActivityDetails, animationIndex = 0, sessionFolderPath, displayMode = "detailed" }) {
|
|
9007
|
+
const [localExpandedGroups, setLocalExpandedGroups] = (0, import_react23.useState)(/* @__PURE__ */ new Set());
|
|
9008
|
+
const expandedGroups = externalExpandedGroups ?? localExpandedGroups;
|
|
9009
|
+
const setExpandedGroups = onExpandedGroupsChange ?? setLocalExpandedGroups;
|
|
9010
|
+
const groupId = group.parent.id;
|
|
9011
|
+
const isExpanded = expandedGroups.has(groupId);
|
|
9012
|
+
const toggleExpanded = (0, import_react23.useCallback)(() => {
|
|
9013
|
+
const next = new Set(expandedGroups);
|
|
9014
|
+
if (next.has(groupId)) {
|
|
9015
|
+
next.delete(groupId);
|
|
9016
|
+
} else {
|
|
9017
|
+
next.add(groupId);
|
|
9018
|
+
}
|
|
9019
|
+
setExpandedGroups(next);
|
|
9020
|
+
}, [groupId, expandedGroups, setExpandedGroups]);
|
|
9021
|
+
const description = group.parent.toolInput?.description;
|
|
9022
|
+
const subagentType = group.parent.toolInput?.subagent_type;
|
|
9023
|
+
const isComplete = group.parent.status === "completed" || group.parent.status === "error";
|
|
9024
|
+
const hasError = group.parent.status === "error";
|
|
9025
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
9026
|
+
import_react24.motion.div,
|
|
9027
|
+
{
|
|
9028
|
+
initial: { opacity: 0, x: -8 },
|
|
9029
|
+
animate: { opacity: 1, x: 0 },
|
|
9030
|
+
transition: { delay: animationIndex < SIZE_CONFIG2.staggeredAnimationLimit ? animationIndex * 0.03 : 0.3 },
|
|
9031
|
+
className: "space-y-0.5",
|
|
9032
|
+
children: [
|
|
9033
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
9034
|
+
"div",
|
|
9035
|
+
{
|
|
9036
|
+
className: cn2(
|
|
9037
|
+
"group/row flex items-center gap-2 py-0.5 rounded-md cursor-pointer text-muted-foreground",
|
|
9038
|
+
"hover:text-foreground transition-colors",
|
|
9039
|
+
SIZE_CONFIG2.fontSize
|
|
9040
|
+
),
|
|
9041
|
+
onClick: toggleExpanded,
|
|
9042
|
+
children: [
|
|
9043
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
9044
|
+
import_react24.motion.div,
|
|
9045
|
+
{
|
|
9046
|
+
initial: false,
|
|
9047
|
+
animate: { rotate: isExpanded ? 90 : 0 },
|
|
9048
|
+
transition: { duration: 0.15, ease: "easeOut" },
|
|
9049
|
+
className: cn2(SIZE_CONFIG2.iconSize, "flex items-center justify-center shrink-0"),
|
|
9050
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react13.ChevronRight, { className: SIZE_CONFIG2.iconSize })
|
|
9051
|
+
}
|
|
9052
|
+
),
|
|
9053
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(ActivityStatusIcon2, { status: group.parent.status, toolName: group.parent.toolName }),
|
|
9054
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "shrink-0 px-1.5 py-0.5 rounded-[4px] bg-background shadow-minimal text-[10px] font-medium", children: subagentType || "Task" }),
|
|
9055
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: cn2(
|
|
9056
|
+
"truncate",
|
|
9057
|
+
hasError && "text-destructive"
|
|
9058
|
+
), children: description || "Task" }),
|
|
9059
|
+
isComplete && group.taskOutputData && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "shrink-0 text-muted-foreground/60 tabular-nums", children: [
|
|
9060
|
+
group.taskOutputData.durationMs !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { children: formatDuration2(group.taskOutputData.durationMs) }),
|
|
9061
|
+
group.taskOutputData.durationMs !== void 0 && (group.taskOutputData.inputTokens !== void 0 || group.taskOutputData.outputTokens !== void 0) && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "mx-1", children: "\xB7" }),
|
|
9062
|
+
(group.taskOutputData.inputTokens !== void 0 || group.taskOutputData.outputTokens !== void 0) && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { children: [
|
|
9063
|
+
formatTokens2((group.taskOutputData.inputTokens || 0) + (group.taskOutputData.outputTokens || 0)),
|
|
9064
|
+
" tokens"
|
|
9065
|
+
] })
|
|
9066
|
+
] }),
|
|
9067
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "flex-1" }),
|
|
9068
|
+
onOpenActivityDetails && isComplete && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
9069
|
+
"div",
|
|
9070
|
+
{
|
|
9071
|
+
role: "button",
|
|
9072
|
+
tabIndex: 0,
|
|
9073
|
+
onClick: (e) => {
|
|
9074
|
+
e.stopPropagation();
|
|
9075
|
+
onOpenActivityDetails(group.parent);
|
|
9076
|
+
},
|
|
9077
|
+
onKeyDown: (e) => {
|
|
9078
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
9079
|
+
e.stopPropagation();
|
|
9080
|
+
onOpenActivityDetails(group.parent);
|
|
9081
|
+
}
|
|
9082
|
+
},
|
|
9083
|
+
className: cn2(
|
|
9084
|
+
"p-0.5 rounded-[3px] opacity-0 group-hover/row:opacity-100 transition-opacity shrink-0",
|
|
9085
|
+
"hover:bg-muted/80 focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
9086
|
+
),
|
|
9087
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_lucide_react13.ArrowUpRight, { className: SIZE_CONFIG2.iconSize })
|
|
9088
|
+
}
|
|
9089
|
+
)
|
|
9090
|
+
]
|
|
9091
|
+
}
|
|
9092
|
+
),
|
|
9093
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_react24.AnimatePresence, { initial: false, children: isExpanded && group.children.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
9094
|
+
import_react24.motion.div,
|
|
9095
|
+
{
|
|
9096
|
+
initial: { height: 0, opacity: 0 },
|
|
9097
|
+
animate: { height: "auto", opacity: 1 },
|
|
9098
|
+
exit: { height: 0, opacity: 0 },
|
|
9099
|
+
transition: {
|
|
9100
|
+
height: { duration: 0.2, ease: [0.4, 0, 0.2, 1] },
|
|
9101
|
+
opacity: { duration: 0.15 }
|
|
9102
|
+
},
|
|
9103
|
+
className: "overflow-hidden",
|
|
9104
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "pl-0 space-y-0.5 border-l-2 border-muted ml-[5px]", children: group.children.map((child, idx) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
9105
|
+
import_react24.motion.div,
|
|
9106
|
+
{
|
|
9107
|
+
initial: { opacity: 0, x: -4 },
|
|
9108
|
+
animate: { opacity: 1, x: 0 },
|
|
9109
|
+
transition: { delay: idx * 0.02 },
|
|
9110
|
+
className: "ml-[-4px]",
|
|
9111
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
9112
|
+
ActivityRow2,
|
|
9113
|
+
{
|
|
9114
|
+
activity: child,
|
|
9115
|
+
onOpenDetails: onOpenActivityDetails ? () => onOpenActivityDetails(child) : void 0,
|
|
9116
|
+
isLastChild: idx === group.children.length - 1,
|
|
9117
|
+
sessionFolderPath,
|
|
9118
|
+
displayMode
|
|
9119
|
+
}
|
|
9120
|
+
)
|
|
9121
|
+
},
|
|
9122
|
+
child.id
|
|
9123
|
+
)) })
|
|
9124
|
+
}
|
|
9125
|
+
) })
|
|
9126
|
+
]
|
|
9127
|
+
}
|
|
9128
|
+
);
|
|
9129
|
+
}
|
|
9130
|
+
var ShikiThemeContext2 = (0, import_react26.createContext)(null);
|
|
9131
|
+
function useShikiTheme2() {
|
|
9132
|
+
return (0, import_react26.useContext)(ShikiThemeContext2);
|
|
9133
|
+
}
|
|
9134
|
+
var LANGUAGE_LOADERS2 = {
|
|
9135
|
+
bash: () => import("@shikijs/langs/bash"),
|
|
9136
|
+
c: () => import("@shikijs/langs/c"),
|
|
9137
|
+
cpp: () => import("@shikijs/langs/cpp"),
|
|
9138
|
+
css: () => import("@shikijs/langs/css"),
|
|
9139
|
+
graphql: () => import("@shikijs/langs/graphql"),
|
|
9140
|
+
html: () => import("@shikijs/langs/html"),
|
|
9141
|
+
java: () => import("@shikijs/langs/java"),
|
|
9142
|
+
javascript: () => import("@shikijs/langs/javascript"),
|
|
9143
|
+
json: () => import("@shikijs/langs/json"),
|
|
9144
|
+
jsx: () => import("@shikijs/langs/jsx"),
|
|
9145
|
+
less: () => import("@shikijs/langs/less"),
|
|
9146
|
+
markdown: () => import("@shikijs/langs/markdown"),
|
|
9147
|
+
php: () => import("@shikijs/langs/php"),
|
|
9148
|
+
python: () => import("@shikijs/langs/python"),
|
|
9149
|
+
scss: () => import("@shikijs/langs/scss"),
|
|
9150
|
+
shell: () => import("@shikijs/langs/shell"),
|
|
9151
|
+
sql: () => import("@shikijs/langs/sql"),
|
|
9152
|
+
svelte: () => import("@shikijs/langs/svelte"),
|
|
9153
|
+
tsx: () => import("@shikijs/langs/tsx"),
|
|
9154
|
+
typescript: () => import("@shikijs/langs/typescript"),
|
|
9155
|
+
vue: () => import("@shikijs/langs/vue"),
|
|
9156
|
+
wasm: () => import("@shikijs/langs/wasm"),
|
|
9157
|
+
yaml: () => import("@shikijs/langs/yaml")
|
|
9158
|
+
};
|
|
9159
|
+
var THEME_LOADERS2 = {
|
|
9160
|
+
"github-dark": () => import("@shikijs/themes/github-dark"),
|
|
9161
|
+
"github-light": () => import("@shikijs/themes/github-light")
|
|
9162
|
+
};
|
|
9163
|
+
var createHighlighter2 = (0, import_core4.createBundledHighlighter)({
|
|
9164
|
+
langs: LANGUAGE_LOADERS2,
|
|
9165
|
+
themes: THEME_LOADERS2,
|
|
9166
|
+
engine: () => (0, import_engine_javascript2.createJavaScriptRegexEngine)()
|
|
9167
|
+
});
|
|
9168
|
+
var { codeToHtml: codeToHtml2 } = (0, import_core4.createSingletonShorthands)(createHighlighter2);
|
|
9169
|
+
var LANGUAGE_ALIASES2 = {
|
|
9170
|
+
"js": "javascript",
|
|
9171
|
+
"ts": "typescript",
|
|
9172
|
+
"py": "python",
|
|
9173
|
+
"sh": "bash",
|
|
9174
|
+
"zsh": "bash",
|
|
9175
|
+
"yml": "yaml",
|
|
9176
|
+
"gql": "graphql"
|
|
9177
|
+
};
|
|
9178
|
+
var highlightCache2 = /* @__PURE__ */ new Map();
|
|
9179
|
+
var CACHE_MAX_SIZE2 = 200;
|
|
9180
|
+
function getCacheKey2(code, lang, theme) {
|
|
9181
|
+
return `${theme}:${lang}:${code}`;
|
|
9182
|
+
}
|
|
9183
|
+
function isValidLanguage2(lang) {
|
|
9184
|
+
const normalized = LANGUAGE_ALIASES2[lang] || lang;
|
|
9185
|
+
return normalized in LANGUAGE_LOADERS2;
|
|
9186
|
+
}
|
|
9187
|
+
function CodeBlock2({ code, language = "text", className, mode = "full", forcedTheme }) {
|
|
9188
|
+
const [highlighted, setHighlighted] = React32.useState(null);
|
|
9189
|
+
const [isLoading, setIsLoading] = React32.useState(true);
|
|
9190
|
+
const [copied, setCopied] = React32.useState(false);
|
|
9191
|
+
const contextShikiTheme = useShikiTheme2();
|
|
9192
|
+
const langLower = language.toLowerCase();
|
|
9193
|
+
const resolvedLang = LANGUAGE_ALIASES2[langLower] || langLower;
|
|
9194
|
+
React32.useEffect(() => {
|
|
9195
|
+
let cancelled = false;
|
|
9196
|
+
async function highlight() {
|
|
9197
|
+
let theme;
|
|
9198
|
+
if (contextShikiTheme) {
|
|
9199
|
+
theme = contextShikiTheme;
|
|
9200
|
+
} else if (forcedTheme) {
|
|
9201
|
+
theme = forcedTheme === "dark" ? "github-dark" : "github-light";
|
|
9202
|
+
} else {
|
|
9203
|
+
const isDark = document.documentElement.classList.contains("dark");
|
|
9204
|
+
theme = isDark ? "github-dark" : "github-light";
|
|
9205
|
+
}
|
|
9206
|
+
const cacheKey = getCacheKey2(code, resolvedLang, theme);
|
|
9207
|
+
const cached = highlightCache2.get(cacheKey);
|
|
9208
|
+
if (cached) {
|
|
9209
|
+
if (!cancelled) {
|
|
9210
|
+
setHighlighted(cached);
|
|
9211
|
+
setIsLoading(false);
|
|
9212
|
+
}
|
|
9213
|
+
return;
|
|
9214
|
+
}
|
|
9215
|
+
try {
|
|
9216
|
+
const lang = isValidLanguage2(resolvedLang) ? resolvedLang : "text";
|
|
9217
|
+
const html = await codeToHtml2(code, {
|
|
9218
|
+
lang,
|
|
9219
|
+
theme
|
|
9220
|
+
});
|
|
9221
|
+
if (highlightCache2.size >= CACHE_MAX_SIZE2) {
|
|
9222
|
+
const firstKey = highlightCache2.keys().next().value;
|
|
9223
|
+
if (firstKey) highlightCache2.delete(firstKey);
|
|
9224
|
+
}
|
|
9225
|
+
highlightCache2.set(cacheKey, html);
|
|
9226
|
+
if (!cancelled) {
|
|
9227
|
+
setHighlighted(html);
|
|
9228
|
+
setIsLoading(false);
|
|
9229
|
+
}
|
|
9230
|
+
} catch (error) {
|
|
9231
|
+
console.warn(`Shiki highlighting failed for language "${resolvedLang}":`, error);
|
|
9232
|
+
if (!cancelled) {
|
|
9233
|
+
setHighlighted(null);
|
|
9234
|
+
setIsLoading(false);
|
|
9235
|
+
}
|
|
9236
|
+
}
|
|
9237
|
+
}
|
|
9238
|
+
highlight();
|
|
9239
|
+
return () => {
|
|
9240
|
+
cancelled = true;
|
|
9241
|
+
};
|
|
9242
|
+
}, [code, resolvedLang, forcedTheme, contextShikiTheme]);
|
|
9243
|
+
const handleCopy = React32.useCallback(async () => {
|
|
9244
|
+
try {
|
|
9245
|
+
await navigator.clipboard.writeText(code);
|
|
9246
|
+
setCopied(true);
|
|
9247
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
9248
|
+
} catch (err) {
|
|
9249
|
+
console.error("Failed to copy code:", err);
|
|
9250
|
+
}
|
|
9251
|
+
}, [code]);
|
|
9252
|
+
if (mode === "terminal") {
|
|
9253
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("pre", { className: cn2("font-mono text-sm whitespace-pre-wrap", className), children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("code", { children: code }) });
|
|
9254
|
+
}
|
|
9255
|
+
if (mode === "minimal") {
|
|
9256
|
+
if (isLoading || !highlighted) {
|
|
9257
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("pre", { className: cn2("font-mono text-sm whitespace-pre-wrap", className), children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("code", { children: code }) });
|
|
9258
|
+
}
|
|
9259
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
9260
|
+
"div",
|
|
9261
|
+
{
|
|
9262
|
+
className: cn2("font-mono text-sm [&_pre]:!bg-transparent [&_pre]:!p-0 [&_pre]:whitespace-pre-wrap [&_pre]:break-all [&_code]:!bg-transparent", className),
|
|
9263
|
+
dangerouslySetInnerHTML: { __html: highlighted }
|
|
9264
|
+
}
|
|
9265
|
+
);
|
|
9266
|
+
}
|
|
9267
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: cn2("relative group rounded-[8px] overflow-hidden border bg-muted/30", className), children: [
|
|
9268
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center justify-between px-3 py-1.5 bg-muted/50 border-b text-xs", children: [
|
|
9269
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "text-muted-foreground font-medium uppercase tracking-wide", children: resolvedLang !== "text" ? resolvedLang : "plain text" }),
|
|
9270
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
9271
|
+
"button",
|
|
9272
|
+
{
|
|
9273
|
+
onClick: handleCopy,
|
|
9274
|
+
className: "opacity-0 group-hover:opacity-100 transition-opacity text-muted-foreground hover:text-foreground",
|
|
9275
|
+
"aria-label": "Copy code",
|
|
9276
|
+
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("svg", { className: "w-4 h-4 text-success", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }) : /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" }) })
|
|
9277
|
+
}
|
|
9278
|
+
)
|
|
9279
|
+
] }),
|
|
9280
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "p-3 overflow-x-auto", children: isLoading || !highlighted ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("pre", { className: "font-mono text-sm whitespace-pre-wrap break-all", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("code", { children: code }) }) : /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
9281
|
+
"div",
|
|
9282
|
+
{
|
|
9283
|
+
className: "font-mono text-sm [&_pre]:!bg-transparent [&_pre]:!m-0 [&_pre]:!p-0 [&_pre]:whitespace-pre-wrap [&_pre]:break-all [&_code]:!bg-transparent",
|
|
9284
|
+
dangerouslySetInnerHTML: { __html: highlighted }
|
|
9285
|
+
}
|
|
9286
|
+
) })
|
|
9287
|
+
] });
|
|
9288
|
+
}
|
|
9289
|
+
function InlineCode2({ children, className }) {
|
|
9290
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("code", { className: cn2(
|
|
9291
|
+
"pl-1 pr-1 py-0 rounded bg-foreground/[0.04] font-mono text-[13px]",
|
|
9292
|
+
className
|
|
9293
|
+
), children });
|
|
9294
|
+
}
|
|
9295
|
+
function getDiffLineKind2(line) {
|
|
9296
|
+
if (line.startsWith("@@")) return "hunk";
|
|
9297
|
+
if (line.startsWith("+++") || line.startsWith("---")) return "file";
|
|
9298
|
+
if (line.startsWith("+")) return "add";
|
|
9299
|
+
if (line.startsWith("-")) return "remove";
|
|
9300
|
+
return "context";
|
|
9301
|
+
}
|
|
9302
|
+
function getLineClass2(kind) {
|
|
9303
|
+
switch (kind) {
|
|
9304
|
+
case "add":
|
|
9305
|
+
return "bg-success/[0.08] text-success";
|
|
9306
|
+
case "remove":
|
|
9307
|
+
return "bg-destructive/[0.08] text-destructive";
|
|
9308
|
+
case "hunk":
|
|
9309
|
+
return "bg-accent/[0.08] text-accent";
|
|
9310
|
+
case "file":
|
|
9311
|
+
return "bg-muted/60 text-muted-foreground";
|
|
9312
|
+
default:
|
|
9313
|
+
return "text-foreground/80";
|
|
9314
|
+
}
|
|
9315
|
+
}
|
|
9316
|
+
function MarkdownDiffBlock2({ code, className }) {
|
|
9317
|
+
const lines = React42.useMemo(() => code.split(/\r?\n/), [code]);
|
|
9318
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
9319
|
+
"pre",
|
|
9320
|
+
{
|
|
9321
|
+
className: cn2(
|
|
9322
|
+
"relative rounded-[8px] overflow-x-auto border bg-muted/30 py-2 text-[13px] leading-relaxed",
|
|
9323
|
+
className
|
|
9324
|
+
),
|
|
9325
|
+
style: { fontFamily: '"JetBrains Mono", monospace' },
|
|
9326
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("code", { children: lines.map((line, index) => {
|
|
9327
|
+
const kind = getDiffLineKind2(line);
|
|
9328
|
+
const sign = line[0] === "+" || line[0] === "-" ? line[0] : " ";
|
|
9329
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
|
|
9330
|
+
"span",
|
|
9331
|
+
{
|
|
9332
|
+
className: cn2("block min-w-max px-3 whitespace-pre", getLineClass2(kind)),
|
|
9333
|
+
children: [
|
|
9334
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "mr-3 inline-block w-3 select-none text-center opacity-70", children: sign }),
|
|
9335
|
+
line || " "
|
|
9336
|
+
]
|
|
9337
|
+
},
|
|
9338
|
+
`${index}:${line}`
|
|
9339
|
+
);
|
|
9340
|
+
}) })
|
|
9341
|
+
}
|
|
9342
|
+
);
|
|
9343
|
+
}
|
|
9344
|
+
function MarkdownJsonBlock2({ code, className }) {
|
|
9345
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("pre", { className: cn2("font-mono text-sm whitespace-pre-wrap", className), children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("code", { children: code }) });
|
|
9346
|
+
}
|
|
9347
|
+
function MarkdownMermaidBlock2({ code, className, showExpandButton = true }) {
|
|
9348
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("pre", { className: cn2("font-mono text-sm whitespace-pre-wrap my-2", className), children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("code", { children: code }) });
|
|
9349
|
+
}
|
|
9350
|
+
function MarkdownDatatableBlock2({ code, className }) {
|
|
9351
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("pre", { className: cn2("font-mono text-sm whitespace-pre-wrap", className), children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("code", { children: code }) });
|
|
9352
|
+
}
|
|
9353
|
+
function MarkdownSpreadsheetBlock2({ code, className }) {
|
|
9354
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("pre", { className: cn2("font-mono text-sm whitespace-pre-wrap", className), children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("code", { children: code }) });
|
|
9355
|
+
}
|
|
9356
|
+
function MarkdownHtmlBlock2({ code, className }) {
|
|
9357
|
+
return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("pre", { className: cn2("font-mono text-sm whitespace-pre-wrap", className), children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("code", { children: code }) });
|
|
9358
|
+
}
|
|
9359
|
+
function MarkdownImageBlock2({ code, className }) {
|
|
9360
|
+
return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("pre", { className: cn2("font-mono text-sm whitespace-pre-wrap", className), children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("code", { children: code }) });
|
|
9361
|
+
}
|
|
9362
|
+
function MarkdownLatexBlock2({ code, className }) {
|
|
9363
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("pre", { className: cn2("font-mono text-sm whitespace-pre-wrap", className), children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("code", { children: code }) });
|
|
9364
|
+
}
|
|
9365
|
+
function MarkdownPdfBlock2({ code, className }) {
|
|
9366
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("pre", { className: cn2("font-mono text-sm whitespace-pre-wrap", className), children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("code", { children: code }) });
|
|
9367
|
+
}
|
|
9368
|
+
function preprocessLinks2(content) {
|
|
9369
|
+
return content;
|
|
9370
|
+
}
|
|
9371
|
+
function resolveMarkdownLinkTarget2(target) {
|
|
9372
|
+
if (target.startsWith("/") || target.startsWith("./") || target.startsWith("../")) {
|
|
9373
|
+
return { kind: "file", path: target };
|
|
9374
|
+
}
|
|
9375
|
+
return { kind: "url", url: target };
|
|
9376
|
+
}
|
|
9377
|
+
var remarkCollapsibleSections2 = function() {
|
|
9378
|
+
return (tree) => tree;
|
|
9379
|
+
};
|
|
9380
|
+
var remarkCollapsibleSections_default2 = remarkCollapsibleSections2;
|
|
9381
|
+
function AnimatedCollapsibleContent2({ isOpen, children }) {
|
|
9382
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_react27.AnimatePresence, { initial: false, children: isOpen && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
9383
|
+
import_react27.motion.div,
|
|
9384
|
+
{
|
|
9385
|
+
initial: { height: 0, opacity: 0 },
|
|
9386
|
+
animate: { height: "auto", opacity: 1 },
|
|
9387
|
+
exit: { height: 0, opacity: 0 },
|
|
9388
|
+
transition: { duration: 0.2, ease: "easeInOut" },
|
|
9389
|
+
className: "overflow-hidden",
|
|
9390
|
+
children
|
|
9391
|
+
}
|
|
9392
|
+
) });
|
|
9393
|
+
}
|
|
9394
|
+
function CollapsibleSection2({
|
|
9395
|
+
sectionId,
|
|
9396
|
+
headingLevel,
|
|
9397
|
+
isCollapsed,
|
|
9398
|
+
onToggle,
|
|
9399
|
+
children
|
|
9400
|
+
}) {
|
|
9401
|
+
const childArray = React52.Children.toArray(children);
|
|
9402
|
+
const heading = childArray[0];
|
|
9403
|
+
const content = childArray.slice(1);
|
|
9404
|
+
if (headingLevel > 4) {
|
|
9405
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_jsx_runtime57.Fragment, { children });
|
|
9406
|
+
}
|
|
9407
|
+
const isExpanded = !isCollapsed;
|
|
9408
|
+
const hasContent = content.length > 0;
|
|
9409
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "markdown-collapsible-section", "data-section-id": sectionId, children: [
|
|
9410
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
|
|
9411
|
+
"div",
|
|
9412
|
+
{
|
|
9413
|
+
className: cn2(
|
|
9414
|
+
"relative group",
|
|
9415
|
+
hasContent && "cursor-pointer"
|
|
9416
|
+
),
|
|
9417
|
+
onClick: () => hasContent && onToggle(sectionId),
|
|
9418
|
+
children: [
|
|
9419
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
|
|
9420
|
+
import_react27.motion.div,
|
|
9421
|
+
{
|
|
9422
|
+
initial: false,
|
|
9423
|
+
animate: { rotate: isExpanded ? 90 : 0 },
|
|
9424
|
+
transition: { type: "spring", stiffness: 300, damping: 25 },
|
|
9425
|
+
className: cn2(
|
|
9426
|
+
"absolute -left-4 top-[5px] select-none transition-opacity",
|
|
9427
|
+
!hasContent && "opacity-0",
|
|
9428
|
+
hasContent && isCollapsed && "opacity-100",
|
|
9429
|
+
hasContent && isExpanded && "opacity-0 group-hover:opacity-100"
|
|
9430
|
+
),
|
|
9431
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_lucide_react15.ChevronRight, { className: "h-3 w-3 text-muted-foreground" })
|
|
9432
|
+
}
|
|
9433
|
+
),
|
|
9434
|
+
heading
|
|
9435
|
+
]
|
|
9436
|
+
}
|
|
9437
|
+
),
|
|
9438
|
+
hasContent && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(AnimatedCollapsibleContent2, { isOpen: isExpanded, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "collapsible-section-content", children: content }) })
|
|
9439
|
+
] });
|
|
9440
|
+
}
|
|
9441
|
+
var CollapsibleMarkdownContext2 = (0, import_react28.createContext)(null);
|
|
9442
|
+
function useCollapsibleMarkdown2() {
|
|
9443
|
+
return (0, import_react28.useContext)(CollapsibleMarkdownContext2);
|
|
9444
|
+
}
|
|
9445
|
+
function wrapWithSafeProxy2(components) {
|
|
9446
|
+
return components;
|
|
9447
|
+
}
|
|
9448
|
+
var MARKDOWN_MATH_OPTIONS2 = {
|
|
9449
|
+
singleDollarTextMath: false
|
|
9450
|
+
};
|
|
9451
|
+
function stableHash2(input) {
|
|
9452
|
+
let hash = 2166136261;
|
|
9453
|
+
for (let i = 0; i < input.length; i += 1) {
|
|
9454
|
+
hash ^= input.charCodeAt(i);
|
|
9455
|
+
hash = Math.imul(hash, 16777619);
|
|
9456
|
+
}
|
|
9457
|
+
return (hash >>> 0).toString(36);
|
|
9458
|
+
}
|
|
9459
|
+
function createComponents2(mode, onUrlClick, onFileClick, collapsibleContext, firstMermaidCodeRef, hideFirstMermaidExpand = true) {
|
|
9460
|
+
let blockIndex = 0;
|
|
9461
|
+
const wrapBlock = (blockType, content, child, nodePosition) => {
|
|
9462
|
+
blockIndex += 1;
|
|
9463
|
+
const startLine = nodePosition?.start?.line;
|
|
9464
|
+
const endLine = nodePosition?.end?.line;
|
|
9465
|
+
const path = startLine && endLine ? `line:${startLine}-${endLine}` : `idx:${blockIndex}`;
|
|
9466
|
+
const blockId = `blk-${stableHash2(`${blockType}|${path}|${content.slice(0, 240)}`)}`;
|
|
9467
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
9468
|
+
"div",
|
|
9469
|
+
{
|
|
9470
|
+
"data-ca-block-type": blockType,
|
|
9471
|
+
"data-ca-block-path": path,
|
|
9472
|
+
"data-ca-block-id": blockId,
|
|
9473
|
+
children: child
|
|
9474
|
+
}
|
|
9475
|
+
);
|
|
9476
|
+
};
|
|
9477
|
+
const baseComponents = {
|
|
9478
|
+
// Section wrapper for collapsible headings
|
|
9479
|
+
div: ({ node, children, ...props }) => {
|
|
9480
|
+
const sectionId = props["data-section-id"];
|
|
9481
|
+
const headingLevel = props["data-heading-level"];
|
|
9482
|
+
if (sectionId && headingLevel && collapsibleContext) {
|
|
9483
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
9484
|
+
CollapsibleSection2,
|
|
9485
|
+
{
|
|
9486
|
+
sectionId,
|
|
9487
|
+
headingLevel,
|
|
9488
|
+
isCollapsed: collapsibleContext.collapsedSections.has(sectionId),
|
|
9489
|
+
onToggle: collapsibleContext.toggleSection,
|
|
9490
|
+
children
|
|
9491
|
+
}
|
|
9492
|
+
);
|
|
9493
|
+
}
|
|
9494
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { ...props, children });
|
|
9495
|
+
},
|
|
9496
|
+
// Links: Make clickable with callbacks
|
|
9497
|
+
a: ({ href, children }) => {
|
|
9498
|
+
const handleClick = (e) => {
|
|
9499
|
+
e.preventDefault();
|
|
9500
|
+
const fallbackText = React62.Children.toArray(children).map((child) => typeof child === "string" ? child : "").join("").trim();
|
|
9501
|
+
const target = href?.trim() || fallbackText;
|
|
9502
|
+
if (!target) return;
|
|
9503
|
+
const resolvedTarget = resolveMarkdownLinkTarget2(target);
|
|
9504
|
+
if (resolvedTarget.kind === "file" && onFileClick) {
|
|
9505
|
+
onFileClick(resolvedTarget.path);
|
|
9506
|
+
} else if (resolvedTarget.kind === "url" && onUrlClick) {
|
|
9507
|
+
onUrlClick(resolvedTarget.url);
|
|
9508
|
+
}
|
|
9509
|
+
};
|
|
9510
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
9511
|
+
"a",
|
|
9512
|
+
{
|
|
9513
|
+
href,
|
|
9514
|
+
onClick: handleClick,
|
|
9515
|
+
className: "text-accent hover:underline cursor-pointer",
|
|
9516
|
+
children
|
|
9517
|
+
}
|
|
9518
|
+
);
|
|
9519
|
+
}
|
|
9520
|
+
};
|
|
9521
|
+
if (mode === "terminal") {
|
|
9522
|
+
return {
|
|
9523
|
+
...baseComponents,
|
|
9524
|
+
// No special code handling - just monospace
|
|
9525
|
+
code: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("code", { className: "font-mono", children }),
|
|
9526
|
+
pre: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("pre", { className: "font-mono whitespace-pre-wrap my-2", children }),
|
|
9527
|
+
// Minimal paragraph spacing
|
|
9528
|
+
p: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("p", { className: "my-1", children }),
|
|
9529
|
+
// Simple lists
|
|
9530
|
+
ul: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("ul", { className: "list-disc list-inside my-1", children }),
|
|
9531
|
+
ol: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("ol", { className: "list-decimal list-inside my-1", children }),
|
|
9532
|
+
li: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("li", { className: "my-0.5", children }),
|
|
9533
|
+
// Plain tables
|
|
9534
|
+
table: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("table", { className: "my-2 font-mono text-sm", children }),
|
|
9535
|
+
th: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("th", { className: "text-left pr-4", children }),
|
|
9536
|
+
td: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("td", { className: "pr-4", children })
|
|
9537
|
+
};
|
|
9538
|
+
}
|
|
9539
|
+
if (mode === "minimal") {
|
|
9540
|
+
return {
|
|
9541
|
+
...baseComponents,
|
|
9542
|
+
// Inline code
|
|
9543
|
+
code: ({ className, children, ...props }) => {
|
|
9544
|
+
const match = /language-([\w-]+)/.exec(className || "");
|
|
9545
|
+
const isBlock = "node" in props && props.node?.position?.start.line !== props.node?.position?.end.line;
|
|
9546
|
+
if (match || isBlock) {
|
|
9547
|
+
const code = String(children).replace(/\n$/, "");
|
|
9548
|
+
if (match?.[1] === "diff") {
|
|
9549
|
+
return wrapBlock("code", code, /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(MarkdownDiffBlock2, { code, className: "my-2" }), props.node?.position);
|
|
9550
|
+
}
|
|
9551
|
+
if (match?.[1] === "json") {
|
|
9552
|
+
return wrapBlock("code", code, /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(MarkdownJsonBlock2, { code, className: "my-2" }), props.node?.position);
|
|
9553
|
+
}
|
|
9554
|
+
if (match?.[1] === "datatable") {
|
|
9555
|
+
return wrapBlock("datatable", code, /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(MarkdownDatatableBlock2, { code, className: "my-2" }), props.node?.position);
|
|
9556
|
+
}
|
|
9557
|
+
if (match?.[1] === "spreadsheet") {
|
|
9558
|
+
return wrapBlock("spreadsheet", code, /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(MarkdownSpreadsheetBlock2, { code, className: "my-2" }), props.node?.position);
|
|
9559
|
+
}
|
|
9560
|
+
if (match?.[1] === "html-preview") {
|
|
9561
|
+
return wrapBlock("html-preview", code, /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(MarkdownHtmlBlock2, { code, className: "my-2" }), props.node?.position);
|
|
9562
|
+
}
|
|
9563
|
+
if (match?.[1] === "pdf-preview") {
|
|
9564
|
+
return wrapBlock("pdf-preview", code, /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(MarkdownPdfBlock2, { code, className: "my-2" }), props.node?.position);
|
|
9565
|
+
}
|
|
9566
|
+
if (match?.[1] === "image-preview") {
|
|
9567
|
+
return wrapBlock("image-preview", code, /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(MarkdownImageBlock2, { code, className: "my-2" }), props.node?.position);
|
|
9568
|
+
}
|
|
9569
|
+
if (match?.[1] === "latex" || match?.[1] === "math") {
|
|
9570
|
+
return wrapBlock("latex", code, /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(MarkdownLatexBlock2, { code, className: "my-2" }), props.node?.position);
|
|
9571
|
+
}
|
|
9572
|
+
if (match?.[1] === "mermaid") {
|
|
9573
|
+
const isFirstBlock = hideFirstMermaidExpand && firstMermaidCodeRef?.current != null && code === firstMermaidCodeRef.current;
|
|
9574
|
+
return wrapBlock(
|
|
9575
|
+
"mermaid",
|
|
9576
|
+
code,
|
|
9577
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)(MarkdownMermaidBlock2, { code, className: "my-2", showExpandButton: !isFirstBlock }),
|
|
9578
|
+
props.node?.position
|
|
9579
|
+
);
|
|
9580
|
+
}
|
|
9581
|
+
return wrapBlock("code", code, /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(CodeBlock2, { code, language: match?.[1], mode: "full", className: "my-2" }), props.node?.position);
|
|
9582
|
+
}
|
|
9583
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(InlineCode2, { children });
|
|
9584
|
+
},
|
|
9585
|
+
pre: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_jsx_runtime59.Fragment, { children }),
|
|
9586
|
+
// Comfortable paragraph spacing
|
|
9587
|
+
p: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("p", { className: "my-2 leading-relaxed", children }),
|
|
9588
|
+
// Styled lists - ul uses tighter spacing, ol uses standard for number alignment
|
|
9589
|
+
ul: ({ children, className }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
9590
|
+
"ul",
|
|
9591
|
+
{
|
|
9592
|
+
className: cn2(
|
|
9593
|
+
"my-2 space-y-1 ps-[16px] pe-2 list-disc marker:text-[var(--md-bullets)]",
|
|
9594
|
+
className?.includes("contains-task-list") && "list-none ps-0 marker:content-none"
|
|
9595
|
+
),
|
|
9596
|
+
children
|
|
9597
|
+
}
|
|
9598
|
+
),
|
|
9599
|
+
ol: ({ children, className }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("ol", { className: cn2("my-2 space-y-1 pl-6 list-decimal", className), children }),
|
|
9600
|
+
li: ({ children, className }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("li", { className: cn2(className?.includes("task-list-item") && "list-none"), children }),
|
|
9601
|
+
input: ({ type, checked }) => {
|
|
9602
|
+
if (type === "checkbox") {
|
|
9603
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
9604
|
+
"input",
|
|
9605
|
+
{
|
|
9606
|
+
type: "checkbox",
|
|
9607
|
+
checked,
|
|
9608
|
+
readOnly: true,
|
|
9609
|
+
className: "mr-2 rounded border-muted-foreground align-middle"
|
|
9610
|
+
}
|
|
9611
|
+
);
|
|
9612
|
+
}
|
|
9613
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("input", { type });
|
|
9614
|
+
},
|
|
9615
|
+
// Clean tables
|
|
9616
|
+
table: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "my-3 overflow-x-auto", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("table", { className: "min-w-full text-sm", children }) }),
|
|
9617
|
+
thead: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("thead", { className: "border-b", children }),
|
|
9618
|
+
th: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("th", { className: "text-left py-2 px-3 font-semibold text-muted-foreground", children }),
|
|
9619
|
+
td: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("td", { className: "py-2 px-3 border-b border-border/50", children }),
|
|
9620
|
+
// Headings - H1/H2 same size, differentiated by weight
|
|
9621
|
+
h1: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("h1", { className: "font-sans text-[16px] font-bold mt-5 mb-3", children }),
|
|
9622
|
+
h2: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("h2", { className: "font-sans text-[16px] font-semibold mt-4 mb-3", children }),
|
|
9623
|
+
h3: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("h3", { className: "font-sans text-[15px] font-semibold mt-4 mb-2", children }),
|
|
9624
|
+
// Blockquotes
|
|
9625
|
+
blockquote: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("blockquote", { className: "border-l-2 border-muted-foreground/30 pl-3 my-2 text-muted-foreground italic", children }),
|
|
9626
|
+
// Horizontal rules
|
|
9627
|
+
hr: () => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("hr", { className: "my-4 border-border" }),
|
|
9628
|
+
// Strong/emphasis
|
|
9629
|
+
strong: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("strong", { className: "font-semibold", children }),
|
|
9630
|
+
em: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("em", { className: "italic", children })
|
|
9631
|
+
};
|
|
9632
|
+
}
|
|
9633
|
+
return {
|
|
9634
|
+
...baseComponents,
|
|
9635
|
+
// Full code blocks with copy button
|
|
9636
|
+
code: ({ className, children, ...props }) => {
|
|
9637
|
+
const match = /language-([\w-]+)/.exec(className || "");
|
|
9638
|
+
const isBlock = "node" in props && props.node?.position?.start.line !== props.node?.position?.end.line;
|
|
9639
|
+
if (match || isBlock) {
|
|
9640
|
+
const code = String(children).replace(/\n$/, "");
|
|
9641
|
+
if (match?.[1] === "diff") {
|
|
9642
|
+
return wrapBlock("code", code, /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(MarkdownDiffBlock2, { code, className: "my-2" }), props.node?.position);
|
|
9643
|
+
}
|
|
9644
|
+
if (match?.[1] === "json") {
|
|
9645
|
+
return wrapBlock("code", code, /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(MarkdownJsonBlock2, { code, className: "my-2" }), props.node?.position);
|
|
9646
|
+
}
|
|
9647
|
+
if (match?.[1] === "datatable") {
|
|
9648
|
+
return wrapBlock("datatable", code, /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(MarkdownDatatableBlock2, { code, className: "my-2" }), props.node?.position);
|
|
9649
|
+
}
|
|
9650
|
+
if (match?.[1] === "spreadsheet") {
|
|
9651
|
+
return wrapBlock("spreadsheet", code, /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(MarkdownSpreadsheetBlock2, { code, className: "my-2" }), props.node?.position);
|
|
9652
|
+
}
|
|
9653
|
+
if (match?.[1] === "html-preview") {
|
|
9654
|
+
return wrapBlock("html-preview", code, /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(MarkdownHtmlBlock2, { code, className: "my-2" }), props.node?.position);
|
|
9655
|
+
}
|
|
9656
|
+
if (match?.[1] === "pdf-preview") {
|
|
9657
|
+
return wrapBlock("pdf-preview", code, /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(MarkdownPdfBlock2, { code, className: "my-2" }), props.node?.position);
|
|
9658
|
+
}
|
|
9659
|
+
if (match?.[1] === "image-preview") {
|
|
9660
|
+
return wrapBlock("image-preview", code, /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(MarkdownImageBlock2, { code, className: "my-2" }), props.node?.position);
|
|
9661
|
+
}
|
|
9662
|
+
if (match?.[1] === "latex" || match?.[1] === "math") {
|
|
9663
|
+
return wrapBlock("latex", code, /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(MarkdownLatexBlock2, { code, className: "my-2" }), props.node?.position);
|
|
9664
|
+
}
|
|
9665
|
+
if (match?.[1] === "mermaid") {
|
|
9666
|
+
const isFirstBlock = hideFirstMermaidExpand && firstMermaidCodeRef?.current != null && code === firstMermaidCodeRef.current;
|
|
9667
|
+
return wrapBlock(
|
|
9668
|
+
"mermaid",
|
|
9669
|
+
code,
|
|
9670
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)(MarkdownMermaidBlock2, { code, className: "my-2", showExpandButton: !isFirstBlock }),
|
|
9671
|
+
props.node?.position
|
|
9672
|
+
);
|
|
9673
|
+
}
|
|
9674
|
+
return wrapBlock("code", code, /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(CodeBlock2, { code, language: match?.[1], mode: "full", className: "my-2" }), props.node?.position);
|
|
9675
|
+
}
|
|
9676
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(InlineCode2, { children });
|
|
9677
|
+
},
|
|
9678
|
+
pre: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_jsx_runtime59.Fragment, { children }),
|
|
9679
|
+
// Rich paragraph spacing
|
|
9680
|
+
p: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("p", { className: "my-3 leading-relaxed", children }),
|
|
9681
|
+
// Styled lists - ul uses tighter spacing, ol uses standard for number alignment
|
|
9682
|
+
ul: ({ children, className }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
9683
|
+
"ul",
|
|
9684
|
+
{
|
|
9685
|
+
className: cn2(
|
|
9686
|
+
"my-3 space-y-1.5 ps-[16px] pe-2 list-disc marker:text-[var(--md-bullets)]",
|
|
9687
|
+
className?.includes("contains-task-list") && "list-none ps-0 marker:content-none"
|
|
9688
|
+
),
|
|
9689
|
+
children
|
|
9690
|
+
}
|
|
9691
|
+
),
|
|
9692
|
+
ol: ({ children, className }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("ol", { className: cn2("my-3 space-y-1.5 pl-6 list-decimal", className), children }),
|
|
9693
|
+
li: ({ children, className }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("li", { className: cn2("leading-relaxed", className?.includes("task-list-item") && "list-none"), children }),
|
|
9694
|
+
// Beautiful tables
|
|
9695
|
+
table: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "my-4 overflow-x-auto rounded-md border", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("table", { className: "min-w-full divide-y divide-border", children }) }),
|
|
9696
|
+
thead: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("thead", { className: "bg-muted/50", children }),
|
|
9697
|
+
tbody: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("tbody", { className: "divide-y divide-border", children }),
|
|
9698
|
+
th: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("th", { className: "text-left py-3 px-4 font-semibold text-sm", children }),
|
|
9699
|
+
td: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("td", { className: "py-3 px-4 text-sm", children }),
|
|
9700
|
+
tr: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("tr", { className: "hover:bg-muted/30 transition-colors", children }),
|
|
9701
|
+
// Rich headings - H1/H2 same size, differentiated by weight
|
|
9702
|
+
h1: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("h1", { className: "font-sans text-[16px] font-bold mt-7 mb-4", children }),
|
|
9703
|
+
h2: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("h2", { className: "font-sans text-[16px] font-semibold mt-6 mb-3", children }),
|
|
9704
|
+
h3: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("h3", { className: "font-sans text-[15px] font-semibold mt-5 mb-3", children }),
|
|
9705
|
+
h4: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("h4", { className: "text-[14px] font-semibold mt-3 mb-1", children }),
|
|
9706
|
+
// Styled blockquotes
|
|
9707
|
+
blockquote: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("blockquote", { className: "border-l-4 border-foreground/30 bg-muted/30 pl-4 pr-3 py-2 my-3 rounded-r-md", children }),
|
|
9708
|
+
// Task lists (GFM)
|
|
9709
|
+
input: ({ type, checked }) => {
|
|
9710
|
+
if (type === "checkbox") {
|
|
9711
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
9712
|
+
"input",
|
|
9713
|
+
{
|
|
9714
|
+
type: "checkbox",
|
|
9715
|
+
checked,
|
|
9716
|
+
readOnly: true,
|
|
9717
|
+
className: "mr-2 rounded border-muted-foreground"
|
|
9718
|
+
}
|
|
9719
|
+
);
|
|
9720
|
+
}
|
|
9721
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("input", { type });
|
|
9722
|
+
},
|
|
9723
|
+
// Horizontal rules
|
|
9724
|
+
hr: () => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("hr", { className: "my-6 border-border" }),
|
|
9725
|
+
// Strong/emphasis
|
|
9726
|
+
strong: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("strong", { className: "font-semibold", children }),
|
|
9727
|
+
em: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("em", { className: "italic", children }),
|
|
9728
|
+
del: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("del", { className: "line-through text-muted-foreground", children }),
|
|
9729
|
+
// Handle unknown <markdown> tags that may come through rehype-raw
|
|
9730
|
+
// Type assertion needed because 'markdown' is not a standard HTML element
|
|
9731
|
+
markdown: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(import_jsx_runtime59.Fragment, { children })
|
|
9732
|
+
};
|
|
9733
|
+
}
|
|
9734
|
+
function Markdown2({
|
|
9735
|
+
children,
|
|
9736
|
+
mode = "minimal",
|
|
9737
|
+
className,
|
|
9738
|
+
id,
|
|
9739
|
+
onUrlClick,
|
|
9740
|
+
onFileClick,
|
|
9741
|
+
collapsible = false,
|
|
9742
|
+
hideFirstMermaidExpand = true
|
|
9743
|
+
}) {
|
|
9744
|
+
const collapsibleContext = useCollapsibleMarkdown2();
|
|
9745
|
+
const firstMermaidCodeRef = React62.useRef(null);
|
|
9746
|
+
const trimmed = children.trimStart();
|
|
9747
|
+
if (trimmed.startsWith("```mermaid")) {
|
|
9748
|
+
const m = trimmed.match(/^```mermaid\n([\s\S]*?)```/);
|
|
9749
|
+
firstMermaidCodeRef.current = m?.[1] ? m[1].replace(/\n$/, "") : null;
|
|
9750
|
+
} else {
|
|
9751
|
+
firstMermaidCodeRef.current = null;
|
|
9752
|
+
}
|
|
9753
|
+
const components = React62.useMemo(
|
|
9754
|
+
() => wrapWithSafeProxy2(createComponents2(mode, onUrlClick, onFileClick, collapsible ? collapsibleContext : null, firstMermaidCodeRef, hideFirstMermaidExpand)),
|
|
9755
|
+
[mode, onUrlClick, onFileClick, collapsible, collapsibleContext, hideFirstMermaidExpand]
|
|
9756
|
+
);
|
|
9757
|
+
const processedContent = React62.useMemo(
|
|
9758
|
+
() => preprocessLinks2(children),
|
|
9759
|
+
[children]
|
|
9760
|
+
);
|
|
9761
|
+
const remarkPlugins = React62.useMemo(
|
|
9762
|
+
() => {
|
|
9763
|
+
const mathPlugin = [
|
|
9764
|
+
import_remark_math2.default,
|
|
9765
|
+
MARKDOWN_MATH_OPTIONS2
|
|
9766
|
+
];
|
|
9767
|
+
return collapsible ? [import_remark_gfm2.default, mathPlugin, remarkCollapsibleSections_default2] : [import_remark_gfm2.default, mathPlugin];
|
|
9768
|
+
},
|
|
9769
|
+
[collapsible]
|
|
9770
|
+
);
|
|
9771
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: cn2("markdown-content", className), children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
9772
|
+
import_react_markdown2.default,
|
|
9773
|
+
{
|
|
9774
|
+
remarkPlugins,
|
|
9775
|
+
rehypePlugins: [import_rehype_katex2.default, import_rehype_raw2.default],
|
|
9776
|
+
components,
|
|
9777
|
+
children: processedContent
|
|
9778
|
+
}
|
|
9779
|
+
) });
|
|
9780
|
+
}
|
|
9781
|
+
var MemoizedMarkdown2 = React62.memo(
|
|
9782
|
+
Markdown2,
|
|
9783
|
+
(prevProps, nextProps) => {
|
|
9784
|
+
if (prevProps.id && nextProps.id) {
|
|
9785
|
+
return prevProps.id === nextProps.id && prevProps.children === nextProps.children && prevProps.mode === nextProps.mode;
|
|
9786
|
+
}
|
|
9787
|
+
return prevProps.children === nextProps.children && prevProps.mode === nextProps.mode;
|
|
9788
|
+
}
|
|
9789
|
+
);
|
|
9790
|
+
MemoizedMarkdown2.displayName = "MemoizedMarkdown";
|
|
9791
|
+
function AnnotationIslandMenu2(_props) {
|
|
9792
|
+
return null;
|
|
9793
|
+
}
|
|
9794
|
+
function buildAnnotationChipEntryTransition2(_snapshot = null) {
|
|
9795
|
+
return {};
|
|
9796
|
+
}
|
|
9797
|
+
function buildSelectionEntryTransition2(_primary = null, _secondary) {
|
|
9798
|
+
return {};
|
|
9799
|
+
}
|
|
9800
|
+
var ANNOTATION_PREFIX_SUFFIX_WINDOW2 = 40;
|
|
9801
|
+
var SELECTION_POINTER_MAX_AGE_MS2 = 5e3;
|
|
9802
|
+
function clamp2(value, min, max) {
|
|
9803
|
+
return Math.max(min, Math.min(max, value));
|
|
9804
|
+
}
|
|
9805
|
+
function hasExistingTextRangeAnnotation2(annotations, start, end) {
|
|
9806
|
+
return annotations.some(
|
|
9807
|
+
(a) => a.target.selectors.some(
|
|
9808
|
+
(s) => s.type === "text-position" && s.start === start && s.end === end
|
|
9809
|
+
)
|
|
9810
|
+
);
|
|
9811
|
+
}
|
|
9812
|
+
function createSelectionPreviewAnnotation2(messageId, sessionIdOrSelection, startOrSessionId, end, exact) {
|
|
9813
|
+
if (typeof sessionIdOrSelection === "object") {
|
|
9814
|
+
const sel = sessionIdOrSelection;
|
|
9815
|
+
const sid = startOrSessionId ?? "";
|
|
9816
|
+
return {
|
|
9817
|
+
id: `preview-${Date.now()}`,
|
|
9818
|
+
schemaVersion: 1,
|
|
9819
|
+
createdAt: Date.now(),
|
|
9820
|
+
body: [{ type: "highlight" }],
|
|
9821
|
+
target: {
|
|
9822
|
+
source: { sessionId: sid, messageId },
|
|
9823
|
+
selectors: [
|
|
9824
|
+
{ type: "text-quote", exact: sel.exact ?? "" },
|
|
9825
|
+
{ type: "text-position", start: sel.start, end: sel.end }
|
|
9826
|
+
]
|
|
9827
|
+
}
|
|
9828
|
+
};
|
|
9829
|
+
}
|
|
9830
|
+
return {
|
|
9831
|
+
id: `preview-${Date.now()}`,
|
|
9832
|
+
schemaVersion: 1,
|
|
9833
|
+
createdAt: Date.now(),
|
|
9834
|
+
body: [{ type: "highlight" }],
|
|
9835
|
+
target: {
|
|
9836
|
+
source: { sessionId: sessionIdOrSelection, messageId },
|
|
9837
|
+
selectors: [
|
|
9838
|
+
{ type: "text-quote", exact: exact ?? "" },
|
|
9839
|
+
{ type: "text-position", start: startOrSessionId, end: end ?? 0 }
|
|
9840
|
+
]
|
|
9841
|
+
}
|
|
9842
|
+
};
|
|
9843
|
+
}
|
|
9844
|
+
function createTextSelectionAnnotation2(messageId, sessionId, start, end, exact, note) {
|
|
9845
|
+
return {
|
|
9846
|
+
id: `sel-${Date.now()}`,
|
|
9847
|
+
schemaVersion: 1,
|
|
9848
|
+
createdAt: Date.now(),
|
|
9849
|
+
body: [{ type: "note", text: note }],
|
|
9850
|
+
target: {
|
|
9851
|
+
source: { sessionId, messageId },
|
|
9852
|
+
selectors: [
|
|
9853
|
+
{ type: "text-quote", exact },
|
|
9854
|
+
{ type: "text-position", start, end }
|
|
9855
|
+
]
|
|
9856
|
+
}
|
|
9857
|
+
};
|
|
9858
|
+
}
|
|
9859
|
+
function getCanonicalText2(_content) {
|
|
9860
|
+
if (typeof _content === "string") return _content;
|
|
9861
|
+
return "";
|
|
9862
|
+
}
|
|
9863
|
+
function resolveNodeOffset2(_root, _node, _offset) {
|
|
9864
|
+
return _offset ?? null;
|
|
9865
|
+
}
|
|
9866
|
+
function getAnnotationRectVisual2(_rect) {
|
|
9867
|
+
return { className: "absolute pointer-events-none", style: {} };
|
|
9868
|
+
}
|
|
9869
|
+
function getAnnotationChipVisual2(_chip) {
|
|
9870
|
+
return { className: "absolute pointer-events-auto", style: {} };
|
|
9871
|
+
}
|
|
9872
|
+
function clearBlockAnnotationMarkers2(_container) {
|
|
9873
|
+
}
|
|
9874
|
+
function applyBlockAnnotationMarker2(_container, _annotationOrId, _blockId) {
|
|
9875
|
+
}
|
|
9876
|
+
function canAnnotateMessage2(_opts) {
|
|
9877
|
+
if (typeof _opts === "string") return true;
|
|
9878
|
+
return _opts.hasAddAnnotationHandler && _opts.hasMessageId && !_opts.isStreaming;
|
|
9879
|
+
}
|
|
9880
|
+
function shouldRenderAnnotationIslandInPortal2(_context) {
|
|
9881
|
+
return true;
|
|
9882
|
+
}
|
|
9883
|
+
function clearDomSelection2() {
|
|
9884
|
+
if (typeof window !== "undefined" && window.getSelection) {
|
|
9885
|
+
const selection = window.getSelection();
|
|
9886
|
+
if (selection) {
|
|
9887
|
+
selection.removeAllRanges();
|
|
9888
|
+
}
|
|
9889
|
+
}
|
|
9890
|
+
}
|
|
9891
|
+
function getAnnotationChipInteraction2(_annotation) {
|
|
9892
|
+
return { clickable: true, openMode: "view" };
|
|
9893
|
+
}
|
|
9894
|
+
function shouldIgnoreSelectionMouseUpTarget2(_target) {
|
|
9895
|
+
return false;
|
|
9896
|
+
}
|
|
9897
|
+
function computeAnnotationOverlayGeometry2(_containerOrOpts, _annotations, _content) {
|
|
9898
|
+
return { rects: [], chips: [], unresolved: [] };
|
|
9899
|
+
}
|
|
9900
|
+
function AnnotationOverlayLayer2({
|
|
9901
|
+
rects,
|
|
9902
|
+
chips,
|
|
9903
|
+
annotations,
|
|
9904
|
+
getTooltipText,
|
|
9905
|
+
allowChipOpen = true,
|
|
9906
|
+
onChipOpen
|
|
9907
|
+
}) {
|
|
9908
|
+
const annotationMap = React72.useMemo(() => {
|
|
9909
|
+
return new Map((annotations ?? []).map((annotation) => [annotation.id, annotation]));
|
|
9910
|
+
}, [annotations]);
|
|
9911
|
+
if (rects.length === 0 && chips.length === 0) {
|
|
9912
|
+
return null;
|
|
9913
|
+
}
|
|
9914
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { "data-ca-annotation-overlay": true, className: "pointer-events-none absolute inset-0 z-[2]", children: [
|
|
9915
|
+
rects.map((rect, idx) => {
|
|
9916
|
+
const rectVisual = getAnnotationRectVisual2(rect);
|
|
9917
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
9918
|
+
"div",
|
|
9919
|
+
{
|
|
9920
|
+
className: rectVisual.className,
|
|
9921
|
+
style: {
|
|
9922
|
+
left: rect.left - 4,
|
|
9923
|
+
top: rect.top - 1,
|
|
9924
|
+
width: rect.width + 8,
|
|
9925
|
+
height: rect.height + 2,
|
|
9926
|
+
backgroundColor: rect.color,
|
|
9927
|
+
borderRadius: "4px",
|
|
9928
|
+
...rectVisual.style
|
|
9929
|
+
}
|
|
9930
|
+
},
|
|
9931
|
+
`rect-${rect.id}-${idx}`
|
|
9932
|
+
);
|
|
9933
|
+
}),
|
|
9934
|
+
chips.map((chip) => {
|
|
9935
|
+
const chipVisual = getAnnotationChipVisual2(chip);
|
|
9936
|
+
const chipAnnotation = annotationMap.get(chip.id) ?? null;
|
|
9937
|
+
const interaction = getAnnotationChipInteraction2(chipAnnotation);
|
|
9938
|
+
const tooltipText = chipAnnotation && getTooltipText ? getTooltipText(chipAnnotation, chip.index) : "";
|
|
9939
|
+
const canOpenChip = allowChipOpen && interaction.clickable;
|
|
9940
|
+
const chipButton = /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
9941
|
+
"button",
|
|
9942
|
+
{
|
|
9943
|
+
type: "button",
|
|
9944
|
+
"data-ca-annotation-id": chip.id,
|
|
9945
|
+
"data-ca-annotation-index": String(chip.index),
|
|
9946
|
+
"aria-disabled": !canOpenChip,
|
|
9947
|
+
onClick: canOpenChip ? (event) => {
|
|
9948
|
+
const rect = event.currentTarget.getBoundingClientRect();
|
|
9949
|
+
onChipOpen({
|
|
9950
|
+
annotationId: chip.id,
|
|
9951
|
+
index: chip.index,
|
|
9952
|
+
anchorX: rect.left + rect.width / 2,
|
|
9953
|
+
anchorY: rect.top - 8,
|
|
9954
|
+
mode: interaction.openMode
|
|
9955
|
+
});
|
|
9956
|
+
} : void 0,
|
|
9957
|
+
className: cn2(chipVisual.className, !canOpenChip && "cursor-default"),
|
|
9958
|
+
style: {
|
|
9959
|
+
left: chip.left,
|
|
9960
|
+
top: chip.top,
|
|
9961
|
+
transform: "translate(-2px, -8px)",
|
|
9962
|
+
minWidth: "16px",
|
|
9963
|
+
height: "15px",
|
|
9964
|
+
padding: "0 3px",
|
|
9965
|
+
borderRadius: "4px",
|
|
9966
|
+
fontSize: "10px",
|
|
9967
|
+
fontWeight: "600",
|
|
9968
|
+
lineHeight: "15px",
|
|
9969
|
+
textAlign: "center",
|
|
9970
|
+
userSelect: "none",
|
|
9971
|
+
position: "absolute",
|
|
9972
|
+
...chipVisual.style
|
|
9973
|
+
},
|
|
9974
|
+
children: chip.sentFollowUp ? "i" : chip.index
|
|
9975
|
+
}
|
|
9976
|
+
);
|
|
9977
|
+
if (tooltipText) {
|
|
9978
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(Tooltip2, { children: [
|
|
9979
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(TooltipTrigger2, { asChild: true, children: chipButton }),
|
|
9980
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(TooltipContent2, { side: "top", className: "max-w-[280px] whitespace-pre-wrap text-xs", children: tooltipText })
|
|
9981
|
+
] }, `chip-${chip.id}`);
|
|
9982
|
+
}
|
|
9983
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(React72.Fragment, { children: chipButton }, `chip-${chip.id}`);
|
|
9984
|
+
})
|
|
9985
|
+
] });
|
|
9986
|
+
}
|
|
9987
|
+
function getAnnotationInteractionAnchor2(_annotation) {
|
|
9988
|
+
return { x: 0, y: 0 };
|
|
9989
|
+
}
|
|
9990
|
+
function getAnnotationInteractionSourceKey2(_annotation, _scope) {
|
|
9991
|
+
return "";
|
|
9992
|
+
}
|
|
9993
|
+
function hasAnnotationInteraction2(_annotation) {
|
|
9994
|
+
return false;
|
|
9995
|
+
}
|
|
9996
|
+
var initialAnnotationInteractionState2 = {
|
|
9997
|
+
isOpen: false,
|
|
9998
|
+
mode: "view",
|
|
9999
|
+
activeDetail: null,
|
|
10000
|
+
draft: "",
|
|
10001
|
+
pendingSelection: null,
|
|
10002
|
+
selectionMenuView: null,
|
|
10003
|
+
followUpDraft: "",
|
|
10004
|
+
followUpMode: "none",
|
|
10005
|
+
activeAnnotationDetail: null
|
|
10006
|
+
};
|
|
10007
|
+
var annotationInteractionActions2 = {
|
|
10008
|
+
setDraft: (_draft) => ({ type: "setDraft", draft: _draft }),
|
|
10009
|
+
openFromSelection: (_selection) => ({ type: "openFromSelection", selection: _selection }),
|
|
10010
|
+
openFollowUpFromSelection: () => ({ type: "openFollowUpFromSelection" }),
|
|
10011
|
+
openFromAnnotation: (_detail, _noteText, _mode) => ({ type: "openFromAnnotation", detail: _detail, noteText: _noteText, mode: _mode }),
|
|
10012
|
+
requestEdit: () => ({ type: "requestEdit" }),
|
|
10013
|
+
cancelFollowUp: () => ({ type: "cancelFollowUp" }),
|
|
10014
|
+
closeAll: () => ({ type: "closeAll" }),
|
|
10015
|
+
submitSuccess: () => ({ type: "submitSuccess" }),
|
|
10016
|
+
deleteSuccess: () => ({ type: "deleteSuccess" })
|
|
10017
|
+
};
|
|
10018
|
+
function annotationInteractionReducer2(state, _action) {
|
|
10019
|
+
return state;
|
|
10020
|
+
}
|
|
10021
|
+
function useAnnotationInteractionController2() {
|
|
10022
|
+
const [state, dispatch] = React82.useReducer(annotationInteractionReducer2, initialAnnotationInteractionState2);
|
|
10023
|
+
const lastHandledOpenRequestNonceRef = React82.useRef(null);
|
|
10024
|
+
const setDraft = React82.useCallback((draft) => {
|
|
10025
|
+
dispatch(annotationInteractionActions2.setDraft(draft));
|
|
10026
|
+
}, []);
|
|
10027
|
+
const openFromSelection = React82.useCallback((selection) => {
|
|
10028
|
+
dispatch(annotationInteractionActions2.openFromSelection(selection));
|
|
10029
|
+
}, []);
|
|
10030
|
+
const openFollowUpFromSelection = React82.useCallback(() => {
|
|
10031
|
+
dispatch(annotationInteractionActions2.openFollowUpFromSelection());
|
|
10032
|
+
}, []);
|
|
10033
|
+
const openFromAnnotation = React82.useCallback((detail, noteText, mode) => {
|
|
10034
|
+
dispatch(annotationInteractionActions2.openFromAnnotation(detail, noteText, mode));
|
|
10035
|
+
}, []);
|
|
10036
|
+
const requestEdit = React82.useCallback(() => {
|
|
10037
|
+
dispatch(annotationInteractionActions2.requestEdit());
|
|
10038
|
+
}, []);
|
|
10039
|
+
const cancelFollowUp = React82.useCallback(() => {
|
|
10040
|
+
const hadPendingSelection = Boolean(state.pendingSelection);
|
|
10041
|
+
const pendingSelection = state.pendingSelection;
|
|
10042
|
+
dispatch(annotationInteractionActions2.cancelFollowUp());
|
|
10043
|
+
return { hadPendingSelection, pendingSelection };
|
|
10044
|
+
}, [state.pendingSelection]);
|
|
10045
|
+
const closeAll = React82.useCallback(() => {
|
|
10046
|
+
dispatch(annotationInteractionActions2.closeAll());
|
|
10047
|
+
}, []);
|
|
10048
|
+
const markSubmitSuccess = React82.useCallback(() => {
|
|
10049
|
+
dispatch(annotationInteractionActions2.submitSuccess());
|
|
10050
|
+
}, []);
|
|
10051
|
+
const markDeleteSuccess = React82.useCallback(() => {
|
|
10052
|
+
dispatch(annotationInteractionActions2.deleteSuccess());
|
|
10053
|
+
}, []);
|
|
10054
|
+
const consumeExternalOpenRequest = React82.useCallback((request, params) => {
|
|
10055
|
+
if (!request || !params.messageId || !params.annotations?.length) return false;
|
|
10056
|
+
if (request.messageId !== params.messageId) return false;
|
|
10057
|
+
if (lastHandledOpenRequestNonceRef.current === request.nonce) return false;
|
|
10058
|
+
const annotationIndex = params.annotations.findIndex((item) => item.id === request.annotationId);
|
|
10059
|
+
if (annotationIndex < 0) return false;
|
|
10060
|
+
lastHandledOpenRequestNonceRef.current = request.nonce;
|
|
10061
|
+
const annotation = params.annotations[annotationIndex];
|
|
10062
|
+
if (!annotation) return false;
|
|
10063
|
+
const noteText = params.getNoteText(annotation);
|
|
10064
|
+
const detail = {
|
|
10065
|
+
annotationId: request.annotationId,
|
|
10066
|
+
index: annotationIndex + 1,
|
|
10067
|
+
anchorX: request.anchorX ?? params.fallbackAnchor.x,
|
|
10068
|
+
anchorY: request.anchorY ?? params.fallbackAnchor.y
|
|
10069
|
+
};
|
|
10070
|
+
dispatch(annotationInteractionActions2.openFromAnnotation(detail, noteText, request.mode));
|
|
10071
|
+
return true;
|
|
10072
|
+
}, []);
|
|
10073
|
+
return {
|
|
10074
|
+
state,
|
|
10075
|
+
setDraft,
|
|
10076
|
+
openFromSelection,
|
|
10077
|
+
openFollowUpFromSelection,
|
|
10078
|
+
openFromAnnotation,
|
|
10079
|
+
requestEdit,
|
|
10080
|
+
cancelFollowUp,
|
|
10081
|
+
closeAll,
|
|
10082
|
+
markSubmitSuccess,
|
|
10083
|
+
markDeleteSuccess,
|
|
10084
|
+
consumeExternalOpenRequest
|
|
10085
|
+
};
|
|
10086
|
+
}
|
|
10087
|
+
function useAnnotationIslandPresentation2(_opts) {
|
|
10088
|
+
return {
|
|
10089
|
+
islandRef: React92.createRef(),
|
|
10090
|
+
islandPosition: { x: 0, y: 0 },
|
|
10091
|
+
islandStyle: {},
|
|
10092
|
+
shouldRenderInPortal: true,
|
|
10093
|
+
renderAnchor: null,
|
|
10094
|
+
renderSourceKey: "",
|
|
10095
|
+
isVisible: false,
|
|
10096
|
+
openedAtRef: React92.createRef(),
|
|
10097
|
+
handleExitComplete: () => {
|
|
10098
|
+
},
|
|
10099
|
+
resetPresentation: () => {
|
|
10100
|
+
}
|
|
10101
|
+
};
|
|
10102
|
+
}
|
|
10103
|
+
function useAnnotationIslandEvents2(_opts) {
|
|
10104
|
+
return {
|
|
10105
|
+
handleAnnotationSubmit: () => {
|
|
10106
|
+
},
|
|
10107
|
+
handleAnnotationDelete: () => {
|
|
10108
|
+
},
|
|
10109
|
+
handleAnnotationEdit: () => {
|
|
10110
|
+
},
|
|
10111
|
+
handleAnnotationCancel: () => {
|
|
10112
|
+
}
|
|
10113
|
+
};
|
|
10114
|
+
}
|
|
10115
|
+
function useAnnotationCancelRestore2(_opts) {
|
|
10116
|
+
return () => {
|
|
10117
|
+
};
|
|
10118
|
+
}
|
|
10119
|
+
function DocumentFormattedMarkdownOverlay2(_props) {
|
|
10120
|
+
return null;
|
|
10121
|
+
}
|
|
10122
|
+
function AcceptPlanDropdown2({
|
|
10123
|
+
onAccept,
|
|
10124
|
+
onAcceptWithCompact,
|
|
10125
|
+
acceptLabel,
|
|
10126
|
+
acceptOptionLabel,
|
|
10127
|
+
className
|
|
10128
|
+
}) {
|
|
10129
|
+
const { t: t22 } = (0, import_react_i18next8.useTranslation)();
|
|
10130
|
+
const effectiveAcceptLabel = acceptLabel ?? t22("plan.acceptPlan");
|
|
10131
|
+
const effectiveAcceptOptionLabel = acceptOptionLabel ?? t22("plan.accept");
|
|
10132
|
+
const [isOpen, setIsOpen] = (0, import_react29.useState)(false);
|
|
10133
|
+
const [position, setPosition] = (0, import_react29.useState)(null);
|
|
10134
|
+
const triggerRef = (0, import_react29.useRef)(null);
|
|
10135
|
+
const menuRef = (0, import_react29.useRef)(null);
|
|
10136
|
+
const updatePosition = (0, import_react29.useCallback)(() => {
|
|
10137
|
+
if (!triggerRef.current) return;
|
|
10138
|
+
const rect = triggerRef.current.getBoundingClientRect();
|
|
10139
|
+
const menuWidth = 280;
|
|
10140
|
+
const menuHeight = 120;
|
|
10141
|
+
const gap = 4;
|
|
10142
|
+
const spaceBelow = window.innerHeight - rect.bottom;
|
|
10143
|
+
const top = spaceBelow >= menuHeight + gap ? rect.bottom + gap : rect.top - menuHeight - gap;
|
|
10144
|
+
let left = rect.right - menuWidth;
|
|
10145
|
+
if (left < 8) left = 8;
|
|
10146
|
+
if (left + menuWidth > window.innerWidth - 8) {
|
|
10147
|
+
left = window.innerWidth - menuWidth - 8;
|
|
10148
|
+
}
|
|
10149
|
+
setPosition({ top, left });
|
|
10150
|
+
}, []);
|
|
10151
|
+
const handleToggle = (0, import_react29.useCallback)((e) => {
|
|
10152
|
+
e.stopPropagation();
|
|
10153
|
+
if (!isOpen) {
|
|
10154
|
+
if (triggerRef.current) {
|
|
10155
|
+
const rect = triggerRef.current.getBoundingClientRect();
|
|
10156
|
+
const menuWidth = 280;
|
|
10157
|
+
const menuHeight = 120;
|
|
10158
|
+
const gap = 4;
|
|
10159
|
+
const spaceBelow = window.innerHeight - rect.bottom;
|
|
10160
|
+
const top = spaceBelow >= menuHeight + gap ? rect.bottom + gap : rect.top - menuHeight - gap;
|
|
10161
|
+
let left = rect.right - menuWidth;
|
|
10162
|
+
if (left < 8) left = 8;
|
|
10163
|
+
if (left + menuWidth > window.innerWidth - 8) {
|
|
10164
|
+
left = window.innerWidth - menuWidth - 8;
|
|
10165
|
+
}
|
|
10166
|
+
setPosition({ top, left });
|
|
10167
|
+
}
|
|
10168
|
+
}
|
|
10169
|
+
setIsOpen((prev) => !prev);
|
|
10170
|
+
}, [isOpen]);
|
|
10171
|
+
const handleClose = (0, import_react29.useCallback)(() => {
|
|
10172
|
+
setIsOpen(false);
|
|
10173
|
+
}, []);
|
|
10174
|
+
const handleSelectAccept = (0, import_react29.useCallback)((e) => {
|
|
10175
|
+
e.stopPropagation();
|
|
10176
|
+
handleClose();
|
|
10177
|
+
onAccept();
|
|
10178
|
+
}, [handleClose, onAccept]);
|
|
10179
|
+
const handleSelectCompact = (0, import_react29.useCallback)((e) => {
|
|
10180
|
+
e.stopPropagation();
|
|
10181
|
+
handleClose();
|
|
10182
|
+
onAcceptWithCompact();
|
|
10183
|
+
}, [handleClose, onAcceptWithCompact]);
|
|
10184
|
+
(0, import_react29.useEffect)(() => {
|
|
10185
|
+
if (isOpen) {
|
|
10186
|
+
updatePosition();
|
|
10187
|
+
}
|
|
10188
|
+
}, [isOpen, updatePosition]);
|
|
10189
|
+
(0, import_react29.useEffect)(() => {
|
|
10190
|
+
if (!isOpen) return;
|
|
10191
|
+
const handleClickOutside = (e) => {
|
|
10192
|
+
if (menuRef.current && !menuRef.current.contains(e.target) && triggerRef.current && !triggerRef.current.contains(e.target)) {
|
|
10193
|
+
handleClose();
|
|
10194
|
+
}
|
|
10195
|
+
};
|
|
10196
|
+
const handleEscape = (e) => {
|
|
10197
|
+
if (e.key === "Escape") {
|
|
10198
|
+
handleClose();
|
|
10199
|
+
}
|
|
10200
|
+
};
|
|
10201
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
10202
|
+
document.addEventListener("keydown", handleEscape);
|
|
10203
|
+
return () => {
|
|
10204
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
10205
|
+
document.removeEventListener("keydown", handleEscape);
|
|
10206
|
+
};
|
|
10207
|
+
}, [isOpen, handleClose]);
|
|
10208
|
+
return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_jsx_runtime61.Fragment, { children: [
|
|
10209
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
10210
|
+
"div",
|
|
10211
|
+
{
|
|
10212
|
+
ref: triggerRef,
|
|
10213
|
+
onClick: handleToggle,
|
|
10214
|
+
className: "inline-flex",
|
|
10215
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(
|
|
10216
|
+
"button",
|
|
10217
|
+
{
|
|
10218
|
+
type: "button",
|
|
10219
|
+
className: cn2(
|
|
10220
|
+
"h-[28px] pl-2.5 pr-2 text-xs font-medium rounded-[6px] flex items-center gap-1.5 transition-all",
|
|
10221
|
+
"bg-success/5 text-success hover:bg-success/10 shadow-tinted",
|
|
10222
|
+
className
|
|
10223
|
+
),
|
|
10224
|
+
style: { "--shadow-color": "34, 136, 82" },
|
|
10225
|
+
children: [
|
|
10226
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("svg", { className: "h-3.5 w-3.5", viewBox: "0 0 25 24", fill: "currentColor", children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("path", { fillRule: "nonzero", d: "M13.7207031,22.6523438 C13.264974,22.6523438 12.9361979,22.4895833 12.734375,22.1640625 C12.5325521,21.8385417 12.360026,21.4316406 12.2167969,20.9433594 L10.6640625,15.7871094 C10.5729167,15.4615885 10.5403646,15.1995443 10.5664062,15.0009766 C10.5924479,14.8024089 10.6998698,14.6022135 10.8886719,14.4003906 L20.859375,3.6484375 C20.9179688,3.58984375 20.9472656,3.52473958 20.9472656,3.453125 C20.9472656,3.38151042 20.921224,3.32291667 20.8691406,3.27734375 C20.8170573,3.23177083 20.7568359,3.20735677 20.6884766,3.20410156 C20.6201172,3.20084635 20.5566406,3.22851562 20.4980469,3.28710938 L9.78515625,13.296875 C9.5703125,13.4921875 9.36197917,13.601237 9.16015625,13.6240234 C8.95833333,13.6468099 8.70117188,13.609375 8.38867188,13.5117188 L3.11523438,11.9101562 C2.64648438,11.7669271 2.25911458,11.5960286 1.953125,11.3974609 C1.64713542,11.1988932 1.49414062,10.875 1.49414062,10.4257812 C1.49414062,10.0742188 1.63411458,9.77148438 1.9140625,9.51757812 C2.19401042,9.26367188 2.5390625,9.05859375 2.94921875,8.90234375 L19.7460938,2.46679688 C19.9739583,2.38216146 20.1871745,2.31542969 20.3857422,2.26660156 C20.5843099,2.21777344 20.764974,2.19335938 20.9277344,2.19335938 C21.2467448,2.19335938 21.4973958,2.28450521 21.6796875,2.46679688 C21.8619792,2.64908854 21.953125,2.89973958 21.953125,3.21875 C21.953125,3.38802083 21.9287109,3.5703125 21.8798828,3.765625 C21.8310547,3.9609375 21.7643229,4.17252604 21.6796875,4.40039062 L15.2832031,21.109375 C15.1009115,21.578125 14.8828125,21.952474 14.6289062,22.2324219 C14.375,22.5123698 14.0722656,22.6523438 13.7207031,22.6523438 Z" }) }),
|
|
10227
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { children: effectiveAcceptLabel }),
|
|
10228
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_lucide_react16.ChevronDown, { className: cn2(
|
|
10229
|
+
"h-3 w-3 transition-transform duration-150",
|
|
10230
|
+
isOpen && "rotate-180"
|
|
10231
|
+
) })
|
|
10232
|
+
]
|
|
10233
|
+
}
|
|
10234
|
+
)
|
|
10235
|
+
}
|
|
10236
|
+
),
|
|
10237
|
+
isOpen && position && ReactDOM2.createPortal(
|
|
10238
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(
|
|
10239
|
+
"div",
|
|
10240
|
+
{
|
|
10241
|
+
ref: menuRef,
|
|
10242
|
+
className: cn2(
|
|
10243
|
+
"fixed z-50 min-w-[280px] p-1.5",
|
|
10244
|
+
"bg-background rounded-[8px] shadow-strong border border-border/50",
|
|
10245
|
+
"animate-in fade-in-0 zoom-in-95 duration-100"
|
|
10246
|
+
),
|
|
10247
|
+
style: { top: position.top, left: position.left },
|
|
10248
|
+
children: [
|
|
10249
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(
|
|
10250
|
+
"button",
|
|
10251
|
+
{
|
|
10252
|
+
type: "button",
|
|
10253
|
+
onClick: handleSelectAccept,
|
|
10254
|
+
className: cn2(
|
|
10255
|
+
"flex flex-col w-full px-3 py-2 text-left rounded-[6px]",
|
|
10256
|
+
"hover:bg-foreground/[0.05] focus:bg-foreground/[0.05] focus:outline-none",
|
|
10257
|
+
"transition-colors"
|
|
10258
|
+
),
|
|
10259
|
+
children: [
|
|
10260
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "text-[13px] font-medium", children: effectiveAcceptOptionLabel }),
|
|
10261
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "text-xs text-muted-foreground", children: t22("plan.executeImmediately") })
|
|
10262
|
+
]
|
|
10263
|
+
}
|
|
10264
|
+
),
|
|
10265
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(
|
|
10266
|
+
"button",
|
|
10267
|
+
{
|
|
10268
|
+
type: "button",
|
|
10269
|
+
onClick: handleSelectCompact,
|
|
10270
|
+
className: cn2(
|
|
10271
|
+
"flex flex-col w-full px-3 py-2 text-left rounded-[6px]",
|
|
10272
|
+
"hover:bg-foreground/[0.05] focus:bg-foreground/[0.05] focus:outline-none",
|
|
10273
|
+
"transition-colors"
|
|
10274
|
+
),
|
|
10275
|
+
children: [
|
|
10276
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "text-[13px] font-medium", children: t22("plan.acceptAndCompact") }),
|
|
10277
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "text-xs text-muted-foreground", children: t22("plan.worksForComplex") })
|
|
10278
|
+
]
|
|
10279
|
+
}
|
|
10280
|
+
)
|
|
10281
|
+
]
|
|
10282
|
+
}
|
|
10283
|
+
),
|
|
10284
|
+
document.body
|
|
10285
|
+
)
|
|
10286
|
+
] });
|
|
10287
|
+
}
|
|
10288
|
+
function DropdownMenu2({ children }) {
|
|
10289
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_jsx_runtime62.Fragment, { children });
|
|
10290
|
+
}
|
|
10291
|
+
function DropdownMenuTrigger2({ children }) {
|
|
10292
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(import_jsx_runtime62.Fragment, { children });
|
|
10293
|
+
}
|
|
10294
|
+
function StyledDropdownMenuContent2({
|
|
10295
|
+
children,
|
|
10296
|
+
align = "end",
|
|
10297
|
+
minWidth,
|
|
10298
|
+
sideOffset,
|
|
10299
|
+
className
|
|
10300
|
+
}) {
|
|
10301
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: cn2(
|
|
10302
|
+
"min-w-[180px] p-1 bg-background rounded-[8px] shadow-strong border border-border/50",
|
|
10303
|
+
align === "end" ? "ml-auto" : "",
|
|
10304
|
+
className
|
|
10305
|
+
), children });
|
|
10306
|
+
}
|
|
10307
|
+
function StyledDropdownMenuItem2({
|
|
10308
|
+
onClick,
|
|
10309
|
+
children,
|
|
10310
|
+
className
|
|
10311
|
+
}) {
|
|
10312
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
10313
|
+
"button",
|
|
10314
|
+
{
|
|
10315
|
+
type: "button",
|
|
10316
|
+
onClick,
|
|
10317
|
+
className: cn2(
|
|
10318
|
+
"flex items-center gap-2 w-full px-2 py-1.5 text-left rounded-[6px]",
|
|
10319
|
+
"hover:bg-foreground/[0.05] text-sm",
|
|
10320
|
+
className
|
|
10321
|
+
),
|
|
10322
|
+
children
|
|
10323
|
+
}
|
|
10324
|
+
);
|
|
10325
|
+
}
|
|
10326
|
+
function BranchDropdown2({ onBranch }) {
|
|
10327
|
+
const { t: t22 } = (0, import_react_i18next7.useTranslation)();
|
|
10328
|
+
const handleBranchClick = () => {
|
|
10329
|
+
onBranch({ newPanel: true });
|
|
10330
|
+
};
|
|
10331
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(DropdownMenu2, { children: [
|
|
10332
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(DropdownMenuTrigger2, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
10333
|
+
"button",
|
|
10334
|
+
{
|
|
10335
|
+
type: "button",
|
|
10336
|
+
"aria-label": t22("chat.branchOptions"),
|
|
10337
|
+
title: t22("chat.branch"),
|
|
10338
|
+
className: cn2(
|
|
10339
|
+
"p-1 rounded-[4px] transition-colors select-none",
|
|
10340
|
+
"text-muted-foreground hover:text-foreground hover:bg-foreground/5",
|
|
10341
|
+
"data-[state=open]:text-foreground data-[state=open]:bg-foreground/5",
|
|
10342
|
+
"focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
10343
|
+
),
|
|
10344
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_lucide_react14.GitBranch, { className: SIZE_CONFIG2.iconSize })
|
|
10345
|
+
}
|
|
10346
|
+
) }),
|
|
10347
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(StyledDropdownMenuContent2, { align: "end", minWidth: "min-w-64", sideOffset: 6, children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(StyledDropdownMenuItem2, { onClick: handleBranchClick, className: "items-start py-2", children: /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "flex flex-col gap-0.5", children: [
|
|
10348
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "text-[13px] leading-tight", children: t22("chat.branchFromThisMessage") }),
|
|
10349
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "max-w-[220px] whitespace-normal text-xs leading-tight text-muted-foreground", children: t22("chat.branchFromThisMessageDescription") })
|
|
10350
|
+
] }) }) })
|
|
10351
|
+
] });
|
|
10352
|
+
}
|
|
10353
|
+
var MAX_HEIGHT2 = 540;
|
|
10354
|
+
function clearAnnotationMarks2(root) {
|
|
10355
|
+
const annotatedInlineCodeNodes = root.querySelectorAll('code[data-ca-annotation-inline-code="true"]');
|
|
10356
|
+
annotatedInlineCodeNodes.forEach((codeNode) => {
|
|
10357
|
+
codeNode.removeAttribute("data-ca-annotation-inline-code");
|
|
10358
|
+
codeNode.style.backgroundColor = "";
|
|
10359
|
+
codeNode.style.boxShadow = "";
|
|
10360
|
+
});
|
|
10361
|
+
const marks = root.querySelectorAll("span[data-ca-annotation-id]");
|
|
10362
|
+
marks.forEach((mark) => {
|
|
10363
|
+
const parent = mark.parentNode;
|
|
10364
|
+
if (!parent) return;
|
|
10365
|
+
const badge = mark.querySelector("[data-ca-annotation-index]");
|
|
10366
|
+
if (badge) badge.remove();
|
|
10367
|
+
parent.replaceChild(document.createTextNode(mark.textContent || ""), mark);
|
|
10368
|
+
parent.normalize();
|
|
10369
|
+
});
|
|
10370
|
+
}
|
|
10371
|
+
function ResponseCard2({
|
|
10372
|
+
text,
|
|
10373
|
+
isStreaming,
|
|
10374
|
+
streamStartTime,
|
|
10375
|
+
onOpenFile,
|
|
10376
|
+
onOpenUrl,
|
|
10377
|
+
onPopOut,
|
|
10378
|
+
variant = "response",
|
|
10379
|
+
sessionId,
|
|
10380
|
+
messageId,
|
|
10381
|
+
annotations,
|
|
10382
|
+
onAccept,
|
|
10383
|
+
onAcceptWithCompact,
|
|
10384
|
+
isLastResponse = true,
|
|
10385
|
+
showAcceptPlan = true,
|
|
10386
|
+
compactMode = false,
|
|
10387
|
+
onBranch,
|
|
10388
|
+
onAddAnnotation,
|
|
10389
|
+
onRemoveAnnotation,
|
|
10390
|
+
onUpdateAnnotation,
|
|
10391
|
+
sendMessageKey = "enter",
|
|
10392
|
+
onSaveAndSendFollowUp,
|
|
10393
|
+
hasActiveFollowUpAnnotations = false,
|
|
10394
|
+
openAnnotationRequest,
|
|
10395
|
+
annotationInteractionMode = "interactive"
|
|
10396
|
+
}) {
|
|
10397
|
+
const { t: t22 } = (0, import_react_i18next7.useTranslation)();
|
|
10398
|
+
const [displayedText, setDisplayedText] = (0, import_react25.useState)(text);
|
|
10399
|
+
const lastUpdateRef = (0, import_react25.useRef)(Date.now());
|
|
10400
|
+
const [copied, setCopied] = (0, import_react25.useState)(false);
|
|
10401
|
+
const [isFullscreen, setIsFullscreen] = (0, import_react25.useState)(false);
|
|
10402
|
+
const [isDarkMode, setIsDarkMode] = (0, import_react25.useState)(false);
|
|
10403
|
+
const interaction = useAnnotationInteractionController2();
|
|
10404
|
+
const {
|
|
10405
|
+
state: interactionState,
|
|
10406
|
+
setDraft: setFollowUpDraft,
|
|
10407
|
+
openFromSelection,
|
|
10408
|
+
openFollowUpFromSelection,
|
|
10409
|
+
openFromAnnotation,
|
|
10410
|
+
requestEdit,
|
|
10411
|
+
cancelFollowUp,
|
|
10412
|
+
closeAll,
|
|
10413
|
+
markSubmitSuccess,
|
|
10414
|
+
markDeleteSuccess,
|
|
10415
|
+
consumeExternalOpenRequest
|
|
10416
|
+
} = interaction;
|
|
10417
|
+
const pendingSelection = interactionState.pendingSelection;
|
|
10418
|
+
const selectionMenuView = interactionState.selectionMenuView;
|
|
10419
|
+
const followUpDraft = interactionState.followUpDraft;
|
|
10420
|
+
const followUpMode = interactionState.followUpMode;
|
|
10421
|
+
const activeAnnotationDetail = interactionState.activeAnnotationDetail;
|
|
10422
|
+
const [selectionMenuShowNonce, setSelectionMenuShowNonce] = (0, import_react25.useState)(0);
|
|
10423
|
+
const [selectionMenuTransitionConfig, setSelectionMenuTransitionConfig] = (0, import_react25.useState)(
|
|
10424
|
+
buildAnnotationChipEntryTransition2()
|
|
10425
|
+
);
|
|
10426
|
+
const [annotationOverlay, setAnnotationOverlay] = (0, import_react25.useState)({ rects: [], chips: [] });
|
|
10427
|
+
const contentRef = (0, import_react25.useRef)(null);
|
|
10428
|
+
const contentLayerRef = (0, import_react25.useRef)(null);
|
|
10429
|
+
const lastPointerRef = (0, import_react25.useRef)(null);
|
|
10430
|
+
const dragStartPointerRef = (0, import_react25.useRef)(null);
|
|
10431
|
+
const selectionStartedInContentRef = (0, import_react25.useRef)(false);
|
|
10432
|
+
const canAnnotate = canAnnotateMessage2({
|
|
10433
|
+
hasAddAnnotationHandler: !!onAddAnnotation,
|
|
10434
|
+
hasMessageId: !!messageId,
|
|
10435
|
+
isStreaming
|
|
10436
|
+
});
|
|
10437
|
+
const allowAnnotationIsland = annotationInteractionMode === "interactive";
|
|
10438
|
+
(0, import_react25.useEffect)(() => {
|
|
10439
|
+
const checkDarkMode = () => {
|
|
10440
|
+
setIsDarkMode(document.documentElement.classList.contains("dark"));
|
|
10441
|
+
};
|
|
10442
|
+
checkDarkMode();
|
|
10443
|
+
const observer = new MutationObserver(checkDarkMode);
|
|
10444
|
+
observer.observe(document.documentElement, { attributes: true, attributeFilter: ["class"] });
|
|
10445
|
+
return () => observer.disconnect();
|
|
10446
|
+
}, []);
|
|
10447
|
+
const closeSelectionMenu = (0, import_react25.useCallback)(() => {
|
|
10448
|
+
closeAll();
|
|
10449
|
+
}, [closeAll]);
|
|
10450
|
+
const isTargetInsideAnnotationIsland = (0, import_react25.useCallback)((target) => {
|
|
10451
|
+
if (!target) return false;
|
|
10452
|
+
const element = target instanceof Element ? target : target.parentElement;
|
|
10453
|
+
if (!element) return false;
|
|
10454
|
+
return !!element.closest('[data-ca-annotation-island="true"]');
|
|
10455
|
+
}, []);
|
|
10456
|
+
const triggerSelectionMenuEntryReplay = (0, import_react25.useCallback)(() => {
|
|
10457
|
+
setSelectionMenuShowNonce((prev) => prev + 1);
|
|
10458
|
+
}, []);
|
|
10459
|
+
const activeMenuAnchor = (0, import_react25.useMemo)(() => {
|
|
10460
|
+
return getAnnotationInteractionAnchor2(interactionState);
|
|
10461
|
+
}, [interactionState]);
|
|
10462
|
+
const selectionMenuSourceKey = (0, import_react25.useMemo)(() => {
|
|
10463
|
+
const messageScope = messageId ?? "no-message";
|
|
10464
|
+
return getAnnotationInteractionSourceKey2(interactionState, messageScope);
|
|
10465
|
+
}, [interactionState, messageId]);
|
|
10466
|
+
const {
|
|
10467
|
+
renderAnchor: selectionMenuRenderAnchor,
|
|
10468
|
+
renderSourceKey: selectionMenuRenderSourceKey,
|
|
10469
|
+
isVisible: isSelectionMenuVisible,
|
|
10470
|
+
openedAtRef: selectionMenuOpenedAtRef,
|
|
10471
|
+
handleExitComplete: handleSelectionMenuExitComplete,
|
|
10472
|
+
resetPresentation
|
|
10473
|
+
} = useAnnotationIslandPresentation2({
|
|
10474
|
+
anchor: activeMenuAnchor,
|
|
10475
|
+
sourceKey: selectionMenuSourceKey
|
|
10476
|
+
});
|
|
10477
|
+
const handleCopy = (0, import_react25.useCallback)(async () => {
|
|
10478
|
+
try {
|
|
10479
|
+
await navigator.clipboard.writeText(text);
|
|
10480
|
+
setCopied(true);
|
|
10481
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
10482
|
+
} catch (err) {
|
|
10483
|
+
console.error("Failed to copy:", err);
|
|
10484
|
+
}
|
|
10485
|
+
}, [text]);
|
|
10486
|
+
const renderedAnnotations = (0, import_react25.useMemo)(() => {
|
|
10487
|
+
const persisted = annotations ?? [];
|
|
10488
|
+
if (!pendingSelection || !selectionMenuView || !messageId) {
|
|
10489
|
+
return persisted;
|
|
10490
|
+
}
|
|
10491
|
+
if (hasExistingTextRangeAnnotation2(persisted, pendingSelection.start, pendingSelection.end)) {
|
|
10492
|
+
return persisted;
|
|
10493
|
+
}
|
|
10494
|
+
return [
|
|
10495
|
+
...persisted,
|
|
10496
|
+
createSelectionPreviewAnnotation2(messageId, pendingSelection, sessionId ?? "")
|
|
10497
|
+
];
|
|
10498
|
+
}, [annotations, pendingSelection, selectionMenuView, messageId]);
|
|
10499
|
+
const activeAnnotation = (0, import_react25.useMemo)(() => {
|
|
10500
|
+
if (!activeAnnotationDetail) return null;
|
|
10501
|
+
return (annotations ?? []).find((annotation) => annotation.id === activeAnnotationDetail.annotationId) ?? null;
|
|
10502
|
+
}, [annotations, activeAnnotationDetail]);
|
|
10503
|
+
(0, import_react25.useEffect)(() => {
|
|
10504
|
+
if (!activeAnnotationDetail) return;
|
|
10505
|
+
if (!activeAnnotation) {
|
|
10506
|
+
closeSelectionMenu();
|
|
10507
|
+
}
|
|
10508
|
+
}, [activeAnnotationDetail, activeAnnotation, closeSelectionMenu]);
|
|
10509
|
+
(0, import_react25.useEffect)(() => {
|
|
10510
|
+
const root = contentLayerRef.current;
|
|
10511
|
+
if (!root) {
|
|
10512
|
+
setAnnotationOverlay({ rects: [], chips: [] });
|
|
10513
|
+
return;
|
|
10514
|
+
}
|
|
10515
|
+
const recomputeOverlay = () => {
|
|
10516
|
+
clearAnnotationMarks2(root);
|
|
10517
|
+
clearBlockAnnotationMarkers2(root);
|
|
10518
|
+
if (!renderedAnnotations.length) {
|
|
10519
|
+
setAnnotationOverlay({ rects: [], chips: [] });
|
|
10520
|
+
return;
|
|
10521
|
+
}
|
|
10522
|
+
const geometry = computeAnnotationOverlayGeometry2({
|
|
10523
|
+
root,
|
|
10524
|
+
renderedAnnotations,
|
|
10525
|
+
persistedAnnotations: annotations
|
|
10526
|
+
});
|
|
10527
|
+
for (const annotation of renderedAnnotations) {
|
|
10528
|
+
applyBlockAnnotationMarker2(root, annotation);
|
|
10529
|
+
}
|
|
10530
|
+
setAnnotationOverlay({ rects: geometry.rects, chips: geometry.chips });
|
|
10531
|
+
if (process.env.NODE_ENV !== "production" && geometry.unresolved.length > 0) {
|
|
10532
|
+
console.debug("[annotations] unresolved annotations", {
|
|
10533
|
+
count: geometry.unresolved.length,
|
|
10534
|
+
ids: geometry.unresolved.map((item) => item.annotation.id),
|
|
10535
|
+
reasons: geometry.unresolved.map((item) => item.reason)
|
|
10536
|
+
});
|
|
10537
|
+
}
|
|
10538
|
+
};
|
|
10539
|
+
recomputeOverlay();
|
|
10540
|
+
window.addEventListener("resize", recomputeOverlay);
|
|
10541
|
+
return () => {
|
|
10542
|
+
window.removeEventListener("resize", recomputeOverlay);
|
|
10543
|
+
};
|
|
10544
|
+
}, [annotations, renderedAnnotations, text, displayedText, isStreaming]);
|
|
10545
|
+
(0, import_react25.useEffect)(() => {
|
|
10546
|
+
if (!canAnnotate) {
|
|
10547
|
+
closeSelectionMenu();
|
|
10548
|
+
}
|
|
10549
|
+
}, [canAnnotate, closeSelectionMenu]);
|
|
10550
|
+
(0, import_react25.useEffect)(() => {
|
|
10551
|
+
closeSelectionMenu();
|
|
10552
|
+
resetPresentation();
|
|
10553
|
+
dragStartPointerRef.current = null;
|
|
10554
|
+
lastPointerRef.current = null;
|
|
10555
|
+
}, [sessionId, closeSelectionMenu, resetPresentation]);
|
|
10556
|
+
(0, import_react25.useEffect)(() => {
|
|
10557
|
+
if (!hasAnnotationInteraction2(interactionState) || !isSelectionMenuVisible) return;
|
|
10558
|
+
const handleSelectionChange = () => {
|
|
10559
|
+
if (selectionMenuOpenedAtRef.current == null || Date.now() - selectionMenuOpenedAtRef.current < 180) {
|
|
10560
|
+
return;
|
|
10561
|
+
}
|
|
10562
|
+
const root = contentLayerRef.current;
|
|
10563
|
+
if (!root) {
|
|
10564
|
+
closeSelectionMenu();
|
|
10565
|
+
return;
|
|
10566
|
+
}
|
|
10567
|
+
const selection = window.getSelection();
|
|
10568
|
+
if (!selection || selection.rangeCount === 0 || selection.isCollapsed) {
|
|
10569
|
+
return;
|
|
10570
|
+
}
|
|
10571
|
+
const range = selection.getRangeAt(0);
|
|
10572
|
+
const common = range.commonAncestorContainer;
|
|
10573
|
+
const commonElement = common.nodeType === Node.ELEMENT_NODE ? common : common.parentElement;
|
|
10574
|
+
if (commonElement && isTargetInsideAnnotationIsland(commonElement)) {
|
|
10575
|
+
return;
|
|
10576
|
+
}
|
|
10577
|
+
if (!root.contains(common)) {
|
|
10578
|
+
closeSelectionMenu();
|
|
10579
|
+
}
|
|
10580
|
+
};
|
|
10581
|
+
document.addEventListener("selectionchange", handleSelectionChange);
|
|
10582
|
+
return () => {
|
|
10583
|
+
document.removeEventListener("selectionchange", handleSelectionChange);
|
|
10584
|
+
};
|
|
10585
|
+
}, [interactionState, isSelectionMenuVisible, closeSelectionMenu, isTargetInsideAnnotationIsland, selectionMenuOpenedAtRef]);
|
|
10586
|
+
const handleOpenFollowUpView = (0, import_react25.useCallback)(() => {
|
|
10587
|
+
if (!pendingSelection) return;
|
|
10588
|
+
clearDomSelection2();
|
|
10589
|
+
openFollowUpFromSelection();
|
|
10590
|
+
}, [pendingSelection, openFollowUpFromSelection]);
|
|
10591
|
+
const handleRequestFollowUpEdit = (0, import_react25.useCallback)(() => {
|
|
10592
|
+
requestEdit();
|
|
10593
|
+
}, [requestEdit]);
|
|
10594
|
+
const saveFollowUp = (0, import_react25.useCallback)(async (note) => {
|
|
10595
|
+
const normalizedNote = note.trim();
|
|
10596
|
+
if (!messageId) return null;
|
|
10597
|
+
if (activeAnnotationDetail) {
|
|
10598
|
+
if (!onUpdateAnnotation || !activeAnnotation) {
|
|
10599
|
+
closeSelectionMenu();
|
|
10600
|
+
return null;
|
|
10601
|
+
}
|
|
10602
|
+
const existingOtherBodies = activeAnnotation.body.filter((body) => body.type !== "highlight" && body.type !== "note");
|
|
10603
|
+
const nextBody = [
|
|
10604
|
+
{ type: "highlight" },
|
|
10605
|
+
...normalizedNote.length > 0 ? [{ type: "note", text: normalizedNote, format: "plain" }] : [],
|
|
10606
|
+
...existingOtherBodies
|
|
10607
|
+
];
|
|
10608
|
+
const nextMeta = { ...activeAnnotation.meta ?? {} };
|
|
10609
|
+
delete nextMeta.followUp;
|
|
10610
|
+
try {
|
|
10611
|
+
await Promise.resolve(onUpdateAnnotation(messageId, activeAnnotationDetail.annotationId, {
|
|
10612
|
+
body: nextBody,
|
|
10613
|
+
intent: normalizedNote.length > 0 ? "comment" : "highlight",
|
|
10614
|
+
updatedAt: Date.now(),
|
|
10615
|
+
meta: normalizedNote.length > 0 ? {
|
|
10616
|
+
...nextMeta,
|
|
10617
|
+
followUp: {
|
|
10618
|
+
text: normalizedNote,
|
|
10619
|
+
updatedAt: Date.now()
|
|
10620
|
+
}
|
|
10621
|
+
} : Object.keys(nextMeta).length > 0 ? nextMeta : void 0
|
|
10622
|
+
}));
|
|
10623
|
+
} catch {
|
|
10624
|
+
return null;
|
|
10625
|
+
}
|
|
10626
|
+
markSubmitSuccess();
|
|
10627
|
+
if (normalizedNote.length === 0) return null;
|
|
10628
|
+
return {
|
|
10629
|
+
messageId,
|
|
10630
|
+
annotationId: activeAnnotationDetail.annotationId,
|
|
10631
|
+
note: normalizedNote,
|
|
10632
|
+
selectedText: extractAnnotationSelectedText2(activeAnnotation, text)
|
|
10633
|
+
};
|
|
10634
|
+
}
|
|
10635
|
+
if (!onAddAnnotation || !pendingSelection) return null;
|
|
10636
|
+
if (hasExistingTextRangeAnnotation2(annotations ?? [], pendingSelection.start, pendingSelection.end)) {
|
|
10637
|
+
closeSelectionMenu();
|
|
10638
|
+
return null;
|
|
10639
|
+
}
|
|
10640
|
+
const annotation = createTextSelectionAnnotation2(messageId, sessionId ?? "", pendingSelection.start, pendingSelection.end, pendingSelection.exact ?? (activeAnnotation ? extractAnnotationSelectedText2(activeAnnotation, text) : ""), normalizedNote);
|
|
10641
|
+
try {
|
|
10642
|
+
await Promise.resolve(onAddAnnotation(messageId, annotation));
|
|
10643
|
+
} catch {
|
|
10644
|
+
return null;
|
|
10645
|
+
}
|
|
10646
|
+
markSubmitSuccess();
|
|
10647
|
+
clearDomSelection2();
|
|
10648
|
+
if (normalizedNote.length === 0) return null;
|
|
10649
|
+
return {
|
|
10650
|
+
messageId,
|
|
10651
|
+
annotationId: annotation.id,
|
|
10652
|
+
note: normalizedNote,
|
|
10653
|
+
selectedText: pendingSelection.selectedText ?? ""
|
|
10654
|
+
};
|
|
10655
|
+
}, [
|
|
10656
|
+
messageId,
|
|
10657
|
+
activeAnnotationDetail,
|
|
10658
|
+
activeAnnotation,
|
|
10659
|
+
onUpdateAnnotation,
|
|
10660
|
+
onAddAnnotation,
|
|
10661
|
+
pendingSelection,
|
|
10662
|
+
annotations,
|
|
10663
|
+
closeSelectionMenu,
|
|
10664
|
+
sessionId,
|
|
10665
|
+
markSubmitSuccess,
|
|
10666
|
+
text
|
|
10667
|
+
]);
|
|
10668
|
+
const handleSubmitFollowUp = (0, import_react25.useCallback)((note) => {
|
|
10669
|
+
void saveFollowUp(note);
|
|
10670
|
+
}, [saveFollowUp]);
|
|
10671
|
+
const handleSubmitAndSendFollowUp = (0, import_react25.useCallback)((note) => {
|
|
10672
|
+
void saveFollowUp(note).then((savedFollowUp) => {
|
|
10673
|
+
if (!savedFollowUp) return;
|
|
10674
|
+
onSaveAndSendFollowUp?.(savedFollowUp);
|
|
10675
|
+
});
|
|
10676
|
+
}, [saveFollowUp, onSaveAndSendFollowUp]);
|
|
10677
|
+
const handleCancelFollowUp = useAnnotationCancelRestore2({
|
|
10678
|
+
contentRootRef: contentLayerRef,
|
|
10679
|
+
cancelFollowUp
|
|
10680
|
+
});
|
|
10681
|
+
const handleOpenAnnotationDetail = (0, import_react25.useCallback)((annotationId, index, anchorX, anchorY, mode = "view") => {
|
|
10682
|
+
if (!allowAnnotationIsland) return;
|
|
10683
|
+
const annotation = (annotations ?? []).find((item) => item.id === annotationId);
|
|
10684
|
+
const noteText = annotation ? getAnnotationNoteText2(annotation) : "";
|
|
10685
|
+
const transition = buildAnnotationChipEntryTransition2();
|
|
10686
|
+
setSelectionMenuTransitionConfig(transition);
|
|
10687
|
+
triggerSelectionMenuEntryReplay();
|
|
10688
|
+
openFromAnnotation({ annotationId, index, anchorX, anchorY }, noteText, mode);
|
|
10689
|
+
}, [allowAnnotationIsland, annotations, triggerSelectionMenuEntryReplay, openFromAnnotation]);
|
|
10690
|
+
(0, import_react25.useEffect)(() => {
|
|
10691
|
+
if (!allowAnnotationIsland) return;
|
|
10692
|
+
const contentRect = contentLayerRef.current?.getBoundingClientRect();
|
|
10693
|
+
const fallbackAnchor = {
|
|
10694
|
+
x: contentRect ? contentRect.left + contentRect.width / 2 : window.innerWidth / 2,
|
|
10695
|
+
y: contentRect ? contentRect.top + 20 : Math.max(24, window.innerHeight * 0.2)
|
|
10696
|
+
};
|
|
10697
|
+
const consumed = consumeExternalOpenRequest(openAnnotationRequest, {
|
|
10698
|
+
messageId,
|
|
10699
|
+
annotations,
|
|
10700
|
+
getNoteText: getAnnotationNoteText2,
|
|
10701
|
+
fallbackAnchor
|
|
10702
|
+
});
|
|
10703
|
+
if (!consumed) return;
|
|
10704
|
+
setSelectionMenuTransitionConfig(buildAnnotationChipEntryTransition2());
|
|
10705
|
+
triggerSelectionMenuEntryReplay();
|
|
10706
|
+
}, [
|
|
10707
|
+
allowAnnotationIsland,
|
|
10708
|
+
openAnnotationRequest,
|
|
10709
|
+
messageId,
|
|
10710
|
+
annotations,
|
|
10711
|
+
consumeExternalOpenRequest,
|
|
10712
|
+
triggerSelectionMenuEntryReplay
|
|
10713
|
+
]);
|
|
10714
|
+
const handleDeleteActiveAnnotation = (0, import_react25.useCallback)(() => {
|
|
10715
|
+
if (!onRemoveAnnotation || !messageId || !activeAnnotationDetail) return;
|
|
10716
|
+
onRemoveAnnotation(messageId, activeAnnotationDetail.annotationId);
|
|
10717
|
+
markDeleteSuccess();
|
|
10718
|
+
}, [onRemoveAnnotation, messageId, activeAnnotationDetail, markDeleteSuccess]);
|
|
10719
|
+
const handleSelectionPointerDown = (0, import_react25.useCallback)((event) => {
|
|
10720
|
+
selectionStartedInContentRef.current = true;
|
|
10721
|
+
const snapshot = {
|
|
10722
|
+
x: event.clientX,
|
|
10723
|
+
y: event.clientY,
|
|
10724
|
+
timestamp: Date.now()
|
|
10725
|
+
};
|
|
10726
|
+
dragStartPointerRef.current = snapshot;
|
|
10727
|
+
lastPointerRef.current = snapshot;
|
|
10728
|
+
}, []);
|
|
10729
|
+
const showSelectionMenuFromCurrentSelection = (0, import_react25.useCallback)(() => {
|
|
10730
|
+
const root = contentLayerRef.current;
|
|
10731
|
+
if (!root) return;
|
|
10732
|
+
requestAnimationFrame(() => {
|
|
10733
|
+
const selection = window.getSelection();
|
|
10734
|
+
if (!selection || selection.rangeCount === 0 || selection.isCollapsed) {
|
|
10735
|
+
closeSelectionMenu();
|
|
10736
|
+
return;
|
|
10737
|
+
}
|
|
10738
|
+
const range = selection.getRangeAt(0);
|
|
10739
|
+
if (!root.contains(range.commonAncestorContainer)) {
|
|
10740
|
+
closeSelectionMenu();
|
|
10741
|
+
return;
|
|
10742
|
+
}
|
|
10743
|
+
const start = resolveNodeOffset2(root, range.startContainer, range.startOffset);
|
|
10744
|
+
const end = resolveNodeOffset2(root, range.endContainer, range.endOffset);
|
|
10745
|
+
if (start == null || end == null || end <= start) {
|
|
10746
|
+
closeSelectionMenu();
|
|
10747
|
+
return;
|
|
10748
|
+
}
|
|
10749
|
+
const selectedText = range.toString();
|
|
10750
|
+
if (!selectedText || !/\S/.test(selectedText)) {
|
|
10751
|
+
closeSelectionMenu();
|
|
10752
|
+
return;
|
|
10753
|
+
}
|
|
10754
|
+
if (hasExistingTextRangeAnnotation2(annotations ?? [], start, end)) {
|
|
10755
|
+
closeSelectionMenu();
|
|
10756
|
+
return;
|
|
10757
|
+
}
|
|
10758
|
+
const fullText = getCanonicalText2(root);
|
|
10759
|
+
const prefix = fullText.slice(Math.max(0, start - ANNOTATION_PREFIX_SUFFIX_WINDOW2), start);
|
|
10760
|
+
const suffix = fullText.slice(end, end + ANNOTATION_PREFIX_SUFFIX_WINDOW2);
|
|
10761
|
+
const rects = Array.from(range.getClientRects()).filter((rect) => rect.width > 0 && rect.height > 0);
|
|
10762
|
+
const pointer = lastPointerRef.current;
|
|
10763
|
+
const hasRecentPointer = Boolean(pointer && Date.now() - pointer.timestamp <= SELECTION_POINTER_MAX_AGE_MS2);
|
|
10764
|
+
const pointerX = hasRecentPointer && pointer ? pointer.x : null;
|
|
10765
|
+
const pointerY = hasRecentPointer && pointer ? pointer.y : null;
|
|
10766
|
+
let anchorRect;
|
|
10767
|
+
if (rects.length > 0) {
|
|
10768
|
+
if (pointerY != null) {
|
|
10769
|
+
const rowCandidates = rects.filter((rect) => pointerY >= rect.top && pointerY <= rect.bottom);
|
|
10770
|
+
if (rowCandidates.length > 0) {
|
|
10771
|
+
if (pointerX != null) {
|
|
10772
|
+
const xContaining = rowCandidates.filter((rect) => pointerX >= rect.left && pointerX <= rect.right);
|
|
10773
|
+
if (xContaining.length > 0) {
|
|
10774
|
+
anchorRect = xContaining.reduce((best, rect) => rect.width > best.width ? rect : best);
|
|
10775
|
+
} else {
|
|
10776
|
+
anchorRect = rowCandidates.reduce((best, rect) => {
|
|
10777
|
+
const bestDistance = Math.min(Math.abs(pointerX - best.left), Math.abs(pointerX - best.right));
|
|
10778
|
+
const rectDistance = Math.min(Math.abs(pointerX - rect.left), Math.abs(pointerX - rect.right));
|
|
10779
|
+
return rectDistance < bestDistance ? rect : best;
|
|
10780
|
+
});
|
|
10781
|
+
}
|
|
10782
|
+
} else {
|
|
10783
|
+
anchorRect = rowCandidates.reduce((best, rect) => rect.width > best.width ? rect : best);
|
|
10784
|
+
}
|
|
10785
|
+
} else {
|
|
10786
|
+
anchorRect = rects.reduce((best, rect) => {
|
|
10787
|
+
const bestDistance = Math.abs((best.top + best.bottom) / 2 - pointerY);
|
|
10788
|
+
const rectDistance = Math.abs((rect.top + rect.bottom) / 2 - pointerY);
|
|
10789
|
+
return rectDistance < bestDistance ? rect : best;
|
|
10790
|
+
});
|
|
10791
|
+
}
|
|
10792
|
+
} else {
|
|
10793
|
+
anchorRect = rects.reduce((best, rect) => rect.top < best.top ? rect : best);
|
|
10794
|
+
}
|
|
10795
|
+
} else {
|
|
10796
|
+
anchorRect = range.getBoundingClientRect();
|
|
10797
|
+
}
|
|
10798
|
+
const anchorRowRects = rects.length > 0 ? rects.filter((rect) => Math.abs(rect.top - anchorRect.top) <= 2) : [];
|
|
10799
|
+
const clampRects = anchorRowRects.length > 0 ? anchorRowRects : rects.length > 0 ? rects : [anchorRect];
|
|
10800
|
+
const selectionMinX = Math.min(...clampRects.map((rect) => rect.left));
|
|
10801
|
+
const selectionMaxX = Math.max(...clampRects.map((rect) => rect.right));
|
|
10802
|
+
const anchorX = pointerX != null ? clamp2(pointerX, selectionMinX, selectionMaxX) : anchorRect.left + anchorRect.width / 2;
|
|
10803
|
+
const anchorY = anchorRect.top - 8;
|
|
10804
|
+
const transition = buildSelectionEntryTransition2(dragStartPointerRef.current, pointer);
|
|
10805
|
+
setSelectionMenuTransitionConfig(transition);
|
|
10806
|
+
triggerSelectionMenuEntryReplay();
|
|
10807
|
+
openFromSelection({
|
|
10808
|
+
start,
|
|
10809
|
+
end,
|
|
10810
|
+
exact: selectedText,
|
|
10811
|
+
selectedText,
|
|
10812
|
+
prefix,
|
|
10813
|
+
suffix,
|
|
10814
|
+
anchorX,
|
|
10815
|
+
anchorY
|
|
10816
|
+
});
|
|
10817
|
+
dragStartPointerRef.current = null;
|
|
10818
|
+
});
|
|
10819
|
+
}, [annotations, closeSelectionMenu, triggerSelectionMenuEntryReplay, openFromSelection]);
|
|
10820
|
+
const handleTextSelection = (0, import_react25.useCallback)((event) => {
|
|
10821
|
+
if (!canAnnotate || !onAddAnnotation || !messageId) return;
|
|
10822
|
+
const root = contentLayerRef.current;
|
|
10823
|
+
if (!root) return;
|
|
10824
|
+
if (shouldIgnoreSelectionMouseUpTarget2(event.target)) {
|
|
10825
|
+
selectionStartedInContentRef.current = false;
|
|
10826
|
+
return;
|
|
10827
|
+
}
|
|
10828
|
+
lastPointerRef.current = {
|
|
10829
|
+
x: event.clientX,
|
|
10830
|
+
y: event.clientY,
|
|
10831
|
+
timestamp: Date.now()
|
|
10832
|
+
};
|
|
10833
|
+
if (event.shiftKey) {
|
|
10834
|
+
const targetElement = event.target instanceof Element ? event.target : null;
|
|
10835
|
+
const blockElement = targetElement?.closest("[data-ca-block-path]");
|
|
10836
|
+
if (blockElement) {
|
|
10837
|
+
const blockPath = blockElement.getAttribute("data-ca-block-path") || "";
|
|
10838
|
+
const blockType = blockElement.getAttribute("data-ca-block-type") || "paragraph";
|
|
10839
|
+
const blockId = blockElement.getAttribute("data-ca-block-id") || void 0;
|
|
10840
|
+
if (blockPath) {
|
|
10841
|
+
const alreadyExists = (annotations ?? []).some((annotation) => {
|
|
10842
|
+
const blockSelector = annotation.target.selectors.find((s) => s.type === "block");
|
|
10843
|
+
if (!blockSelector) return false;
|
|
10844
|
+
if (blockId && blockSelector.blockId) return blockSelector.blockId === blockId;
|
|
10845
|
+
return blockSelector.path === blockPath;
|
|
10846
|
+
});
|
|
10847
|
+
if (!alreadyExists) {
|
|
10848
|
+
const annotation = {
|
|
10849
|
+
id: `ann-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
10850
|
+
schemaVersion: 1,
|
|
10851
|
+
createdAt: Date.now(),
|
|
10852
|
+
intent: "highlight",
|
|
10853
|
+
body: [{ type: "highlight" }],
|
|
10854
|
+
target: {
|
|
10855
|
+
source: {
|
|
10856
|
+
sessionId: "",
|
|
10857
|
+
messageId
|
|
10858
|
+
},
|
|
10859
|
+
selectors: [
|
|
10860
|
+
{
|
|
10861
|
+
type: "block",
|
|
10862
|
+
blockType,
|
|
10863
|
+
path: blockPath,
|
|
10864
|
+
...blockId ? { blockId } : {}
|
|
10865
|
+
}
|
|
10866
|
+
]
|
|
10867
|
+
},
|
|
10868
|
+
style: { color: "yellow" }
|
|
10869
|
+
};
|
|
10870
|
+
onAddAnnotation(messageId, annotation);
|
|
10871
|
+
}
|
|
10872
|
+
}
|
|
10873
|
+
}
|
|
10874
|
+
selectionStartedInContentRef.current = false;
|
|
10875
|
+
closeSelectionMenu();
|
|
10876
|
+
return;
|
|
10877
|
+
}
|
|
10878
|
+
selectionStartedInContentRef.current = false;
|
|
10879
|
+
showSelectionMenuFromCurrentSelection();
|
|
10880
|
+
}, [canAnnotate, onAddAnnotation, messageId, annotations, showSelectionMenuFromCurrentSelection, closeSelectionMenu]);
|
|
10881
|
+
(0, import_react25.useEffect)(() => {
|
|
10882
|
+
if (!canAnnotate || !onAddAnnotation || !messageId) return;
|
|
10883
|
+
const handleDocumentMouseUp = (event) => {
|
|
10884
|
+
if (!selectionStartedInContentRef.current) return;
|
|
10885
|
+
selectionStartedInContentRef.current = false;
|
|
10886
|
+
lastPointerRef.current = {
|
|
10887
|
+
x: event.clientX,
|
|
10888
|
+
y: event.clientY,
|
|
10889
|
+
timestamp: Date.now()
|
|
10890
|
+
};
|
|
10891
|
+
const root = contentLayerRef.current;
|
|
10892
|
+
if (!root) return;
|
|
10893
|
+
const target = event.target;
|
|
10894
|
+
if (target && root.contains(target)) {
|
|
10895
|
+
return;
|
|
10896
|
+
}
|
|
10897
|
+
showSelectionMenuFromCurrentSelection();
|
|
10898
|
+
};
|
|
10899
|
+
document.addEventListener("mouseup", handleDocumentMouseUp);
|
|
10900
|
+
return () => {
|
|
10901
|
+
document.removeEventListener("mouseup", handleDocumentMouseUp);
|
|
10902
|
+
};
|
|
10903
|
+
}, [canAnnotate, onAddAnnotation, messageId, showSelectionMenuFromCurrentSelection]);
|
|
10904
|
+
const handleSelectionMenuRequestBack = (0, import_react25.useCallback)(() => {
|
|
10905
|
+
if (selectionMenuView !== "compact") {
|
|
10906
|
+
handleCancelFollowUp();
|
|
10907
|
+
return true;
|
|
10908
|
+
}
|
|
10909
|
+
return false;
|
|
10910
|
+
}, [selectionMenuView, handleCancelFollowUp]);
|
|
10911
|
+
useAnnotationIslandEvents2({
|
|
10912
|
+
enabled: allowAnnotationIsland && hasAnnotationInteraction2(interactionState) && isSelectionMenuVisible,
|
|
10913
|
+
openedAtRef: selectionMenuOpenedAtRef,
|
|
10914
|
+
isCompactView: selectionMenuView === "compact",
|
|
10915
|
+
isTargetInsideAnnotationIsland,
|
|
10916
|
+
onBack: handleSelectionMenuRequestBack,
|
|
10917
|
+
onClose: closeSelectionMenu
|
|
10918
|
+
});
|
|
10919
|
+
const selectionMenu = allowAnnotationIsland ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
10920
|
+
AnnotationIslandMenu2,
|
|
10921
|
+
{
|
|
10922
|
+
anchor: selectionMenuRenderAnchor,
|
|
10923
|
+
sourceKey: selectionMenuRenderSourceKey,
|
|
10924
|
+
replayNonce: selectionMenuShowNonce,
|
|
10925
|
+
isVisible: isSelectionMenuVisible,
|
|
10926
|
+
activeView: selectionMenuView,
|
|
10927
|
+
mode: followUpMode,
|
|
10928
|
+
draft: followUpDraft,
|
|
10929
|
+
onDraftChange: setFollowUpDraft,
|
|
10930
|
+
onOpenFollowUp: handleOpenFollowUpView,
|
|
10931
|
+
onCancel: handleCancelFollowUp,
|
|
10932
|
+
onRequestBack: handleSelectionMenuRequestBack,
|
|
10933
|
+
onRequestEdit: handleRequestFollowUpEdit,
|
|
10934
|
+
onSubmit: handleSubmitFollowUp,
|
|
10935
|
+
onSubmitAndSend: handleSubmitAndSendFollowUp,
|
|
10936
|
+
onDelete: activeAnnotationDetail ? handleDeleteActiveAnnotation : void 0,
|
|
10937
|
+
sendMessageKey,
|
|
10938
|
+
transitionConfig: selectionMenuTransitionConfig,
|
|
10939
|
+
onExitComplete: handleSelectionMenuExitComplete,
|
|
10940
|
+
usePortal: shouldRenderAnnotationIslandInPortal2("turncard")
|
|
10941
|
+
}
|
|
10942
|
+
) : null;
|
|
10943
|
+
const annotationOverlayLayer = /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
10944
|
+
AnnotationOverlayLayer2,
|
|
10945
|
+
{
|
|
10946
|
+
rects: annotationOverlay.rects,
|
|
10947
|
+
chips: annotationOverlay.chips,
|
|
10948
|
+
annotations: renderedAnnotations,
|
|
10949
|
+
getTooltipText: (annotation) => formatAnnotationFollowUpTooltipText2(annotation),
|
|
10950
|
+
allowChipOpen: allowAnnotationIsland,
|
|
10951
|
+
onChipOpen: ({ annotationId, index, anchorX, anchorY, mode }) => {
|
|
10952
|
+
handleOpenAnnotationDetail(annotationId, index, anchorX, anchorY, mode);
|
|
10953
|
+
}
|
|
10954
|
+
}
|
|
10955
|
+
);
|
|
10956
|
+
(0, import_react25.useEffect)(() => {
|
|
10957
|
+
if (!isStreaming) {
|
|
10958
|
+
setDisplayedText(text);
|
|
10959
|
+
return;
|
|
10960
|
+
}
|
|
10961
|
+
const now = Date.now();
|
|
10962
|
+
const elapsed = now - lastUpdateRef.current;
|
|
10963
|
+
if (elapsed >= BUFFER_CONFIG2.CONTENT_THROTTLE_MS) {
|
|
10964
|
+
setDisplayedText(text);
|
|
10965
|
+
lastUpdateRef.current = now;
|
|
10966
|
+
} else {
|
|
10967
|
+
const timeout = setTimeout(() => {
|
|
10968
|
+
setDisplayedText(text);
|
|
10969
|
+
lastUpdateRef.current = Date.now();
|
|
10970
|
+
}, BUFFER_CONFIG2.CONTENT_THROTTLE_MS - elapsed);
|
|
10971
|
+
return () => clearTimeout(timeout);
|
|
10972
|
+
}
|
|
10973
|
+
}, [text, isStreaming]);
|
|
10974
|
+
const bufferDecision = (0, import_react25.useMemo)(() => {
|
|
10975
|
+
return shouldShowStreamingContent2(text, isStreaming, streamStartTime);
|
|
10976
|
+
}, [text, isStreaming, streamStartTime]);
|
|
10977
|
+
const isCompleted = !isStreaming;
|
|
10978
|
+
const isBuffering = isStreaming && !bufferDecision.shouldShow;
|
|
10979
|
+
if (isBuffering) {
|
|
10980
|
+
return null;
|
|
10981
|
+
}
|
|
10982
|
+
if (isCompleted || variant === "plan") {
|
|
10983
|
+
const isPlan = variant === "plan";
|
|
10984
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
|
|
10985
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "bg-background shadow-minimal rounded-[8px] overflow-hidden relative group", children: [
|
|
10986
|
+
!compactMode && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
10987
|
+
"button",
|
|
10988
|
+
{
|
|
10989
|
+
onClick: () => setIsFullscreen(true),
|
|
10990
|
+
className: cn2(
|
|
10991
|
+
"absolute top-2 right-2 p-1 rounded-[6px] transition-all z-10 select-none",
|
|
10992
|
+
"opacity-0 group-hover:opacity-100",
|
|
10993
|
+
"bg-background shadow-minimal",
|
|
10994
|
+
"text-muted-foreground/50 hover:text-foreground",
|
|
10995
|
+
"focus:outline-none focus-visible:ring-1 focus-visible:ring-ring focus-visible:opacity-100"
|
|
10996
|
+
),
|
|
10997
|
+
title: t22("common.viewFullscreen"),
|
|
10998
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_lucide_react14.Maximize2, { className: "w-3.5 h-3.5" })
|
|
10999
|
+
}
|
|
11000
|
+
),
|
|
11001
|
+
isPlan && /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
|
|
11002
|
+
"div",
|
|
11003
|
+
{
|
|
11004
|
+
className: cn2(
|
|
11005
|
+
"px-4 py-2 border-b border-border/30 flex items-center gap-2 bg-success/5 select-none",
|
|
11006
|
+
SIZE_CONFIG2.fontSize
|
|
11007
|
+
),
|
|
11008
|
+
children: [
|
|
11009
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_lucide_react14.ListTodo, { className: cn2(SIZE_CONFIG2.iconSize, "text-success") }),
|
|
11010
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "font-medium text-success", children: "Plan" })
|
|
11011
|
+
]
|
|
11012
|
+
}
|
|
11013
|
+
),
|
|
11014
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
11015
|
+
"div",
|
|
11016
|
+
{
|
|
11017
|
+
ref: contentRef,
|
|
11018
|
+
"data-search-root": "response",
|
|
11019
|
+
onMouseDown: handleSelectionPointerDown,
|
|
11020
|
+
onMouseUp: handleTextSelection,
|
|
11021
|
+
className: "pl-[22px] pr-[16px] py-3 text-sm overflow-y-auto scrollbar-hover",
|
|
11022
|
+
style: {
|
|
11023
|
+
maxHeight: MAX_HEIGHT2,
|
|
11024
|
+
// Subtle fade at top and bottom edges (16px) - only in dark mode for better contrast
|
|
11025
|
+
...isDarkMode && {
|
|
11026
|
+
maskImage: "linear-gradient(to bottom, transparent 0%, black 16px, black calc(100% - 16px), transparent 100%)",
|
|
11027
|
+
WebkitMaskImage: "linear-gradient(to bottom, transparent 0%, black 16px, black calc(100% - 16px), transparent 100%)"
|
|
11028
|
+
}
|
|
11029
|
+
},
|
|
11030
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { ref: contentLayerRef, className: "relative", children: [
|
|
11031
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
11032
|
+
Markdown2,
|
|
11033
|
+
{
|
|
11034
|
+
mode: "minimal",
|
|
11035
|
+
onUrlClick: onOpenUrl,
|
|
11036
|
+
onFileClick: onOpenFile,
|
|
11037
|
+
children: text
|
|
11038
|
+
}
|
|
11039
|
+
),
|
|
11040
|
+
annotationOverlayLayer
|
|
11041
|
+
] })
|
|
11042
|
+
}
|
|
11043
|
+
),
|
|
11044
|
+
!compactMode && /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: cn2(
|
|
11045
|
+
"pl-4 pr-2.5 py-2 border-t border-border/30 flex items-center justify-between bg-muted/20",
|
|
11046
|
+
SIZE_CONFIG2.fontSize
|
|
11047
|
+
), children: [
|
|
11048
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
11049
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
11050
|
+
"button",
|
|
11051
|
+
{
|
|
11052
|
+
onClick: handleCopy,
|
|
11053
|
+
className: cn2(
|
|
11054
|
+
"turn-action-btn flex items-center gap-1.5 transition-colors select-none",
|
|
11055
|
+
copied ? "text-success" : "text-muted-foreground hover:text-foreground",
|
|
11056
|
+
"focus:outline-none focus-visible:underline"
|
|
11057
|
+
),
|
|
11058
|
+
children: copied ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
|
|
11059
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_lucide_react14.Check, { className: SIZE_CONFIG2.iconSize }),
|
|
11060
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { children: t22("common.copied") })
|
|
11061
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
|
|
11062
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_lucide_react14.Copy, { className: SIZE_CONFIG2.iconSize }),
|
|
11063
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { children: t22("common.copy") })
|
|
11064
|
+
] })
|
|
11065
|
+
}
|
|
11066
|
+
),
|
|
11067
|
+
onPopOut && /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
|
|
11068
|
+
"button",
|
|
11069
|
+
{
|
|
11070
|
+
onClick: onPopOut,
|
|
11071
|
+
className: cn2(
|
|
11072
|
+
"turn-action-btn flex items-center gap-1.5 transition-colors select-none",
|
|
11073
|
+
"text-muted-foreground hover:text-foreground",
|
|
11074
|
+
"focus:outline-none focus-visible:underline"
|
|
11075
|
+
),
|
|
11076
|
+
children: [
|
|
11077
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(import_lucide_react14.FileText, { className: SIZE_CONFIG2.iconSize }),
|
|
11078
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { children: "Markdown" })
|
|
11079
|
+
]
|
|
11080
|
+
}
|
|
11081
|
+
)
|
|
11082
|
+
] }),
|
|
11083
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
11084
|
+
isPlan && showAcceptPlan && onAccept && onAcceptWithCompact && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
11085
|
+
"div",
|
|
11086
|
+
{
|
|
11087
|
+
className: cn2(
|
|
11088
|
+
"flex items-center gap-3 transition-all duration-200",
|
|
11089
|
+
isLastResponse ? "opacity-100 translate-x-0" : "opacity-0 translate-x-2 pointer-events-none"
|
|
11090
|
+
),
|
|
11091
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
11092
|
+
AcceptPlanDropdown2,
|
|
11093
|
+
{
|
|
11094
|
+
onAccept,
|
|
11095
|
+
onAcceptWithCompact,
|
|
11096
|
+
acceptLabel: hasActiveFollowUpAnnotations ? t22("plan.acceptAndSendFollowups") : t22("plan.acceptPlan"),
|
|
11097
|
+
acceptOptionLabel: hasActiveFollowUpAnnotations ? t22("plan.acceptAndSendFollowups") : t22("plan.accept")
|
|
11098
|
+
}
|
|
11099
|
+
)
|
|
11100
|
+
}
|
|
11101
|
+
),
|
|
11102
|
+
onBranch && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(BranchDropdown2, { onBranch })
|
|
11103
|
+
] })
|
|
11104
|
+
] })
|
|
11105
|
+
] }),
|
|
11106
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
11107
|
+
DocumentFormattedMarkdownOverlay2,
|
|
11108
|
+
{
|
|
11109
|
+
content: text,
|
|
11110
|
+
isOpen: isFullscreen,
|
|
11111
|
+
onClose: () => setIsFullscreen(false),
|
|
11112
|
+
variant: isPlan ? "plan" : void 0,
|
|
11113
|
+
onOpenUrl,
|
|
11114
|
+
onOpenFile,
|
|
11115
|
+
sessionId,
|
|
11116
|
+
messageId,
|
|
11117
|
+
annotations,
|
|
11118
|
+
onAddAnnotation,
|
|
11119
|
+
onRemoveAnnotation,
|
|
11120
|
+
onUpdateAnnotation,
|
|
11121
|
+
sendMessageKey,
|
|
11122
|
+
openAnnotationRequest,
|
|
11123
|
+
isStreaming
|
|
11124
|
+
}
|
|
11125
|
+
),
|
|
11126
|
+
selectionMenu
|
|
11127
|
+
] });
|
|
11128
|
+
}
|
|
11129
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(import_jsx_runtime63.Fragment, { children: [
|
|
11130
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "bg-background shadow-minimal rounded-[8px] overflow-hidden group", children: [
|
|
11131
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
11132
|
+
"div",
|
|
11133
|
+
{
|
|
11134
|
+
ref: contentRef,
|
|
11135
|
+
"data-search-root": "response",
|
|
11136
|
+
onMouseDown: handleSelectionPointerDown,
|
|
11137
|
+
onMouseUp: handleTextSelection,
|
|
11138
|
+
className: "pl-[22px] pr-4 py-3 text-sm overflow-y-auto scrollbar-hover",
|
|
11139
|
+
style: {
|
|
11140
|
+
maxHeight: MAX_HEIGHT2,
|
|
11141
|
+
// Subtle fade at top and bottom edges (16px) - only in dark mode for better contrast
|
|
11142
|
+
...isDarkMode && {
|
|
11143
|
+
maskImage: "linear-gradient(to bottom, transparent 0%, black 16px, black calc(100% - 16px), transparent 100%)",
|
|
11144
|
+
WebkitMaskImage: "linear-gradient(to bottom, transparent 0%, black 16px, black calc(100% - 16px), transparent 100%)"
|
|
11145
|
+
}
|
|
11146
|
+
},
|
|
11147
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { ref: contentLayerRef, className: "relative", children: [
|
|
11148
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
11149
|
+
Markdown2,
|
|
11150
|
+
{
|
|
11151
|
+
mode: "minimal",
|
|
11152
|
+
onUrlClick: onOpenUrl,
|
|
11153
|
+
onFileClick: onOpenFile,
|
|
11154
|
+
children: displayedText
|
|
11155
|
+
}
|
|
11156
|
+
),
|
|
11157
|
+
annotationOverlayLayer
|
|
11158
|
+
] })
|
|
11159
|
+
}
|
|
11160
|
+
),
|
|
11161
|
+
!compactMode && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: cn2("px-4 py-2 border-t border-border/30 flex items-center bg-muted/20", SIZE_CONFIG2.fontSize), children: /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "flex items-center gap-2 text-muted-foreground", children: [
|
|
11162
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(Spinner2, { className: SIZE_CONFIG2.spinnerSize }),
|
|
11163
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { children: "Streaming..." })
|
|
11164
|
+
] }) })
|
|
11165
|
+
] }),
|
|
11166
|
+
selectionMenu
|
|
11167
|
+
] });
|
|
11168
|
+
}
|
|
11169
|
+
function TodoStatusIcon2({ status }) {
|
|
11170
|
+
switch (status) {
|
|
11171
|
+
case "pending":
|
|
11172
|
+
return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_lucide_react17.Circle, { className: cn2(SIZE_CONFIG2.iconSize, "shrink-0 text-muted-foreground/50") });
|
|
11173
|
+
case "in_progress":
|
|
11174
|
+
return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("div", { className: cn2(SIZE_CONFIG2.iconSize, "flex items-center justify-center shrink-0"), children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(Spinner2, { className: SIZE_CONFIG2.spinnerSize }) });
|
|
11175
|
+
case "completed":
|
|
11176
|
+
return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_lucide_react17.CircleCheck, { className: cn2(SIZE_CONFIG2.iconSize, "shrink-0 text-accent") });
|
|
11177
|
+
case "interrupted":
|
|
11178
|
+
return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(import_lucide_react17.Ban, { className: cn2(SIZE_CONFIG2.iconSize, "shrink-0 text-muted-foreground/50") });
|
|
11179
|
+
}
|
|
11180
|
+
}
|
|
11181
|
+
function TodoRow2({ todo }) {
|
|
11182
|
+
const displayText = todo.status === "in_progress" && todo.activeForm ? todo.activeForm : todo.content;
|
|
11183
|
+
return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: cn2(
|
|
11184
|
+
"flex items-center gap-2 py-0.5 text-muted-foreground",
|
|
11185
|
+
SIZE_CONFIG2.fontSize,
|
|
11186
|
+
todo.status === "completed" && "opacity-50"
|
|
11187
|
+
), children: [
|
|
11188
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)(TodoStatusIcon2, { status: todo.status }),
|
|
11189
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: cn2(
|
|
11190
|
+
"truncate flex-1",
|
|
11191
|
+
todo.status === "completed" && "line-through"
|
|
11192
|
+
), children: displayText })
|
|
11193
|
+
] });
|
|
11194
|
+
}
|
|
11195
|
+
function TodoList2({ todos }) {
|
|
11196
|
+
if (todos.length === 0) return null;
|
|
11197
|
+
return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "pl-4 pr-2 pt-2.5 pb-1.5 space-y-0.5 border-l-2 border-muted ml-[13px]", children: [
|
|
11198
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("div", { className: cn2("text-muted-foreground pb-1", SIZE_CONFIG2.fontSize), children: "Todo List" }),
|
|
11199
|
+
todos.map((todo, index) => /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
|
|
11200
|
+
import_react30.motion.div,
|
|
11201
|
+
{
|
|
11202
|
+
initial: { opacity: 0, x: -8 },
|
|
11203
|
+
animate: { opacity: 1, x: 0 },
|
|
11204
|
+
transition: { delay: index * 0.03 },
|
|
11205
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(TodoRow2, { todo })
|
|
11206
|
+
},
|
|
11207
|
+
`${todo.content}-${index}`
|
|
11208
|
+
))
|
|
11209
|
+
] });
|
|
11210
|
+
}
|
|
11211
|
+
var TurnCard3 = React102.memo(function TurnCard22({
|
|
11212
|
+
sessionId,
|
|
11213
|
+
turnId,
|
|
11214
|
+
activities,
|
|
11215
|
+
response,
|
|
11216
|
+
intent,
|
|
11217
|
+
isStreaming,
|
|
11218
|
+
isComplete,
|
|
11219
|
+
defaultExpanded = false,
|
|
11220
|
+
isExpanded: externalIsExpanded,
|
|
11221
|
+
onExpandedChange,
|
|
11222
|
+
expandedActivityGroups: externalExpandedActivityGroups,
|
|
11223
|
+
onExpandedActivityGroupsChange,
|
|
11224
|
+
onOpenFile,
|
|
11225
|
+
onOpenUrl,
|
|
11226
|
+
onPopOut,
|
|
11227
|
+
onOpenDetails,
|
|
11228
|
+
onOpenActivityDetails,
|
|
11229
|
+
onOpenMultiFileDiff,
|
|
11230
|
+
hasEditOrWriteActivities,
|
|
11231
|
+
todos,
|
|
11232
|
+
renderActionsMenu,
|
|
11233
|
+
onAcceptPlan,
|
|
11234
|
+
onAcceptPlanWithCompact,
|
|
11235
|
+
isLastResponse,
|
|
11236
|
+
sessionFolderPath,
|
|
11237
|
+
displayMode = "detailed",
|
|
11238
|
+
animateResponse = false,
|
|
11239
|
+
compactMode = false,
|
|
11240
|
+
onBranch,
|
|
11241
|
+
onAddAnnotation,
|
|
11242
|
+
onRemoveAnnotation,
|
|
11243
|
+
onUpdateAnnotation,
|
|
11244
|
+
sendMessageKey = "enter",
|
|
11245
|
+
onSaveAndSendFollowUp,
|
|
11246
|
+
hasActiveFollowUpAnnotations = false,
|
|
11247
|
+
openAnnotationRequest,
|
|
11248
|
+
annotationInteractionMode = "interactive"
|
|
11249
|
+
}) {
|
|
11250
|
+
const turnPhase = (0, import_react21.useMemo)(() => {
|
|
11251
|
+
const turnData = {
|
|
11252
|
+
isComplete,
|
|
11253
|
+
response,
|
|
11254
|
+
activities
|
|
11255
|
+
};
|
|
11256
|
+
return deriveTurnPhase2(turnData);
|
|
11257
|
+
}, [isComplete, response, activities]);
|
|
11258
|
+
const [localExpandedTurns, setLocalExpandedTurns] = (0, import_react21.useState)(() => defaultExpanded ? /* @__PURE__ */ new Set([turnId]) : /* @__PURE__ */ new Set());
|
|
11259
|
+
const isExpanded = externalIsExpanded ?? localExpandedTurns.has(turnId);
|
|
11260
|
+
const hasUserToggled = (0, import_react21.useRef)(false);
|
|
11261
|
+
const activitiesContainerRef = (0, import_react21.useRef)(null);
|
|
11262
|
+
const hasMounted = (0, import_react21.useRef)(false);
|
|
11263
|
+
(0, import_react21.useEffect)(() => {
|
|
11264
|
+
hasMounted.current = true;
|
|
11265
|
+
}, []);
|
|
11266
|
+
const toggleExpanded = (0, import_react21.useCallback)(() => {
|
|
11267
|
+
hasUserToggled.current = true;
|
|
11268
|
+
const newExpanded = !isExpanded;
|
|
11269
|
+
if (onExpandedChange) {
|
|
11270
|
+
onExpandedChange(newExpanded);
|
|
11271
|
+
} else {
|
|
11272
|
+
setLocalExpandedTurns((prev) => {
|
|
11273
|
+
const next = new Set(prev);
|
|
11274
|
+
if (next.has(turnId)) {
|
|
11275
|
+
next.delete(turnId);
|
|
11276
|
+
} else {
|
|
11277
|
+
next.add(turnId);
|
|
11278
|
+
}
|
|
11279
|
+
return next;
|
|
11280
|
+
});
|
|
11281
|
+
}
|
|
11282
|
+
}, [turnId, isExpanded, onExpandedChange]);
|
|
11283
|
+
(0, import_react21.useEffect)(() => {
|
|
11284
|
+
if (isExpanded && hasUserToggled.current && activitiesContainerRef.current) {
|
|
11285
|
+
const timer = setTimeout(() => {
|
|
11286
|
+
activitiesContainerRef.current?.scrollTo({
|
|
11287
|
+
top: activitiesContainerRef.current.scrollHeight,
|
|
11288
|
+
behavior: "smooth"
|
|
11289
|
+
});
|
|
11290
|
+
}, 260);
|
|
11291
|
+
return () => clearTimeout(timer);
|
|
11292
|
+
}
|
|
11293
|
+
}, [isExpanded]);
|
|
11294
|
+
const [localExpandedActivityGroups, setLocalExpandedActivityGroups] = (0, import_react21.useState)(/* @__PURE__ */ new Set());
|
|
11295
|
+
const expandedActivityGroups = externalExpandedActivityGroups ?? localExpandedActivityGroups;
|
|
11296
|
+
const handleExpandedActivityGroupsChange = onExpandedActivityGroupsChange ?? setLocalExpandedActivityGroups;
|
|
11297
|
+
const isBuffering = (0, import_react21.useMemo)(
|
|
11298
|
+
() => isResponseBuffering2(response),
|
|
11299
|
+
[response]
|
|
11300
|
+
);
|
|
11301
|
+
const previewText = (0, import_react21.useMemo)(
|
|
11302
|
+
() => getPreviewText2(activities, intent, isStreaming, !!response, isComplete),
|
|
11303
|
+
[activities, intent, isStreaming, response, isComplete, import_i18next3.default.language]
|
|
11304
|
+
);
|
|
11305
|
+
const allSortedActivities = (0, import_react21.useMemo)(
|
|
11306
|
+
() => [...activities].sort((a, b) => a.timestamp - b.timestamp),
|
|
11307
|
+
[activities]
|
|
11308
|
+
);
|
|
11309
|
+
const planActivities = (0, import_react21.useMemo)(
|
|
11310
|
+
() => allSortedActivities.filter((a) => a.type === "plan"),
|
|
11311
|
+
[allSortedActivities]
|
|
11312
|
+
);
|
|
11313
|
+
const sortedActivities = (0, import_react21.useMemo)(
|
|
11314
|
+
() => allSortedActivities.filter((a) => a.type !== "plan"),
|
|
11315
|
+
[allSortedActivities]
|
|
11316
|
+
);
|
|
11317
|
+
const hasTaskSubagents = (0, import_react21.useMemo)(
|
|
11318
|
+
() => sortedActivities.some((a) => a.toolName === "Task"),
|
|
11319
|
+
[sortedActivities]
|
|
11320
|
+
);
|
|
11321
|
+
const groupedActivities = (0, import_react21.useMemo)(
|
|
11322
|
+
() => hasTaskSubagents ? groupActivitiesByParent2(sortedActivities) : null,
|
|
11323
|
+
[sortedActivities, hasTaskSubagents]
|
|
11324
|
+
);
|
|
11325
|
+
const lastChildSet = (0, import_react21.useMemo)(
|
|
11326
|
+
() => !hasTaskSubagents ? computeLastChildSet2(sortedActivities) : /* @__PURE__ */ new Set(),
|
|
11327
|
+
[sortedActivities, hasTaskSubagents]
|
|
11328
|
+
);
|
|
11329
|
+
if (activities.length === 0 && !response && isComplete) {
|
|
11330
|
+
return null;
|
|
11331
|
+
}
|
|
11332
|
+
const hasNoMeaningfulWork = activities.length > 0 && activities.every((a) => {
|
|
11333
|
+
if (a.type === "tool") return a.status === "error";
|
|
11334
|
+
if (a.type === "intermediate") return !a.content?.trim();
|
|
11335
|
+
if (a.type === "plan") return false;
|
|
11336
|
+
return true;
|
|
11337
|
+
}) && !response;
|
|
11338
|
+
if (hasNoMeaningfulWork) {
|
|
11339
|
+
return null;
|
|
11340
|
+
}
|
|
11341
|
+
const hasActivities = sortedActivities.length > 0;
|
|
11342
|
+
const isThinking = shouldShowThinkingIndicator2(turnPhase, isBuffering);
|
|
11343
|
+
return /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className: "space-y-1", children: [
|
|
11344
|
+
hasActivities && /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className: "group select-none", "data-search-exclude": "true", children: [
|
|
11345
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(
|
|
11346
|
+
"button",
|
|
11347
|
+
{
|
|
11348
|
+
onClick: toggleExpanded,
|
|
11349
|
+
className: cn2(
|
|
11350
|
+
"flex items-center gap-2 w-full pl-2.5 pr-1.5 py-1.5 rounded-[8px] text-left",
|
|
11351
|
+
SIZE_CONFIG2.fontSize,
|
|
11352
|
+
"text-muted-foreground",
|
|
11353
|
+
"hover:bg-muted/50 transition-colors",
|
|
11354
|
+
"focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
|
11355
|
+
),
|
|
11356
|
+
children: [
|
|
11357
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
11358
|
+
import_react22.motion.div,
|
|
11359
|
+
{
|
|
11360
|
+
initial: false,
|
|
11361
|
+
animate: { rotate: isExpanded ? 90 : 0 },
|
|
11362
|
+
transition: { duration: 0.15, ease: "easeOut" },
|
|
11363
|
+
className: cn2(SIZE_CONFIG2.iconSize, "flex items-center justify-center shrink-0"),
|
|
11364
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(import_lucide_react11.ChevronRight, { className: SIZE_CONFIG2.iconSize })
|
|
11365
|
+
}
|
|
11366
|
+
),
|
|
11367
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("span", { className: "-ml-0.5 shrink-0 px-1.5 py-0.5 rounded-[4px] bg-background shadow-minimal text-[10px] font-medium tabular-nums", children: activities.length }),
|
|
11368
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("span", { className: "relative flex-1 min-w-0 h-5 flex items-center", children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(import_react22.AnimatePresence, { initial: false, children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
11369
|
+
import_react22.motion.span,
|
|
11370
|
+
{
|
|
11371
|
+
initial: { opacity: 0 },
|
|
11372
|
+
animate: { opacity: 1 },
|
|
11373
|
+
exit: { opacity: 0 },
|
|
11374
|
+
transition: { duration: 0.2 },
|
|
11375
|
+
className: "absolute inset-0 truncate",
|
|
11376
|
+
children: previewText
|
|
11377
|
+
},
|
|
11378
|
+
previewText
|
|
11379
|
+
) }) }),
|
|
11380
|
+
renderActionsMenu ? renderActionsMenu() : /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
11381
|
+
TurnCardActionsMenu2,
|
|
11382
|
+
{
|
|
11383
|
+
onOpenDetails,
|
|
11384
|
+
onOpenMultiFileDiff,
|
|
11385
|
+
hasEditOrWriteActivities
|
|
11386
|
+
}
|
|
11387
|
+
)
|
|
11388
|
+
]
|
|
11389
|
+
}
|
|
11390
|
+
),
|
|
11391
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(import_react22.AnimatePresence, { initial: false, children: isExpanded && /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(
|
|
11392
|
+
import_react22.motion.div,
|
|
11393
|
+
{
|
|
11394
|
+
initial: { height: 0, opacity: 0 },
|
|
11395
|
+
animate: { height: "auto", opacity: 1 },
|
|
11396
|
+
exit: { height: 0, opacity: 0 },
|
|
11397
|
+
transition: {
|
|
11398
|
+
height: { duration: 0.25, ease: [0.4, 0, 0.2, 1] },
|
|
11399
|
+
opacity: { duration: 0.15 }
|
|
11400
|
+
},
|
|
11401
|
+
className: "overflow-hidden",
|
|
11402
|
+
children: [
|
|
11403
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
11404
|
+
"div",
|
|
11405
|
+
{
|
|
11406
|
+
ref: activitiesContainerRef,
|
|
11407
|
+
className: cn2(
|
|
11408
|
+
"pl-4 pr-2 py-0 space-y-0.5 border-l-2 border-muted ml-[13px]",
|
|
11409
|
+
sortedActivities.length > SIZE_CONFIG2.maxVisibleActivities && "rounded-r-md overflow-y-auto scrollbar-hover py-1.5"
|
|
11410
|
+
),
|
|
11411
|
+
style: {
|
|
11412
|
+
maxHeight: sortedActivities.length > SIZE_CONFIG2.maxVisibleActivities ? SIZE_CONFIG2.maxVisibleActivities * SIZE_CONFIG2.activityRowHeight : void 0
|
|
11413
|
+
},
|
|
11414
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(import_react22.AnimatePresence, { mode: "sync", children: [
|
|
11415
|
+
groupedActivities ? groupedActivities.map((item, index) => isActivityGroup2(item) ? /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
11416
|
+
ActivityGroupRow2,
|
|
11417
|
+
{
|
|
11418
|
+
group: item,
|
|
11419
|
+
expandedGroups: expandedActivityGroups,
|
|
11420
|
+
onExpandedGroupsChange: handleExpandedActivityGroupsChange,
|
|
11421
|
+
onOpenActivityDetails,
|
|
11422
|
+
animationIndex: index,
|
|
11423
|
+
sessionFolderPath,
|
|
11424
|
+
displayMode
|
|
11425
|
+
},
|
|
11426
|
+
item.parent.id
|
|
11427
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
11428
|
+
import_react22.motion.div,
|
|
11429
|
+
{
|
|
11430
|
+
initial: hasUserToggled.current || hasMounted.current ? { opacity: 0, x: -8 } : false,
|
|
11431
|
+
animate: { opacity: 1, x: 0 },
|
|
11432
|
+
transition: { delay: hasUserToggled.current ? index < SIZE_CONFIG2.staggeredAnimationLimit ? index * 0.03 : SIZE_CONFIG2.staggeredAnimationLimit * 0.03 : 0 },
|
|
11433
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
11434
|
+
ActivityRow2,
|
|
11435
|
+
{
|
|
11436
|
+
activity: item,
|
|
11437
|
+
onOpenDetails: onOpenActivityDetails ? () => onOpenActivityDetails(item) : void 0,
|
|
11438
|
+
sessionFolderPath,
|
|
11439
|
+
displayMode
|
|
11440
|
+
}
|
|
11441
|
+
)
|
|
11442
|
+
},
|
|
11443
|
+
item.id
|
|
11444
|
+
)) : (
|
|
11445
|
+
/* Flat view for simple tool calls */
|
|
11446
|
+
sortedActivities.map((activity, index) => /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
11447
|
+
import_react22.motion.div,
|
|
11448
|
+
{
|
|
11449
|
+
initial: hasUserToggled.current || hasMounted.current ? { opacity: 0, x: -8 } : false,
|
|
11450
|
+
animate: { opacity: 1, x: 0 },
|
|
11451
|
+
transition: { delay: hasUserToggled.current ? index < SIZE_CONFIG2.staggeredAnimationLimit ? index * 0.03 : SIZE_CONFIG2.staggeredAnimationLimit * 0.03 : 0 },
|
|
11452
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
11453
|
+
ActivityRow2,
|
|
11454
|
+
{
|
|
11455
|
+
activity,
|
|
11456
|
+
onOpenDetails: onOpenActivityDetails ? () => onOpenActivityDetails(activity) : void 0,
|
|
11457
|
+
isLastChild: lastChildSet.has(activity.id),
|
|
11458
|
+
sessionFolderPath,
|
|
11459
|
+
displayMode
|
|
11460
|
+
}
|
|
11461
|
+
)
|
|
11462
|
+
},
|
|
11463
|
+
activity.id
|
|
11464
|
+
))
|
|
11465
|
+
),
|
|
11466
|
+
isThinking && /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(
|
|
11467
|
+
import_react22.motion.div,
|
|
11468
|
+
{
|
|
11469
|
+
initial: { opacity: 0, x: -8 },
|
|
11470
|
+
animate: { opacity: 1, x: 0 },
|
|
11471
|
+
transition: {
|
|
11472
|
+
delay: Math.min(sortedActivities.length, SIZE_CONFIG2.staggeredAnimationLimit) * 0.03,
|
|
11473
|
+
duration: 0.3,
|
|
11474
|
+
ease: "easeOut"
|
|
11475
|
+
},
|
|
11476
|
+
className: cn2("flex items-center gap-2 py-0.5 text-muted-foreground/70", SIZE_CONFIG2.fontSize),
|
|
11477
|
+
children: [
|
|
11478
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(Spinner2, { className: SIZE_CONFIG2.spinnerSize }),
|
|
11479
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("span", { children: isBuffering ? "Preparing response..." : "Thinking..." })
|
|
11480
|
+
]
|
|
11481
|
+
},
|
|
11482
|
+
"thinking"
|
|
11483
|
+
)
|
|
11484
|
+
] })
|
|
11485
|
+
}
|
|
11486
|
+
),
|
|
11487
|
+
todos && todos.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(TodoList2, { todos })
|
|
11488
|
+
]
|
|
11489
|
+
}
|
|
11490
|
+
) })
|
|
11491
|
+
] }),
|
|
11492
|
+
!hasActivities && isThinking && /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className: cn2("flex items-center gap-2 px-3 py-1.5 text-muted-foreground", SIZE_CONFIG2.fontSize), children: [
|
|
11493
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(Spinner2, { className: SIZE_CONFIG2.spinnerSize }),
|
|
11494
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("span", { children: isBuffering ? "Preparing response..." : "Thinking..." })
|
|
11495
|
+
] }),
|
|
11496
|
+
planActivities.map((planActivity, index) => /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("div", { className: cn2("select-text", (hasActivities || index > 0) && "mt-2"), children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
11497
|
+
ResponseCard2,
|
|
11498
|
+
{
|
|
11499
|
+
text: planActivity.content || "",
|
|
11500
|
+
isStreaming: false,
|
|
11501
|
+
sessionId,
|
|
11502
|
+
onOpenFile,
|
|
11503
|
+
onOpenUrl,
|
|
11504
|
+
onPopOut: onPopOut ? () => onPopOut(planActivity.content || "") : void 0,
|
|
11505
|
+
variant: "plan",
|
|
11506
|
+
messageId: planActivity.messageId,
|
|
11507
|
+
annotations: planActivity.annotations,
|
|
11508
|
+
onAddAnnotation,
|
|
11509
|
+
onRemoveAnnotation,
|
|
11510
|
+
onUpdateAnnotation,
|
|
11511
|
+
onSaveAndSendFollowUp,
|
|
11512
|
+
onAccept: onAcceptPlan,
|
|
11513
|
+
onAcceptWithCompact: onAcceptPlanWithCompact,
|
|
11514
|
+
isLastResponse: isLastResponse && index === planActivities.length - 1,
|
|
11515
|
+
compactMode,
|
|
11516
|
+
onBranch: onBranch ? (options) => onBranch(planActivity.messageId ?? planActivity.id, options) : void 0,
|
|
11517
|
+
sendMessageKey,
|
|
11518
|
+
hasActiveFollowUpAnnotations,
|
|
11519
|
+
openAnnotationRequest,
|
|
11520
|
+
annotationInteractionMode
|
|
11521
|
+
}
|
|
11522
|
+
) }, planActivity.id)),
|
|
11523
|
+
animateResponse && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(import_react22.AnimatePresence, { children: response && !isBuffering && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
11524
|
+
import_react22.motion.div,
|
|
11525
|
+
{
|
|
11526
|
+
initial: { opacity: 0, y: 8 },
|
|
11527
|
+
animate: { opacity: 1, y: 0 },
|
|
11528
|
+
transition: { duration: 0.3, ease: "easeOut" },
|
|
11529
|
+
className: cn2("select-text", hasActivities && "mt-2"),
|
|
11530
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
11531
|
+
ResponseCard2,
|
|
11532
|
+
{
|
|
11533
|
+
text: response.text,
|
|
11534
|
+
isStreaming: response.isStreaming,
|
|
11535
|
+
streamStartTime: response.streamStartTime,
|
|
11536
|
+
sessionId,
|
|
11537
|
+
onOpenFile,
|
|
11538
|
+
onOpenUrl,
|
|
11539
|
+
onPopOut: onPopOut ? () => onPopOut(response.text) : void 0,
|
|
11540
|
+
variant: response.isPlan ? "plan" : "response",
|
|
11541
|
+
messageId: response.messageId,
|
|
11542
|
+
annotations: response.annotations,
|
|
11543
|
+
onAddAnnotation,
|
|
11544
|
+
onRemoveAnnotation,
|
|
11545
|
+
onUpdateAnnotation,
|
|
11546
|
+
onSaveAndSendFollowUp,
|
|
11547
|
+
onAccept: onAcceptPlan,
|
|
11548
|
+
onAcceptWithCompact: onAcceptPlanWithCompact,
|
|
11549
|
+
isLastResponse,
|
|
11550
|
+
compactMode,
|
|
11551
|
+
onBranch: onBranch && response.messageId ? (options) => onBranch(response.messageId, options) : void 0,
|
|
11552
|
+
sendMessageKey,
|
|
11553
|
+
hasActiveFollowUpAnnotations,
|
|
11554
|
+
openAnnotationRequest,
|
|
11555
|
+
annotationInteractionMode
|
|
11556
|
+
}
|
|
11557
|
+
)
|
|
11558
|
+
}
|
|
11559
|
+
) }),
|
|
11560
|
+
!animateResponse && response && !isBuffering && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("div", { className: cn2("select-text", hasActivities && "mt-2"), children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
11561
|
+
ResponseCard2,
|
|
11562
|
+
{
|
|
11563
|
+
text: response.text,
|
|
11564
|
+
isStreaming: response.isStreaming,
|
|
11565
|
+
streamStartTime: response.streamStartTime,
|
|
11566
|
+
sessionId,
|
|
11567
|
+
onOpenFile,
|
|
11568
|
+
onOpenUrl,
|
|
11569
|
+
onPopOut: onPopOut ? () => onPopOut(response.text) : void 0,
|
|
11570
|
+
variant: response.isPlan ? "plan" : "response",
|
|
11571
|
+
messageId: response.messageId,
|
|
11572
|
+
annotations: response.annotations,
|
|
11573
|
+
onAddAnnotation,
|
|
11574
|
+
onRemoveAnnotation,
|
|
11575
|
+
onUpdateAnnotation,
|
|
11576
|
+
onSaveAndSendFollowUp,
|
|
11577
|
+
onAccept: onAcceptPlan,
|
|
11578
|
+
onAcceptWithCompact: onAcceptPlanWithCompact,
|
|
11579
|
+
isLastResponse,
|
|
11580
|
+
compactMode,
|
|
11581
|
+
onBranch: onBranch && response.messageId ? (options) => onBranch(response.messageId, options) : void 0,
|
|
11582
|
+
sendMessageKey,
|
|
11583
|
+
hasActiveFollowUpAnnotations,
|
|
11584
|
+
openAnnotationRequest,
|
|
11585
|
+
annotationInteractionMode
|
|
11586
|
+
}
|
|
11587
|
+
) })
|
|
11588
|
+
] });
|
|
11589
|
+
}, (prev, next) => {
|
|
11590
|
+
if (prev.isStreaming || next.isStreaming) return false;
|
|
11591
|
+
if (!prev.isComplete || !next.isComplete) return false;
|
|
11592
|
+
if (prev.isExpanded !== next.isExpanded) return false;
|
|
11593
|
+
if (prev.expandedActivityGroups !== next.expandedActivityGroups) return false;
|
|
11594
|
+
if (prev.isLastResponse !== next.isLastResponse) return false;
|
|
11595
|
+
if (prev.displayMode !== next.displayMode) return false;
|
|
11596
|
+
if (prev.annotationInteractionMode !== next.annotationInteractionMode) return false;
|
|
11597
|
+
if (prev.activities !== next.activities) {
|
|
11598
|
+
if (prev.activities.length !== next.activities.length) return false;
|
|
11599
|
+
for (let i = 0; i < prev.activities.length; i++) {
|
|
11600
|
+
const pa = prev.activities[i], na = next.activities[i];
|
|
11601
|
+
if (pa.id !== na.id || pa.status !== na.status || pa.content !== na.content) return false;
|
|
11602
|
+
}
|
|
11603
|
+
}
|
|
11604
|
+
if (prev.response !== next.response) {
|
|
11605
|
+
if (!prev.response !== !next.response) return false;
|
|
11606
|
+
if (prev.response && next.response) {
|
|
11607
|
+
if (prev.response.text !== next.response.text || prev.response.isStreaming !== next.response.isStreaming || prev.response.messageId !== next.response.messageId || prev.response.annotations?.length !== next.response.annotations?.length) return false;
|
|
11608
|
+
}
|
|
11609
|
+
}
|
|
11610
|
+
if (prev.openAnnotationRequest !== next.openAnnotationRequest) return false;
|
|
11611
|
+
if (prev.hasActiveFollowUpAnnotations !== next.hasActiveFollowUpAnnotations) return false;
|
|
11612
|
+
return prev.sessionId === next.sessionId && prev.turnId === next.turnId;
|
|
11613
|
+
});
|
|
11614
|
+
var PlatformContext2 = (0, import_react34.createContext)({});
|
|
11615
|
+
var initialRuntimeState = {
|
|
11616
|
+
status: "idle",
|
|
11617
|
+
acceptedMessages: [],
|
|
11618
|
+
queuedMessages: []
|
|
11619
|
+
};
|
|
11620
|
+
function useAgentSession(options) {
|
|
11621
|
+
const createRuntimeRef = (0, import_react41.useRef)(options.createRuntime);
|
|
11622
|
+
createRuntimeRef.current = options.createRuntime;
|
|
11623
|
+
const runtime = (0, import_react41.useMemo)(() => {
|
|
11624
|
+
return createDeferredAgentRuntime({
|
|
11625
|
+
provider: options.provider ?? "agent",
|
|
11626
|
+
runtimeKind: options.runtimeKind ?? "app-server",
|
|
11627
|
+
sessionId: options.sessionId,
|
|
11628
|
+
createRuntime: () => createRuntimeRef.current()
|
|
11629
|
+
});
|
|
11630
|
+
}, [options.sessionId]);
|
|
11631
|
+
(0, import_react41.useEffect)(() => {
|
|
11632
|
+
return () => {
|
|
11633
|
+
void runtime.disposeIfCreated();
|
|
11634
|
+
};
|
|
11635
|
+
}, [runtime]);
|
|
11636
|
+
return { runtime, sessionId: options.sessionId };
|
|
11637
|
+
}
|
|
11638
|
+
function createDeferredAgentRuntime(options) {
|
|
11639
|
+
let runtime = null;
|
|
11640
|
+
let disposed = false;
|
|
11641
|
+
const getRuntime = () => {
|
|
11642
|
+
if (disposed) {
|
|
11643
|
+
throw new Error("Agent runtime has been disposed");
|
|
11644
|
+
}
|
|
11645
|
+
runtime ??= options.createRuntime();
|
|
11646
|
+
return runtime;
|
|
11647
|
+
};
|
|
11648
|
+
return {
|
|
11649
|
+
get sessionId() {
|
|
11650
|
+
return runtime?.sessionId ?? options.sessionId;
|
|
11651
|
+
},
|
|
11652
|
+
get provider() {
|
|
11653
|
+
return runtime?.provider ?? options.provider;
|
|
11654
|
+
},
|
|
11655
|
+
get runtimeKind() {
|
|
11656
|
+
return runtime?.runtimeKind ?? options.runtimeKind;
|
|
11657
|
+
},
|
|
11658
|
+
events: {
|
|
11659
|
+
connect(onEvent, onError, onClose) {
|
|
11660
|
+
getRuntime().events.connect(onEvent, onError, onClose);
|
|
11661
|
+
},
|
|
11662
|
+
disconnect() {
|
|
11663
|
+
runtime?.events.disconnect();
|
|
11664
|
+
},
|
|
11665
|
+
isConnected() {
|
|
11666
|
+
return runtime?.events.isConnected() ?? false;
|
|
11667
|
+
}
|
|
11668
|
+
},
|
|
11669
|
+
commands: {
|
|
11670
|
+
sendMessage(message, sendOptions) {
|
|
11671
|
+
return getRuntime().commands.sendMessage(message, sendOptions);
|
|
11672
|
+
},
|
|
11673
|
+
abort(reason) {
|
|
11674
|
+
return getRuntime().commands.abort(reason);
|
|
11675
|
+
},
|
|
11676
|
+
respondToPermission(requestId, allowed, remember) {
|
|
11677
|
+
return getRuntime().commands.respondToPermission(requestId, allowed, remember);
|
|
11678
|
+
},
|
|
11679
|
+
async resumeTool(runId, resumeData) {
|
|
11680
|
+
const commands = getRuntime().commands;
|
|
11681
|
+
if (!commands.resumeTool) {
|
|
11682
|
+
throw new Error(`resumeTool is not supported by the ${options.provider} runtime`);
|
|
11683
|
+
}
|
|
11684
|
+
await commands.resumeTool(runId, resumeData);
|
|
11685
|
+
},
|
|
11686
|
+
dispose() {
|
|
11687
|
+
disposed = true;
|
|
11688
|
+
const current = runtime;
|
|
11689
|
+
runtime = null;
|
|
11690
|
+
return current?.commands.dispose() ?? Promise.resolve();
|
|
11691
|
+
}
|
|
11692
|
+
},
|
|
11693
|
+
preflight() {
|
|
11694
|
+
return getRuntime().preflight();
|
|
11695
|
+
},
|
|
11696
|
+
fetchTimeline(request) {
|
|
11697
|
+
return getRuntime().fetchTimeline(request);
|
|
11698
|
+
},
|
|
11699
|
+
getState() {
|
|
11700
|
+
return runtime?.getState() ?? {
|
|
11701
|
+
status: initialRuntimeState.status,
|
|
11702
|
+
acceptedMessages: [],
|
|
11703
|
+
queuedMessages: []
|
|
11704
|
+
};
|
|
11705
|
+
},
|
|
11706
|
+
async disposeIfCreated() {
|
|
11707
|
+
if (!runtime) return;
|
|
11708
|
+
const current = runtime;
|
|
11709
|
+
runtime = null;
|
|
11710
|
+
await current.commands.dispose();
|
|
11711
|
+
}
|
|
11712
|
+
};
|
|
11713
|
+
}
|
|
7900
11714
|
// Annotate the CommonJS export names for ESM import in node:
|
|
7901
11715
|
0 && (module.exports = {
|
|
7902
11716
|
ActivityDetailsPanel,
|
|
@@ -7957,6 +11771,7 @@ function TimelineAgentChatPanel({
|
|
|
7957
11771
|
toStoredSession,
|
|
7958
11772
|
updateMessageAt,
|
|
7959
11773
|
useAgentChatSession,
|
|
11774
|
+
useAgentSession,
|
|
7960
11775
|
useEventProcessor,
|
|
7961
11776
|
useTimelineAgentChatSession
|
|
7962
11777
|
});
|