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