@workerdeck/ui 2.15.0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -5
- package/build/{SessionPanel-BVKqPs_3.d.mts → SessionPanel-C1bU4yTM.d.mts} +11 -11
- package/build/index.d.mts +46 -9
- package/build/index.mjs +70 -43
- package/build/index.mjs.map +1 -1
- package/build/scoped.css +156 -16
- package/build/{use-path-links-BgWXmfAS.mjs → use-path-links-BEWxt0ZM.mjs} +1566 -852
- package/build/use-path-links-BEWxt0ZM.mjs.map +1 -0
- package/build/workspace.d.mts +3 -3
- package/build/workspace.mjs +3 -3
- package/build/workspace.mjs.map +1 -1
- package/package.json +4 -4
- package/src/components/agent/PermissionPrompt.tsx +16 -2
- package/src/components/agent/Response.tsx +8 -1
- package/src/components/agent/SessionBrowser.tsx +6 -0
- package/src/components/agent/SessionItem.tsx +3 -0
- package/src/components/agent/SessionPanel.tsx +28 -33
- package/src/components/agent/SessionSteps.tsx +46 -5
- package/src/components/agent/SessionWorkspace.tsx +3 -3
- package/src/components/agent/ShellStrip.tsx +27 -4
- package/src/components/agent/ShellTerminal.tsx +1 -1
- package/src/components/agent/ToolCallCard.tsx +18 -41
- package/src/components/agent/Transcript.tsx +98 -93
- package/src/components/agent/TranscriptItemView.tsx +102 -59
- package/src/components/agent/TranscriptRows.tsx +4 -2
- package/src/components/agent/image-viewer.tsx +326 -0
- package/src/components/agent/markdown-image.tsx +91 -0
- package/src/components/agent/shell-actions.tsx +2 -0
- package/src/components/agent/tool-result-image.tsx +40 -0
- package/src/components/agent/transcript-variant.tsx +3 -21
- package/src/components/prompt-area/use-prompt-area-keydown.ts +4 -2
- package/src/components/terminal/PermissionPrompt.tsx +20 -4
- package/src/components/terminal/TerminalTranscript.tsx +38 -21
- package/src/components/terminal/affordances.tsx +100 -74
- package/src/components/terminal/height.ts +48 -32
- package/src/components/terminal/image-box.ts +31 -0
- package/src/components/terminal/items.tsx +92 -14
- package/src/components/terminal/markdown.tsx +4 -1
- package/src/components/terminal/shell-row.ts +17 -3
- package/src/index.ts +19 -4
- package/src/lib/shell-request.ts +115 -0
- package/src/lib/tool-icon.ts +13 -1
- package/src/styles/terminal.css +129 -22
- package/src/styles/theme.css +4 -0
- package/build/use-path-links-BgWXmfAS.mjs.map +0 -1
|
@@ -5,13 +5,13 @@ import { clsx } from "clsx";
|
|
|
5
5
|
import { extendTailwindMerge } from "tailwind-merge";
|
|
6
6
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
import { Select } from "@base-ui/react/select";
|
|
8
|
-
import { ArrowDown, ArrowDownCircle, ArrowLeft, ArrowRight, ArrowUp, AtSign, Brain, ChartPie, Check, CheckSquare, ChevronDown, ChevronLeft, ChevronRight, ChevronsUpDown, Circle, CircleAlert, ClipboardList, Clock, Code, Copy, Download, File, FileDiff, FileText, Folder, FolderSearch, FolderTree, Gauge, Globe, Hand, Image, Info, Link2, LoaderCircle, MessageCircleQuestion, MessageSquareText, MoreHorizontal, Paperclip, PencilLine, Plug, Power, PowerOff, Puzzle, RefreshCw, RotateCcw, RotateCw, Search, ShieldCheck, SlashSquare, SlidersHorizontal, Sparkles, Square, SquarePen, Terminal, TriangleAlert, Users, UsersRound, WifiOff, Wrench, X, Zap } from "lucide-react";
|
|
8
|
+
import { ArrowDown, ArrowDownCircle, ArrowLeft, ArrowRight, ArrowUp, AtSign, Bot, BotOff, Brain, ChartPie, Check, CheckSquare, ChevronDown, ChevronLeft, ChevronRight, ChevronsUpDown, Circle, CircleAlert, ClipboardList, Clock, Code, Copy, Download, File, FileDiff, FileText, Folder, FolderSearch, FolderTree, Gauge, Globe, Hand, Image, Info, Link2, LoaderCircle, Maximize, Maximize2, MessageCircleQuestion, MessageSquareText, Minus, MoreHorizontal, Paperclip, PencilLine, Plug, Plus, Power, PowerOff, Puzzle, RefreshCw, RotateCcw, RotateCw, Search, ShieldCheck, SlashSquare, SlidersHorizontal, Sparkles, Square, SquarePen, SquareTerminal, Star, Terminal, TriangleAlert, Users, UsersRound, WifiOff, Wrench, X, Zap } from "lucide-react";
|
|
9
9
|
import { Menu } from "@base-ui/react/menu";
|
|
10
10
|
import { Dialog } from "@base-ui/react/dialog";
|
|
11
11
|
import { Tooltip } from "@base-ui/react/tooltip";
|
|
12
|
-
import { PRICING_NOTE, PROTOCOL_VERSION, UNPRICED_WARN_SHARE, canonicalModel, costOf, costOfByModel, isPeerSendTool, mergeUsage, orderUsageWindows, parseTodoWriteInput, parseUserQuestions, peerDeliveredTo, pricingAgeNote, rateFor, sessionTasks, subagentLabel, taskCountLabel, taskSummary, toolTitle, totalTokens, unknownBasisModels, usageInfos, usageIsStale, visibleTasks } from "@workerdeck/protocol";
|
|
12
|
+
import { PRICING_NOTE, PROTOCOL_VERSION, SHELL_INTERACTIVE_NOTE, UNPRICED_WARN_SHARE, canonicalModel, costOf, costOfByModel, isPeerSendTool, mergeUsage, orderUsageWindows, parseTodoWriteInput, parseUserQuestions, peerDeliveredTo, pricingAgeNote, rateFor, sessionTasks, subagentLabel, taskCountLabel, taskSummary, toolTitle, totalTokens, unknownBasisModels, usageInfos, usageIsStale, visibleTasks } from "@workerdeck/protocol";
|
|
13
13
|
import { recapLine, scanPromptTokens, summarizeSince, useAttachments, useClaudeSession, useDraft, useHostFileSearch, usePeerSessions, useProfileUsage, useShellTerminal, useToolCallHost } from "@workerdeck/react";
|
|
14
|
-
import { Streamdown } from "streamdown";
|
|
14
|
+
import { Streamdown, defaultRehypePlugins } from "streamdown";
|
|
15
15
|
import { StickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
|
|
16
16
|
import { createPortal } from "react-dom";
|
|
17
17
|
import { defaultRangeExtractor, useVirtualizer } from "@tanstack/react-virtual";
|
|
@@ -2775,10 +2775,11 @@ function usePromptAreaKeydown({ editorRef, triggers, markdownEnabled, submitOnEn
|
|
|
2775
2775
|
const launcher = triggers.find((t) => t.mode === "launch" && t.char === e.key);
|
|
2776
2776
|
const editor = editorRef.current;
|
|
2777
2777
|
if (launcher?.onActivate && editor) {
|
|
2778
|
-
const
|
|
2779
|
-
if (
|
|
2778
|
+
const caret = getCursorOffset(editor);
|
|
2779
|
+
if (caret !== null) {
|
|
2780
2780
|
const segments = readSegmentsFromDOM();
|
|
2781
2781
|
const plainText = segmentsToPlainText(segments);
|
|
2782
|
+
const cursorPos = Math.min(caret, plainText.length);
|
|
2782
2783
|
if (isValidTriggerPosition(plainText, cursorPos, launcher.position)) {
|
|
2783
2784
|
e.preventDefault();
|
|
2784
2785
|
launcher.onActivate({
|
|
@@ -4575,36 +4576,14 @@ function TranscriptVariantProvider({ value, children }) {
|
|
|
4575
4576
|
function useTranscriptVariant() {
|
|
4576
4577
|
return useContext(VariantContext);
|
|
4577
4578
|
}
|
|
4578
|
-
const DensityContext = createContext("comfortable");
|
|
4579
|
-
function TranscriptDensityProvider({ value, children }) {
|
|
4580
|
-
return /* @__PURE__ */ jsx(DensityContext.Provider, {
|
|
4581
|
-
value,
|
|
4582
|
-
children
|
|
4583
|
-
});
|
|
4584
|
-
}
|
|
4585
|
-
function useTranscriptDensity() {
|
|
4586
|
-
return useContext(DensityContext);
|
|
4587
|
-
}
|
|
4588
4579
|
const ROW_GAP = {
|
|
4589
4580
|
terminal: {
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
px: 18
|
|
4593
|
-
},
|
|
4594
|
-
compact: {
|
|
4595
|
-
className: "term-row-gap",
|
|
4596
|
-
px: 18
|
|
4597
|
-
}
|
|
4581
|
+
className: "term-row-gap",
|
|
4582
|
+
px: 18
|
|
4598
4583
|
},
|
|
4599
4584
|
cards: {
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
px: 16
|
|
4603
|
-
},
|
|
4604
|
-
compact: {
|
|
4605
|
-
className: "pt-2",
|
|
4606
|
-
px: 8
|
|
4607
|
-
}
|
|
4585
|
+
className: "pt-5",
|
|
4586
|
+
px: 20
|
|
4608
4587
|
}
|
|
4609
4588
|
};
|
|
4610
4589
|
//#endregion
|
|
@@ -4613,7 +4592,19 @@ function toolIcon(toolName) {
|
|
|
4613
4592
|
switch (toolName) {
|
|
4614
4593
|
case "Bash":
|
|
4615
4594
|
case "BashOutput":
|
|
4616
|
-
case "KillShell":
|
|
4595
|
+
case "KillShell":
|
|
4596
|
+
case "shell_list":
|
|
4597
|
+
case "shell_read":
|
|
4598
|
+
case "shell_run":
|
|
4599
|
+
case "shell_write":
|
|
4600
|
+
case "shell_kill":
|
|
4601
|
+
case "shell_request_write":
|
|
4602
|
+
case "mcp__workerdeck__shell_list":
|
|
4603
|
+
case "mcp__workerdeck__shell_read":
|
|
4604
|
+
case "mcp__workerdeck__shell_run":
|
|
4605
|
+
case "mcp__workerdeck__shell_write":
|
|
4606
|
+
case "mcp__workerdeck__shell_kill":
|
|
4607
|
+
case "mcp__workerdeck__shell_request_write": return Terminal;
|
|
4617
4608
|
case "Read": return FileText;
|
|
4618
4609
|
case "Write": return SquarePen;
|
|
4619
4610
|
case "Edit":
|
|
@@ -4765,69 +4756,11 @@ function PromptTokenText({ text, className }) {
|
|
|
4765
4756
|
});
|
|
4766
4757
|
}
|
|
4767
4758
|
//#endregion
|
|
4768
|
-
//#region src/components/terminal/shell-row.ts
|
|
4769
|
-
const SHELL_GLYPH = "$";
|
|
4770
|
-
const SHELL_KILL_GLYPH = "✕";
|
|
4771
|
-
const SHELL_MISSING = "output expired or not tracked by this gateway";
|
|
4772
|
-
function shellInfoLabel(shell) {
|
|
4773
|
-
return shell.label || shell.command.split("\n")[0] || "";
|
|
4774
|
-
}
|
|
4775
|
-
function shellTitle(shell) {
|
|
4776
|
-
return `#${shell.ordinal} ${shellInfoLabel(shell)}`;
|
|
4777
|
-
}
|
|
4778
|
-
function shellLabel(item) {
|
|
4779
|
-
return shellInfoLabel(item.shell);
|
|
4780
|
-
}
|
|
4781
|
-
function shellStatusText(item) {
|
|
4782
|
-
return shellInfoStatusText(item.shell);
|
|
4783
|
-
}
|
|
4784
|
-
function shellInfoFailed(shell) {
|
|
4785
|
-
return shell.status === "exited" && shell.exitCode !== 0;
|
|
4786
|
-
}
|
|
4787
|
-
function shellInfoStatusText(shell) {
|
|
4788
|
-
if (shell.status === "running") return "running";
|
|
4789
|
-
if (typeof shell.exitCode === "number") return shell.exitCode === 0 ? "exit 0" : `exit ${shell.exitCode}`;
|
|
4790
|
-
switch (shell.endReason) {
|
|
4791
|
-
case "killed": return "killed";
|
|
4792
|
-
case "timeout": return "timed out";
|
|
4793
|
-
case "server_stopped": return "killed: the gateway stopped";
|
|
4794
|
-
case "server_restarted": return "ended: the gateway restarted, the process may still be running";
|
|
4795
|
-
case "spawn_failed": return "failed to start";
|
|
4796
|
-
default: return "ended";
|
|
4797
|
-
}
|
|
4798
|
-
}
|
|
4799
|
-
function shellFailed(item) {
|
|
4800
|
-
return shellInfoFailed(item.shell);
|
|
4801
|
-
}
|
|
4802
|
-
function shellHeaderText(item) {
|
|
4803
|
-
return `${shellLabel(item)} · ${shellStatusText(item)}`;
|
|
4804
|
-
}
|
|
4805
|
-
function shellBodyLines(item, open) {
|
|
4806
|
-
const source = open && item.expanded !== void 0 ? item.expanded : item.text;
|
|
4807
|
-
if (source === "") return [];
|
|
4808
|
-
const lines = source.split("\n");
|
|
4809
|
-
if (!open) return lines;
|
|
4810
|
-
const kept = [];
|
|
4811
|
-
let chars = 0;
|
|
4812
|
-
for (const line of lines) {
|
|
4813
|
-
if (kept.length > 0 && chars + line.length > 1e5) break;
|
|
4814
|
-
kept.push(line);
|
|
4815
|
-
chars += line.length + 1;
|
|
4816
|
-
}
|
|
4817
|
-
return kept;
|
|
4818
|
-
}
|
|
4819
|
-
function shellFooterText(item, open, shown) {
|
|
4820
|
-
if (item.missing) return SHELL_MISSING;
|
|
4821
|
-
if (!open) return item.truncated ? "… more output - expand to fetch it" : void 0;
|
|
4822
|
-
const total = item.expanded === void 0 ? void 0 : item.expanded.split("\n").length;
|
|
4823
|
-
if (total !== void 0 && total > shown) return `… +${(total - shown).toLocaleString()} lines not shown`;
|
|
4824
|
-
if (item.expanded === void 0 && item.truncated) return "… fetching the full output";
|
|
4825
|
-
}
|
|
4826
|
-
//#endregion
|
|
4827
4759
|
//#region src/components/terminal/affordances.tsx
|
|
4828
4760
|
const DEFAULTS = {
|
|
4829
4761
|
hover: true,
|
|
4830
|
-
actions: true
|
|
4762
|
+
actions: true,
|
|
4763
|
+
labels: false
|
|
4831
4764
|
};
|
|
4832
4765
|
const AffordanceContext = createContext(DEFAULTS);
|
|
4833
4766
|
function useAffordances() {
|
|
@@ -4836,7 +4769,8 @@ function useAffordances() {
|
|
|
4836
4769
|
function resolveAffordances(value) {
|
|
4837
4770
|
if (value === false) return {
|
|
4838
4771
|
hover: false,
|
|
4839
|
-
actions: false
|
|
4772
|
+
actions: false,
|
|
4773
|
+
labels: false
|
|
4840
4774
|
};
|
|
4841
4775
|
if (value === true || value === void 0) return DEFAULTS;
|
|
4842
4776
|
return {
|
|
@@ -4850,17 +4784,52 @@ function AffordanceProvider({ value, children }) {
|
|
|
4850
4784
|
children
|
|
4851
4785
|
});
|
|
4852
4786
|
}
|
|
4853
|
-
|
|
4787
|
+
const PlacementContext = createContext("below");
|
|
4788
|
+
function ActionPlacementProvider({ value, children }) {
|
|
4789
|
+
return /* @__PURE__ */ jsx(PlacementContext.Provider, {
|
|
4790
|
+
value,
|
|
4791
|
+
children
|
|
4792
|
+
});
|
|
4793
|
+
}
|
|
4794
|
+
function WithActions({ actions, children, className, placement }) {
|
|
4854
4795
|
const { actions: enabled } = useAffordances();
|
|
4796
|
+
const inherited = useContext(PlacementContext);
|
|
4855
4797
|
if (!enabled) return /* @__PURE__ */ jsx(Fragment$1, { children });
|
|
4856
4798
|
return /* @__PURE__ */ jsxs("div", {
|
|
4857
4799
|
className: cn("term-hoverable", className),
|
|
4858
|
-
|
|
4800
|
+
"data-placement": placement ?? inherited,
|
|
4801
|
+
children: [/* @__PURE__ */ jsx(PlacementContext.Provider, {
|
|
4802
|
+
value: "below",
|
|
4803
|
+
children
|
|
4804
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
4859
4805
|
className: "term-actions",
|
|
4860
4806
|
children: actions
|
|
4861
4807
|
})]
|
|
4862
4808
|
});
|
|
4863
4809
|
}
|
|
4810
|
+
function ActionButton({ icon: Icon, word, label, tone, pressed, filled, onPress }) {
|
|
4811
|
+
const { labels } = useAffordances();
|
|
4812
|
+
return /* @__PURE__ */ jsxs("button", {
|
|
4813
|
+
type: "button",
|
|
4814
|
+
className: "term-action",
|
|
4815
|
+
title: label,
|
|
4816
|
+
"aria-label": label,
|
|
4817
|
+
"aria-pressed": pressed,
|
|
4818
|
+
"data-tone": tone,
|
|
4819
|
+
onClick: (event) => {
|
|
4820
|
+
event.stopPropagation();
|
|
4821
|
+
onPress();
|
|
4822
|
+
},
|
|
4823
|
+
children: [/* @__PURE__ */ jsx(Icon, {
|
|
4824
|
+
"aria-hidden": true,
|
|
4825
|
+
className: "term-action-icon",
|
|
4826
|
+
fill: filled ? "currentColor" : "none"
|
|
4827
|
+
}), labels ? /* @__PURE__ */ jsx("span", {
|
|
4828
|
+
className: "term-action-word",
|
|
4829
|
+
children: word
|
|
4830
|
+
}) : null]
|
|
4831
|
+
});
|
|
4832
|
+
}
|
|
4864
4833
|
const BookmarkContext = createContext(void 0);
|
|
4865
4834
|
function BookmarkProvider({ value, children }) {
|
|
4866
4835
|
return /* @__PURE__ */ jsx(BookmarkContext.Provider, {
|
|
@@ -4872,77 +4841,71 @@ function BookmarkAction({ id }) {
|
|
|
4872
4841
|
const handle = useContext(BookmarkContext);
|
|
4873
4842
|
if (!handle) return null;
|
|
4874
4843
|
const active = handle.has(id);
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
"
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
event.stopPropagation();
|
|
4884
|
-
handle.toggle(id);
|
|
4885
|
-
},
|
|
4886
|
-
children: active ? "★" : "☆"
|
|
4844
|
+
return /* @__PURE__ */ jsx(ActionButton, {
|
|
4845
|
+
icon: Star,
|
|
4846
|
+
filled: true,
|
|
4847
|
+
word: active ? "bookmarked" : "bookmark",
|
|
4848
|
+
label: active ? "Remove bookmark" : "Bookmark",
|
|
4849
|
+
tone: active ? "yellow" : void 0,
|
|
4850
|
+
pressed: active,
|
|
4851
|
+
onPress: () => handle.toggle(id)
|
|
4887
4852
|
});
|
|
4888
4853
|
}
|
|
4889
4854
|
function OpenSubagentAction({ onOpen, label = "Open sub-agent" }) {
|
|
4890
|
-
return /* @__PURE__ */ jsx(
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
onClick: (event) => {
|
|
4896
|
-
event.stopPropagation();
|
|
4897
|
-
onOpen();
|
|
4898
|
-
},
|
|
4899
|
-
children: "⤢"
|
|
4855
|
+
return /* @__PURE__ */ jsx(ActionButton, {
|
|
4856
|
+
icon: Maximize2,
|
|
4857
|
+
word: "open",
|
|
4858
|
+
label,
|
|
4859
|
+
onPress: onOpen
|
|
4900
4860
|
});
|
|
4901
4861
|
}
|
|
4902
4862
|
function OpenShellAction({ onOpen, label = "Open terminal" }) {
|
|
4903
|
-
return /* @__PURE__ */ jsx(
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
"
|
|
4908
|
-
|
|
4909
|
-
onClick: (event) => {
|
|
4910
|
-
event.stopPropagation();
|
|
4911
|
-
onOpen();
|
|
4912
|
-
},
|
|
4913
|
-
children: "⤢"
|
|
4863
|
+
return /* @__PURE__ */ jsx(ActionButton, {
|
|
4864
|
+
icon: SquareTerminal,
|
|
4865
|
+
word: "enter shell",
|
|
4866
|
+
label,
|
|
4867
|
+
tone: "magenta",
|
|
4868
|
+
onPress: onOpen
|
|
4914
4869
|
});
|
|
4915
4870
|
}
|
|
4916
4871
|
function KillShellAction({ onKill, label = "Kill this shell" }) {
|
|
4917
|
-
return /* @__PURE__ */ jsx(
|
|
4918
|
-
|
|
4919
|
-
|
|
4920
|
-
|
|
4921
|
-
"
|
|
4922
|
-
|
|
4923
|
-
|
|
4924
|
-
|
|
4925
|
-
|
|
4926
|
-
|
|
4927
|
-
|
|
4872
|
+
return /* @__PURE__ */ jsx(ActionButton, {
|
|
4873
|
+
icon: X,
|
|
4874
|
+
word: "kill",
|
|
4875
|
+
label,
|
|
4876
|
+
tone: "danger",
|
|
4877
|
+
onPress: onKill
|
|
4878
|
+
});
|
|
4879
|
+
}
|
|
4880
|
+
function AgentWriteAction({ granted, label, onToggle }) {
|
|
4881
|
+
return /* @__PURE__ */ jsx(ActionButton, {
|
|
4882
|
+
icon: granted ? Bot : BotOff,
|
|
4883
|
+
word: granted ? "agent can type" : "agent read-only",
|
|
4884
|
+
label,
|
|
4885
|
+
tone: granted ? "yellow" : void 0,
|
|
4886
|
+
pressed: granted,
|
|
4887
|
+
onPress: onToggle
|
|
4928
4888
|
});
|
|
4929
4889
|
}
|
|
4930
4890
|
function CopyAction({ text, label = "Copy" }) {
|
|
4931
4891
|
const [copied, setCopied] = useState(false);
|
|
4932
|
-
return /* @__PURE__ */ jsx(
|
|
4933
|
-
|
|
4934
|
-
|
|
4935
|
-
|
|
4936
|
-
|
|
4937
|
-
onClick: (event) => {
|
|
4938
|
-
event.stopPropagation();
|
|
4892
|
+
return /* @__PURE__ */ jsx(ActionButton, {
|
|
4893
|
+
icon: copied ? Check : Copy,
|
|
4894
|
+
word: copied ? "copied" : "copy",
|
|
4895
|
+
label,
|
|
4896
|
+
onPress: () => {
|
|
4939
4897
|
copyText(text).then((ok) => {
|
|
4940
4898
|
if (!ok) return;
|
|
4941
4899
|
setCopied(true);
|
|
4942
4900
|
setTimeout(() => setCopied(false), 1200);
|
|
4943
4901
|
});
|
|
4944
|
-
}
|
|
4945
|
-
|
|
4902
|
+
}
|
|
4903
|
+
});
|
|
4904
|
+
}
|
|
4905
|
+
function AgentWriteIcon({ granted, className }) {
|
|
4906
|
+
return /* @__PURE__ */ jsx(granted ? Bot : BotOff, {
|
|
4907
|
+
"aria-hidden": true,
|
|
4908
|
+
className
|
|
4946
4909
|
});
|
|
4947
4910
|
}
|
|
4948
4911
|
//#endregion
|
|
@@ -5133,119 +5096,650 @@ function useFileLinks() {
|
|
|
5133
5096
|
return useContext(FileLinkContext);
|
|
5134
5097
|
}
|
|
5135
5098
|
//#endregion
|
|
5136
|
-
//#region src/components/terminal/
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
|
|
5099
|
+
//#region src/components/terminal/image-box.ts
|
|
5100
|
+
const HOST_IMAGE_TOOLS = /* @__PURE__ */ new Set(["CodexImageGeneration", "CodexImageView"]);
|
|
5101
|
+
const MEDIA_EXTENSIONS = {
|
|
5102
|
+
"image/png": "png",
|
|
5103
|
+
"image/jpeg": "jpg",
|
|
5104
|
+
"image/gif": "gif",
|
|
5105
|
+
"image/webp": "webp",
|
|
5106
|
+
"image/svg+xml": "svg"
|
|
5107
|
+
};
|
|
5108
|
+
function imagePlaceholder(image) {
|
|
5109
|
+
return `image · ${formatBytes(image.bytes)}`;
|
|
5143
5110
|
}
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
|
|
5111
|
+
const IMAGE_UNAVAILABLE = "image unavailable";
|
|
5112
|
+
function hostImagePathOf(item) {
|
|
5113
|
+
if (!HOST_IMAGE_TOOLS.has(item.name)) return;
|
|
5114
|
+
const input = item.input;
|
|
5115
|
+
const path = input?.savedPath ?? input?.path;
|
|
5116
|
+
return typeof path === "string" ? path : void 0;
|
|
5147
5117
|
}
|
|
5148
|
-
function
|
|
5149
|
-
return
|
|
5150
|
-
className: "term-block",
|
|
5151
|
-
actions: /* @__PURE__ */ jsx(CopyAction, {
|
|
5152
|
-
text: code,
|
|
5153
|
-
label: "Copy code"
|
|
5154
|
-
}),
|
|
5155
|
-
children: /* @__PURE__ */ jsx(Band, {
|
|
5156
|
-
className: "term-code",
|
|
5157
|
-
"data-language": language,
|
|
5158
|
-
children: /* @__PURE__ */ jsx("pre", {
|
|
5159
|
-
className: "term-pre",
|
|
5160
|
-
children: code
|
|
5161
|
-
})
|
|
5162
|
-
})
|
|
5163
|
-
});
|
|
5118
|
+
function baseName(path) {
|
|
5119
|
+
return path.split(/[\\/]/).pop() || path;
|
|
5164
5120
|
}
|
|
5165
|
-
function
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
className: "term-block",
|
|
5169
|
-
"data-tone": tone,
|
|
5170
|
-
"data-weight": "bold",
|
|
5171
|
-
children
|
|
5172
|
-
});
|
|
5173
|
-
};
|
|
5121
|
+
function resultImageName(toolName, image) {
|
|
5122
|
+
const extension = MEDIA_EXTENSIONS[image.mediaType] ?? image.mediaType.split("/").pop() ?? "img";
|
|
5123
|
+
return `${toolName.toLowerCase()}-${image.partIndex + 1}.${extension}`;
|
|
5174
5124
|
}
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5125
|
+
//#endregion
|
|
5126
|
+
//#region src/components/agent/image-viewer.tsx
|
|
5127
|
+
const ZOOM_STEPS = [
|
|
5128
|
+
.1,
|
|
5129
|
+
.25,
|
|
5130
|
+
.33,
|
|
5131
|
+
.5,
|
|
5132
|
+
.67,
|
|
5133
|
+
.75,
|
|
5134
|
+
1,
|
|
5135
|
+
1.25,
|
|
5136
|
+
1.5,
|
|
5137
|
+
2,
|
|
5138
|
+
3,
|
|
5139
|
+
4,
|
|
5140
|
+
6,
|
|
5141
|
+
8
|
|
5142
|
+
];
|
|
5143
|
+
const STAGE_PADDING = 16;
|
|
5144
|
+
const DRAG_SLOP$1 = 4;
|
|
5145
|
+
const WHEEL_ZOOM_RATE = .01;
|
|
5146
|
+
const WHEEL_DELTA_CAP = 25;
|
|
5147
|
+
const ViewerContext = createContext(void 0);
|
|
5148
|
+
function useOpenImage() {
|
|
5149
|
+
return useContext(ViewerContext);
|
|
5150
|
+
}
|
|
5151
|
+
function ImageViewerProvider({ children }) {
|
|
5152
|
+
const [image, setImage] = useState();
|
|
5153
|
+
const close = useCallback(() => setImage(void 0), []);
|
|
5154
|
+
return /* @__PURE__ */ jsxs(ViewerContext.Provider, {
|
|
5155
|
+
value: setImage,
|
|
5156
|
+
children: [children, image ? /* @__PURE__ */ jsx(ImageViewer, {
|
|
5157
|
+
image,
|
|
5158
|
+
onClose: close
|
|
5159
|
+
}, image.src) : null]
|
|
5160
|
+
});
|
|
5161
|
+
}
|
|
5162
|
+
function ViewableImage({ image, className, children }) {
|
|
5163
|
+
const open = useOpenImage();
|
|
5164
|
+
if (!open) return /* @__PURE__ */ jsx(Fragment$1, { children });
|
|
5165
|
+
return /* @__PURE__ */ jsx("button", {
|
|
5179
5166
|
type: "button",
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5167
|
+
"aria-label": `View ${image.name}`,
|
|
5168
|
+
title: image.name,
|
|
5169
|
+
"data-slot": "viewable-image",
|
|
5170
|
+
className: cn("cursor-zoom-in", className),
|
|
5183
5171
|
onClick: (event) => {
|
|
5184
5172
|
event.stopPropagation();
|
|
5185
|
-
|
|
5173
|
+
open(image);
|
|
5186
5174
|
},
|
|
5187
5175
|
children
|
|
5188
5176
|
});
|
|
5189
|
-
return /* @__PURE__ */ jsx("a", {
|
|
5190
|
-
className: "term-link",
|
|
5191
|
-
"data-tone": "blue",
|
|
5192
|
-
href,
|
|
5193
|
-
target: "_blank",
|
|
5194
|
-
rel: "noreferrer",
|
|
5195
|
-
children
|
|
5196
|
-
});
|
|
5197
5177
|
}
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
})
|
|
5217
|
-
|
|
5218
|
-
|
|
5219
|
-
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
})
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
})
|
|
5236
|
-
|
|
5237
|
-
|
|
5238
|
-
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5245
|
-
|
|
5246
|
-
|
|
5247
|
-
|
|
5248
|
-
|
|
5178
|
+
function ImageViewer({ image, onClose, className }) {
|
|
5179
|
+
const rootRef = useRef(null);
|
|
5180
|
+
const stageRef = useRef(null);
|
|
5181
|
+
const [natural, setNatural] = useState();
|
|
5182
|
+
const [stage, setStage] = useState();
|
|
5183
|
+
const [zoom, setZoom] = useState("fit");
|
|
5184
|
+
const [failed, setFailed] = useState(false);
|
|
5185
|
+
const anchor = useRef(void 0);
|
|
5186
|
+
const wheelScale = useRef(void 0);
|
|
5187
|
+
const drag = useRef(void 0);
|
|
5188
|
+
const dragged = useRef(false);
|
|
5189
|
+
const fitScale = natural && stage ? Math.min(1, (stage.width - 32) / natural.width, (stage.height - 32) / natural.height) : 1;
|
|
5190
|
+
const scale = zoom === "fit" ? Math.max(fitScale, .01) : zoom;
|
|
5191
|
+
const scrollable = natural !== void 0 && stage !== void 0 && (natural.width * scale > stage.width || natural.height * scale > stage.height);
|
|
5192
|
+
useEffect(() => {
|
|
5193
|
+
const previous = document.activeElement;
|
|
5194
|
+
rootRef.current?.focus();
|
|
5195
|
+
return () => previous?.focus?.();
|
|
5196
|
+
}, []);
|
|
5197
|
+
useEffect(() => {
|
|
5198
|
+
const element = stageRef.current;
|
|
5199
|
+
if (!element) return;
|
|
5200
|
+
const observer = new ResizeObserver(() => setStage({
|
|
5201
|
+
width: element.clientWidth,
|
|
5202
|
+
height: element.clientHeight
|
|
5203
|
+
}));
|
|
5204
|
+
observer.observe(element);
|
|
5205
|
+
return () => observer.disconnect();
|
|
5206
|
+
}, []);
|
|
5207
|
+
useLayoutEffect(() => {
|
|
5208
|
+
const element = stageRef.current;
|
|
5209
|
+
const point = anchor.current;
|
|
5210
|
+
if (!element || !point) return;
|
|
5211
|
+
anchor.current = void 0;
|
|
5212
|
+
wheelScale.current = void 0;
|
|
5213
|
+
element.scrollLeft = point.x * element.scrollWidth - point.viewX;
|
|
5214
|
+
element.scrollTop = point.y * element.scrollHeight - point.viewY;
|
|
5215
|
+
}, [scale]);
|
|
5216
|
+
const zoomTo = useCallback((next, focus) => {
|
|
5217
|
+
const element = stageRef.current;
|
|
5218
|
+
if (element && element.scrollWidth > 0 && element.scrollHeight > 0) {
|
|
5219
|
+
const rect = element.getBoundingClientRect();
|
|
5220
|
+
const viewX = focus ? focus.clientX - rect.left : element.clientWidth / 2;
|
|
5221
|
+
const viewY = focus ? focus.clientY - rect.top : element.clientHeight / 2;
|
|
5222
|
+
anchor.current = {
|
|
5223
|
+
x: (element.scrollLeft + viewX) / element.scrollWidth,
|
|
5224
|
+
y: (element.scrollTop + viewY) / element.scrollHeight,
|
|
5225
|
+
viewX,
|
|
5226
|
+
viewY
|
|
5227
|
+
};
|
|
5228
|
+
}
|
|
5229
|
+
setZoom(next);
|
|
5230
|
+
}, []);
|
|
5231
|
+
const step = (direction) => {
|
|
5232
|
+
const next = direction > 0 ? ZOOM_STEPS.find((value) => value > scale + .001) : ZOOM_STEPS.filter((value) => value < scale - .001).at(-1);
|
|
5233
|
+
zoomTo(next ?? (direction > 0 ? ZOOM_STEPS[ZOOM_STEPS.length - 1] : ZOOM_STEPS[0]));
|
|
5234
|
+
};
|
|
5235
|
+
const onKeyDown = (event) => {
|
|
5236
|
+
event.stopPropagation();
|
|
5237
|
+
if (event.key === "Escape") {
|
|
5238
|
+
event.preventDefault();
|
|
5239
|
+
onClose();
|
|
5240
|
+
} else if (event.key === "+" || event.key === "=") {
|
|
5241
|
+
event.preventDefault();
|
|
5242
|
+
step(1);
|
|
5243
|
+
} else if (event.key === "-" || event.key === "_") {
|
|
5244
|
+
event.preventDefault();
|
|
5245
|
+
step(-1);
|
|
5246
|
+
} else if (event.key === "0") {
|
|
5247
|
+
event.preventDefault();
|
|
5248
|
+
zoomTo("fit");
|
|
5249
|
+
} else if (event.key === "1") {
|
|
5250
|
+
event.preventDefault();
|
|
5251
|
+
zoomTo(1);
|
|
5252
|
+
}
|
|
5253
|
+
};
|
|
5254
|
+
const scaleRef = useRef(scale);
|
|
5255
|
+
scaleRef.current = scale;
|
|
5256
|
+
useEffect(() => {
|
|
5257
|
+
const element = stageRef.current;
|
|
5258
|
+
if (!element) return;
|
|
5259
|
+
const onWheel = (event) => {
|
|
5260
|
+
if (!event.ctrlKey && !event.metaKey) return;
|
|
5261
|
+
event.preventDefault();
|
|
5262
|
+
const delta = Math.max(-25, Math.min(WHEEL_DELTA_CAP, event.deltaY));
|
|
5263
|
+
const base = wheelScale.current ?? scaleRef.current;
|
|
5264
|
+
const next = Math.min(ZOOM_STEPS[ZOOM_STEPS.length - 1], Math.max(ZOOM_STEPS[0], base * Math.exp(-delta * WHEEL_ZOOM_RATE)));
|
|
5265
|
+
wheelScale.current = next;
|
|
5266
|
+
zoomTo(next, event);
|
|
5267
|
+
};
|
|
5268
|
+
element.addEventListener("wheel", onWheel, { passive: false });
|
|
5269
|
+
return () => element.removeEventListener("wheel", onWheel);
|
|
5270
|
+
}, [zoomTo]);
|
|
5271
|
+
const onPointerDown = (event) => {
|
|
5272
|
+
const element = stageRef.current;
|
|
5273
|
+
if (!scrollable || !element || event.button !== 0) return;
|
|
5274
|
+
dragged.current = false;
|
|
5275
|
+
drag.current = {
|
|
5276
|
+
x: event.clientX,
|
|
5277
|
+
y: event.clientY,
|
|
5278
|
+
left: element.scrollLeft,
|
|
5279
|
+
top: element.scrollTop
|
|
5280
|
+
};
|
|
5281
|
+
element.setPointerCapture(event.pointerId);
|
|
5282
|
+
};
|
|
5283
|
+
const onPointerMove = (event) => {
|
|
5284
|
+
const element = stageRef.current;
|
|
5285
|
+
const start = drag.current;
|
|
5286
|
+
if (!element || !start) return;
|
|
5287
|
+
if (Math.abs(event.clientX - start.x) + Math.abs(event.clientY - start.y) > DRAG_SLOP$1) dragged.current = true;
|
|
5288
|
+
element.scrollLeft = start.left - (event.clientX - start.x);
|
|
5289
|
+
element.scrollTop = start.top - (event.clientY - start.y);
|
|
5290
|
+
};
|
|
5291
|
+
const endDrag = (event) => {
|
|
5292
|
+
drag.current = void 0;
|
|
5293
|
+
stageRef.current?.releasePointerCapture?.(event.pointerId);
|
|
5294
|
+
};
|
|
5295
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
5296
|
+
ref: rootRef,
|
|
5297
|
+
role: "dialog",
|
|
5298
|
+
"aria-modal": "true",
|
|
5299
|
+
"aria-label": image.name,
|
|
5300
|
+
tabIndex: -1,
|
|
5301
|
+
"data-slot": "image-viewer",
|
|
5302
|
+
onKeyDown,
|
|
5303
|
+
onClick: (event) => event.stopPropagation(),
|
|
5304
|
+
className: cn("absolute inset-0 z-50 flex flex-col bg-bg outline-none", className),
|
|
5305
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
5306
|
+
className: "flex shrink-0 items-center gap-1 border-b border-border px-2 py-1.5",
|
|
5307
|
+
children: [
|
|
5308
|
+
/* @__PURE__ */ jsxs("div", {
|
|
5309
|
+
className: "min-w-0 flex-1 px-1",
|
|
5310
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
5311
|
+
className: "truncate font-mono text-body-sm text-fg-1",
|
|
5312
|
+
title: image.name,
|
|
5313
|
+
children: image.name
|
|
5314
|
+
}), natural ? /* @__PURE__ */ jsxs("div", {
|
|
5315
|
+
className: "text-label text-fg-4",
|
|
5316
|
+
children: [
|
|
5317
|
+
natural.width,
|
|
5318
|
+
" × ",
|
|
5319
|
+
natural.height
|
|
5320
|
+
]
|
|
5321
|
+
}) : null]
|
|
5322
|
+
}),
|
|
5323
|
+
/* @__PURE__ */ jsx(Button, {
|
|
5324
|
+
variant: "ghost",
|
|
5325
|
+
size: "icon-sm",
|
|
5326
|
+
"aria-label": "Zoom out",
|
|
5327
|
+
title: "Zoom out (-)",
|
|
5328
|
+
onClick: () => step(-1),
|
|
5329
|
+
disabled: failed,
|
|
5330
|
+
children: /* @__PURE__ */ jsx(Minus, {})
|
|
5331
|
+
}),
|
|
5332
|
+
/* @__PURE__ */ jsxs("span", {
|
|
5333
|
+
className: "w-12 text-center font-mono text-label text-fg-3 tabular-nums",
|
|
5334
|
+
children: [Math.round(scale * 100), "%"]
|
|
5335
|
+
}),
|
|
5336
|
+
/* @__PURE__ */ jsx(Button, {
|
|
5337
|
+
variant: "ghost",
|
|
5338
|
+
size: "icon-sm",
|
|
5339
|
+
"aria-label": "Zoom in",
|
|
5340
|
+
title: "Zoom in (+)",
|
|
5341
|
+
onClick: () => step(1),
|
|
5342
|
+
disabled: failed,
|
|
5343
|
+
children: /* @__PURE__ */ jsx(Plus, {})
|
|
5344
|
+
}),
|
|
5345
|
+
/* @__PURE__ */ jsx(Button, {
|
|
5346
|
+
variant: zoom === "fit" ? "secondary" : "ghost",
|
|
5347
|
+
size: "icon-sm",
|
|
5348
|
+
"aria-label": "Fit to view",
|
|
5349
|
+
"aria-pressed": zoom === "fit",
|
|
5350
|
+
title: "Fit to view (0)",
|
|
5351
|
+
onClick: () => zoomTo("fit"),
|
|
5352
|
+
disabled: failed,
|
|
5353
|
+
children: /* @__PURE__ */ jsx(Maximize, {})
|
|
5354
|
+
}),
|
|
5355
|
+
/* @__PURE__ */ jsx(Button, {
|
|
5356
|
+
variant: zoom === 1 ? "secondary" : "ghost",
|
|
5357
|
+
size: "sm",
|
|
5358
|
+
"aria-label": "Actual size",
|
|
5359
|
+
"aria-pressed": zoom === 1,
|
|
5360
|
+
title: "Actual size (1)",
|
|
5361
|
+
onClick: () => zoomTo(1),
|
|
5362
|
+
disabled: failed,
|
|
5363
|
+
className: "font-mono",
|
|
5364
|
+
children: "1:1"
|
|
5365
|
+
}),
|
|
5366
|
+
/* @__PURE__ */ jsx("a", {
|
|
5367
|
+
href: image.src,
|
|
5368
|
+
download: image.name,
|
|
5369
|
+
"aria-label": "Download",
|
|
5370
|
+
title: "Download",
|
|
5371
|
+
className: "inline-flex size-7 items-center justify-center rounded-md text-fg-2 transition-colors hover:bg-surface-hover hover:text-foreground",
|
|
5372
|
+
children: /* @__PURE__ */ jsx(Download, { className: "size-4" })
|
|
5373
|
+
}),
|
|
5374
|
+
/* @__PURE__ */ jsx(Button, {
|
|
5375
|
+
variant: "ghost",
|
|
5376
|
+
size: "icon-sm",
|
|
5377
|
+
"aria-label": "Close",
|
|
5378
|
+
title: "Close (Esc)",
|
|
5379
|
+
onClick: onClose,
|
|
5380
|
+
children: /* @__PURE__ */ jsx(X, {})
|
|
5381
|
+
})
|
|
5382
|
+
]
|
|
5383
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
5384
|
+
ref: stageRef,
|
|
5385
|
+
"data-slot": "image-viewer-stage",
|
|
5386
|
+
onPointerDown,
|
|
5387
|
+
onPointerMove,
|
|
5388
|
+
onPointerUp: endDrag,
|
|
5389
|
+
onPointerCancel: endDrag,
|
|
5390
|
+
onClick: (event) => {
|
|
5391
|
+
if (dragged.current) {
|
|
5392
|
+
dragged.current = false;
|
|
5393
|
+
return;
|
|
5394
|
+
}
|
|
5395
|
+
if (event.target === event.currentTarget || event.target === event.currentTarget.firstElementChild) onClose();
|
|
5396
|
+
},
|
|
5397
|
+
className: cn("min-h-0 flex-1 overflow-auto bg-surface-hover/40", scrollable && "cursor-grab active:cursor-grabbing"),
|
|
5398
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
5399
|
+
className: "flex min-h-full w-max min-w-full items-center justify-center",
|
|
5400
|
+
style: { padding: STAGE_PADDING },
|
|
5401
|
+
children: failed ? /* @__PURE__ */ jsx("span", {
|
|
5402
|
+
className: "text-body-sm text-fg-4",
|
|
5403
|
+
children: "Image could not be displayed"
|
|
5404
|
+
}) : /* @__PURE__ */ jsx("img", {
|
|
5405
|
+
src: image.src,
|
|
5406
|
+
alt: image.name,
|
|
5407
|
+
draggable: false,
|
|
5408
|
+
onLoad: (event) => setNatural({
|
|
5409
|
+
width: event.currentTarget.naturalWidth,
|
|
5410
|
+
height: event.currentTarget.naturalHeight
|
|
5411
|
+
}),
|
|
5412
|
+
onError: () => setFailed(true),
|
|
5413
|
+
onDoubleClick: () => zoomTo(zoom === "fit" ? 1 : "fit"),
|
|
5414
|
+
className: "block max-w-none select-none",
|
|
5415
|
+
style: natural ? {
|
|
5416
|
+
width: natural.width * scale,
|
|
5417
|
+
height: natural.height * scale,
|
|
5418
|
+
imageRendering: scale > 2 ? "pixelated" : void 0
|
|
5419
|
+
} : {
|
|
5420
|
+
maxWidth: "100%",
|
|
5421
|
+
maxHeight: "100%",
|
|
5422
|
+
visibility: "hidden"
|
|
5423
|
+
}
|
|
5424
|
+
})
|
|
5425
|
+
})
|
|
5426
|
+
})]
|
|
5427
|
+
});
|
|
5428
|
+
}
|
|
5429
|
+
//#endregion
|
|
5430
|
+
//#region src/components/agent/tool-result-image.tsx
|
|
5431
|
+
const noop$1 = async () => void 0;
|
|
5432
|
+
const ImageContext = createContext(noop$1);
|
|
5433
|
+
function ToolResultImageProvider({ value, children }) {
|
|
5434
|
+
return /* @__PURE__ */ jsx(ImageContext.Provider, {
|
|
5435
|
+
value: value ?? noop$1,
|
|
5436
|
+
children
|
|
5437
|
+
});
|
|
5438
|
+
}
|
|
5439
|
+
function useToolResultImageLoader() {
|
|
5440
|
+
return useContext(ImageContext);
|
|
5441
|
+
}
|
|
5442
|
+
const MOUNT_SETTLE_MS = 150;
|
|
5443
|
+
function useToolResultImageSrc(ref) {
|
|
5444
|
+
const load = useToolResultImageLoader();
|
|
5445
|
+
const [state, setState] = useState({ failed: false });
|
|
5446
|
+
const { toolUseId, sourceSeq, partIndex, mediaType, bytes } = ref;
|
|
5447
|
+
useEffect(() => {
|
|
5448
|
+
let live = true;
|
|
5449
|
+
setState({ failed: false });
|
|
5450
|
+
const timer = setTimeout(() => {
|
|
5451
|
+
load({
|
|
5452
|
+
toolUseId,
|
|
5453
|
+
sourceSeq,
|
|
5454
|
+
partIndex,
|
|
5455
|
+
mediaType,
|
|
5456
|
+
bytes
|
|
5457
|
+
}).then((src) => {
|
|
5458
|
+
if (live) setState({
|
|
5459
|
+
src,
|
|
5460
|
+
failed: src === void 0
|
|
5461
|
+
});
|
|
5462
|
+
}).catch(() => {
|
|
5463
|
+
if (live) setState({ failed: true });
|
|
5464
|
+
});
|
|
5465
|
+
}, MOUNT_SETTLE_MS);
|
|
5466
|
+
return () => {
|
|
5467
|
+
live = false;
|
|
5468
|
+
clearTimeout(timer);
|
|
5469
|
+
};
|
|
5470
|
+
}, [
|
|
5471
|
+
load,
|
|
5472
|
+
toolUseId,
|
|
5473
|
+
sourceSeq,
|
|
5474
|
+
partIndex,
|
|
5475
|
+
mediaType,
|
|
5476
|
+
bytes
|
|
5477
|
+
]);
|
|
5478
|
+
return state;
|
|
5479
|
+
}
|
|
5480
|
+
const HostImageContext = createContext(void 0);
|
|
5481
|
+
function HostImageProvider({ value, children }) {
|
|
5482
|
+
return /* @__PURE__ */ jsx(HostImageContext.Provider, {
|
|
5483
|
+
value,
|
|
5484
|
+
children
|
|
5485
|
+
});
|
|
5486
|
+
}
|
|
5487
|
+
function useHostImageSrc(path, override) {
|
|
5488
|
+
const provided = useContext(HostImageContext);
|
|
5489
|
+
const load = override ?? provided;
|
|
5490
|
+
const [state, setState] = useState({ failed: false });
|
|
5491
|
+
useEffect(() => {
|
|
5492
|
+
if (path === void 0) return;
|
|
5493
|
+
if (!load) {
|
|
5494
|
+
setState({ failed: true });
|
|
5495
|
+
return;
|
|
5496
|
+
}
|
|
5497
|
+
let live = true;
|
|
5498
|
+
setState({ failed: false });
|
|
5499
|
+
load(path).then((src) => {
|
|
5500
|
+
if (live) setState({
|
|
5501
|
+
src,
|
|
5502
|
+
failed: src === void 0
|
|
5503
|
+
});
|
|
5504
|
+
}).catch(() => {
|
|
5505
|
+
if (live) setState({ failed: true });
|
|
5506
|
+
});
|
|
5507
|
+
return () => {
|
|
5508
|
+
live = false;
|
|
5509
|
+
};
|
|
5510
|
+
}, [load, path]);
|
|
5511
|
+
return state;
|
|
5512
|
+
}
|
|
5513
|
+
const CACHE_BUDGET_BYTES = 67108864;
|
|
5514
|
+
function useToolResultImages(client, sessionId) {
|
|
5515
|
+
const cache = useRef(/* @__PURE__ */ new Map());
|
|
5516
|
+
useEffect(() => () => {
|
|
5517
|
+
for (const entry of cache.current.values()) if (entry.url) URL.revokeObjectURL(entry.url);
|
|
5518
|
+
cache.current.clear();
|
|
5519
|
+
}, []);
|
|
5520
|
+
return useCallback((ref) => {
|
|
5521
|
+
if (!sessionId) return Promise.resolve(void 0);
|
|
5522
|
+
const key = `${sessionId}:${ref.sourceSeq}:${ref.toolUseId}:${ref.partIndex}`;
|
|
5523
|
+
const hit = cache.current.get(key);
|
|
5524
|
+
if (hit) {
|
|
5525
|
+
cache.current.delete(key);
|
|
5526
|
+
cache.current.set(key, hit);
|
|
5527
|
+
return hit.pending;
|
|
5528
|
+
}
|
|
5529
|
+
const pending = client.toolResultImage(sessionId, ref.sourceSeq, ref.toolUseId, ref.partIndex).then((blob) => {
|
|
5530
|
+
if (blob.size === 0) return;
|
|
5531
|
+
const url = URL.createObjectURL(blob);
|
|
5532
|
+
const entry = cache.current.get(key);
|
|
5533
|
+
if (entry) {
|
|
5534
|
+
entry.url = url;
|
|
5535
|
+
entry.bytes = blob.size;
|
|
5536
|
+
evict(cache.current, key);
|
|
5537
|
+
} else URL.revokeObjectURL(url);
|
|
5538
|
+
return url;
|
|
5539
|
+
}).catch(() => void 0);
|
|
5540
|
+
cache.current.set(key, {
|
|
5541
|
+
pending,
|
|
5542
|
+
bytes: ref.bytes
|
|
5543
|
+
});
|
|
5544
|
+
return pending;
|
|
5545
|
+
}, [client, sessionId]);
|
|
5546
|
+
}
|
|
5547
|
+
function evict(cache, keep) {
|
|
5548
|
+
let held = 0;
|
|
5549
|
+
for (const entry of cache.values()) held += entry.bytes;
|
|
5550
|
+
for (const [key, entry] of cache) {
|
|
5551
|
+
if (held <= CACHE_BUDGET_BYTES) return;
|
|
5552
|
+
if (key === keep) continue;
|
|
5553
|
+
if (entry.url) URL.revokeObjectURL(entry.url);
|
|
5554
|
+
cache.delete(key);
|
|
5555
|
+
held -= entry.bytes;
|
|
5556
|
+
}
|
|
5557
|
+
}
|
|
5558
|
+
//#endregion
|
|
5559
|
+
//#region src/components/agent/markdown-image.tsx
|
|
5560
|
+
const LOCAL_PREFIX = "https://local-image.invalid/";
|
|
5561
|
+
const WEB_SOURCE = /^(?:https?:|data:image\/|blob:)/i;
|
|
5562
|
+
function shieldLocalImages() {
|
|
5563
|
+
return (tree) => {
|
|
5564
|
+
walk(tree);
|
|
5565
|
+
};
|
|
5566
|
+
}
|
|
5567
|
+
function walk(node) {
|
|
5568
|
+
if (node.type === "element" && node.tagName === "img" && node.properties) {
|
|
5569
|
+
const src = node.properties.src;
|
|
5570
|
+
if (typeof src === "string" && src.trim() && !WEB_SOURCE.test(src.trim())) node.properties.src = LOCAL_PREFIX + encodeURIComponent(src.trim());
|
|
5571
|
+
}
|
|
5572
|
+
for (const child of node.children ?? []) walk(child);
|
|
5573
|
+
}
|
|
5574
|
+
const MARKDOWN_REHYPE_PLUGINS = [shieldLocalImages, ...Object.values(defaultRehypePlugins)];
|
|
5575
|
+
function localImagePath(src) {
|
|
5576
|
+
if (!src?.startsWith(LOCAL_PREFIX)) return;
|
|
5577
|
+
try {
|
|
5578
|
+
return decodeURIComponent(src.slice(28));
|
|
5579
|
+
} catch {
|
|
5580
|
+
return;
|
|
5581
|
+
}
|
|
5582
|
+
}
|
|
5583
|
+
function MarkdownImage({ src, alt, terminal }) {
|
|
5584
|
+
const links = useFileLinks();
|
|
5585
|
+
const raw = typeof src === "string" ? src : void 0;
|
|
5586
|
+
const local = localImagePath(raw);
|
|
5587
|
+
const path = local === void 0 ? void 0 : parseFileLink(local, links?.cwd)?.path;
|
|
5588
|
+
const host = useHostImageSrc(path);
|
|
5589
|
+
const resolved = local === void 0 ? raw : host.src;
|
|
5590
|
+
const label = typeof alt === "string" && alt ? alt : void 0;
|
|
5591
|
+
const name = path ? baseName(path) : label ?? "image";
|
|
5592
|
+
const failed = local !== void 0 && (path === void 0 || host.failed);
|
|
5593
|
+
if (terminal) return /* @__PURE__ */ jsx("span", {
|
|
5594
|
+
className: "term-image",
|
|
5595
|
+
"data-state": resolved ? "loaded" : failed ? "failed" : "pending",
|
|
5596
|
+
style: { height: `calc(var(--term-line) * 12)` },
|
|
5597
|
+
children: resolved ? /* @__PURE__ */ jsx(ViewableImage, {
|
|
5598
|
+
image: {
|
|
5599
|
+
src: resolved,
|
|
5600
|
+
name
|
|
5601
|
+
},
|
|
5602
|
+
children: /* @__PURE__ */ jsx("img", {
|
|
5603
|
+
src: resolved,
|
|
5604
|
+
alt: label ?? name
|
|
5605
|
+
})
|
|
5606
|
+
}) : /* @__PURE__ */ jsx("span", {
|
|
5607
|
+
"data-tone": "faint",
|
|
5608
|
+
children: failed ? `${IMAGE_UNAVAILABLE} · ${local ?? name}` : name
|
|
5609
|
+
})
|
|
5610
|
+
});
|
|
5611
|
+
if (!resolved) return /* @__PURE__ */ jsx("span", {
|
|
5612
|
+
className: "my-1 inline-block rounded-md border border-border bg-surface-hover px-2 py-1 text-label text-fg-4",
|
|
5613
|
+
children: failed ? `${IMAGE_UNAVAILABLE} · ${local ?? name}` : name
|
|
5614
|
+
});
|
|
5615
|
+
return /* @__PURE__ */ jsx(ViewableImage, {
|
|
5616
|
+
image: {
|
|
5617
|
+
src: resolved,
|
|
5618
|
+
name
|
|
5619
|
+
},
|
|
5620
|
+
className: "my-1 block max-w-full",
|
|
5621
|
+
children: /* @__PURE__ */ jsx("img", {
|
|
5622
|
+
src: resolved,
|
|
5623
|
+
alt: label ?? name,
|
|
5624
|
+
className: "max-h-96 w-auto max-w-full rounded-md border border-border"
|
|
5625
|
+
})
|
|
5626
|
+
});
|
|
5627
|
+
}
|
|
5628
|
+
//#endregion
|
|
5629
|
+
//#region src/components/terminal/markdown.tsx
|
|
5630
|
+
function codeText(node) {
|
|
5631
|
+
if (node === null || node === void 0 || typeof node === "boolean") return "";
|
|
5632
|
+
if (typeof node === "string" || typeof node === "number") return String(node);
|
|
5633
|
+
if (Array.isArray(node)) return node.map(codeText).join("");
|
|
5634
|
+
const element = node;
|
|
5635
|
+
return element.props ? codeText(element.props.children) : "";
|
|
5636
|
+
}
|
|
5637
|
+
function fenceLanguage(node) {
|
|
5638
|
+
const className = (Array.isArray(node) ? node.find(Boolean) : node)?.props?.className;
|
|
5639
|
+
return /language-([\w-]+)/.exec(className ?? "")?.[1];
|
|
5640
|
+
}
|
|
5641
|
+
function CodeBand({ code, language }) {
|
|
5642
|
+
return /* @__PURE__ */ jsx(WithActions, {
|
|
5643
|
+
className: "term-block",
|
|
5644
|
+
placement: "inline",
|
|
5645
|
+
actions: /* @__PURE__ */ jsx(CopyAction, {
|
|
5646
|
+
text: code,
|
|
5647
|
+
label: "Copy code"
|
|
5648
|
+
}),
|
|
5649
|
+
children: /* @__PURE__ */ jsx(Band, {
|
|
5650
|
+
className: "term-code",
|
|
5651
|
+
"data-language": language,
|
|
5652
|
+
children: /* @__PURE__ */ jsx("pre", {
|
|
5653
|
+
className: "term-pre",
|
|
5654
|
+
children: code
|
|
5655
|
+
})
|
|
5656
|
+
})
|
|
5657
|
+
});
|
|
5658
|
+
}
|
|
5659
|
+
function heading(tone) {
|
|
5660
|
+
return function Heading({ children }) {
|
|
5661
|
+
return /* @__PURE__ */ jsx("div", {
|
|
5662
|
+
className: "term-block",
|
|
5663
|
+
"data-tone": tone,
|
|
5664
|
+
"data-weight": "bold",
|
|
5665
|
+
children
|
|
5666
|
+
});
|
|
5667
|
+
};
|
|
5668
|
+
}
|
|
5669
|
+
function Link({ href, children }) {
|
|
5670
|
+
const links = useFileLinks();
|
|
5671
|
+
const file = links ? parseFileLink(href, links.cwd) : void 0;
|
|
5672
|
+
if (file) return /* @__PURE__ */ jsx("button", {
|
|
5673
|
+
type: "button",
|
|
5674
|
+
className: "term-link",
|
|
5675
|
+
"data-tone": "blue",
|
|
5676
|
+
title: file.line === void 0 ? file.path : `${file.path}:${file.line}`,
|
|
5677
|
+
onClick: (event) => {
|
|
5678
|
+
event.stopPropagation();
|
|
5679
|
+
links?.open(file.path, file.line);
|
|
5680
|
+
},
|
|
5681
|
+
children
|
|
5682
|
+
});
|
|
5683
|
+
return /* @__PURE__ */ jsx("a", {
|
|
5684
|
+
className: "term-link",
|
|
5685
|
+
"data-tone": "blue",
|
|
5686
|
+
href,
|
|
5687
|
+
target: "_blank",
|
|
5688
|
+
rel: "noreferrer",
|
|
5689
|
+
children
|
|
5690
|
+
});
|
|
5691
|
+
}
|
|
5692
|
+
const TERMINAL_COMPONENTS = {
|
|
5693
|
+
p: ({ children }) => /* @__PURE__ */ jsx("div", {
|
|
5694
|
+
className: "term-block",
|
|
5695
|
+
children
|
|
5696
|
+
}),
|
|
5697
|
+
h1: heading("bright"),
|
|
5698
|
+
h2: heading("bright"),
|
|
5699
|
+
h3: heading("bright"),
|
|
5700
|
+
h4: heading("fg"),
|
|
5701
|
+
h5: heading("fg"),
|
|
5702
|
+
h6: heading("fg"),
|
|
5703
|
+
ul: ({ children }) => /* @__PURE__ */ jsx("ul", {
|
|
5704
|
+
className: "term-block term-list",
|
|
5705
|
+
children
|
|
5706
|
+
}),
|
|
5707
|
+
ol: ({ children }) => /* @__PURE__ */ jsx("ol", {
|
|
5708
|
+
className: "term-block term-list term-list-ordered",
|
|
5709
|
+
children
|
|
5710
|
+
}),
|
|
5711
|
+
li: ({ children }) => /* @__PURE__ */ jsxs("li", {
|
|
5712
|
+
className: "term-row term-li",
|
|
5713
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
5714
|
+
className: "term-gutter",
|
|
5715
|
+
"aria-hidden": true
|
|
5716
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
5717
|
+
className: "term-body",
|
|
5718
|
+
children
|
|
5719
|
+
})]
|
|
5720
|
+
}),
|
|
5721
|
+
blockquote: ({ children }) => /* @__PURE__ */ jsx("blockquote", {
|
|
5722
|
+
className: "term-block term-quote",
|
|
5723
|
+
"data-tone": "dim",
|
|
5724
|
+
children
|
|
5725
|
+
}),
|
|
5726
|
+
hr: () => /* @__PURE__ */ jsx("div", {
|
|
5727
|
+
className: "term-block term-rule",
|
|
5728
|
+
"aria-hidden": true
|
|
5729
|
+
}),
|
|
5730
|
+
pre: ({ children }) => /* @__PURE__ */ jsx(CodeBand, {
|
|
5731
|
+
code: codeText(children),
|
|
5732
|
+
language: fenceLanguage(children)
|
|
5733
|
+
}),
|
|
5734
|
+
code: ({ children }) => /* @__PURE__ */ jsx("code", {
|
|
5735
|
+
className: "term-inline-code",
|
|
5736
|
+
"data-tone": "blue",
|
|
5737
|
+
children
|
|
5738
|
+
}),
|
|
5739
|
+
strong: ({ children }) => /* @__PURE__ */ jsx("strong", {
|
|
5740
|
+
"data-tone": "bright",
|
|
5741
|
+
"data-weight": "bold",
|
|
5742
|
+
children
|
|
5249
5743
|
}),
|
|
5250
5744
|
em: ({ children }) => /* @__PURE__ */ jsx("em", {
|
|
5251
5745
|
className: "term-em",
|
|
@@ -5255,6 +5749,11 @@ const TERMINAL_COMPONENTS = {
|
|
|
5255
5749
|
href,
|
|
5256
5750
|
children
|
|
5257
5751
|
}),
|
|
5752
|
+
img: ({ src, alt }) => /* @__PURE__ */ jsx(MarkdownImage, {
|
|
5753
|
+
src,
|
|
5754
|
+
alt,
|
|
5755
|
+
terminal: true
|
|
5756
|
+
}),
|
|
5258
5757
|
table: ({ children }) => /* @__PURE__ */ jsx("div", {
|
|
5259
5758
|
className: "term-block term-table-wrap",
|
|
5260
5759
|
children: /* @__PURE__ */ jsx("table", {
|
|
@@ -5281,6 +5780,7 @@ const TerminalMarkdown = memo(function TerminalMarkdown({ children, streaming, c
|
|
|
5281
5780
|
parseIncompleteMarkdown: streaming,
|
|
5282
5781
|
controls: false,
|
|
5283
5782
|
components: TERMINAL_COMPONENTS,
|
|
5783
|
+
rehypePlugins: MARKDOWN_REHYPE_PLUGINS,
|
|
5284
5784
|
className: cn("term-md", className),
|
|
5285
5785
|
children
|
|
5286
5786
|
});
|
|
@@ -5479,12 +5979,6 @@ function scrollParent(from) {
|
|
|
5479
5979
|
return null;
|
|
5480
5980
|
}
|
|
5481
5981
|
//#endregion
|
|
5482
|
-
//#region src/components/terminal/image-box.ts
|
|
5483
|
-
function imagePlaceholder(image) {
|
|
5484
|
-
return `image · ${formatBytes(image.bytes)}`;
|
|
5485
|
-
}
|
|
5486
|
-
const IMAGE_UNAVAILABLE = "image unavailable";
|
|
5487
|
-
//#endregion
|
|
5488
5982
|
//#region src/components/terminal/result-preview.ts
|
|
5489
5983
|
const PREVIEW_LINES = 4;
|
|
5490
5984
|
const PREVIEW_CHARS = 400;
|
|
@@ -5521,11 +6015,11 @@ function collapsedResult(lines, totalChars) {
|
|
|
5521
6015
|
}
|
|
5522
6016
|
//#endregion
|
|
5523
6017
|
//#region src/components/agent/tool-result-fetch.tsx
|
|
5524
|
-
const noop
|
|
5525
|
-
const FetchContext = createContext(noop
|
|
6018
|
+
const noop = async () => false;
|
|
6019
|
+
const FetchContext = createContext(noop);
|
|
5526
6020
|
function ToolResultFetchProvider({ value, children }) {
|
|
5527
6021
|
return /* @__PURE__ */ jsx(FetchContext.Provider, {
|
|
5528
|
-
value: value ?? noop
|
|
6022
|
+
value: value ?? noop,
|
|
5529
6023
|
children
|
|
5530
6024
|
});
|
|
5531
6025
|
}
|
|
@@ -5545,102 +6039,6 @@ function useToolTitle(name) {
|
|
|
5545
6039
|
return toolTitle(name, useContext(TitlesContext));
|
|
5546
6040
|
}
|
|
5547
6041
|
//#endregion
|
|
5548
|
-
//#region src/components/agent/tool-result-image.tsx
|
|
5549
|
-
const noop = async () => void 0;
|
|
5550
|
-
const ImageContext = createContext(noop);
|
|
5551
|
-
function ToolResultImageProvider({ value, children }) {
|
|
5552
|
-
return /* @__PURE__ */ jsx(ImageContext.Provider, {
|
|
5553
|
-
value: value ?? noop,
|
|
5554
|
-
children
|
|
5555
|
-
});
|
|
5556
|
-
}
|
|
5557
|
-
function useToolResultImageLoader() {
|
|
5558
|
-
return useContext(ImageContext);
|
|
5559
|
-
}
|
|
5560
|
-
const MOUNT_SETTLE_MS = 150;
|
|
5561
|
-
function useToolResultImageSrc(ref) {
|
|
5562
|
-
const load = useToolResultImageLoader();
|
|
5563
|
-
const [state, setState] = useState({ failed: false });
|
|
5564
|
-
const { toolUseId, sourceSeq, partIndex, mediaType, bytes } = ref;
|
|
5565
|
-
useEffect(() => {
|
|
5566
|
-
let live = true;
|
|
5567
|
-
setState({ failed: false });
|
|
5568
|
-
const timer = setTimeout(() => {
|
|
5569
|
-
load({
|
|
5570
|
-
toolUseId,
|
|
5571
|
-
sourceSeq,
|
|
5572
|
-
partIndex,
|
|
5573
|
-
mediaType,
|
|
5574
|
-
bytes
|
|
5575
|
-
}).then((src) => {
|
|
5576
|
-
if (live) setState({
|
|
5577
|
-
src,
|
|
5578
|
-
failed: src === void 0
|
|
5579
|
-
});
|
|
5580
|
-
}).catch(() => {
|
|
5581
|
-
if (live) setState({ failed: true });
|
|
5582
|
-
});
|
|
5583
|
-
}, MOUNT_SETTLE_MS);
|
|
5584
|
-
return () => {
|
|
5585
|
-
live = false;
|
|
5586
|
-
clearTimeout(timer);
|
|
5587
|
-
};
|
|
5588
|
-
}, [
|
|
5589
|
-
load,
|
|
5590
|
-
toolUseId,
|
|
5591
|
-
sourceSeq,
|
|
5592
|
-
partIndex,
|
|
5593
|
-
mediaType,
|
|
5594
|
-
bytes
|
|
5595
|
-
]);
|
|
5596
|
-
return state;
|
|
5597
|
-
}
|
|
5598
|
-
const CACHE_BUDGET_BYTES = 67108864;
|
|
5599
|
-
function useToolResultImages(client, sessionId) {
|
|
5600
|
-
const cache = useRef(/* @__PURE__ */ new Map());
|
|
5601
|
-
useEffect(() => () => {
|
|
5602
|
-
for (const entry of cache.current.values()) if (entry.url) URL.revokeObjectURL(entry.url);
|
|
5603
|
-
cache.current.clear();
|
|
5604
|
-
}, []);
|
|
5605
|
-
return useCallback((ref) => {
|
|
5606
|
-
if (!sessionId) return Promise.resolve(void 0);
|
|
5607
|
-
const key = `${sessionId}:${ref.sourceSeq}:${ref.toolUseId}:${ref.partIndex}`;
|
|
5608
|
-
const hit = cache.current.get(key);
|
|
5609
|
-
if (hit) {
|
|
5610
|
-
cache.current.delete(key);
|
|
5611
|
-
cache.current.set(key, hit);
|
|
5612
|
-
return hit.pending;
|
|
5613
|
-
}
|
|
5614
|
-
const pending = client.toolResultImage(sessionId, ref.sourceSeq, ref.toolUseId, ref.partIndex).then((blob) => {
|
|
5615
|
-
if (blob.size === 0) return;
|
|
5616
|
-
const url = URL.createObjectURL(blob);
|
|
5617
|
-
const entry = cache.current.get(key);
|
|
5618
|
-
if (entry) {
|
|
5619
|
-
entry.url = url;
|
|
5620
|
-
entry.bytes = blob.size;
|
|
5621
|
-
evict(cache.current, key);
|
|
5622
|
-
} else URL.revokeObjectURL(url);
|
|
5623
|
-
return url;
|
|
5624
|
-
}).catch(() => void 0);
|
|
5625
|
-
cache.current.set(key, {
|
|
5626
|
-
pending,
|
|
5627
|
-
bytes: ref.bytes
|
|
5628
|
-
});
|
|
5629
|
-
return pending;
|
|
5630
|
-
}, [client, sessionId]);
|
|
5631
|
-
}
|
|
5632
|
-
function evict(cache, keep) {
|
|
5633
|
-
let held = 0;
|
|
5634
|
-
for (const entry of cache.values()) held += entry.bytes;
|
|
5635
|
-
for (const [key, entry] of cache) {
|
|
5636
|
-
if (held <= CACHE_BUDGET_BYTES) return;
|
|
5637
|
-
if (key === keep) continue;
|
|
5638
|
-
if (entry.url) URL.revokeObjectURL(entry.url);
|
|
5639
|
-
cache.delete(key);
|
|
5640
|
-
held -= entry.bytes;
|
|
5641
|
-
}
|
|
5642
|
-
}
|
|
5643
|
-
//#endregion
|
|
5644
6042
|
//#region src/components/terminal/todos.ts
|
|
5645
6043
|
const PREVIEW_TODOS = 8;
|
|
5646
6044
|
const GLYPH = {
|
|
@@ -5678,8 +6076,75 @@ function ShellActionsProvider({ value, children }) {
|
|
|
5678
6076
|
children
|
|
5679
6077
|
});
|
|
5680
6078
|
}
|
|
5681
|
-
function useShellActions() {
|
|
5682
|
-
return useContext(ShellActionsContext);
|
|
6079
|
+
function useShellActions() {
|
|
6080
|
+
return useContext(ShellActionsContext);
|
|
6081
|
+
}
|
|
6082
|
+
//#endregion
|
|
6083
|
+
//#region src/components/terminal/shell-row.ts
|
|
6084
|
+
const SHELL_GLYPH = "$";
|
|
6085
|
+
const SHELL_KILL_GLYPH = "✕";
|
|
6086
|
+
const SHELL_MISSING = "output expired or not tracked by this gateway";
|
|
6087
|
+
const SHELL_AGENT_WRITE_NOTE = "agent may type";
|
|
6088
|
+
function shellGrantable(shell) {
|
|
6089
|
+
return shell.status === "running" && shell.owner === "user";
|
|
6090
|
+
}
|
|
6091
|
+
function shellAgentWriteLabel(shell) {
|
|
6092
|
+
return shell.agentWrite === true ? "Revoke the agent’s access to this shell" : "Let the agent type into this shell";
|
|
6093
|
+
}
|
|
6094
|
+
function shellInfoLabel(shell) {
|
|
6095
|
+
return shell.label || shell.command.split("\n")[0] || "";
|
|
6096
|
+
}
|
|
6097
|
+
function shellTitle(shell) {
|
|
6098
|
+
return `#${shell.ordinal} ${shellInfoLabel(shell)}`;
|
|
6099
|
+
}
|
|
6100
|
+
function shellLabel(item) {
|
|
6101
|
+
return shellInfoLabel(item.shell);
|
|
6102
|
+
}
|
|
6103
|
+
function shellStatusText(item) {
|
|
6104
|
+
return shellInfoStatusText(item.shell);
|
|
6105
|
+
}
|
|
6106
|
+
function shellInfoFailed(shell) {
|
|
6107
|
+
return shell.status === "exited" && shell.exitCode !== 0;
|
|
6108
|
+
}
|
|
6109
|
+
function shellInfoStatusText(shell) {
|
|
6110
|
+
if (shell.status === "running") return shell.agentWrite === true ? `running · ${SHELL_AGENT_WRITE_NOTE}` : "running";
|
|
6111
|
+
if (typeof shell.exitCode === "number") return shell.exitCode === 0 ? "exit 0" : `exit ${shell.exitCode}`;
|
|
6112
|
+
switch (shell.endReason) {
|
|
6113
|
+
case "killed": return "killed";
|
|
6114
|
+
case "timeout": return "timed out";
|
|
6115
|
+
case "server_stopped": return "killed: the gateway stopped";
|
|
6116
|
+
case "server_restarted": return "ended: the gateway restarted, the process may still be running";
|
|
6117
|
+
case "spawn_failed": return "failed to start";
|
|
6118
|
+
default: return "ended";
|
|
6119
|
+
}
|
|
6120
|
+
}
|
|
6121
|
+
function shellFailed(item) {
|
|
6122
|
+
return shellInfoFailed(item.shell);
|
|
6123
|
+
}
|
|
6124
|
+
function shellHeaderText(item) {
|
|
6125
|
+
return `${shellLabel(item)} · ${shellStatusText(item)}`;
|
|
6126
|
+
}
|
|
6127
|
+
function shellBodyLines(item, open) {
|
|
6128
|
+
const source = open && item.expanded !== void 0 ? item.expanded : item.text;
|
|
6129
|
+
if (source === "" || item.shell.interactive) return [];
|
|
6130
|
+
const lines = source.split("\n");
|
|
6131
|
+
if (!open) return lines;
|
|
6132
|
+
const kept = [];
|
|
6133
|
+
let chars = 0;
|
|
6134
|
+
for (const line of lines) {
|
|
6135
|
+
if (kept.length > 0 && chars + line.length > 1e5) break;
|
|
6136
|
+
kept.push(line);
|
|
6137
|
+
chars += line.length + 1;
|
|
6138
|
+
}
|
|
6139
|
+
return kept;
|
|
6140
|
+
}
|
|
6141
|
+
function shellFooterText(item, open, shown) {
|
|
6142
|
+
if (item.shell.interactive) return SHELL_INTERACTIVE_NOTE;
|
|
6143
|
+
if (item.missing) return SHELL_MISSING;
|
|
6144
|
+
if (!open) return item.truncated ? "… more output - expand to fetch it" : void 0;
|
|
6145
|
+
const total = item.expanded === void 0 ? void 0 : item.expanded.split("\n").length;
|
|
6146
|
+
if (total !== void 0 && total > shown) return `… +${(total - shown).toLocaleString()} lines not shown`;
|
|
6147
|
+
if (item.expanded === void 0 && item.truncated) return "… fetching the full output";
|
|
5683
6148
|
}
|
|
5684
6149
|
const RESULT_PREVIEW_CHARS$1 = 2e3;
|
|
5685
6150
|
function clipToChars(lines, maxChars) {
|
|
@@ -5747,7 +6212,7 @@ function PeerSendRow({ item }) {
|
|
|
5747
6212
|
})
|
|
5748
6213
|
});
|
|
5749
6214
|
}
|
|
5750
|
-
function UserRow({ item }) {
|
|
6215
|
+
function UserRow({ item, attachmentUrl }) {
|
|
5751
6216
|
return /* @__PURE__ */ jsx(WithActions, {
|
|
5752
6217
|
actions: /* @__PURE__ */ jsx(BookmarkAction, { id: item.id }),
|
|
5753
6218
|
children: /* @__PURE__ */ jsxs("div", {
|
|
@@ -5757,7 +6222,10 @@ function UserRow({ item }) {
|
|
|
5757
6222
|
glyph: "❯",
|
|
5758
6223
|
glyphTone: "dim",
|
|
5759
6224
|
tone: "dim",
|
|
5760
|
-
children: item.attachments.map((attachment) =>
|
|
6225
|
+
children: item.attachments.map((attachment, index) => /* @__PURE__ */ jsxs(Fragment, { children: [index > 0 ? ", " : null, /* @__PURE__ */ jsx(AttachmentName, {
|
|
6226
|
+
attachment,
|
|
6227
|
+
href: attachmentUrl?.(attachment.id)
|
|
6228
|
+
})] }, attachment.id))
|
|
5761
6229
|
}) : null, item.text ? item.text.split("\n").map((line, index) => item.origin && index === 0 ? /* @__PURE__ */ jsx(PeerRow, {
|
|
5762
6230
|
glyph: "↦",
|
|
5763
6231
|
who: peerName(item.origin),
|
|
@@ -5829,6 +6297,7 @@ function ToolRow({ item }) {
|
|
|
5829
6297
|
const copyable = typeof command === "string" ? command : text;
|
|
5830
6298
|
const todos = todoPreview(item.name, item.input);
|
|
5831
6299
|
const title = useToolTitle(item.name);
|
|
6300
|
+
const hostPath = hostImagePathOf(item);
|
|
5832
6301
|
return /* @__PURE__ */ jsx("div", {
|
|
5833
6302
|
ref: reveal,
|
|
5834
6303
|
className: open ? "term-open" : void 0,
|
|
@@ -5872,8 +6341,10 @@ function ToolRow({ item }) {
|
|
|
5872
6341
|
]
|
|
5873
6342
|
})
|
|
5874
6343
|
}),
|
|
6344
|
+
hostPath !== void 0 ? /* @__PURE__ */ jsx(TerminalHostImage, { path: hostPath }) : null,
|
|
5875
6345
|
item.result?.images?.map((image) => /* @__PURE__ */ jsx(TerminalImage, {
|
|
5876
6346
|
toolUseId: item.id,
|
|
6347
|
+
name: resultImageName(item.name, image),
|
|
5877
6348
|
image
|
|
5878
6349
|
}, image.partIndex)),
|
|
5879
6350
|
item.patch && !open ? /* @__PURE__ */ jsx(TerminalDiff, { patch: item.patch }) : todos && !open ? /* @__PURE__ */ jsx(TerminalTodos, { preview: todos }) : text ? /* @__PURE__ */ jsxs(Fragment$1, { children: [preview.map((line, index) => /* @__PURE__ */ jsx(Row, {
|
|
@@ -5945,11 +6416,43 @@ function TerminalTodos({ preview }) {
|
|
|
5945
6416
|
children: preview.more
|
|
5946
6417
|
}) : null] });
|
|
5947
6418
|
}
|
|
5948
|
-
function
|
|
5949
|
-
const
|
|
6419
|
+
function AttachmentName({ attachment, href }) {
|
|
6420
|
+
const open = useOpenImage();
|
|
6421
|
+
if (!open || !href || !attachment.mediaType.startsWith("image/")) return /* @__PURE__ */ jsx(Fragment$1, { children: attachment.name });
|
|
6422
|
+
return /* @__PURE__ */ jsx("button", {
|
|
6423
|
+
type: "button",
|
|
6424
|
+
className: "term-press term-link",
|
|
6425
|
+
onClick: (event) => {
|
|
6426
|
+
event.stopPropagation();
|
|
6427
|
+
open({
|
|
6428
|
+
src: href,
|
|
6429
|
+
name: attachment.name
|
|
6430
|
+
});
|
|
6431
|
+
},
|
|
6432
|
+
children: attachment.name
|
|
6433
|
+
});
|
|
6434
|
+
}
|
|
6435
|
+
function TerminalImage({ toolUseId, name, image }) {
|
|
6436
|
+
const state = useToolResultImageSrc({
|
|
5950
6437
|
toolUseId,
|
|
5951
6438
|
...image
|
|
5952
6439
|
});
|
|
6440
|
+
return /* @__PURE__ */ jsx(TerminalImageBox, {
|
|
6441
|
+
state,
|
|
6442
|
+
name,
|
|
6443
|
+
placeholder: imagePlaceholder(image)
|
|
6444
|
+
});
|
|
6445
|
+
}
|
|
6446
|
+
function TerminalHostImage({ path }) {
|
|
6447
|
+
const state = useHostImageSrc(path);
|
|
6448
|
+
return /* @__PURE__ */ jsx(TerminalImageBox, {
|
|
6449
|
+
state,
|
|
6450
|
+
name: baseName(path),
|
|
6451
|
+
placeholder: baseName(path)
|
|
6452
|
+
});
|
|
6453
|
+
}
|
|
6454
|
+
function TerminalImageBox({ state, name, placeholder }) {
|
|
6455
|
+
const { src, failed } = state;
|
|
5953
6456
|
return /* @__PURE__ */ jsx(Row, {
|
|
5954
6457
|
indent: 1,
|
|
5955
6458
|
columns: 3,
|
|
@@ -5957,12 +6460,18 @@ function TerminalImage({ toolUseId, image }) {
|
|
|
5957
6460
|
className: "term-image",
|
|
5958
6461
|
"data-state": src ? "loaded" : failed ? "failed" : "pending",
|
|
5959
6462
|
style: { height: `calc(var(--term-line) * 12)` },
|
|
5960
|
-
children: src ? /* @__PURE__ */ jsx(
|
|
5961
|
-
|
|
5962
|
-
|
|
6463
|
+
children: src ? /* @__PURE__ */ jsx(ViewableImage, {
|
|
6464
|
+
image: {
|
|
6465
|
+
src,
|
|
6466
|
+
name
|
|
6467
|
+
},
|
|
6468
|
+
children: /* @__PURE__ */ jsx("img", {
|
|
6469
|
+
src,
|
|
6470
|
+
alt: name
|
|
6471
|
+
})
|
|
5963
6472
|
}) : /* @__PURE__ */ jsx(Ink, {
|
|
5964
6473
|
tone: "faint",
|
|
5965
|
-
children: failed ? IMAGE_UNAVAILABLE :
|
|
6474
|
+
children: failed ? IMAGE_UNAVAILABLE : placeholder
|
|
5966
6475
|
})
|
|
5967
6476
|
})
|
|
5968
6477
|
});
|
|
@@ -5991,7 +6500,10 @@ function ToolRunRow({ items }) {
|
|
|
5991
6500
|
children: runSummary(items, busy)
|
|
5992
6501
|
}) : runSummary(items, busy)
|
|
5993
6502
|
})
|
|
5994
|
-
}), open ? /* @__PURE__ */ jsx("div", { children: items.map((item) => /* @__PURE__ */
|
|
6503
|
+
}), open ? /* @__PURE__ */ jsx("div", { children: items.map((item, index) => /* @__PURE__ */ jsxs(Fragment, { children: [index > 0 ? /* @__PURE__ */ jsx(Blank, {}) : null, index < items.length - 1 ? /* @__PURE__ */ jsx(ActionPlacementProvider, {
|
|
6504
|
+
value: "below",
|
|
6505
|
+
children: /* @__PURE__ */ jsx(ToolRow, { item })
|
|
6506
|
+
}) : /* @__PURE__ */ jsx(ToolRow, { item })] }, item.id)) }) : null]
|
|
5995
6507
|
});
|
|
5996
6508
|
}
|
|
5997
6509
|
function RunRow({ items }) {
|
|
@@ -6068,6 +6580,11 @@ function ShellRow({ item }) {
|
|
|
6068
6580
|
children: /* @__PURE__ */ jsxs(WithActions, {
|
|
6069
6581
|
actions: /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
6070
6582
|
actions.open ? /* @__PURE__ */ jsx(OpenShellAction, { onOpen: () => actions.open?.(shellId) }) : null,
|
|
6583
|
+
actions.agentWrite && shellGrantable(item.shell) ? /* @__PURE__ */ jsx(AgentWriteAction, {
|
|
6584
|
+
granted: item.shell.agentWrite === true,
|
|
6585
|
+
label: shellAgentWriteLabel(item.shell),
|
|
6586
|
+
onToggle: () => void actions.agentWrite?.(shellId, item.shell.agentWrite !== true)
|
|
6587
|
+
}) : null,
|
|
6071
6588
|
running ? /* @__PURE__ */ jsx(KillShellAction, { onKill: () => void actions.kill(shellId) }) : null,
|
|
6072
6589
|
/* @__PURE__ */ jsx(BookmarkAction, { id: item.id }),
|
|
6073
6590
|
/* @__PURE__ */ jsx(CopyAction, {
|
|
@@ -7632,13 +8149,103 @@ function planFromRequest(request) {
|
|
|
7632
8149
|
return plan;
|
|
7633
8150
|
}
|
|
7634
8151
|
//#endregion
|
|
8152
|
+
//#region src/lib/shell-request.ts
|
|
8153
|
+
const CONTROL_NAMES = {
|
|
8154
|
+
"\r": "enter",
|
|
8155
|
+
"\n": "newline",
|
|
8156
|
+
" ": "tab",
|
|
8157
|
+
"\x1B": "escape",
|
|
8158
|
+
"": "backspace"
|
|
8159
|
+
};
|
|
8160
|
+
const SHELL_WRITE_TOOLS = [
|
|
8161
|
+
"shell_run",
|
|
8162
|
+
"shell_write",
|
|
8163
|
+
"shell_kill",
|
|
8164
|
+
"shell_request_write"
|
|
8165
|
+
];
|
|
8166
|
+
function shellToolOf(toolName) {
|
|
8167
|
+
if (typeof toolName !== "string") return;
|
|
8168
|
+
const bare = toolName.startsWith("mcp__") ? toolName.slice(toolName.indexOf("__", 5) + 2) : toolName;
|
|
8169
|
+
return SHELL_WRITE_TOOLS.includes(bare) ? bare : void 0;
|
|
8170
|
+
}
|
|
8171
|
+
function shellRequestPayload(request) {
|
|
8172
|
+
const tool = shellToolOf(request?.toolName);
|
|
8173
|
+
if (!tool) return;
|
|
8174
|
+
const input = request?.input !== null && typeof request?.input === "object" ? request.input : {};
|
|
8175
|
+
const shellId = typeof input.shellId === "string" ? input.shellId : "";
|
|
8176
|
+
switch (tool) {
|
|
8177
|
+
case "shell_run": return {
|
|
8178
|
+
kind: "run",
|
|
8179
|
+
command: typeof input.command === "string" ? input.command : ""
|
|
8180
|
+
};
|
|
8181
|
+
case "shell_write": {
|
|
8182
|
+
const keys = Array.isArray(input.keys) ? input.keys.filter((key) => typeof key === "string") : void 0;
|
|
8183
|
+
return {
|
|
8184
|
+
kind: "write",
|
|
8185
|
+
shellId,
|
|
8186
|
+
...typeof input.data === "string" ? { data: input.data } : {},
|
|
8187
|
+
...keys && keys.length > 0 ? { keys } : {}
|
|
8188
|
+
};
|
|
8189
|
+
}
|
|
8190
|
+
case "shell_kill": return {
|
|
8191
|
+
kind: "kill",
|
|
8192
|
+
shellId
|
|
8193
|
+
};
|
|
8194
|
+
case "shell_request_write": return {
|
|
8195
|
+
kind: "grant",
|
|
8196
|
+
shellId,
|
|
8197
|
+
reason: typeof input.reason === "string" ? input.reason : ""
|
|
8198
|
+
};
|
|
8199
|
+
}
|
|
8200
|
+
}
|
|
8201
|
+
function shellRequestTitle(payload) {
|
|
8202
|
+
switch (payload.kind) {
|
|
8203
|
+
case "run": return "Agent wants to start a shell";
|
|
8204
|
+
case "write": return `Agent wants to type into shell ${payload.shellId}`;
|
|
8205
|
+
case "kill": return `Agent wants to kill shell ${payload.shellId}`;
|
|
8206
|
+
case "grant": return `Agent asks to type into your shell ${payload.shellId}`;
|
|
8207
|
+
}
|
|
8208
|
+
}
|
|
8209
|
+
function shellRequestLines(payload) {
|
|
8210
|
+
switch (payload.kind) {
|
|
8211
|
+
case "run": return payload.command.split("\n").map((line, index) => index === 0 ? `$ ${line}` : ` ${line}`);
|
|
8212
|
+
case "write": {
|
|
8213
|
+
const lines = [];
|
|
8214
|
+
if (payload.data !== void 0) lines.push(`types: ${visibleControls(payload.data)}`);
|
|
8215
|
+
if (payload.keys) lines.push(`presses: ${payload.keys.map((key) => `[${key}]`).join(" ")}`);
|
|
8216
|
+
return lines;
|
|
8217
|
+
}
|
|
8218
|
+
case "kill": return [`kill ${payload.shellId}`];
|
|
8219
|
+
case "grant": return [`why: ${visibleControls(payload.reason)}`, "until the shell ends or you revoke it"];
|
|
8220
|
+
}
|
|
8221
|
+
}
|
|
8222
|
+
function visibleControls(text) {
|
|
8223
|
+
let out = "";
|
|
8224
|
+
for (const char of text) {
|
|
8225
|
+
const code = char.codePointAt(0);
|
|
8226
|
+
if (code >= 32 && code !== 127) {
|
|
8227
|
+
out += char;
|
|
8228
|
+
continue;
|
|
8229
|
+
}
|
|
8230
|
+
const named = CONTROL_NAMES[char];
|
|
8231
|
+
out += named ? `[${named}]` : `[ctrl-${String.fromCharCode(code + 64).toLowerCase()}]`;
|
|
8232
|
+
}
|
|
8233
|
+
return out;
|
|
8234
|
+
}
|
|
8235
|
+
//#endregion
|
|
7635
8236
|
//#region src/components/agent/Response.tsx
|
|
8237
|
+
const COMPONENTS = { img: ({ src, alt }) => /* @__PURE__ */ jsx(MarkdownImage, {
|
|
8238
|
+
src,
|
|
8239
|
+
alt
|
|
8240
|
+
}) };
|
|
7636
8241
|
const Response = memo(function Response({ children, streaming, className }) {
|
|
7637
8242
|
return /* @__PURE__ */ jsx(Streamdown, {
|
|
7638
8243
|
mode: streaming ? "streaming" : "static",
|
|
7639
8244
|
parseIncompleteMarkdown: streaming,
|
|
7640
8245
|
shikiTheme: ["github-light", "github-dark"],
|
|
7641
8246
|
linkSafety: { enabled: false },
|
|
8247
|
+
components: COMPONENTS,
|
|
8248
|
+
rehypePlugins: MARKDOWN_REHYPE_PLUGINS,
|
|
7642
8249
|
className: cn("size-full [&>*:first-child]:mt-0 [&>*:last-child]:mb-0", className),
|
|
7643
8250
|
children
|
|
7644
8251
|
});
|
|
@@ -7656,6 +8263,7 @@ function PermissionPrompt({ request, onApprove, onDeny, className }) {
|
|
|
7656
8263
|
setDenying(false);
|
|
7657
8264
|
};
|
|
7658
8265
|
const plan = planFromRequest(request);
|
|
8266
|
+
const shell = plan ? void 0 : shellRequestPayload(request);
|
|
7659
8267
|
const summary = toolInputPreview(request.input);
|
|
7660
8268
|
const ToolIcon = toolIcon(request.toolName);
|
|
7661
8269
|
return /* @__PURE__ */ jsxs("div", {
|
|
@@ -7670,7 +8278,7 @@ function PermissionPrompt({ request, onApprove, onDeny, className }) {
|
|
|
7670
8278
|
children: [
|
|
7671
8279
|
/* @__PURE__ */ jsx("div", {
|
|
7672
8280
|
className: "text-body-sm font-medium text-fg-1",
|
|
7673
|
-
children: plan ? "Plan ready for review" : request.title ?? request.displayName ?? "Permission needed"
|
|
8281
|
+
children: plan ? "Plan ready for review" : shell ? shellRequestTitle(shell) : request.title ?? request.displayName ?? "Permission needed"
|
|
7674
8282
|
}),
|
|
7675
8283
|
request.description ? /* @__PURE__ */ jsx("div", {
|
|
7676
8284
|
className: "mt-0.5 text-label text-fg-3",
|
|
@@ -7684,6 +8292,11 @@ function PermissionPrompt({ request, onApprove, onDeny, className }) {
|
|
|
7684
8292
|
className: "mt-1.5 max-h-72 overflow-y-auto rounded-md bg-code-bg px-2.5 py-2 text-body-sm text-fg-2",
|
|
7685
8293
|
children: /* @__PURE__ */ jsx(Response, { children: plan })
|
|
7686
8294
|
}) : /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
8295
|
+
shell ? /* @__PURE__ */ jsx("pre", {
|
|
8296
|
+
"data-slot": "shell-request",
|
|
8297
|
+
className: "mt-1.5 max-h-48 overflow-auto rounded-md bg-code-bg px-2.5 py-1.5 font-mono text-body-sm whitespace-pre-wrap text-fg-1",
|
|
8298
|
+
children: shellRequestLines(shell).join("\n")
|
|
8299
|
+
}) : null,
|
|
7687
8300
|
/* @__PURE__ */ jsxs("div", {
|
|
7688
8301
|
className: "mt-1.5 flex min-w-0 items-center gap-2",
|
|
7689
8302
|
children: [
|
|
@@ -7692,7 +8305,7 @@ function PermissionPrompt({ request, onApprove, onDeny, className }) {
|
|
|
7692
8305
|
className: "shrink-0 font-mono text-label font-medium text-fg-2",
|
|
7693
8306
|
children: request.toolName
|
|
7694
8307
|
}),
|
|
7695
|
-
summary ? /* @__PURE__ */ jsx("span", {
|
|
8308
|
+
summary && !shell ? /* @__PURE__ */ jsx("span", {
|
|
7696
8309
|
className: "min-w-0 truncate font-mono text-label text-fg-4",
|
|
7697
8310
|
children: summary
|
|
7698
8311
|
}) : null
|
|
@@ -7988,19 +8601,26 @@ function useSubagentFrame(options) {
|
|
|
7988
8601
|
}
|
|
7989
8602
|
//#endregion
|
|
7990
8603
|
//#region src/components/agent/ShellStrip.tsx
|
|
7991
|
-
function ShellStrip({ shell, label, cols, onBack, onKill, terminal, fontSize, lineHeight }) {
|
|
8604
|
+
function ShellStrip({ shell, label, cols, onBack, onKill, onAgentWrite, terminal, fontSize, lineHeight }) {
|
|
7992
8605
|
const running = shell?.status === "running";
|
|
7993
8606
|
const failed = shell ? shellInfoFailed(shell) : false;
|
|
7994
8607
|
const name = shell ? shellTitle(shell) : label;
|
|
7995
8608
|
const status = shell ? shellInfoStatusText(shell) : void 0;
|
|
7996
8609
|
const width = cols ?? shell?.cols;
|
|
7997
8610
|
const detail = width === void 0 ? void 0 : `${width} cols`;
|
|
8611
|
+
const granted = shell?.agentWrite === true;
|
|
8612
|
+
const grant = shell && onAgentWrite && shellGrantable(shell) ? () => onAgentWrite(!granted) : void 0;
|
|
7998
8613
|
if (terminal) return /* @__PURE__ */ jsx(TerminalSurface, {
|
|
7999
8614
|
fontSize,
|
|
8000
8615
|
lineHeight,
|
|
8001
8616
|
className: "shrink-0",
|
|
8002
8617
|
children: /* @__PURE__ */ jsx(WithActions, {
|
|
8003
|
-
|
|
8618
|
+
placement: "inline",
|
|
8619
|
+
actions: /* @__PURE__ */ jsxs(Fragment$1, { children: [grant && shell ? /* @__PURE__ */ jsx(AgentWriteAction, {
|
|
8620
|
+
granted,
|
|
8621
|
+
label: shellAgentWriteLabel(shell),
|
|
8622
|
+
onToggle: grant
|
|
8623
|
+
}) : null, running && onKill ? /* @__PURE__ */ jsx(KillShellAction, { onKill }) : null] }),
|
|
8004
8624
|
children: /* @__PURE__ */ jsxs(Row, {
|
|
8005
8625
|
glyph: "←",
|
|
8006
8626
|
glyphTone: "dim",
|
|
@@ -8048,6 +8668,18 @@ function ShellStrip({ shell, label, cols, onBack, onKill, terminal, fontSize, li
|
|
|
8048
8668
|
className: "shrink-0 text-label text-fg-4",
|
|
8049
8669
|
children: detail
|
|
8050
8670
|
}) : null,
|
|
8671
|
+
grant && shell ? /* @__PURE__ */ jsx("button", {
|
|
8672
|
+
type: "button",
|
|
8673
|
+
"aria-label": shellAgentWriteLabel(shell),
|
|
8674
|
+
"aria-pressed": granted,
|
|
8675
|
+
title: shellAgentWriteLabel(shell),
|
|
8676
|
+
className: cn("shrink-0 text-label", granted ? "text-warning" : "text-fg-3 hover:text-fg-1"),
|
|
8677
|
+
onClick: grant,
|
|
8678
|
+
children: /* @__PURE__ */ jsx(AgentWriteIcon, {
|
|
8679
|
+
granted,
|
|
8680
|
+
className: "size-3.5"
|
|
8681
|
+
})
|
|
8682
|
+
}) : null,
|
|
8051
8683
|
running && onKill ? /* @__PURE__ */ jsx("button", {
|
|
8052
8684
|
type: "button",
|
|
8053
8685
|
"aria-label": "Kill this shell",
|
|
@@ -8158,7 +8790,7 @@ function ShellTerminal({ handle, shellId, onEnded, onShell, fontSize, className
|
|
|
8158
8790
|
return () => observer.disconnect();
|
|
8159
8791
|
}, [ready]);
|
|
8160
8792
|
return /* @__PURE__ */ jsxs("div", {
|
|
8161
|
-
className: cn("relative min-h-0 flex-1 overflow-hidden px-2 py-1", className),
|
|
8793
|
+
className: cn("wd-shell-term relative min-h-0 flex-1 overflow-hidden px-2 py-1", className),
|
|
8162
8794
|
children: [/* @__PURE__ */ jsx("div", {
|
|
8163
8795
|
ref: host,
|
|
8164
8796
|
className: "h-full w-full",
|
|
@@ -8592,9 +9224,10 @@ function TerminalPermissionPrompt({ request, onApprove, onDeny, className }) {
|
|
|
8592
9224
|
setDenying(false);
|
|
8593
9225
|
};
|
|
8594
9226
|
const plan = planFromRequest(request);
|
|
8595
|
-
const
|
|
8596
|
-
const
|
|
8597
|
-
const
|
|
9227
|
+
const shell = plan ? void 0 : shellRequestPayload(request);
|
|
9228
|
+
const patch = plan || shell ? void 0 : previewPatch(request.input);
|
|
9229
|
+
const summary = plan || shell ? "" : toolInputPreview(request.input);
|
|
9230
|
+
const heading = plan ? "Plan ready for review" : shell ? shellRequestTitle(shell) : request.displayName ?? request.title ?? "Permission needed";
|
|
8598
9231
|
const subject = patch?.path ?? (summary || void 0);
|
|
8599
9232
|
const reasonInput = denying ? /* @__PURE__ */ jsx(PromptInput, {
|
|
8600
9233
|
value: reason,
|
|
@@ -8657,6 +9290,13 @@ function TerminalPermissionPrompt({ request, onApprove, onDeny, className }) {
|
|
|
8657
9290
|
}),
|
|
8658
9291
|
/* @__PURE__ */ jsx(Blank, {}),
|
|
8659
9292
|
/* @__PURE__ */ jsx(Rule, { dashed: true })
|
|
9293
|
+
] }) : shell ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
9294
|
+
shellRequestLines(shell).map((line, index) => /* @__PURE__ */ jsx(Row, {
|
|
9295
|
+
bold: true,
|
|
9296
|
+
children: line
|
|
9297
|
+
}, index)),
|
|
9298
|
+
/* @__PURE__ */ jsx(Blank, {}),
|
|
9299
|
+
/* @__PURE__ */ jsx(Rule, { dashed: true })
|
|
8660
9300
|
] }) : patch ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
8661
9301
|
/* @__PURE__ */ jsx(TerminalDiff, { patch }),
|
|
8662
9302
|
/* @__PURE__ */ jsx(Blank, {}),
|
|
@@ -8669,7 +9309,7 @@ function TerminalPermissionPrompt({ request, onApprove, onDeny, className }) {
|
|
|
8669
9309
|
tone: "faint",
|
|
8670
9310
|
children: request.decisionReason
|
|
8671
9311
|
}) : null,
|
|
8672
|
-
/* @__PURE__ */ jsx(Row, { children: plan ? "Ready to implement this plan?" : request.title ?? `Do you want to proceed?` }),
|
|
9312
|
+
/* @__PURE__ */ jsx(Row, { children: plan ? "Ready to implement this plan?" : shell ? "Do you want to let it?" : request.title ?? `Do you want to proceed?` }),
|
|
8673
9313
|
/* @__PURE__ */ jsx(Choices, {
|
|
8674
9314
|
label: heading,
|
|
8675
9315
|
options,
|
|
@@ -9428,6 +10068,8 @@ function measureCh(surface) {
|
|
|
9428
10068
|
probe.remove();
|
|
9429
10069
|
return width;
|
|
9430
10070
|
}
|
|
10071
|
+
const MARKDOWN_IMAGE = /!\[[^\]]*\]\([^)]*\)/;
|
|
10072
|
+
const MARKDOWN_IMAGE_LINE = /^\s*!\[[^\]]*\]\([^)\s]+\)\s*$/;
|
|
9431
10073
|
const segmenter = new Intl.Segmenter("en", { granularity: "grapheme" });
|
|
9432
10074
|
const WIDE_RANGES = [
|
|
9433
10075
|
[4352, 4447],
|
|
@@ -9651,11 +10293,39 @@ function hardLines(source) {
|
|
|
9651
10293
|
if (current.length) out.push(current.join(" "));
|
|
9652
10294
|
return out;
|
|
9653
10295
|
}
|
|
10296
|
+
function isBlank(s) {
|
|
10297
|
+
return s !== void 0 && s.trim() === "";
|
|
10298
|
+
}
|
|
10299
|
+
function listMarker(s) {
|
|
10300
|
+
const m = /^(\s*)([-*+]|\d+\.)\s+(.*)$/.exec(s);
|
|
10301
|
+
if (!m) return;
|
|
10302
|
+
return {
|
|
10303
|
+
depth: Math.floor(m[1].length / 2),
|
|
10304
|
+
ordered: /\d/.test(m[2]),
|
|
10305
|
+
text: m[3]
|
|
10306
|
+
};
|
|
10307
|
+
}
|
|
10308
|
+
function numberHunk(hunk) {
|
|
10309
|
+
let newLine = hunk.newStart;
|
|
10310
|
+
let oldLine = hunk.oldStart;
|
|
10311
|
+
return hunk.lines.map((line) => {
|
|
10312
|
+
const kind = line.startsWith("+") ? "add" : line.startsWith("-") ? "remove" : "context";
|
|
10313
|
+
const text = line.slice(1);
|
|
10314
|
+
const number = kind === "add" ? newLine++ : kind === "remove" ? oldLine++ : newLine;
|
|
10315
|
+
if (kind === "context") {
|
|
10316
|
+
oldLine++;
|
|
10317
|
+
newLine++;
|
|
10318
|
+
}
|
|
10319
|
+
return {
|
|
10320
|
+
number,
|
|
10321
|
+
text
|
|
10322
|
+
};
|
|
10323
|
+
});
|
|
10324
|
+
}
|
|
9654
10325
|
function parseBlocks(md) {
|
|
9655
10326
|
const lines = md.split("\n");
|
|
9656
10327
|
const blocks = [];
|
|
9657
10328
|
let i = 0;
|
|
9658
|
-
const isBlank = (s) => s !== void 0 && s.trim() === "";
|
|
9659
10329
|
while (i < lines.length) {
|
|
9660
10330
|
const line = lines[i];
|
|
9661
10331
|
if (line.trim() === "") {
|
|
@@ -9709,15 +10379,6 @@ function parseBlocks(md) {
|
|
|
9709
10379
|
});
|
|
9710
10380
|
continue;
|
|
9711
10381
|
}
|
|
9712
|
-
const listMarker = (s) => {
|
|
9713
|
-
const m = /^(\s*)([-*+]|\d+\.)\s+(.*)$/.exec(s);
|
|
9714
|
-
if (!m) return;
|
|
9715
|
-
return {
|
|
9716
|
-
depth: Math.floor(m[1].length / 2),
|
|
9717
|
-
ordered: /\d/.test(m[2]),
|
|
9718
|
-
text: m[3]
|
|
9719
|
-
};
|
|
9720
|
-
};
|
|
9721
10382
|
if (listMarker(line)) {
|
|
9722
10383
|
const items = [];
|
|
9723
10384
|
const gutters = [];
|
|
@@ -9773,9 +10434,11 @@ function parseBlocks(md) {
|
|
|
9773
10434
|
para.push(lines[i]);
|
|
9774
10435
|
i += 1;
|
|
9775
10436
|
}
|
|
9776
|
-
blocks.push({
|
|
10437
|
+
if (para.length === 1 && MARKDOWN_IMAGE_LINE.test(para[0])) blocks.push({ t: "image" });
|
|
10438
|
+
else blocks.push({
|
|
9777
10439
|
t: "p",
|
|
9778
|
-
lines: hardLines(para)
|
|
10440
|
+
lines: hardLines(para),
|
|
10441
|
+
images: para.some((row) => MARKDOWN_IMAGE.test(row))
|
|
9779
10442
|
});
|
|
9780
10443
|
}
|
|
9781
10444
|
return blocks;
|
|
@@ -9799,10 +10462,16 @@ function markdownHeight(md, m, extraPx = 0) {
|
|
|
9799
10462
|
const r = textLines(line, cols);
|
|
9800
10463
|
acc = add(acc, {
|
|
9801
10464
|
px: r.lines * m.line,
|
|
9802
|
-
exact: r.exact
|
|
10465
|
+
exact: r.exact && !block.images
|
|
9803
10466
|
});
|
|
9804
10467
|
}
|
|
9805
10468
|
break;
|
|
10469
|
+
case "image":
|
|
10470
|
+
acc = add(acc, {
|
|
10471
|
+
px: 12 * m.line,
|
|
10472
|
+
exact: true
|
|
10473
|
+
});
|
|
10474
|
+
break;
|
|
9806
10475
|
case "h": {
|
|
9807
10476
|
const r = textLines(block.text, cols);
|
|
9808
10477
|
acc = add(acc, {
|
|
@@ -9874,24 +10543,7 @@ function markdownHeight(md, m, extraPx = 0) {
|
|
|
9874
10543
|
};
|
|
9875
10544
|
}
|
|
9876
10545
|
function diffHeight(patch, m, extraPx = 0) {
|
|
9877
|
-
const
|
|
9878
|
-
let newLine = hunk.newStart;
|
|
9879
|
-
let oldLine = hunk.oldStart;
|
|
9880
|
-
return hunk.lines.map((line) => {
|
|
9881
|
-
const kind = line.startsWith("+") ? "add" : line.startsWith("-") ? "remove" : "context";
|
|
9882
|
-
const text = line.slice(1);
|
|
9883
|
-
const number = kind === "add" ? newLine++ : kind === "remove" ? oldLine++ : newLine;
|
|
9884
|
-
if (kind === "context") {
|
|
9885
|
-
oldLine++;
|
|
9886
|
-
newLine++;
|
|
9887
|
-
}
|
|
9888
|
-
return {
|
|
9889
|
-
number,
|
|
9890
|
-
text
|
|
9891
|
-
};
|
|
9892
|
-
});
|
|
9893
|
-
};
|
|
9894
|
-
const hunks = patch.hunks.map(walk);
|
|
10546
|
+
const hunks = patch.hunks.map(numberHunk);
|
|
9895
10547
|
const numbered = patch.hunks.some((hunk) => hunk.newStart > 0);
|
|
9896
10548
|
const width = numbered ? String(Math.max(...hunks.flat().map((row) => row.number), 1)).length : 0;
|
|
9897
10549
|
const columns = numbered ? width + 3 : 2;
|
|
@@ -9924,9 +10576,9 @@ function toolRowHeight(item, m, extraPx) {
|
|
|
9924
10576
|
gutterCells: 2,
|
|
9925
10577
|
extraPx
|
|
9926
10578
|
});
|
|
9927
|
-
const
|
|
9928
|
-
if (
|
|
9929
|
-
px:
|
|
10579
|
+
const boxes = (item.result?.images?.length ?? 0) + (hostImagePathOf(item) === void 0 ? 0 : 1);
|
|
10580
|
+
if (boxes > 0) acc = add(acc, {
|
|
10581
|
+
px: boxes * 12 * m.line,
|
|
9930
10582
|
exact: true
|
|
9931
10583
|
});
|
|
9932
10584
|
if (item.patch) return add(acc, diffHeight(item.patch, m, extraPx));
|
|
@@ -10951,9 +11603,12 @@ function useTranscriptJumps(options) {
|
|
|
10951
11603
|
}
|
|
10952
11604
|
//#endregion
|
|
10953
11605
|
//#region src/components/terminal/TerminalTranscript.tsx
|
|
10954
|
-
function TerminalItemView({ item, fileUrl }) {
|
|
11606
|
+
function TerminalItemView({ item, fileUrl, attachmentUrl }) {
|
|
10955
11607
|
switch (item.kind) {
|
|
10956
|
-
case "user": return /* @__PURE__ */ jsx(UserRow, {
|
|
11608
|
+
case "user": return /* @__PURE__ */ jsx(UserRow, {
|
|
11609
|
+
item,
|
|
11610
|
+
attachmentUrl
|
|
11611
|
+
});
|
|
10957
11612
|
case "assistant_text": return /* @__PURE__ */ jsx(AssistantRow, { item });
|
|
10958
11613
|
case "thinking": return /* @__PURE__ */ jsx(ThinkingRow, { item });
|
|
10959
11614
|
case "tool_call": return isPeerSend(item) ? /* @__PURE__ */ jsx(PeerSendRow, { item }) : /* @__PURE__ */ jsx(ToolRow, { item });
|
|
@@ -11021,10 +11676,17 @@ function TaskRow({ block, fileUrl, onOpenSubagent }) {
|
|
|
11021
11676
|
children: [brief ? /* @__PURE__ */ jsx(BriefRow, {
|
|
11022
11677
|
text: brief,
|
|
11023
11678
|
terminal: true
|
|
11024
|
-
}) : null, block.children.map((leaf, index) =>
|
|
11025
|
-
|
|
11026
|
-
|
|
11027
|
-
|
|
11679
|
+
}) : null, block.children.map((leaf, index) => {
|
|
11680
|
+
const next = block.children[index + 1];
|
|
11681
|
+
const view = "run" in leaf ? /* @__PURE__ */ jsx(RunRow, { items: leaf.run }) : /* @__PURE__ */ jsx(TerminalItemView, {
|
|
11682
|
+
item: leaf.item,
|
|
11683
|
+
fileUrl
|
|
11684
|
+
});
|
|
11685
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [index > 0 && blockNeedsBlank(block.children[index - 1], leaf) ? /* @__PURE__ */ jsx(Blank, {}) : null, next && !blockNeedsBlank(leaf, next) ? /* @__PURE__ */ jsx(ActionPlacementProvider, {
|
|
11686
|
+
value: "inline",
|
|
11687
|
+
children: view
|
|
11688
|
+
}) : view] }, leaf.key);
|
|
11689
|
+
})]
|
|
11028
11690
|
}) : null]
|
|
11029
11691
|
});
|
|
11030
11692
|
return onOpenSubagent === void 0 ? row : /* @__PURE__ */ jsx(WithActions, {
|
|
@@ -11059,13 +11721,19 @@ function TerminalTranscript({ state, fileUrl, fontSize, lineHeight, affordances,
|
|
|
11059
11721
|
className: cn("term-transcript", className),
|
|
11060
11722
|
children: /* @__PURE__ */ jsxs(PeerNamesProvider, {
|
|
11061
11723
|
items: state.items,
|
|
11062
|
-
children: [blocks.map((block, index) =>
|
|
11063
|
-
|
|
11064
|
-
|
|
11065
|
-
|
|
11066
|
-
|
|
11067
|
-
|
|
11068
|
-
|
|
11724
|
+
children: [blocks.map((block, index) => {
|
|
11725
|
+
const next = blocks[index + 1];
|
|
11726
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [index > 0 && blockNeedsBlank(blocks[index - 1], block) ? /* @__PURE__ */ jsx(Blank, {}) : null, /* @__PURE__ */ jsx(ActionPlacementProvider, {
|
|
11727
|
+
value: next && !blockNeedsBlank(block, next) ? "inline" : "below",
|
|
11728
|
+
children: "run" in block ? /* @__PURE__ */ jsx(RunRow, { items: block.run }) : "item" in block ? /* @__PURE__ */ jsx(TerminalItemView, {
|
|
11729
|
+
item: block.item,
|
|
11730
|
+
fileUrl
|
|
11731
|
+
}) : /* @__PURE__ */ jsx(TaskRow, {
|
|
11732
|
+
block,
|
|
11733
|
+
fileUrl
|
|
11734
|
+
})
|
|
11735
|
+
})] }, block.key);
|
|
11736
|
+
}), working(state) ? /* @__PURE__ */ jsxs(Fragment$1, { children: [state.items.length > 0 ? /* @__PURE__ */ jsx(Blank, {}) : null, /* @__PURE__ */ jsx(WorkingRow, {
|
|
11069
11737
|
label: state.status === "starting" ? "Starting…" : "Working…",
|
|
11070
11738
|
startedAt: runStartedAt,
|
|
11071
11739
|
tokens: state.contextUsage?.totalTokens
|
|
@@ -11163,13 +11831,6 @@ function Reasoning({ children, isStreaming = false, defaultOpen, className }) {
|
|
|
11163
11831
|
//#endregion
|
|
11164
11832
|
//#region src/components/agent/ToolCallCard.tsx
|
|
11165
11833
|
const RESULT_PREVIEW_CHARS = 2e3;
|
|
11166
|
-
const IMAGE_TOOLS = /* @__PURE__ */ new Set(["CodexImageGeneration", "CodexImageView"]);
|
|
11167
|
-
function imagePathOf(item) {
|
|
11168
|
-
if (!IMAGE_TOOLS.has(item.name)) return;
|
|
11169
|
-
const input = item.input;
|
|
11170
|
-
const path = input?.savedPath ?? input?.path;
|
|
11171
|
-
return typeof path === "string" ? path : void 0;
|
|
11172
|
-
}
|
|
11173
11834
|
const STATE_BADGE = {
|
|
11174
11835
|
running: {
|
|
11175
11836
|
label: "Running",
|
|
@@ -11252,7 +11913,7 @@ function ToolCallCard({ item, hostImage, className }) {
|
|
|
11252
11913
|
const [fullResult, setFullResult] = useState(false);
|
|
11253
11914
|
const [fetching, setFetching] = useState(false);
|
|
11254
11915
|
const fetchResult = useToolResultFetcher();
|
|
11255
|
-
const imagePath =
|
|
11916
|
+
const imagePath = hostImagePathOf(item);
|
|
11256
11917
|
const status = item.status ?? (item.result === void 0 ? "running" : "settled");
|
|
11257
11918
|
const badge = STATE_BADGE[status];
|
|
11258
11919
|
const isError = status === "failed" || item.result?.isError === true;
|
|
@@ -11308,7 +11969,7 @@ function ToolCallCard({ item, hostImage, className }) {
|
|
|
11308
11969
|
}) : null] }) : null
|
|
11309
11970
|
]
|
|
11310
11971
|
}) : null;
|
|
11311
|
-
const image = imagePath
|
|
11972
|
+
const image = imagePath ? /* @__PURE__ */ jsx(HostImage, {
|
|
11312
11973
|
path: imagePath,
|
|
11313
11974
|
load: hostImage
|
|
11314
11975
|
}) : null;
|
|
@@ -11316,6 +11977,7 @@ function ToolCallCard({ item, hostImage, className }) {
|
|
|
11316
11977
|
className: "flex flex-col gap-2 border-t border-border p-2.5",
|
|
11317
11978
|
children: item.result.images.map((ref) => /* @__PURE__ */ jsx(ResultImage, {
|
|
11318
11979
|
toolUseId: item.id,
|
|
11980
|
+
name: resultImageName(item.name, ref),
|
|
11319
11981
|
image: ref
|
|
11320
11982
|
}, ref.partIndex))
|
|
11321
11983
|
}) : null;
|
|
@@ -11371,17 +12033,24 @@ function PlainPayload({ code, label, className }) {
|
|
|
11371
12033
|
className
|
|
11372
12034
|
});
|
|
11373
12035
|
}
|
|
11374
|
-
function ResultImage({ toolUseId, image }) {
|
|
12036
|
+
function ResultImage({ toolUseId, name, image }) {
|
|
11375
12037
|
const { src, failed } = useToolResultImageSrc({
|
|
11376
12038
|
toolUseId,
|
|
11377
12039
|
...image
|
|
11378
12040
|
});
|
|
11379
12041
|
return /* @__PURE__ */ jsx("div", {
|
|
11380
12042
|
className: "flex h-60 items-start overflow-hidden rounded-md border border-border bg-surface-hover",
|
|
11381
|
-
children: src ? /* @__PURE__ */ jsx(
|
|
11382
|
-
|
|
11383
|
-
|
|
11384
|
-
|
|
12043
|
+
children: src ? /* @__PURE__ */ jsx(ViewableImage, {
|
|
12044
|
+
image: {
|
|
12045
|
+
src,
|
|
12046
|
+
name
|
|
12047
|
+
},
|
|
12048
|
+
className: "h-full max-w-full",
|
|
12049
|
+
children: /* @__PURE__ */ jsx("img", {
|
|
12050
|
+
src,
|
|
12051
|
+
alt: name,
|
|
12052
|
+
className: "h-full max-w-full object-contain"
|
|
12053
|
+
})
|
|
11385
12054
|
}) : /* @__PURE__ */ jsx("span", {
|
|
11386
12055
|
className: "p-2 text-label text-fg-4",
|
|
11387
12056
|
children: failed ? IMAGE_UNAVAILABLE : imagePlaceholder(image)
|
|
@@ -11389,24 +12058,22 @@ function ResultImage({ toolUseId, image }) {
|
|
|
11389
12058
|
});
|
|
11390
12059
|
}
|
|
11391
12060
|
function HostImage({ path, load }) {
|
|
11392
|
-
const
|
|
11393
|
-
useEffect(() => {
|
|
11394
|
-
let cancelled = false;
|
|
11395
|
-
setSrc(void 0);
|
|
11396
|
-
load(path).then((url) => {
|
|
11397
|
-
if (!cancelled) setSrc(url);
|
|
11398
|
-
}).catch(() => {});
|
|
11399
|
-
return () => {
|
|
11400
|
-
cancelled = true;
|
|
11401
|
-
};
|
|
11402
|
-
}, [path, load]);
|
|
12061
|
+
const { src } = useHostImageSrc(path, load);
|
|
11403
12062
|
if (!src) return null;
|
|
12063
|
+
const name = baseName(path);
|
|
11404
12064
|
return /* @__PURE__ */ jsx("div", {
|
|
11405
12065
|
className: "border-t border-border p-2.5",
|
|
11406
|
-
children: /* @__PURE__ */ jsx(
|
|
11407
|
-
|
|
11408
|
-
|
|
11409
|
-
|
|
12066
|
+
children: /* @__PURE__ */ jsx(ViewableImage, {
|
|
12067
|
+
image: {
|
|
12068
|
+
src,
|
|
12069
|
+
name
|
|
12070
|
+
},
|
|
12071
|
+
className: "block max-w-full",
|
|
12072
|
+
children: /* @__PURE__ */ jsx("img", {
|
|
12073
|
+
src,
|
|
12074
|
+
alt: name,
|
|
12075
|
+
className: "max-h-96 w-auto max-w-full rounded-md border border-border"
|
|
12076
|
+
})
|
|
11410
12077
|
})
|
|
11411
12078
|
});
|
|
11412
12079
|
}
|
|
@@ -11451,35 +12118,45 @@ function NoticeRow({ item }) {
|
|
|
11451
12118
|
function TranscriptItemView({ item, fileUrl, attachmentUrl, hostImage, terminal }) {
|
|
11452
12119
|
if (terminal) return /* @__PURE__ */ jsx(TerminalItemView, {
|
|
11453
12120
|
item,
|
|
11454
|
-
fileUrl
|
|
12121
|
+
fileUrl,
|
|
12122
|
+
attachmentUrl
|
|
11455
12123
|
});
|
|
11456
12124
|
switch (item.kind) {
|
|
11457
|
-
case "user": return /* @__PURE__ */
|
|
11458
|
-
|
|
11459
|
-
children:
|
|
11460
|
-
|
|
11461
|
-
|
|
11462
|
-
|
|
11463
|
-
|
|
11464
|
-
|
|
11465
|
-
|
|
11466
|
-
|
|
11467
|
-
|
|
11468
|
-
|
|
11469
|
-
|
|
12125
|
+
case "user": return /* @__PURE__ */ jsx(WithActions, {
|
|
12126
|
+
actions: /* @__PURE__ */ jsx(BookmarkAction, { id: item.id }),
|
|
12127
|
+
children: /* @__PURE__ */ jsxs(Message, {
|
|
12128
|
+
from: "user",
|
|
12129
|
+
children: [
|
|
12130
|
+
item.origin ? /* @__PURE__ */ jsx("div", {
|
|
12131
|
+
className: "wd-peer-origin text-xs text-muted-foreground",
|
|
12132
|
+
children: peerLabel(item.origin)
|
|
12133
|
+
}) : null,
|
|
12134
|
+
item.attachments?.length ? /* @__PURE__ */ jsx(SentAttachments, {
|
|
12135
|
+
attachments: item.attachments,
|
|
12136
|
+
attachmentUrl
|
|
12137
|
+
}) : null,
|
|
12138
|
+
item.text ? /* @__PURE__ */ jsx(MessageContent, { children: /* @__PURE__ */ jsx(PromptTokenText, { text: item.text }) }) : null
|
|
12139
|
+
]
|
|
12140
|
+
})
|
|
11470
12141
|
});
|
|
11471
|
-
case "assistant_text": return /* @__PURE__ */ jsx(
|
|
11472
|
-
|
|
11473
|
-
|
|
11474
|
-
|
|
11475
|
-
|
|
11476
|
-
|
|
12142
|
+
case "assistant_text": return /* @__PURE__ */ jsx(WithActions, {
|
|
12143
|
+
actions: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(BookmarkAction, { id: item.id }), item.streaming ? null : /* @__PURE__ */ jsx(CopyAction, {
|
|
12144
|
+
text: item.text,
|
|
12145
|
+
label: "Copy message"
|
|
12146
|
+
})] }),
|
|
12147
|
+
children: /* @__PURE__ */ jsx(Message, {
|
|
12148
|
+
from: "assistant",
|
|
12149
|
+
children: /* @__PURE__ */ jsx(MessageContent, { children: /* @__PURE__ */ jsx(Response, {
|
|
12150
|
+
streaming: item.streaming,
|
|
12151
|
+
children: item.text
|
|
12152
|
+
}) })
|
|
12153
|
+
})
|
|
11477
12154
|
});
|
|
11478
12155
|
case "thinking": return /* @__PURE__ */ jsx(Reasoning, {
|
|
11479
12156
|
isStreaming: item.id === "streaming-thinking",
|
|
11480
12157
|
children: item.text
|
|
11481
12158
|
});
|
|
11482
|
-
case "tool_call": return /* @__PURE__ */ jsx(
|
|
12159
|
+
case "tool_call": return /* @__PURE__ */ jsx(ToolCard, {
|
|
11483
12160
|
item,
|
|
11484
12161
|
hostImage
|
|
11485
12162
|
});
|
|
@@ -11494,6 +12171,20 @@ function TranscriptItemView({ item, fileUrl, attachmentUrl, hostImage, terminal
|
|
|
11494
12171
|
default: return null;
|
|
11495
12172
|
}
|
|
11496
12173
|
}
|
|
12174
|
+
function ToolCard({ item, hostImage }) {
|
|
12175
|
+
const command = item.input?.command;
|
|
12176
|
+
const copyable = typeof command === "string" ? command : item.result?.text ?? "";
|
|
12177
|
+
return /* @__PURE__ */ jsx(WithActions, {
|
|
12178
|
+
actions: /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(BookmarkAction, { id: item.id }), copyable ? /* @__PURE__ */ jsx(CopyAction, {
|
|
12179
|
+
text: copyable,
|
|
12180
|
+
label: "Copy"
|
|
12181
|
+
}) : null] }),
|
|
12182
|
+
children: /* @__PURE__ */ jsx(ToolCallCard, {
|
|
12183
|
+
item,
|
|
12184
|
+
hostImage
|
|
12185
|
+
})
|
|
12186
|
+
});
|
|
12187
|
+
}
|
|
11497
12188
|
function ShellCard({ item }) {
|
|
11498
12189
|
const [open, setOpen] = useState(false);
|
|
11499
12190
|
const actions = useShellActions();
|
|
@@ -11510,58 +12201,59 @@ function ShellCard({ item }) {
|
|
|
11510
12201
|
shellId,
|
|
11511
12202
|
verify
|
|
11512
12203
|
]);
|
|
11513
|
-
return /* @__PURE__ */
|
|
11514
|
-
|
|
11515
|
-
|
|
11516
|
-
|
|
11517
|
-
|
|
11518
|
-
|
|
11519
|
-
|
|
11520
|
-
/* @__PURE__ */ jsx("span", {
|
|
11521
|
-
className: "font-mono text-label text-[var(--wd-shell-accent)]",
|
|
11522
|
-
children: "$"
|
|
11523
|
-
}),
|
|
11524
|
-
/* @__PURE__ */ jsx("button", {
|
|
11525
|
-
type: "button",
|
|
11526
|
-
"aria-expanded": open,
|
|
11527
|
-
className: "min-w-0 flex-1 truncate text-left font-mono text-label text-fg-1",
|
|
11528
|
-
onClick: () => {
|
|
11529
|
-
const next = !open;
|
|
11530
|
-
setOpen(next);
|
|
11531
|
-
if (next && item.truncated && item.expanded === void 0 && !item.missing) actions.loadOutput(shellId);
|
|
11532
|
-
},
|
|
11533
|
-
children: shellLabel(item)
|
|
11534
|
-
}),
|
|
11535
|
-
/* @__PURE__ */ jsx("span", {
|
|
11536
|
-
className: cn("shrink-0 text-label", failed ? "text-danger" : "text-fg-4"),
|
|
11537
|
-
children: shellStatusText(item)
|
|
11538
|
-
}),
|
|
11539
|
-
actions.open ? /* @__PURE__ */ jsx("button", {
|
|
11540
|
-
type: "button",
|
|
11541
|
-
"aria-label": "Open terminal",
|
|
11542
|
-
title: "Open terminal",
|
|
11543
|
-
className: "shrink-0 text-label text-fg-3 hover:text-fg-1",
|
|
11544
|
-
onClick: () => actions.open?.(shellId),
|
|
11545
|
-
children: "⤢"
|
|
11546
|
-
}) : null,
|
|
11547
|
-
running ? /* @__PURE__ */ jsx("button", {
|
|
11548
|
-
type: "button",
|
|
11549
|
-
"aria-label": "Kill this shell",
|
|
11550
|
-
className: "shrink-0 text-label text-fg-3",
|
|
11551
|
-
onClick: () => void actions.kill(shellId),
|
|
11552
|
-
children: "✕"
|
|
11553
|
-
}) : null
|
|
11554
|
-
]
|
|
11555
|
-
}),
|
|
11556
|
-
lines.length > 0 ? /* @__PURE__ */ jsx("pre", {
|
|
11557
|
-
className: "overflow-x-auto border-t border-border px-3 py-2 font-mono text-label whitespace-pre-wrap text-fg-2",
|
|
11558
|
-
children: lines.join("\n")
|
|
12204
|
+
return /* @__PURE__ */ jsx(WithActions, {
|
|
12205
|
+
actions: /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
12206
|
+
actions.open ? /* @__PURE__ */ jsx(OpenShellAction, { onOpen: () => actions.open?.(shellId) }) : null,
|
|
12207
|
+
actions.agentWrite && shellGrantable(item.shell) ? /* @__PURE__ */ jsx(AgentWriteAction, {
|
|
12208
|
+
granted: item.shell.agentWrite === true,
|
|
12209
|
+
label: shellAgentWriteLabel(item.shell),
|
|
12210
|
+
onToggle: () => void actions.agentWrite?.(shellId, item.shell.agentWrite !== true)
|
|
11559
12211
|
}) : null,
|
|
11560
|
-
|
|
11561
|
-
|
|
11562
|
-
|
|
11563
|
-
|
|
11564
|
-
|
|
12212
|
+
running ? /* @__PURE__ */ jsx(KillShellAction, { onKill: () => void actions.kill(shellId) }) : null,
|
|
12213
|
+
/* @__PURE__ */ jsx(BookmarkAction, { id: item.id }),
|
|
12214
|
+
/* @__PURE__ */ jsx(CopyAction, {
|
|
12215
|
+
text: item.shell.command,
|
|
12216
|
+
label: "Copy command"
|
|
12217
|
+
})
|
|
12218
|
+
] }),
|
|
12219
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
12220
|
+
"data-slot": "shell",
|
|
12221
|
+
className: "overflow-hidden rounded-md border border-border bg-surface",
|
|
12222
|
+
children: [
|
|
12223
|
+
/* @__PURE__ */ jsxs("div", {
|
|
12224
|
+
className: "flex items-center gap-2 px-3 py-1.5",
|
|
12225
|
+
children: [
|
|
12226
|
+
/* @__PURE__ */ jsx("span", {
|
|
12227
|
+
className: "font-mono text-label text-[var(--wd-shell-accent)]",
|
|
12228
|
+
children: "$"
|
|
12229
|
+
}),
|
|
12230
|
+
/* @__PURE__ */ jsx("button", {
|
|
12231
|
+
type: "button",
|
|
12232
|
+
"aria-expanded": open,
|
|
12233
|
+
className: "min-w-0 flex-1 truncate text-left font-mono text-label text-fg-1",
|
|
12234
|
+
onClick: () => {
|
|
12235
|
+
const next = !open;
|
|
12236
|
+
setOpen(next);
|
|
12237
|
+
if (next && item.truncated && item.expanded === void 0 && !item.missing) actions.loadOutput(shellId);
|
|
12238
|
+
},
|
|
12239
|
+
children: shellLabel(item)
|
|
12240
|
+
}),
|
|
12241
|
+
/* @__PURE__ */ jsx("span", {
|
|
12242
|
+
className: cn("shrink-0 text-label", failed ? "text-danger" : "text-fg-4"),
|
|
12243
|
+
children: shellStatusText(item)
|
|
12244
|
+
})
|
|
12245
|
+
]
|
|
12246
|
+
}),
|
|
12247
|
+
lines.length > 0 ? /* @__PURE__ */ jsx("pre", {
|
|
12248
|
+
className: "overflow-x-auto border-t border-border px-3 py-2 font-mono text-label whitespace-pre-wrap text-fg-2",
|
|
12249
|
+
children: lines.join("\n")
|
|
12250
|
+
}) : null,
|
|
12251
|
+
footer ? /* @__PURE__ */ jsx("div", {
|
|
12252
|
+
className: "px-3 pb-2 text-label text-fg-4",
|
|
12253
|
+
children: footer
|
|
12254
|
+
}) : null
|
|
12255
|
+
]
|
|
12256
|
+
})
|
|
11565
12257
|
});
|
|
11566
12258
|
}
|
|
11567
12259
|
function CompactionRow({ item }) {
|
|
@@ -11612,10 +12304,17 @@ function SentAttachments({ attachments, attachmentUrl }) {
|
|
|
11612
12304
|
className: "mb-1 flex flex-wrap justify-start gap-1.5",
|
|
11613
12305
|
children: attachments.map((attachment) => {
|
|
11614
12306
|
const href = attachmentUrl?.(attachment.id);
|
|
11615
|
-
return attachment.mediaType.startsWith("image/") && href ? /* @__PURE__ */ jsx(
|
|
11616
|
-
|
|
11617
|
-
|
|
11618
|
-
|
|
12307
|
+
return attachment.mediaType.startsWith("image/") && href ? /* @__PURE__ */ jsx(ViewableImage, {
|
|
12308
|
+
image: {
|
|
12309
|
+
src: href,
|
|
12310
|
+
name: attachment.name
|
|
12311
|
+
},
|
|
12312
|
+
className: "rounded-md",
|
|
12313
|
+
children: /* @__PURE__ */ jsx("img", {
|
|
12314
|
+
src: href,
|
|
12315
|
+
alt: attachment.name,
|
|
12316
|
+
className: "size-20 rounded-md border border-border object-cover"
|
|
12317
|
+
})
|
|
11619
12318
|
}, attachment.id) : /* @__PURE__ */ jsx("span", {
|
|
11620
12319
|
className: "rounded-full border border-border bg-surface px-2.5 py-1 text-body-xs text-fg-3",
|
|
11621
12320
|
children: attachment.name
|
|
@@ -11839,7 +12538,8 @@ function TranscriptRows({ rows, boundary, since, terminal, replaying, stickyProm
|
|
|
11839
12538
|
children: virtualizer.getVirtualItems().map((virtualRow) => {
|
|
11840
12539
|
const row = rows[virtualRow.index];
|
|
11841
12540
|
const gapClass = virtualRow.index > 0 && (!terminal || gapBefore(rows, virtualRow.index)) ? gap.className : void 0;
|
|
11842
|
-
const
|
|
12541
|
+
const flushBelow = terminal && virtualRow.index < rows.length - 1 && !gapBefore(rows, virtualRow.index + 1);
|
|
12542
|
+
const view = "run" in row ? /* @__PURE__ */ jsx("div", {
|
|
11843
12543
|
className: cn(read(boundary, row.index) && "opacity-45"),
|
|
11844
12544
|
children: /* @__PURE__ */ jsx(RunRow, { items: row.run })
|
|
11845
12545
|
}) : "item" in row ? /* @__PURE__ */ jsx("div", {
|
|
@@ -11866,6 +12566,10 @@ function TranscriptRows({ rows, boundary, since, terminal, replaying, stickyProm
|
|
|
11866
12566
|
onOpenSubagent
|
|
11867
12567
|
})
|
|
11868
12568
|
});
|
|
12569
|
+
const content = /* @__PURE__ */ jsx(ActionPlacementProvider, {
|
|
12570
|
+
value: flushBelow ? "inline" : "below",
|
|
12571
|
+
children: view
|
|
12572
|
+
});
|
|
11869
12573
|
if (stickyPrompt && "item" in row && row.item.kind === "user" && parentOf(row.item) === void 0) {
|
|
11870
12574
|
const next = promptRows.find((index) => index > virtualRow.index);
|
|
11871
12575
|
const laneEnd = next === void 0 ? virtualizer.getTotalSize() : measurements[next]?.start ?? virtualRow.start;
|
|
@@ -11937,7 +12641,14 @@ function showLoader(state) {
|
|
|
11937
12641
|
return last.kind !== "turn_result" || state.status === "running";
|
|
11938
12642
|
}
|
|
11939
12643
|
function TerminalShell({ active, fontSize, lineHeight, affordances, children }) {
|
|
11940
|
-
if (!active) return /* @__PURE__ */ jsx(
|
|
12644
|
+
if (!active) return /* @__PURE__ */ jsx("div", {
|
|
12645
|
+
"data-cards": "",
|
|
12646
|
+
className: "contents",
|
|
12647
|
+
children: /* @__PURE__ */ jsx(AffordanceProvider, {
|
|
12648
|
+
value: resolveAffordances(affordances),
|
|
12649
|
+
children
|
|
12650
|
+
})
|
|
12651
|
+
});
|
|
11941
12652
|
return /* @__PURE__ */ jsx(TerminalSurface, {
|
|
11942
12653
|
fontSize,
|
|
11943
12654
|
lineHeight,
|
|
@@ -11947,11 +12658,11 @@ function TerminalShell({ active, fontSize, lineHeight, affordances, children })
|
|
|
11947
12658
|
children
|
|
11948
12659
|
});
|
|
11949
12660
|
}
|
|
11950
|
-
function Transcript({ state, fileUrl, attachmentUrl, canBrowseFiles, hostImage, variant = "cards",
|
|
12661
|
+
function Transcript({ state, fileUrl, attachmentUrl, canBrowseFiles, hostImage, variant = "cards", fontSize, lineHeight, affordances, stickyPrompt = false, scrubber, bookmarks, sessionNames, replaying = false, catchUp, jumpToRecapRef, repinRef, reveal, frame, onOpenSubagent, emptyState, className }) {
|
|
11951
12662
|
const terminal = variant === "terminal";
|
|
11952
12663
|
const items = useMemo(() => frame ? subagentItems(state.items, frame.parentToolUseId) : state.items, [state.items, frame]);
|
|
11953
12664
|
const frameTask = useMemo(() => frame ? state.items.find((item) => item.kind === "tool_call" && item.id === frame.parentToolUseId) : void 0, [state.items, frame]);
|
|
11954
|
-
const gap = ROW_GAP[variant]
|
|
12665
|
+
const gap = ROW_GAP[variant];
|
|
11955
12666
|
const runStartedAt = useRunStart(state.status);
|
|
11956
12667
|
const boundary = !frame && catchUp && catchUp.from > 0 && catchUp.from < state.items.length ? catchUp.from : void 0;
|
|
11957
12668
|
const recap = useMemo(() => boundary === void 0 ? void 0 : recapLine(summarizeSince(state, boundary)), [state, boundary]);
|
|
@@ -11985,83 +12696,86 @@ function Transcript({ state, fileUrl, attachmentUrl, canBrowseFiles, hostImage,
|
|
|
11985
12696
|
const skillNames = useMemo(() => state.skills?.map((skill) => skill.name), [state.skills]);
|
|
11986
12697
|
return /* @__PURE__ */ jsx(TranscriptVariantProvider, {
|
|
11987
12698
|
value: variant,
|
|
11988
|
-
children: /* @__PURE__ */ jsx(
|
|
11989
|
-
|
|
11990
|
-
children: /* @__PURE__ */ jsx(
|
|
11991
|
-
names:
|
|
11992
|
-
children: /* @__PURE__ */
|
|
11993
|
-
|
|
11994
|
-
children:
|
|
11995
|
-
|
|
11996
|
-
|
|
11997
|
-
|
|
11998
|
-
|
|
11999
|
-
|
|
12000
|
-
|
|
12001
|
-
affordances,
|
|
12002
|
-
children: [
|
|
12003
|
-
frame ? frameTask === void 0 && !replaying ? /* @__PURE__ */ jsx("div", {
|
|
12004
|
-
className: cn(terminal ? "term-row text-fg-4" : "p-4 text-body-sm text-fg-4"),
|
|
12005
|
-
children: "This sub-agent's work is not in this transcript."
|
|
12006
|
-
}) : null : items.length === 0 && state.status !== "starting" ? emptyState !== void 0 ? emptyState : /* @__PURE__ */ jsx(SessionEmptyState, {
|
|
12007
|
-
cwd: state.cwd,
|
|
12008
|
-
hasCommands: !!state.commands?.length,
|
|
12009
|
-
hasSkills: !!state.skills?.some((s) => s.enabled),
|
|
12010
|
-
canBrowseFiles
|
|
12011
|
-
}) : null,
|
|
12012
|
-
frame && frameTask === void 0 && !replaying ? null : /* @__PURE__ */ jsx(TranscriptRows, {
|
|
12013
|
-
rows,
|
|
12014
|
-
boundary,
|
|
12015
|
-
since: catchUp?.since,
|
|
12016
|
-
terminal,
|
|
12017
|
-
replaying,
|
|
12018
|
-
stickyPrompt: !frame && stickyPrompt,
|
|
12019
|
-
gap,
|
|
12020
|
-
fontSize,
|
|
12021
|
-
lineHeight,
|
|
12022
|
-
items,
|
|
12023
|
-
pendingApprovals: state.pendingApprovals,
|
|
12024
|
-
scrubber,
|
|
12025
|
-
bookmarks: frame ? void 0 : bookmarks,
|
|
12026
|
-
affordances,
|
|
12027
|
-
fileUrl,
|
|
12028
|
-
attachmentUrl,
|
|
12029
|
-
hostImage,
|
|
12030
|
-
jumpToRecapRef,
|
|
12031
|
-
repinRef,
|
|
12032
|
-
reveal: frame ? void 0 : reveal,
|
|
12033
|
-
frameParentId: frame?.parentToolUseId,
|
|
12034
|
-
onOpenSubagent: frame ? void 0 : onOpenSubagent
|
|
12035
|
-
}),
|
|
12036
|
-
(frame ? frameTask !== void 0 && taskBusy(frameTask, items) : showLoader(state)) ? terminal ? /* @__PURE__ */ jsxs(Fragment$1, { children: [state.items.length > 0 ? /* @__PURE__ */ jsx("div", {
|
|
12037
|
-
className: "term-blank",
|
|
12038
|
-
"aria-hidden": true
|
|
12039
|
-
}) : null, /* @__PURE__ */ jsx(WorkingRow, {
|
|
12040
|
-
label: state.status === "starting" ? "Starting…" : "Working…",
|
|
12041
|
-
startedAt: runStartedAt,
|
|
12042
|
-
tokens: state.contextUsage?.totalTokens
|
|
12043
|
-
})] }) : /* @__PURE__ */ jsx(Loader, { label: state.status === "starting" ? "Starting session…" : void 0 }) : null
|
|
12044
|
-
]
|
|
12045
|
-
})
|
|
12046
|
-
}),
|
|
12047
|
-
/* @__PURE__ */ jsx(ConversationScrollButton, {}),
|
|
12048
|
-
replaying ? /* @__PURE__ */ jsx("div", {
|
|
12049
|
-
"data-slot": "transcript-hold",
|
|
12050
|
-
"aria-hidden": true,
|
|
12051
|
-
className: "wd-hold-appear visible pointer-events-none absolute inset-0 overflow-hidden",
|
|
12052
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
12053
|
-
className: cn("mx-auto w-full max-w-[var(--wd-transcript-max-width)]", !terminal && "px-4 py-4"),
|
|
12054
|
-
children: terminal ? /* @__PURE__ */ jsx(TerminalSurface, {
|
|
12699
|
+
children: /* @__PURE__ */ jsx(HostImageProvider, {
|
|
12700
|
+
value: hostImage,
|
|
12701
|
+
children: /* @__PURE__ */ jsx(SkillNamesProvider, {
|
|
12702
|
+
names: skillNames,
|
|
12703
|
+
children: /* @__PURE__ */ jsx(SessionNamesProvider, {
|
|
12704
|
+
names: sessionNames,
|
|
12705
|
+
children: /* @__PURE__ */ jsxs(Conversation, {
|
|
12706
|
+
className: cn(replaying && "invisible", className),
|
|
12707
|
+
children: [
|
|
12708
|
+
/* @__PURE__ */ jsx(ConversationContent, {
|
|
12709
|
+
className: cn(terminal && "gap-0 p-0"),
|
|
12710
|
+
children: /* @__PURE__ */ jsxs(TerminalShell, {
|
|
12711
|
+
active: terminal,
|
|
12055
12712
|
fontSize,
|
|
12056
12713
|
lineHeight,
|
|
12057
|
-
affordances
|
|
12058
|
-
|
|
12059
|
-
|
|
12060
|
-
|
|
12061
|
-
|
|
12062
|
-
|
|
12063
|
-
|
|
12064
|
-
|
|
12714
|
+
affordances,
|
|
12715
|
+
children: [
|
|
12716
|
+
frame ? frameTask === void 0 && !replaying ? /* @__PURE__ */ jsx("div", {
|
|
12717
|
+
className: cn(terminal ? "term-row text-fg-4" : "p-4 text-body-sm text-fg-4"),
|
|
12718
|
+
children: "This sub-agent's work is not in this transcript."
|
|
12719
|
+
}) : null : items.length === 0 && state.status !== "starting" ? emptyState !== void 0 ? emptyState : /* @__PURE__ */ jsx(SessionEmptyState, {
|
|
12720
|
+
cwd: state.cwd,
|
|
12721
|
+
hasCommands: !!state.commands?.length,
|
|
12722
|
+
hasSkills: !!state.skills?.some((s) => s.enabled),
|
|
12723
|
+
canBrowseFiles
|
|
12724
|
+
}) : null,
|
|
12725
|
+
frame && frameTask === void 0 && !replaying ? null : /* @__PURE__ */ jsx(TranscriptRows, {
|
|
12726
|
+
rows,
|
|
12727
|
+
boundary,
|
|
12728
|
+
since: catchUp?.since,
|
|
12729
|
+
terminal,
|
|
12730
|
+
replaying,
|
|
12731
|
+
stickyPrompt: !frame && stickyPrompt,
|
|
12732
|
+
gap,
|
|
12733
|
+
fontSize,
|
|
12734
|
+
lineHeight,
|
|
12735
|
+
items,
|
|
12736
|
+
pendingApprovals: state.pendingApprovals,
|
|
12737
|
+
scrubber,
|
|
12738
|
+
bookmarks: frame ? void 0 : bookmarks,
|
|
12739
|
+
affordances,
|
|
12740
|
+
fileUrl,
|
|
12741
|
+
attachmentUrl,
|
|
12742
|
+
hostImage,
|
|
12743
|
+
jumpToRecapRef,
|
|
12744
|
+
repinRef,
|
|
12745
|
+
reveal: frame ? void 0 : reveal,
|
|
12746
|
+
frameParentId: frame?.parentToolUseId,
|
|
12747
|
+
onOpenSubagent: frame ? void 0 : onOpenSubagent
|
|
12748
|
+
}),
|
|
12749
|
+
(frame ? frameTask !== void 0 && taskBusy(frameTask, items) : showLoader(state)) ? terminal ? /* @__PURE__ */ jsxs(Fragment$1, { children: [state.items.length > 0 ? /* @__PURE__ */ jsx("div", {
|
|
12750
|
+
className: "term-blank",
|
|
12751
|
+
"aria-hidden": true
|
|
12752
|
+
}) : null, /* @__PURE__ */ jsx(WorkingRow, {
|
|
12753
|
+
label: state.status === "starting" ? "Starting…" : "Working…",
|
|
12754
|
+
startedAt: runStartedAt,
|
|
12755
|
+
tokens: state.contextUsage?.totalTokens
|
|
12756
|
+
})] }) : /* @__PURE__ */ jsx(Loader, { label: state.status === "starting" ? "Starting session…" : void 0 }) : null
|
|
12757
|
+
]
|
|
12758
|
+
})
|
|
12759
|
+
}),
|
|
12760
|
+
/* @__PURE__ */ jsx(ConversationScrollButton, {}),
|
|
12761
|
+
replaying ? /* @__PURE__ */ jsx("div", {
|
|
12762
|
+
"data-slot": "transcript-hold",
|
|
12763
|
+
"aria-hidden": true,
|
|
12764
|
+
className: "wd-hold-appear visible pointer-events-none absolute inset-0 overflow-hidden",
|
|
12765
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
12766
|
+
className: cn("mx-auto w-full max-w-[var(--wd-transcript-max-width)]", !terminal && "px-4 py-4"),
|
|
12767
|
+
children: terminal ? /* @__PURE__ */ jsx(TerminalSurface, {
|
|
12768
|
+
fontSize,
|
|
12769
|
+
lineHeight,
|
|
12770
|
+
affordances: false,
|
|
12771
|
+
bleed: "1ch",
|
|
12772
|
+
className: "term-transcript",
|
|
12773
|
+
children: /* @__PURE__ */ jsx(WorkingRow, { label: "Loading…" })
|
|
12774
|
+
}) : /* @__PURE__ */ jsx(Loader, { label: "Loading session…" })
|
|
12775
|
+
})
|
|
12776
|
+
}) : null
|
|
12777
|
+
]
|
|
12778
|
+
})
|
|
12065
12779
|
})
|
|
12066
12780
|
})
|
|
12067
12781
|
})
|
|
@@ -12395,7 +13109,7 @@ const INTERACTIVE = [
|
|
|
12395
13109
|
"[role=\"radio\"]",
|
|
12396
13110
|
"[role=\"tab\"]"
|
|
12397
13111
|
].join(",");
|
|
12398
|
-
function SessionPanel({ client, sessionId, header, panelSurface = "internal", statusSurface = "internal", statusPlacement = "top", onOpenPanel, onVitals, transcriptVariant = "cards",
|
|
13112
|
+
function SessionPanel({ client, sessionId, header, panelSurface = "internal", statusSurface = "internal", statusPlacement = "top", onOpenPanel, onVitals, transcriptVariant = "cards", transcriptFont = "sans", affordances, terminalMetrics, scrubber = false, bookmarks, peerMentions = true, onToggleBookmark, reveal, subagents, shells, openSubagent, onSubagentChange, openShell, onShellChange, stickyPrompt = false, controlsSurface = "internal", onControls, focusComposerOnClick = false, unseen, readOnly = false, approvalPrompts, toolHost, clientTools, cacheTranscript, emptyState, onLinkClick, onOpenFile, fontSize, className }) {
|
|
12399
13113
|
const effectiveTermFontSize = terminalMetrics?.fontSize ?? fontSize;
|
|
12400
13114
|
const effectiveTermLineHeight = terminalMetrics?.lineHeight ?? (fontSize !== void 0 ? Math.round(fontSize * (18 / 13)) : void 0);
|
|
12401
13115
|
const external = panelSurface === "external";
|
|
@@ -12406,7 +13120,7 @@ function SessionPanel({ client, sessionId, header, panelSurface = "internal", st
|
|
|
12406
13120
|
const [panel, setPanel] = useState();
|
|
12407
13121
|
const [showCompletedTasks, setShowCompletedTasks] = useState(false);
|
|
12408
13122
|
const [taskReveal, setTaskReveal] = useState();
|
|
12409
|
-
const { state, connection, replaying, protocolMismatch, shell, pricing, models, effectiveModel, handle, send, runShell, approve, deny, interrupt, clearContext, setModel, setPermissionMode, reconnectNow, loadFullResult, loadShellOutput, verifyShell, killShell } = useClaudeSession(client, sessionId, {
|
|
13123
|
+
const { state, connection, replaying, protocolMismatch, shell, pricing, models, effectiveModel, handle, send, runShell, approve, deny, interrupt, clearContext, setModel, setPermissionMode, reconnectNow, loadFullResult, loadShellOutput, verifyShell, killShell, setShellAgentWrite } = useClaudeSession(client, sessionId, {
|
|
12410
13124
|
onProtocolError: setProtocolError,
|
|
12411
13125
|
cacheTranscript
|
|
12412
13126
|
});
|
|
@@ -12419,16 +13133,19 @@ function SessionPanel({ client, sessionId, header, panelSurface = "internal", st
|
|
|
12419
13133
|
openShell,
|
|
12420
13134
|
onShellChange
|
|
12421
13135
|
});
|
|
13136
|
+
const agentWrite = state.session?.shellAgentWrite !== void 0 ? setShellAgentWrite : void 0;
|
|
12422
13137
|
const shellActions = useMemo(() => ({
|
|
12423
13138
|
loadOutput: loadShellOutput,
|
|
12424
13139
|
verify: verifyShell,
|
|
12425
13140
|
kill: killShell,
|
|
12426
|
-
open: enterShell
|
|
13141
|
+
open: enterShell,
|
|
13142
|
+
agentWrite
|
|
12427
13143
|
}), [
|
|
12428
13144
|
loadShellOutput,
|
|
12429
13145
|
verifyShell,
|
|
12430
13146
|
killShell,
|
|
12431
|
-
enterShell
|
|
13147
|
+
enterShell,
|
|
13148
|
+
agentWrite
|
|
12432
13149
|
]);
|
|
12433
13150
|
useEffect(() => setProtocolError(void 0), [sessionId]);
|
|
12434
13151
|
const { subagentId, enterSubagent, leaveSubagent, returnReveal, frameItems: subagentFrameItems, task: subagentTask, fallbackLabel: subagentFallbackLabel } = useSubagentFrame({
|
|
@@ -12762,251 +13479,248 @@ function SessionPanel({ client, sessionId, header, panelSurface = "internal", st
|
|
|
12762
13479
|
};
|
|
12763
13480
|
return /* @__PURE__ */ jsx(TranscriptVariantProvider, {
|
|
12764
13481
|
value: transcriptVariant,
|
|
12765
|
-
children: /* @__PURE__ */ jsx(
|
|
12766
|
-
value:
|
|
12767
|
-
children: /* @__PURE__ */ jsx(
|
|
12768
|
-
value:
|
|
12769
|
-
children: /* @__PURE__ */ jsx(
|
|
12770
|
-
value:
|
|
12771
|
-
children: /* @__PURE__ */ jsx(
|
|
12772
|
-
value:
|
|
12773
|
-
children: /* @__PURE__ */ jsx(
|
|
12774
|
-
value:
|
|
12775
|
-
children: /* @__PURE__ */ jsx(
|
|
12776
|
-
|
|
12777
|
-
|
|
12778
|
-
|
|
12779
|
-
|
|
12780
|
-
|
|
12781
|
-
|
|
12782
|
-
|
|
12783
|
-
|
|
12784
|
-
|
|
12785
|
-
|
|
12786
|
-
|
|
12787
|
-
|
|
12788
|
-
|
|
13482
|
+
children: /* @__PURE__ */ jsx(FileLinkProvider, {
|
|
13483
|
+
value: fileLinks,
|
|
13484
|
+
children: /* @__PURE__ */ jsx(ToolResultFetchProvider, {
|
|
13485
|
+
value: loadFullResult,
|
|
13486
|
+
children: /* @__PURE__ */ jsx(ShellActionsProvider, {
|
|
13487
|
+
value: shellActions,
|
|
13488
|
+
children: /* @__PURE__ */ jsx(ToolTitleProvider, {
|
|
13489
|
+
value: state.toolTitles,
|
|
13490
|
+
children: /* @__PURE__ */ jsx(ToolResultImageProvider, {
|
|
13491
|
+
value: resultImages,
|
|
13492
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
13493
|
+
ref: panelRef,
|
|
13494
|
+
"data-slot": "session-panel",
|
|
13495
|
+
"data-agent-font": transcriptFont,
|
|
13496
|
+
onClick: handleClick,
|
|
13497
|
+
className: cn("relative flex h-full min-h-0 flex-col overflow-hidden bg-bg", className),
|
|
13498
|
+
style: fontSize !== void 0 ? { "--wd-font-size": `${Math.round(fontSize)}px` } : void 0,
|
|
13499
|
+
children: /* @__PURE__ */ jsxs(ImageViewerProvider, { children: [
|
|
13500
|
+
headerTakesActions ? header({ actions: menu }) : header,
|
|
13501
|
+
statusPlacement === "top" ? statusBar : null,
|
|
13502
|
+
protocolMismatch !== void 0 ? /* @__PURE__ */ jsxs(Notice, {
|
|
13503
|
+
level: "warning",
|
|
13504
|
+
children: [
|
|
13505
|
+
"Server speaks protocol v",
|
|
13506
|
+
protocolMismatch,
|
|
13507
|
+
", this build renders v",
|
|
13508
|
+
PROTOCOL_VERSION,
|
|
13509
|
+
". Some events may not render."
|
|
13510
|
+
]
|
|
13511
|
+
}) : null,
|
|
13512
|
+
protocolError ? /* @__PURE__ */ jsx(Notice, {
|
|
13513
|
+
level: "error",
|
|
13514
|
+
onDismiss: () => setProtocolError(void 0),
|
|
13515
|
+
children: protocolError
|
|
13516
|
+
}) : null,
|
|
13517
|
+
framedShellId !== void 0 ? /* @__PURE__ */ jsx(ShellStrip, {
|
|
13518
|
+
shell: framedShell,
|
|
13519
|
+
label: framedShellLabel,
|
|
13520
|
+
onBack: leaveShell,
|
|
13521
|
+
onKill: () => void killShell(framedShellId),
|
|
13522
|
+
onAgentWrite: agentWrite ? (enabled) => void agentWrite(framedShellId, enabled) : void 0,
|
|
13523
|
+
terminal,
|
|
13524
|
+
fontSize: effectiveTermFontSize,
|
|
13525
|
+
lineHeight: effectiveTermLineHeight
|
|
13526
|
+
}) : null,
|
|
13527
|
+
framedShellId === void 0 && subagentId !== void 0 ? /* @__PURE__ */ jsx(SubagentStrip, {
|
|
13528
|
+
task: subagentTask,
|
|
13529
|
+
items: subagentFrameItems,
|
|
13530
|
+
label: subagentFallbackLabel,
|
|
13531
|
+
onBack: leaveSubagent,
|
|
13532
|
+
terminal,
|
|
13533
|
+
fontSize: effectiveTermFontSize,
|
|
13534
|
+
lineHeight: effectiveTermLineHeight
|
|
13535
|
+
}) : null,
|
|
13536
|
+
framedShellId !== void 0 ? /* @__PURE__ */ jsx(ShellTerminal, {
|
|
13537
|
+
handle,
|
|
13538
|
+
shellId: framedShellId,
|
|
13539
|
+
fontSize: effectiveTermFontSize
|
|
13540
|
+
}, framedShellId) : /* @__PURE__ */ jsx(BookmarkProvider, {
|
|
13541
|
+
value: bookmarkHandle,
|
|
13542
|
+
children: /* @__PURE__ */ jsx(Transcript, {
|
|
13543
|
+
state,
|
|
13544
|
+
fileUrl: sessionId ? (path) => client.sessionFileUrl(sessionId, path) : void 0,
|
|
13545
|
+
attachmentUrl: sessionId ? (id) => client.attachmentUrl(sessionId, id) : void 0,
|
|
13546
|
+
canBrowseFiles: hostFiles.available,
|
|
13547
|
+
sessionNames: peers.names,
|
|
13548
|
+
hostImage,
|
|
13549
|
+
variant: transcriptVariant,
|
|
13550
|
+
fontSize: effectiveTermFontSize,
|
|
13551
|
+
lineHeight: effectiveTermLineHeight,
|
|
13552
|
+
affordances,
|
|
13553
|
+
stickyPrompt,
|
|
13554
|
+
scrubber,
|
|
13555
|
+
bookmarks,
|
|
13556
|
+
replaying,
|
|
13557
|
+
catchUp: catchUp && newCount > 0 ? {
|
|
13558
|
+
from: catchUp.itemCount,
|
|
13559
|
+
since: catchUp.since
|
|
13560
|
+
} : void 0,
|
|
13561
|
+
reveal: taskReveal ?? frameReturnReveal ?? reveal,
|
|
13562
|
+
frame: subagentId === void 0 ? void 0 : { parentToolUseId: subagentId },
|
|
13563
|
+
onOpenSubagent: enterSubagent,
|
|
13564
|
+
emptyState,
|
|
13565
|
+
jumpToRecapRef: jumpToRecap,
|
|
13566
|
+
repinRef: repinTranscript
|
|
13567
|
+
}, subagentId ?? "session")
|
|
13568
|
+
}),
|
|
13569
|
+
catchUp && newCount > 0 && !replaying && subagentId === void 0 && framedShellId === void 0 ? /* @__PURE__ */ jsx("div", {
|
|
13570
|
+
className: "px-3 pb-1",
|
|
13571
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
13572
|
+
"data-slot": "catch-up",
|
|
13573
|
+
className: "mx-auto flex w-full max-w-[var(--wd-transcript-max-width)] items-center gap-2 text-label text-fg-3",
|
|
12789
13574
|
children: [
|
|
12790
|
-
|
|
12791
|
-
|
|
12792
|
-
|
|
12793
|
-
|
|
12794
|
-
|
|
13575
|
+
/* @__PURE__ */ jsx("span", {
|
|
13576
|
+
"aria-hidden": true,
|
|
13577
|
+
className: cn("select-none", terminal ? "text-fg-3" : "text-accent"),
|
|
13578
|
+
children: "※"
|
|
13579
|
+
}),
|
|
13580
|
+
/* @__PURE__ */ jsxs("span", {
|
|
13581
|
+
className: "min-w-0 flex-1 truncate",
|
|
13582
|
+
children: [
|
|
13583
|
+
newCount,
|
|
13584
|
+
" new ",
|
|
13585
|
+
newCount === 1 ? "row" : "rows",
|
|
13586
|
+
catchUp.since !== void 0 ? ` since you were last here` : ""
|
|
13587
|
+
]
|
|
13588
|
+
}),
|
|
13589
|
+
/* @__PURE__ */ jsx("button", {
|
|
13590
|
+
type: "button",
|
|
13591
|
+
onClick: () => jumpToRecap.current?.(),
|
|
13592
|
+
className: "shrink-0 underline-offset-2 hover:text-fg-1 hover:underline",
|
|
13593
|
+
children: "jump"
|
|
13594
|
+
}),
|
|
13595
|
+
/* @__PURE__ */ jsx("button", {
|
|
13596
|
+
type: "button",
|
|
13597
|
+
onClick: () => setCaughtUp(true),
|
|
13598
|
+
className: "shrink-0 underline-offset-2 hover:text-fg-1 hover:underline",
|
|
13599
|
+
children: "dismiss"
|
|
13600
|
+
})
|
|
12795
13601
|
]
|
|
12796
|
-
})
|
|
12797
|
-
|
|
12798
|
-
|
|
12799
|
-
|
|
12800
|
-
|
|
12801
|
-
}) : null,
|
|
12802
|
-
framedShellId !== void 0 ? /* @__PURE__ */ jsx(ShellStrip, {
|
|
12803
|
-
shell: framedShell,
|
|
12804
|
-
label: framedShellLabel,
|
|
12805
|
-
onBack: leaveShell,
|
|
12806
|
-
onKill: () => void killShell(framedShellId),
|
|
12807
|
-
terminal,
|
|
12808
|
-
fontSize: effectiveTermFontSize,
|
|
12809
|
-
lineHeight: effectiveTermLineHeight
|
|
12810
|
-
}) : null,
|
|
12811
|
-
framedShellId === void 0 && subagentId !== void 0 ? /* @__PURE__ */ jsx(SubagentStrip, {
|
|
12812
|
-
task: subagentTask,
|
|
12813
|
-
items: subagentFrameItems,
|
|
12814
|
-
label: subagentFallbackLabel,
|
|
12815
|
-
onBack: leaveSubagent,
|
|
13602
|
+
})
|
|
13603
|
+
}) : null,
|
|
13604
|
+
!readOnly && capabilities.interactiveApprovals && state.pendingApprovals.length > 0 ? /* @__PURE__ */ jsx("div", {
|
|
13605
|
+
className: cn(terminal ? "pb-2" : "px-3 pb-2"),
|
|
13606
|
+
children: /* @__PURE__ */ jsx(PromptSurface, {
|
|
12816
13607
|
terminal,
|
|
12817
|
-
|
|
12818
|
-
lineHeight: effectiveTermLineHeight
|
|
12819
|
-
}) : null,
|
|
12820
|
-
framedShellId !== void 0 ? /* @__PURE__ */ jsx(ShellTerminal, {
|
|
12821
|
-
handle,
|
|
12822
|
-
shellId: framedShellId,
|
|
12823
|
-
fontSize: effectiveTermFontSize
|
|
12824
|
-
}, framedShellId) : /* @__PURE__ */ jsx(BookmarkProvider, {
|
|
12825
|
-
value: bookmarkHandle,
|
|
12826
|
-
children: /* @__PURE__ */ jsx(Transcript, {
|
|
12827
|
-
state,
|
|
12828
|
-
fileUrl: sessionId ? (path) => client.sessionFileUrl(sessionId, path) : void 0,
|
|
12829
|
-
attachmentUrl: sessionId ? (id) => client.attachmentUrl(sessionId, id) : void 0,
|
|
12830
|
-
canBrowseFiles: hostFiles.available,
|
|
12831
|
-
sessionNames: peers.names,
|
|
12832
|
-
hostImage,
|
|
12833
|
-
variant: transcriptVariant,
|
|
12834
|
-
density: transcriptDensity,
|
|
13608
|
+
metrics: {
|
|
12835
13609
|
fontSize: effectiveTermFontSize,
|
|
12836
|
-
lineHeight: effectiveTermLineHeight
|
|
12837
|
-
|
|
12838
|
-
|
|
12839
|
-
|
|
12840
|
-
|
|
12841
|
-
|
|
12842
|
-
|
|
12843
|
-
|
|
12844
|
-
|
|
12845
|
-
}
|
|
12846
|
-
|
|
12847
|
-
|
|
12848
|
-
|
|
12849
|
-
|
|
12850
|
-
|
|
12851
|
-
|
|
12852
|
-
|
|
12853
|
-
|
|
12854
|
-
|
|
12855
|
-
|
|
12856
|
-
|
|
12857
|
-
|
|
12858
|
-
|
|
12859
|
-
|
|
12860
|
-
|
|
12861
|
-
|
|
12862
|
-
|
|
12863
|
-
|
|
12864
|
-
|
|
12865
|
-
/* @__PURE__ */ jsxs("span", {
|
|
12866
|
-
className: "min-w-0 flex-1 truncate",
|
|
12867
|
-
children: [
|
|
12868
|
-
newCount,
|
|
12869
|
-
" new ",
|
|
12870
|
-
newCount === 1 ? "row" : "rows",
|
|
12871
|
-
catchUp.since !== void 0 ? ` since you were last here` : ""
|
|
12872
|
-
]
|
|
12873
|
-
}),
|
|
12874
|
-
/* @__PURE__ */ jsx("button", {
|
|
12875
|
-
type: "button",
|
|
12876
|
-
onClick: () => jumpToRecap.current?.(),
|
|
12877
|
-
className: "shrink-0 underline-offset-2 hover:text-fg-1 hover:underline",
|
|
12878
|
-
children: "jump"
|
|
12879
|
-
}),
|
|
12880
|
-
/* @__PURE__ */ jsx("button", {
|
|
12881
|
-
type: "button",
|
|
12882
|
-
onClick: () => setCaughtUp(true),
|
|
12883
|
-
className: "shrink-0 underline-offset-2 hover:text-fg-1 hover:underline",
|
|
12884
|
-
children: "dismiss"
|
|
12885
|
-
})
|
|
12886
|
-
]
|
|
12887
|
-
})
|
|
12888
|
-
}) : null,
|
|
12889
|
-
!readOnly && capabilities.interactiveApprovals && state.pendingApprovals.length > 0 ? /* @__PURE__ */ jsx("div", {
|
|
12890
|
-
className: cn(terminal ? "pb-2" : "px-3 pb-2"),
|
|
12891
|
-
children: /* @__PURE__ */ jsx(PromptSurface, {
|
|
12892
|
-
terminal,
|
|
12893
|
-
metrics: {
|
|
12894
|
-
fontSize: effectiveTermFontSize,
|
|
12895
|
-
lineHeight: effectiveTermLineHeight
|
|
12896
|
-
},
|
|
12897
|
-
affordances,
|
|
12898
|
-
children: state.pendingApprovals.map((request) => {
|
|
12899
|
-
const HostPrompt = approvalPrompts?.[request.toolName];
|
|
12900
|
-
if (HostPrompt) return /* @__PURE__ */ jsx(HostPrompt, {
|
|
12901
|
-
request,
|
|
12902
|
-
onApprove: approve,
|
|
12903
|
-
onDeny: deny
|
|
12904
|
-
}, request.id);
|
|
12905
|
-
const isQuestion = request.toolName === "AskUserQuestion" && parseUserQuestions(request.input).length > 0;
|
|
12906
|
-
if (terminal) return isQuestion ? /* @__PURE__ */ jsx(TerminalQuestionPrompt, {
|
|
12907
|
-
request,
|
|
12908
|
-
onAnswer: approve,
|
|
12909
|
-
onDismiss: (id) => deny(id, "Question dismissed by user")
|
|
12910
|
-
}, request.id) : /* @__PURE__ */ jsx(TerminalPermissionPrompt, {
|
|
12911
|
-
request,
|
|
12912
|
-
onApprove: approve,
|
|
12913
|
-
onDeny: deny
|
|
12914
|
-
}, request.id);
|
|
12915
|
-
return isQuestion ? /* @__PURE__ */ jsx(QuestionPrompt, {
|
|
12916
|
-
request,
|
|
12917
|
-
onAnswer: approve,
|
|
12918
|
-
onDismiss: (id) => deny(id, "Question dismissed by user")
|
|
12919
|
-
}, request.id) : /* @__PURE__ */ jsx(PermissionPrompt, {
|
|
12920
|
-
request,
|
|
12921
|
-
onApprove: approve,
|
|
12922
|
-
onDeny: deny
|
|
12923
|
-
}, request.id);
|
|
12924
|
-
})
|
|
12925
|
-
})
|
|
12926
|
-
}) : null,
|
|
12927
|
-
readOnly || subagentId !== void 0 || framedShellId !== void 0 ? null : /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx(Composer, {
|
|
12928
|
-
ref: composerRef,
|
|
12929
|
-
onSend: handleSend,
|
|
12930
|
-
onInterrupt: interrupt,
|
|
12931
|
-
busy,
|
|
12932
|
-
disabled: ended || !sessionId,
|
|
12933
|
-
commands: capabilities.slashCommands ? state.commands : void 0,
|
|
12934
|
-
skills: capabilities.skillsList ? state.skills : void 0,
|
|
12935
|
-
clientCommands,
|
|
12936
|
-
attachments,
|
|
12937
|
-
draft,
|
|
12938
|
-
onSearchFiles: hostFiles.available ? searchComposerFiles : void 0,
|
|
12939
|
-
peers: peers.peers,
|
|
12940
|
-
onShellCommand: shell ? runShell : void 0,
|
|
12941
|
-
layout: controlsExternal ? "inline" : "stacked",
|
|
12942
|
-
toolbar: controlsExternal ? void 0 : sessionControls,
|
|
12943
|
-
fontSize: effectiveTermFontSize,
|
|
12944
|
-
lineHeight: effectiveTermLineHeight,
|
|
12945
|
-
affordances
|
|
12946
|
-
}) }),
|
|
12947
|
-
statusPlacement === "bottom" ? statusBar : null,
|
|
12948
|
-
!external ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
12949
|
-
/* @__PURE__ */ jsx(SessionInfoDialog, {
|
|
12950
|
-
state,
|
|
12951
|
-
client,
|
|
12952
|
-
sessionId,
|
|
12953
|
-
open: panel === "info",
|
|
12954
|
-
onOpenChange: (next) => setPanel(next ? "info" : void 0)
|
|
12955
|
-
}),
|
|
12956
|
-
/* @__PURE__ */ jsx(ContextDialog, {
|
|
12957
|
-
usage: state.contextUsage,
|
|
12958
|
-
engine: state.engine ?? "claude",
|
|
12959
|
-
open: panel === "context",
|
|
12960
|
-
onOpenChange: (next) => setPanel(next ? "context" : void 0)
|
|
12961
|
-
}),
|
|
12962
|
-
/* @__PURE__ */ jsx(UsageDialog, {
|
|
12963
|
-
rateLimits: windows,
|
|
12964
|
-
subscriptionType: state.subscriptionType,
|
|
12965
|
-
engine: state.engine ?? "claude",
|
|
12966
|
-
totalCostUsd: state.totalCostUsd,
|
|
12967
|
-
costUsd: state.costUsd,
|
|
12968
|
-
usageByModel: state.usageByModel,
|
|
12969
|
-
pricing,
|
|
12970
|
-
spend: profileSpend,
|
|
12971
|
-
updatedAt: usageUpdatedAt,
|
|
12972
|
-
open: panel === "usage",
|
|
12973
|
-
onOpenChange: (next) => setPanel(next ? "usage" : void 0)
|
|
12974
|
-
}),
|
|
12975
|
-
/* @__PURE__ */ jsx(McpDialog, {
|
|
12976
|
-
client,
|
|
12977
|
-
sessionId,
|
|
12978
|
-
canManageServers: capabilities.mcpServerActions,
|
|
12979
|
-
open: panel === "mcp",
|
|
12980
|
-
onOpenChange: (next) => setPanel(next ? "mcp" : void 0)
|
|
12981
|
-
}),
|
|
12982
|
-
/* @__PURE__ */ jsx(TasksDialog, {
|
|
12983
|
-
tasks,
|
|
12984
|
-
showCompleted: showCompletedTasks,
|
|
12985
|
-
onShowCompletedChange: setShowCompletedTasks,
|
|
12986
|
-
onSelectTask: (task) => {
|
|
12987
|
-
if (task.toolUseId) setTaskReveal({
|
|
12988
|
-
toolUseId: task.toolUseId,
|
|
12989
|
-
nonce: Date.now()
|
|
12990
|
-
});
|
|
12991
|
-
},
|
|
12992
|
-
open: panel === "tasks",
|
|
12993
|
-
onOpenChange: (next) => setPanel(next ? "tasks" : void 0)
|
|
12994
|
-
}),
|
|
12995
|
-
/* @__PURE__ */ jsx(SkillsDialog, {
|
|
12996
|
-
skills: state.skills,
|
|
12997
|
-
open: panel === "skills",
|
|
12998
|
-
onOpenChange: (next) => setPanel(next ? "skills" : void 0),
|
|
12999
|
-
onUse: (skill) => composerRef.current?.insertText(skillPrompt(skill))
|
|
13000
|
-
}),
|
|
13001
|
-
/* @__PURE__ */ jsx(HostFilesDialog, {
|
|
13002
|
-
client,
|
|
13003
|
-
cwd: state.cwd,
|
|
13004
|
-
open: panel === "files",
|
|
13005
|
-
onOpenChange: (next) => setPanel(next ? "files" : void 0)
|
|
13610
|
+
lineHeight: effectiveTermLineHeight
|
|
13611
|
+
},
|
|
13612
|
+
affordances,
|
|
13613
|
+
children: state.pendingApprovals.map((request) => {
|
|
13614
|
+
const HostPrompt = approvalPrompts?.[request.toolName];
|
|
13615
|
+
if (HostPrompt) return /* @__PURE__ */ jsx(HostPrompt, {
|
|
13616
|
+
request,
|
|
13617
|
+
onApprove: approve,
|
|
13618
|
+
onDeny: deny
|
|
13619
|
+
}, request.id);
|
|
13620
|
+
const isQuestion = request.toolName === "AskUserQuestion" && parseUserQuestions(request.input).length > 0;
|
|
13621
|
+
if (terminal) return isQuestion ? /* @__PURE__ */ jsx(TerminalQuestionPrompt, {
|
|
13622
|
+
request,
|
|
13623
|
+
onAnswer: approve,
|
|
13624
|
+
onDismiss: (id) => deny(id, "Question dismissed by user")
|
|
13625
|
+
}, request.id) : /* @__PURE__ */ jsx(TerminalPermissionPrompt, {
|
|
13626
|
+
request,
|
|
13627
|
+
onApprove: approve,
|
|
13628
|
+
onDeny: deny
|
|
13629
|
+
}, request.id);
|
|
13630
|
+
return isQuestion ? /* @__PURE__ */ jsx(QuestionPrompt, {
|
|
13631
|
+
request,
|
|
13632
|
+
onAnswer: approve,
|
|
13633
|
+
onDismiss: (id) => deny(id, "Question dismissed by user")
|
|
13634
|
+
}, request.id) : /* @__PURE__ */ jsx(PermissionPrompt, {
|
|
13635
|
+
request,
|
|
13636
|
+
onApprove: approve,
|
|
13637
|
+
onDeny: deny
|
|
13638
|
+
}, request.id);
|
|
13006
13639
|
})
|
|
13007
|
-
|
|
13008
|
-
|
|
13009
|
-
|
|
13640
|
+
})
|
|
13641
|
+
}) : null,
|
|
13642
|
+
readOnly || subagentId !== void 0 || framedShellId !== void 0 ? null : /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx(Composer, {
|
|
13643
|
+
ref: composerRef,
|
|
13644
|
+
onSend: handleSend,
|
|
13645
|
+
onInterrupt: interrupt,
|
|
13646
|
+
busy,
|
|
13647
|
+
disabled: ended || !sessionId,
|
|
13648
|
+
commands: capabilities.slashCommands ? state.commands : void 0,
|
|
13649
|
+
skills: capabilities.skillsList ? state.skills : void 0,
|
|
13650
|
+
clientCommands,
|
|
13651
|
+
attachments,
|
|
13652
|
+
draft,
|
|
13653
|
+
onSearchFiles: hostFiles.available ? searchComposerFiles : void 0,
|
|
13654
|
+
peers: peers.peers,
|
|
13655
|
+
onShellCommand: shell ? runShell : void 0,
|
|
13656
|
+
layout: controlsExternal ? "inline" : "stacked",
|
|
13657
|
+
toolbar: controlsExternal ? void 0 : sessionControls,
|
|
13658
|
+
fontSize: effectiveTermFontSize,
|
|
13659
|
+
lineHeight: effectiveTermLineHeight,
|
|
13660
|
+
affordances
|
|
13661
|
+
}) }),
|
|
13662
|
+
statusPlacement === "bottom" ? statusBar : null,
|
|
13663
|
+
!external ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
13664
|
+
/* @__PURE__ */ jsx(SessionInfoDialog, {
|
|
13665
|
+
state,
|
|
13666
|
+
client,
|
|
13667
|
+
sessionId,
|
|
13668
|
+
open: panel === "info",
|
|
13669
|
+
onOpenChange: (next) => setPanel(next ? "info" : void 0)
|
|
13670
|
+
}),
|
|
13671
|
+
/* @__PURE__ */ jsx(ContextDialog, {
|
|
13672
|
+
usage: state.contextUsage,
|
|
13673
|
+
engine: state.engine ?? "claude",
|
|
13674
|
+
open: panel === "context",
|
|
13675
|
+
onOpenChange: (next) => setPanel(next ? "context" : void 0)
|
|
13676
|
+
}),
|
|
13677
|
+
/* @__PURE__ */ jsx(UsageDialog, {
|
|
13678
|
+
rateLimits: windows,
|
|
13679
|
+
subscriptionType: state.subscriptionType,
|
|
13680
|
+
engine: state.engine ?? "claude",
|
|
13681
|
+
totalCostUsd: state.totalCostUsd,
|
|
13682
|
+
costUsd: state.costUsd,
|
|
13683
|
+
usageByModel: state.usageByModel,
|
|
13684
|
+
pricing,
|
|
13685
|
+
spend: profileSpend,
|
|
13686
|
+
updatedAt: usageUpdatedAt,
|
|
13687
|
+
open: panel === "usage",
|
|
13688
|
+
onOpenChange: (next) => setPanel(next ? "usage" : void 0)
|
|
13689
|
+
}),
|
|
13690
|
+
/* @__PURE__ */ jsx(McpDialog, {
|
|
13691
|
+
client,
|
|
13692
|
+
sessionId,
|
|
13693
|
+
canManageServers: capabilities.mcpServerActions,
|
|
13694
|
+
open: panel === "mcp",
|
|
13695
|
+
onOpenChange: (next) => setPanel(next ? "mcp" : void 0)
|
|
13696
|
+
}),
|
|
13697
|
+
/* @__PURE__ */ jsx(TasksDialog, {
|
|
13698
|
+
tasks,
|
|
13699
|
+
showCompleted: showCompletedTasks,
|
|
13700
|
+
onShowCompletedChange: setShowCompletedTasks,
|
|
13701
|
+
onSelectTask: (task) => {
|
|
13702
|
+
if (task.toolUseId) setTaskReveal({
|
|
13703
|
+
toolUseId: task.toolUseId,
|
|
13704
|
+
nonce: Date.now()
|
|
13705
|
+
});
|
|
13706
|
+
},
|
|
13707
|
+
open: panel === "tasks",
|
|
13708
|
+
onOpenChange: (next) => setPanel(next ? "tasks" : void 0)
|
|
13709
|
+
}),
|
|
13710
|
+
/* @__PURE__ */ jsx(SkillsDialog, {
|
|
13711
|
+
skills: state.skills,
|
|
13712
|
+
open: panel === "skills",
|
|
13713
|
+
onOpenChange: (next) => setPanel(next ? "skills" : void 0),
|
|
13714
|
+
onUse: (skill) => composerRef.current?.insertText(skillPrompt(skill))
|
|
13715
|
+
}),
|
|
13716
|
+
/* @__PURE__ */ jsx(HostFilesDialog, {
|
|
13717
|
+
client,
|
|
13718
|
+
cwd: state.cwd,
|
|
13719
|
+
open: panel === "files",
|
|
13720
|
+
onOpenChange: (next) => setPanel(next ? "files" : void 0)
|
|
13721
|
+
})
|
|
13722
|
+
] }) : null
|
|
13723
|
+
] })
|
|
13010
13724
|
})
|
|
13011
13725
|
})
|
|
13012
13726
|
})
|
|
@@ -13179,6 +13893,6 @@ function resolveAgainstCwd(path, cwd) {
|
|
|
13179
13893
|
return parseFileLink(path, cwd)?.path ?? path;
|
|
13180
13894
|
}
|
|
13181
13895
|
//#endregion
|
|
13182
|
-
export {
|
|
13896
|
+
export { shellAgentWriteLabel as $, Tip as $t, ShellTerminal as A, isMutatingTool as At, SkillsDialog as B, hashtagTrigger as Bt, SessionInfoDialog as C, Badge as Cn, AgentWriteIcon as Ct, QuestionPrompt as D, cn as Dn, PromptTokenText as Dt, QUESTION_BEHAVIORS as E, buttonVariants as En, useAffordances as Et, PERMISSION_MODES as F, mergeComposerRows as Ft, TaskList as G, plainTextToSegments as Gt, HostFilesDialog as H, mentionTrigger as Ht, PermissionModeSelect as I, rankComposerRows as It, Composer as J, Splitter as Jt, ContextDialog as K, segmentsToPlainText as Kt, permissionModeChoices as L, rankPeerSessions as Lt, SubagentStrip as M, TranscriptVariantProvider as Mt, PermissionPrompt as N, useTranscriptVariant as Nt, parseUserQuestions as O, SessionNamesProvider as Ot, Response as P, matchClientCommand as Pt, SHELL_KILL_GLYPH as Q, copyText as Qt, permissionModeMeta as R, skillPrompt as Rt, STATUS_META as S, Input as Sn, Row as St, TerminalPermissionPrompt as T, Button as Tn, WithActions as Tt, EntryIcon as U, usePromptAreaState as Ut, McpDialog as V, launchTrigger as Vt, TasksDialog as W, PromptArea as Wt, SHELL_AGENT_WRITE_NOTE as X, Spinner as Xt, TerminalSurface as Y, CodeBlock as Yt, SHELL_GLYPH as Z, CopyButton as Zt, Loader as _, SelectItemText as _n, TerminalDiff as _t, UsageDialog as a, DialogContent as an, ShellActionsProvider as at, ConversationScrollButton as b, PortalScope as bn, Blank as bt, Transcript as c, DialogTrigger as cn, useToolTitle as ct, Message as d, MenuItem as dn, ImageViewerProvider as dt, TooltipContent as en, shellGrantable as et, MessageContent as f, MenuSeparator as fn, ViewableImage as ft, SessionEmptyState as g, SelectItem as gn, parseFileLink as gt, TerminalTranscript as h, SelectContent as hn, useFileLinks as ht, SessionPanel as i, DialogClose as in, shellTitle as it, ShellStrip as j, toolIcon as jt, useShellFrame as k, SkillNamesProvider as kt, ToolCallCard as l, Menu$1 as ln, TerminalMarkdown as lt, TerminalItemView as m, Select$1 as mn, FileLinkProvider as mt, usePathLinks as n, Dialog$1 as nn, shellInfoLabel as nt, UsageMeters as o, DialogHeader as on, useShellActions as ot, FileCard as p, MenuTrigger as pn, useOpenImage as pt, contextNote as q, ProgressRing as qt, matchPath as r, DialogBody as rn, shellInfoStatusText as rt, useMinuteClock as s, DialogRow as sn, ToolTitleProvider as st, resolveAgainstCwd as t, TooltipProvider as tn, shellInfoFailed as tt, Reasoning as u, MenuContent as un, ImageViewer as ut, Conversation as v, SelectTrigger as vn, previewPatch as vt, TerminalQuestionPrompt as w, badgeVariants as wn, CopyAction as wt, StatusBar as x, Textarea as xn, Ink as xt, ConversationContent as y, SelectValue as yn, Band as yt, ModelSelect as z, commandTrigger as zt };
|
|
13183
13897
|
|
|
13184
|
-
//# sourceMappingURL=use-path-links-
|
|
13898
|
+
//# sourceMappingURL=use-path-links-BEWxt0ZM.mjs.map
|