@workerdeck/ui 2.13.0 → 2.14.0
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/build/{SessionPanel-CJwp5B3q.d.mts → SessionPanel-BVKqPs_3.d.mts} +9 -3
- package/build/index.d.mts +84 -6
- package/build/index.mjs +83 -37
- package/build/index.mjs.map +1 -1
- package/build/scoped.css +24 -3
- package/build/{use-path-links-CepFsMdW.mjs → use-path-links-BgWXmfAS.mjs} +849 -236
- package/build/use-path-links-BgWXmfAS.mjs.map +1 -0
- package/build/workspace.d.mts +19 -4
- package/build/workspace.mjs +7 -4
- package/build/workspace.mjs.map +1 -1
- package/package.json +16 -6
- package/src/components/agent/Composer.tsx +18 -13
- package/src/components/agent/SessionBrowser.tsx +24 -1
- package/src/components/agent/SessionItem.tsx +13 -3
- package/src/components/agent/SessionPanel.tsx +264 -211
- package/src/components/agent/SessionSteps.tsx +78 -27
- package/src/components/agent/SessionWorkspace.tsx +10 -1
- package/src/components/agent/ShellStrip.tsx +71 -0
- package/src/components/agent/ShellTerminal.tsx +170 -0
- package/src/components/agent/SubagentToggle.tsx +7 -1
- package/src/components/agent/TranscriptItemView.tsx +74 -1
- package/src/components/agent/scrubber-marks.ts +9 -1
- package/src/components/agent/shell-actions.tsx +25 -0
- package/src/components/agent/use-shell-frame.ts +111 -0
- package/src/components/terminal/TerminalTranscript.tsx +4 -0
- package/src/components/terminal/affordances.tsx +37 -0
- package/src/components/terminal/height.ts +14 -0
- package/src/components/terminal/items.tsx +72 -3
- package/src/components/terminal/press.tsx +5 -3
- package/src/components/terminal/scrubber.tsx +9 -1
- package/src/components/terminal/shell-row.ts +106 -0
- package/src/index.ts +12 -1
- package/src/styles/terminal.css +11 -0
- package/src/styles/theme.css +3 -0
- package/src/workspace.ts +1 -0
- package/build/use-path-links-CepFsMdW.mjs.map +0 -1
|
@@ -10,7 +10,7 @@ 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
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";
|
|
13
|
-
import { recapLine, scanPromptTokens, summarizeSince, useAttachments, useClaudeSession, useDraft, useHostFileSearch, usePeerSessions, useProfileUsage, useToolCallHost } from "@workerdeck/react";
|
|
13
|
+
import { recapLine, scanPromptTokens, summarizeSince, useAttachments, useClaudeSession, useDraft, useHostFileSearch, usePeerSessions, useProfileUsage, useShellTerminal, useToolCallHost } from "@workerdeck/react";
|
|
14
14
|
import { Streamdown } from "streamdown";
|
|
15
15
|
import { StickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
|
|
16
16
|
import { createPortal } from "react-dom";
|
|
@@ -4765,6 +4765,65 @@ function PromptTokenText({ text, className }) {
|
|
|
4765
4765
|
});
|
|
4766
4766
|
}
|
|
4767
4767
|
//#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
|
|
4768
4827
|
//#region src/components/terminal/affordances.tsx
|
|
4769
4828
|
const DEFAULTS = {
|
|
4770
4829
|
hover: true,
|
|
@@ -4840,6 +4899,34 @@ function OpenSubagentAction({ onOpen, label = "Open sub-agent" }) {
|
|
|
4840
4899
|
children: "⤢"
|
|
4841
4900
|
});
|
|
4842
4901
|
}
|
|
4902
|
+
function OpenShellAction({ onOpen, label = "Open terminal" }) {
|
|
4903
|
+
return /* @__PURE__ */ jsx("button", {
|
|
4904
|
+
type: "button",
|
|
4905
|
+
className: "term-action",
|
|
4906
|
+
title: label,
|
|
4907
|
+
"aria-label": label,
|
|
4908
|
+
"data-tone": "magenta",
|
|
4909
|
+
onClick: (event) => {
|
|
4910
|
+
event.stopPropagation();
|
|
4911
|
+
onOpen();
|
|
4912
|
+
},
|
|
4913
|
+
children: "⤢"
|
|
4914
|
+
});
|
|
4915
|
+
}
|
|
4916
|
+
function KillShellAction({ onKill, label = "Kill this shell" }) {
|
|
4917
|
+
return /* @__PURE__ */ jsx("button", {
|
|
4918
|
+
type: "button",
|
|
4919
|
+
className: "term-action",
|
|
4920
|
+
title: label,
|
|
4921
|
+
"aria-label": label,
|
|
4922
|
+
"data-tone": "red",
|
|
4923
|
+
onClick: (event) => {
|
|
4924
|
+
event.stopPropagation();
|
|
4925
|
+
onKill();
|
|
4926
|
+
},
|
|
4927
|
+
children: "✕"
|
|
4928
|
+
});
|
|
4929
|
+
}
|
|
4843
4930
|
function CopyAction({ text, label = "Copy" }) {
|
|
4844
4931
|
const [copied, setCopied] = useState(false);
|
|
4845
4932
|
return /* @__PURE__ */ jsx("button", {
|
|
@@ -5343,12 +5430,20 @@ function Pressable({ onPress, expanded, className, children }) {
|
|
|
5343
5430
|
if (from && Math.abs(event.clientX - from.x) + Math.abs(event.clientY - from.y) > DRAG_SLOP) return;
|
|
5344
5431
|
const selection = window.getSelection?.();
|
|
5345
5432
|
if (selection && !selection.isCollapsed && selection.containsNode(event.currentTarget, true)) return;
|
|
5346
|
-
onPress(
|
|
5433
|
+
onPress({
|
|
5434
|
+
meta: event.metaKey,
|
|
5435
|
+
ctrl: event.ctrlKey,
|
|
5436
|
+
alt: event.altKey
|
|
5437
|
+
});
|
|
5347
5438
|
},
|
|
5348
5439
|
onKeyDown: (event) => {
|
|
5349
5440
|
if (event.key !== "Enter" && event.key !== " ") return;
|
|
5350
5441
|
event.preventDefault();
|
|
5351
|
-
onPress(
|
|
5442
|
+
onPress({
|
|
5443
|
+
meta: event.metaKey,
|
|
5444
|
+
ctrl: event.ctrlKey,
|
|
5445
|
+
alt: event.altKey
|
|
5446
|
+
});
|
|
5352
5447
|
},
|
|
5353
5448
|
children
|
|
5354
5449
|
});
|
|
@@ -5569,6 +5664,23 @@ function todoPreview(name, input) {
|
|
|
5569
5664
|
function todoLine(todo) {
|
|
5570
5665
|
return `${GLYPH[todo.status]} ${todo.text}`;
|
|
5571
5666
|
}
|
|
5667
|
+
//#endregion
|
|
5668
|
+
//#region src/components/agent/shell-actions.tsx
|
|
5669
|
+
const NOOP = {
|
|
5670
|
+
loadOutput: async () => false,
|
|
5671
|
+
verify: async () => false,
|
|
5672
|
+
kill: async () => false
|
|
5673
|
+
};
|
|
5674
|
+
const ShellActionsContext = createContext(NOOP);
|
|
5675
|
+
function ShellActionsProvider({ value, children }) {
|
|
5676
|
+
return /* @__PURE__ */ jsx(ShellActionsContext.Provider, {
|
|
5677
|
+
value: value ?? NOOP,
|
|
5678
|
+
children
|
|
5679
|
+
});
|
|
5680
|
+
}
|
|
5681
|
+
function useShellActions() {
|
|
5682
|
+
return useContext(ShellActionsContext);
|
|
5683
|
+
}
|
|
5572
5684
|
const RESULT_PREVIEW_CHARS$1 = 2e3;
|
|
5573
5685
|
function clipToChars(lines, maxChars) {
|
|
5574
5686
|
const out = [];
|
|
@@ -5920,6 +6032,79 @@ function NoticeRow$1({ item }) {
|
|
|
5920
6032
|
children: item.text
|
|
5921
6033
|
});
|
|
5922
6034
|
}
|
|
6035
|
+
function ShellRow({ item }) {
|
|
6036
|
+
const [open, setOpen] = useState(false);
|
|
6037
|
+
const [busy, setBusy] = useState(false);
|
|
6038
|
+
const actions = useShellActions();
|
|
6039
|
+
const reveal = useRevealOnOpen(open);
|
|
6040
|
+
const running = item.shell.status === "running";
|
|
6041
|
+
const failed = shellFailed(item);
|
|
6042
|
+
const tone = failed ? "red" : running ? "magenta" : "dim";
|
|
6043
|
+
const lines = shellBodyLines(item, open);
|
|
6044
|
+
const footer = shellFooterText(item, open, lines.length);
|
|
6045
|
+
const shellId = item.shell.id;
|
|
6046
|
+
const verify = actions.verify;
|
|
6047
|
+
useEffect(() => {
|
|
6048
|
+
if (running) verify(shellId);
|
|
6049
|
+
}, [
|
|
6050
|
+
running,
|
|
6051
|
+
shellId,
|
|
6052
|
+
verify
|
|
6053
|
+
]);
|
|
6054
|
+
const press = (modifiers) => {
|
|
6055
|
+
if ((modifiers.meta || modifiers.ctrl) && actions.open) {
|
|
6056
|
+
actions.open(shellId);
|
|
6057
|
+
return;
|
|
6058
|
+
}
|
|
6059
|
+
const next = !open;
|
|
6060
|
+
setOpen(next);
|
|
6061
|
+
if (!next || !item.truncated || item.expanded !== void 0 || item.missing) return;
|
|
6062
|
+
setBusy(true);
|
|
6063
|
+
actions.loadOutput(shellId).finally(() => setBusy(false));
|
|
6064
|
+
};
|
|
6065
|
+
return /* @__PURE__ */ jsx("div", {
|
|
6066
|
+
ref: reveal,
|
|
6067
|
+
className: open ? "term-open" : void 0,
|
|
6068
|
+
children: /* @__PURE__ */ jsxs(WithActions, {
|
|
6069
|
+
actions: /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
6070
|
+
actions.open ? /* @__PURE__ */ jsx(OpenShellAction, { onOpen: () => actions.open?.(shellId) }) : null,
|
|
6071
|
+
running ? /* @__PURE__ */ jsx(KillShellAction, { onKill: () => void actions.kill(shellId) }) : null,
|
|
6072
|
+
/* @__PURE__ */ jsx(BookmarkAction, { id: item.id }),
|
|
6073
|
+
/* @__PURE__ */ jsx(CopyAction, {
|
|
6074
|
+
text: item.shell.command,
|
|
6075
|
+
label: "Copy command"
|
|
6076
|
+
})
|
|
6077
|
+
] }),
|
|
6078
|
+
children: [
|
|
6079
|
+
/* @__PURE__ */ jsx(Pressable, {
|
|
6080
|
+
onPress: press,
|
|
6081
|
+
expanded: open,
|
|
6082
|
+
children: /* @__PURE__ */ jsxs(Row, {
|
|
6083
|
+
glyph: "$",
|
|
6084
|
+
glyphTone: tone,
|
|
6085
|
+
tone: "fg",
|
|
6086
|
+
children: [/* @__PURE__ */ jsx(Ink, {
|
|
6087
|
+
bold: true,
|
|
6088
|
+
tone: "bright",
|
|
6089
|
+
children: shellLabel(item)
|
|
6090
|
+
}), /* @__PURE__ */ jsxs(Ink, {
|
|
6091
|
+
tone: failed ? "red" : "faint",
|
|
6092
|
+
children: [" · ", shellStatusText(item)]
|
|
6093
|
+
})]
|
|
6094
|
+
})
|
|
6095
|
+
}),
|
|
6096
|
+
lines.map((line, index) => /* @__PURE__ */ jsx(Row, {
|
|
6097
|
+
tone: failed ? "red" : "dim",
|
|
6098
|
+
children: line || " "
|
|
6099
|
+
}, index)),
|
|
6100
|
+
footer || busy ? /* @__PURE__ */ jsx(Row, {
|
|
6101
|
+
tone: "faint",
|
|
6102
|
+
children: busy ? "… fetching the full output" : footer
|
|
6103
|
+
}) : null
|
|
6104
|
+
]
|
|
6105
|
+
})
|
|
6106
|
+
});
|
|
6107
|
+
}
|
|
5923
6108
|
function FileRow({ item, href }) {
|
|
5924
6109
|
return /* @__PURE__ */ jsxs(Row, {
|
|
5925
6110
|
glyph: "⤓",
|
|
@@ -6001,7 +6186,7 @@ function TerminalSurface({ fontSize, lineHeight, bleed, affordances, className,
|
|
|
6001
6186
|
//#endregion
|
|
6002
6187
|
//#region src/components/agent/Composer.tsx
|
|
6003
6188
|
const SHELL_PLACEHOLDER = "Run a command on the host…";
|
|
6004
|
-
const SHELL_HINT = "
|
|
6189
|
+
const SHELL_HINT = "$ shell mode · esc to exit";
|
|
6005
6190
|
function Composer({ onSend, onInterrupt, busy, disabled, placeholder = "Message the agent…", commands, skills, clientCommands, onSearchFiles, peers, onShellCommand, attachments, toolbar, layout = "stacked", fontSize, lineHeight, affordances, draft, className, ref }) {
|
|
6006
6191
|
const inline = layout === "inline";
|
|
6007
6192
|
const terminal = useTranscriptVariant() === "terminal";
|
|
@@ -6093,7 +6278,7 @@ function Composer({ onSend, onInterrupt, busy, disabled, placeholder = "Message
|
|
|
6093
6278
|
emptyMessage: "No matching sessions"
|
|
6094
6279
|
}));
|
|
6095
6280
|
if (onShellCommand) configured.push(launchTrigger({
|
|
6096
|
-
char: "
|
|
6281
|
+
char: "$",
|
|
6097
6282
|
accessibilityLabel: "shell mode",
|
|
6098
6283
|
onActivate: () => setShellMode(true)
|
|
6099
6284
|
}));
|
|
@@ -6130,8 +6315,9 @@ function Composer({ onSend, onInterrupt, busy, disabled, placeholder = "Message
|
|
|
6130
6315
|
clear();
|
|
6131
6316
|
focus();
|
|
6132
6317
|
};
|
|
6133
|
-
const leaveShellMode = () => {
|
|
6318
|
+
const leaveShellMode = (restore) => {
|
|
6134
6319
|
setShellMode(false);
|
|
6320
|
+
if (restore) bind.ref.current?.setText(`$${plainText}`);
|
|
6135
6321
|
focus();
|
|
6136
6322
|
};
|
|
6137
6323
|
const hints = [
|
|
@@ -6148,7 +6334,7 @@ function Composer({ onSend, onInterrupt, busy, disabled, placeholder = "Message
|
|
|
6148
6334
|
what: "refer to another session"
|
|
6149
6335
|
} : void 0,
|
|
6150
6336
|
onShellCommand ? {
|
|
6151
|
-
key: "
|
|
6337
|
+
key: "$",
|
|
6152
6338
|
what: "run a shell command"
|
|
6153
6339
|
} : void 0,
|
|
6154
6340
|
{
|
|
@@ -6157,11 +6343,11 @@ function Composer({ onSend, onInterrupt, busy, disabled, placeholder = "Message
|
|
|
6157
6343
|
}
|
|
6158
6344
|
].filter((h) => h !== void 0);
|
|
6159
6345
|
const shellKeys = shellMode ? {
|
|
6160
|
-
onEscape: leaveShellMode,
|
|
6346
|
+
onEscape: () => leaveShellMode(true),
|
|
6161
6347
|
onKeyDown: (e) => {
|
|
6162
6348
|
if (e.key === "Backspace" && isEmpty) {
|
|
6163
6349
|
e.preventDefault();
|
|
6164
|
-
leaveShellMode();
|
|
6350
|
+
leaveShellMode(false);
|
|
6165
6351
|
}
|
|
6166
6352
|
}
|
|
6167
6353
|
} : {
|
|
@@ -6215,8 +6401,8 @@ function Composer({ onSend, onInterrupt, busy, disabled, placeholder = "Message
|
|
|
6215
6401
|
gutter: true,
|
|
6216
6402
|
label: "Leave shell mode",
|
|
6217
6403
|
tone: "magenta",
|
|
6218
|
-
onClick: leaveShellMode,
|
|
6219
|
-
children: "
|
|
6404
|
+
onClick: () => leaveShellMode(false),
|
|
6405
|
+
children: "$"
|
|
6220
6406
|
}) : busy ? /* @__PURE__ */ jsx(GlyphButton, {
|
|
6221
6407
|
gutter: true,
|
|
6222
6408
|
label: "Interrupt",
|
|
@@ -6377,7 +6563,7 @@ function Composer({ onSend, onInterrupt, busy, disabled, placeholder = "Message
|
|
|
6377
6563
|
children: [staged.length > 0 && attachments ? /* @__PURE__ */ jsx(AttachmentStrip, { attachments }) : null, inline ? /* @__PURE__ */ jsxs("div", {
|
|
6378
6564
|
className: "flex items-end gap-1 p-1",
|
|
6379
6565
|
children: [
|
|
6380
|
-
shellMode ? /* @__PURE__ */ jsx(ShellBadge, { onLeave: leaveShellMode }) : attach,
|
|
6566
|
+
shellMode ? /* @__PURE__ */ jsx(ShellBadge, { onLeave: () => leaveShellMode(false) }) : attach,
|
|
6381
6567
|
/* @__PURE__ */ jsx(PromptArea, {
|
|
6382
6568
|
...bind,
|
|
6383
6569
|
triggers,
|
|
@@ -6413,7 +6599,7 @@ function Composer({ onSend, onInterrupt, busy, disabled, placeholder = "Message
|
|
|
6413
6599
|
className: "flex items-center justify-between gap-2 px-2 pb-2",
|
|
6414
6600
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
6415
6601
|
className: "flex min-w-0 items-center gap-1",
|
|
6416
|
-
children: [shellMode ? /* @__PURE__ */ jsx(ShellBadge, { onLeave: leaveShellMode }) : attach, shellMode ? /* @__PURE__ */ jsx("span", {
|
|
6602
|
+
children: [shellMode ? /* @__PURE__ */ jsx(ShellBadge, { onLeave: () => leaveShellMode(false) }) : attach, shellMode ? /* @__PURE__ */ jsx("span", {
|
|
6417
6603
|
className: "text-label text-text-muted",
|
|
6418
6604
|
children: SHELL_HINT
|
|
6419
6605
|
}) : toolbar]
|
|
@@ -6503,7 +6689,7 @@ function ShellBadge({ onLeave }) {
|
|
|
6503
6689
|
title: "Leave shell mode",
|
|
6504
6690
|
onClick: onLeave,
|
|
6505
6691
|
className: "shrink-0 rounded px-1.5 py-0.5 font-mono text-label font-semibold text-[var(--wd-shell-accent)]",
|
|
6506
|
-
children: "
|
|
6692
|
+
children: "$"
|
|
6507
6693
|
});
|
|
6508
6694
|
}
|
|
6509
6695
|
//#endregion
|
|
@@ -7801,6 +7987,296 @@ function useSubagentFrame(options) {
|
|
|
7801
7987
|
};
|
|
7802
7988
|
}
|
|
7803
7989
|
//#endregion
|
|
7990
|
+
//#region src/components/agent/ShellStrip.tsx
|
|
7991
|
+
function ShellStrip({ shell, label, cols, onBack, onKill, terminal, fontSize, lineHeight }) {
|
|
7992
|
+
const running = shell?.status === "running";
|
|
7993
|
+
const failed = shell ? shellInfoFailed(shell) : false;
|
|
7994
|
+
const name = shell ? shellTitle(shell) : label;
|
|
7995
|
+
const status = shell ? shellInfoStatusText(shell) : void 0;
|
|
7996
|
+
const width = cols ?? shell?.cols;
|
|
7997
|
+
const detail = width === void 0 ? void 0 : `${width} cols`;
|
|
7998
|
+
if (terminal) return /* @__PURE__ */ jsx(TerminalSurface, {
|
|
7999
|
+
fontSize,
|
|
8000
|
+
lineHeight,
|
|
8001
|
+
className: "shrink-0",
|
|
8002
|
+
children: /* @__PURE__ */ jsx(WithActions, {
|
|
8003
|
+
actions: running && onKill ? /* @__PURE__ */ jsx(KillShellAction, { onKill }) : null,
|
|
8004
|
+
children: /* @__PURE__ */ jsxs(Row, {
|
|
8005
|
+
glyph: "←",
|
|
8006
|
+
glyphTone: "dim",
|
|
8007
|
+
indent: 1,
|
|
8008
|
+
tone: failed ? "red" : "magenta",
|
|
8009
|
+
children: [
|
|
8010
|
+
/* @__PURE__ */ jsx("button", {
|
|
8011
|
+
type: "button",
|
|
8012
|
+
onClick: onBack,
|
|
8013
|
+
"aria-label": "Back to the session",
|
|
8014
|
+
className: "cursor-pointer text-left",
|
|
8015
|
+
children: name
|
|
8016
|
+
}),
|
|
8017
|
+
status ? /* @__PURE__ */ jsxs(Ink, {
|
|
8018
|
+
tone: failed ? "red" : running ? "magenta" : "dim",
|
|
8019
|
+
children: [" · ", status]
|
|
8020
|
+
}) : null,
|
|
8021
|
+
detail ? /* @__PURE__ */ jsxs(Ink, {
|
|
8022
|
+
tone: "faint",
|
|
8023
|
+
children: [" · ", detail]
|
|
8024
|
+
}) : null
|
|
8025
|
+
]
|
|
8026
|
+
})
|
|
8027
|
+
})
|
|
8028
|
+
});
|
|
8029
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
8030
|
+
className: "flex shrink-0 items-center gap-2 border-b border-border px-3 py-1.5",
|
|
8031
|
+
children: [
|
|
8032
|
+
/* @__PURE__ */ jsxs(Button, {
|
|
8033
|
+
variant: "ghost",
|
|
8034
|
+
size: "sm",
|
|
8035
|
+
onClick: onBack,
|
|
8036
|
+
className: "h-6 gap-1 px-1.5",
|
|
8037
|
+
children: [/* @__PURE__ */ jsx(ArrowLeft, { className: "size-3.5" }), "Back"]
|
|
8038
|
+
}),
|
|
8039
|
+
/* @__PURE__ */ jsx("span", {
|
|
8040
|
+
className: cn("min-w-0 flex-1 truncate font-mono text-body-sm", failed ? "text-danger" : "text-fg-2"),
|
|
8041
|
+
children: name
|
|
8042
|
+
}),
|
|
8043
|
+
status ? /* @__PURE__ */ jsx("span", {
|
|
8044
|
+
className: cn("shrink-0 text-label", failed ? "text-danger" : running ? "text-[var(--wd-shell-accent)]" : "text-fg-3"),
|
|
8045
|
+
children: status
|
|
8046
|
+
}) : null,
|
|
8047
|
+
detail ? /* @__PURE__ */ jsx("span", {
|
|
8048
|
+
className: "shrink-0 text-label text-fg-4",
|
|
8049
|
+
children: detail
|
|
8050
|
+
}) : null,
|
|
8051
|
+
running && onKill ? /* @__PURE__ */ jsx("button", {
|
|
8052
|
+
type: "button",
|
|
8053
|
+
"aria-label": "Kill this shell",
|
|
8054
|
+
title: "Kill this shell",
|
|
8055
|
+
className: "shrink-0 text-label text-fg-3 hover:text-danger",
|
|
8056
|
+
onClick: onKill,
|
|
8057
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-3.5" })
|
|
8058
|
+
}) : null
|
|
8059
|
+
]
|
|
8060
|
+
});
|
|
8061
|
+
}
|
|
8062
|
+
//#endregion
|
|
8063
|
+
//#region src/components/agent/ShellTerminal.tsx
|
|
8064
|
+
function ShellTerminal({ handle, shellId, onEnded, onShell, fontSize, className }) {
|
|
8065
|
+
const host = useRef(null);
|
|
8066
|
+
const term = useRef(null);
|
|
8067
|
+
const fit = useRef(null);
|
|
8068
|
+
const [ready, setReady] = useState(false);
|
|
8069
|
+
const attached = useRef(false);
|
|
8070
|
+
const theme = useDocumentTheme();
|
|
8071
|
+
const onShellRef = useRef(onShell);
|
|
8072
|
+
onShellRef.current = onShell;
|
|
8073
|
+
const shell = useShellTerminal(handle, shellId, {
|
|
8074
|
+
onData: (data) => term.current?.write(data),
|
|
8075
|
+
onAttached: (attachment) => {
|
|
8076
|
+
const instance = term.current;
|
|
8077
|
+
if (!instance) return;
|
|
8078
|
+
instance.reset();
|
|
8079
|
+
if (attachment.scrollback) instance.write(attachment.scrollback);
|
|
8080
|
+
try {
|
|
8081
|
+
fit.current?.fit();
|
|
8082
|
+
} catch {}
|
|
8083
|
+
onShellRef.current?.(attachment.shell);
|
|
8084
|
+
},
|
|
8085
|
+
onEnded: (reason) => {
|
|
8086
|
+
term.current?.write(`\r\n\x1b[2m[${reason}]\x1b[0m\r\n`);
|
|
8087
|
+
onEnded?.(reason);
|
|
8088
|
+
}
|
|
8089
|
+
});
|
|
8090
|
+
const shellRef = useRef(shell);
|
|
8091
|
+
shellRef.current = shell;
|
|
8092
|
+
useEffect(() => {
|
|
8093
|
+
let disposed = false;
|
|
8094
|
+
loadXterm().then(({ Terminal, FitAddon: Fit }) => {
|
|
8095
|
+
if (disposed || !host.current) return;
|
|
8096
|
+
const instance = new Terminal({
|
|
8097
|
+
allowProposedApi: true,
|
|
8098
|
+
convertEol: false,
|
|
8099
|
+
cursorBlink: true,
|
|
8100
|
+
fontSize: fontSize ?? 12,
|
|
8101
|
+
lineHeight: 1.35,
|
|
8102
|
+
fontFamily: "ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace",
|
|
8103
|
+
theme: xtermTheme(document.documentElement.getAttribute("data-theme")),
|
|
8104
|
+
scrollback: 5e3
|
|
8105
|
+
});
|
|
8106
|
+
const addon = new Fit();
|
|
8107
|
+
instance.loadAddon(addon);
|
|
8108
|
+
instance.open(host.current);
|
|
8109
|
+
addon.fit();
|
|
8110
|
+
instance.onData((data) => shellRef.current.write(data));
|
|
8111
|
+
instance.onResize(({ cols, rows }) => shellRef.current.resize({
|
|
8112
|
+
cols,
|
|
8113
|
+
rows
|
|
8114
|
+
}));
|
|
8115
|
+
term.current = instance;
|
|
8116
|
+
fit.current = addon;
|
|
8117
|
+
setReady(true);
|
|
8118
|
+
});
|
|
8119
|
+
return () => {
|
|
8120
|
+
disposed = true;
|
|
8121
|
+
attached.current = false;
|
|
8122
|
+
shellRef.current.detach();
|
|
8123
|
+
term.current?.dispose();
|
|
8124
|
+
term.current = null;
|
|
8125
|
+
fit.current = null;
|
|
8126
|
+
setReady(false);
|
|
8127
|
+
};
|
|
8128
|
+
}, []);
|
|
8129
|
+
useEffect(() => {
|
|
8130
|
+
attached.current = false;
|
|
8131
|
+
}, [shellId]);
|
|
8132
|
+
useEffect(() => {
|
|
8133
|
+
const instance = term.current;
|
|
8134
|
+
if (!ready || !handle || shellId === void 0 || !instance || attached.current) return;
|
|
8135
|
+
attached.current = true;
|
|
8136
|
+
shellRef.current.attach({
|
|
8137
|
+
cols: instance.cols,
|
|
8138
|
+
rows: instance.rows
|
|
8139
|
+
});
|
|
8140
|
+
}, [
|
|
8141
|
+
ready,
|
|
8142
|
+
handle,
|
|
8143
|
+
shellId
|
|
8144
|
+
]);
|
|
8145
|
+
useEffect(() => {
|
|
8146
|
+
const instance = term.current;
|
|
8147
|
+
if (instance) instance.options.theme = xtermTheme(theme);
|
|
8148
|
+
}, [theme]);
|
|
8149
|
+
useEffect(() => {
|
|
8150
|
+
const node = host.current;
|
|
8151
|
+
if (!node || !ready) return;
|
|
8152
|
+
const observer = new ResizeObserver(() => {
|
|
8153
|
+
try {
|
|
8154
|
+
fit.current?.fit();
|
|
8155
|
+
} catch {}
|
|
8156
|
+
});
|
|
8157
|
+
observer.observe(node);
|
|
8158
|
+
return () => observer.disconnect();
|
|
8159
|
+
}, [ready]);
|
|
8160
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
8161
|
+
className: cn("relative min-h-0 flex-1 overflow-hidden px-2 py-1", className),
|
|
8162
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
8163
|
+
ref: host,
|
|
8164
|
+
className: "h-full w-full",
|
|
8165
|
+
onClick: () => term.current?.focus()
|
|
8166
|
+
}), ready && shell.status !== "idle" ? null : /* @__PURE__ */ jsx("div", {
|
|
8167
|
+
className: "absolute inset-0 grid place-items-center",
|
|
8168
|
+
children: /* @__PURE__ */ jsx(Spinner, {})
|
|
8169
|
+
})]
|
|
8170
|
+
});
|
|
8171
|
+
}
|
|
8172
|
+
function useDocumentTheme() {
|
|
8173
|
+
const [theme, setTheme] = useState(() => typeof document === "undefined" ? null : document.documentElement.getAttribute("data-theme"));
|
|
8174
|
+
useEffect(() => {
|
|
8175
|
+
const root = document.documentElement;
|
|
8176
|
+
const sync = () => setTheme(root.getAttribute("data-theme"));
|
|
8177
|
+
sync();
|
|
8178
|
+
const observer = new MutationObserver(sync);
|
|
8179
|
+
observer.observe(root, {
|
|
8180
|
+
attributes: true,
|
|
8181
|
+
attributeFilter: ["data-theme"]
|
|
8182
|
+
});
|
|
8183
|
+
return () => observer.disconnect();
|
|
8184
|
+
}, []);
|
|
8185
|
+
return theme;
|
|
8186
|
+
}
|
|
8187
|
+
function xtermTheme(theme) {
|
|
8188
|
+
return theme === "light" ? {
|
|
8189
|
+
background: "#00000000",
|
|
8190
|
+
foreground: "#1f2328",
|
|
8191
|
+
cursor: "#1f2328",
|
|
8192
|
+
selectionBackground: "#b9c7d980"
|
|
8193
|
+
} : {
|
|
8194
|
+
background: "#00000000",
|
|
8195
|
+
foreground: "#d4d4d4",
|
|
8196
|
+
cursor: "#d4d4d4",
|
|
8197
|
+
selectionBackground: "#3a4a5f80"
|
|
8198
|
+
};
|
|
8199
|
+
}
|
|
8200
|
+
let xtermPromise;
|
|
8201
|
+
function loadXterm() {
|
|
8202
|
+
xtermPromise ??= (async () => {
|
|
8203
|
+
const [core, fitAddon] = await Promise.all([import("@xterm/xterm"), import("@xterm/addon-fit")]);
|
|
8204
|
+
return {
|
|
8205
|
+
Terminal: core.Terminal,
|
|
8206
|
+
FitAddon: fitAddon.FitAddon
|
|
8207
|
+
};
|
|
8208
|
+
})();
|
|
8209
|
+
return xtermPromise;
|
|
8210
|
+
}
|
|
8211
|
+
//#endregion
|
|
8212
|
+
//#region src/components/agent/use-shell-frame.ts
|
|
8213
|
+
function useShellFrame(options) {
|
|
8214
|
+
const { sessionId, items, session, shells, reveal, openShell, onShellChange } = options;
|
|
8215
|
+
const [shellId, setShellId] = useState(void 0);
|
|
8216
|
+
const [returnReveal, setReturnReveal] = useState(void 0);
|
|
8217
|
+
useEffect(() => {
|
|
8218
|
+
setShellId(void 0);
|
|
8219
|
+
setReturnReveal(void 0);
|
|
8220
|
+
}, [sessionId]);
|
|
8221
|
+
const rowIdRef = useRef(void 0);
|
|
8222
|
+
const row = useMemo(() => shellId === void 0 ? void 0 : items.find((item) => item.kind === "shell" && item.shell.id === shellId), [items, shellId]);
|
|
8223
|
+
rowIdRef.current = row?.id;
|
|
8224
|
+
const leaveShell = useCallback(() => {
|
|
8225
|
+
setShellId((current) => {
|
|
8226
|
+
const rowId = rowIdRef.current;
|
|
8227
|
+
if (current !== void 0 && rowId !== void 0) setReturnReveal({
|
|
8228
|
+
toolUseId: rowId,
|
|
8229
|
+
nonce: Date.now()
|
|
8230
|
+
});
|
|
8231
|
+
});
|
|
8232
|
+
}, []);
|
|
8233
|
+
const openShellNonce = openShell?.nonce;
|
|
8234
|
+
const openShellId = openShell?.shellId;
|
|
8235
|
+
useEffect(() => {
|
|
8236
|
+
if (openShellId === void 0) leaveShell();
|
|
8237
|
+
else setShellId(openShellId);
|
|
8238
|
+
}, [openShellNonce]);
|
|
8239
|
+
const revealNonce = reveal?.nonce;
|
|
8240
|
+
useEffect(() => {
|
|
8241
|
+
if (revealNonce === void 0) return;
|
|
8242
|
+
setShellId(void 0);
|
|
8243
|
+
}, [revealNonce]);
|
|
8244
|
+
useEffect(() => {
|
|
8245
|
+
if (shellId === void 0) return;
|
|
8246
|
+
const onKey = (event) => {
|
|
8247
|
+
if (event.key !== "Escape" || event.defaultPrevented) return;
|
|
8248
|
+
leaveShell();
|
|
8249
|
+
};
|
|
8250
|
+
window.addEventListener("keydown", onKey);
|
|
8251
|
+
return () => window.removeEventListener("keydown", onKey);
|
|
8252
|
+
}, [shellId, leaveShell]);
|
|
8253
|
+
const onShellChangeRef = useRef(onShellChange);
|
|
8254
|
+
onShellChangeRef.current = onShellChange;
|
|
8255
|
+
const reportedShellId = useRef(void 0);
|
|
8256
|
+
useEffect(() => {
|
|
8257
|
+
if (reportedShellId.current === shellId) return;
|
|
8258
|
+
reportedShellId.current = shellId;
|
|
8259
|
+
onShellChangeRef.current?.(shellId);
|
|
8260
|
+
}, [shellId]);
|
|
8261
|
+
const shell = useMemo(() => {
|
|
8262
|
+
if (shellId === void 0) return;
|
|
8263
|
+
return row?.shell ?? shells?.find((record) => record.id === shellId) ?? session?.shells?.find((record) => record.id === shellId);
|
|
8264
|
+
}, [
|
|
8265
|
+
row,
|
|
8266
|
+
shells,
|
|
8267
|
+
session,
|
|
8268
|
+
shellId
|
|
8269
|
+
]);
|
|
8270
|
+
return {
|
|
8271
|
+
shellId,
|
|
8272
|
+
enterShell: setShellId,
|
|
8273
|
+
leaveShell,
|
|
8274
|
+
returnReveal,
|
|
8275
|
+
shell,
|
|
8276
|
+
label: shell ? shell.label || shell.command.split("\n")[0] || "shell" : "shell"
|
|
8277
|
+
};
|
|
8278
|
+
}
|
|
8279
|
+
//#endregion
|
|
7804
8280
|
//#region src/components/agent/QuestionPrompt.tsx
|
|
7805
8281
|
const QUESTION_BEHAVIORS = [
|
|
7806
8282
|
{
|
|
@@ -9516,6 +9992,14 @@ function itemHeight(item, m) {
|
|
|
9516
9992
|
case "notice": return rowH(item.text, m, { extraPx });
|
|
9517
9993
|
case "compaction": return rowH(compactionText(item), m, { extraPx });
|
|
9518
9994
|
case "file_delivered": return rowH(`${item.path} · ${formatBytes(item.bytes)}` + (item.description ? ` · ${item.description}` : ""), m, { extraPx });
|
|
9995
|
+
case "shell": {
|
|
9996
|
+
const lines = shellBodyLines(item, false);
|
|
9997
|
+
let acc = rowH(shellHeaderText(item), m, { extraPx });
|
|
9998
|
+
for (const line of lines) acc = add(acc, rowH(line || " ", m, { extraPx }));
|
|
9999
|
+
const footer = shellFooterText(item, false, lines.length);
|
|
10000
|
+
if (footer) acc = add(acc, rowH(footer, m, { extraPx }));
|
|
10001
|
+
return acc;
|
|
10002
|
+
}
|
|
9519
10003
|
default: return {
|
|
9520
10004
|
px: 0,
|
|
9521
10005
|
exact: false
|
|
@@ -9542,6 +10026,7 @@ function nearestMember$1(cluster, y) {
|
|
|
9542
10026
|
const LANE$1 = {
|
|
9543
10027
|
user: "l",
|
|
9544
10028
|
subagent: "l",
|
|
10029
|
+
shell: "l",
|
|
9545
10030
|
turn: "r",
|
|
9546
10031
|
turnFailed: "r",
|
|
9547
10032
|
toolFailed: "r",
|
|
@@ -9559,11 +10044,13 @@ const LOUDNESS$1 = {
|
|
|
9559
10044
|
turn: 2,
|
|
9560
10045
|
bookmark: 1,
|
|
9561
10046
|
subagent: 1,
|
|
10047
|
+
shell: 1,
|
|
9562
10048
|
recap: 0
|
|
9563
10049
|
};
|
|
9564
10050
|
const KIND_NAME$1 = {
|
|
9565
10051
|
user: "you",
|
|
9566
10052
|
subagent: "sub-agent",
|
|
10053
|
+
shell: "shell",
|
|
9567
10054
|
turn: "response · turn end",
|
|
9568
10055
|
turnFailed: "turn failed",
|
|
9569
10056
|
toolFailed: "tool failed",
|
|
@@ -9585,6 +10072,7 @@ function excerpt$1(item) {
|
|
|
9585
10072
|
case "assistant_text":
|
|
9586
10073
|
case "thinking":
|
|
9587
10074
|
case "notice": return item.text;
|
|
10075
|
+
case "shell": return item.shell.command;
|
|
9588
10076
|
case "tool_call": return `${item.name}(${toolInputPreview(item.input)})`;
|
|
9589
10077
|
case "turn_result": return doneLine$1(item);
|
|
9590
10078
|
case "file_delivered": return item.path;
|
|
@@ -9637,6 +10125,11 @@ function buildClusters(props, railH) {
|
|
|
9637
10125
|
itemIndex: index,
|
|
9638
10126
|
rowIndex: rowIndexFor(index)
|
|
9639
10127
|
});
|
|
10128
|
+
else if (item.kind === "shell") marks.push({
|
|
10129
|
+
kind: "shell",
|
|
10130
|
+
itemIndex: index,
|
|
10131
|
+
rowIndex: rowIndexFor(index)
|
|
10132
|
+
});
|
|
9640
10133
|
else if (item.kind === "tool_call" && (item.status === "failed" || item.result?.isError === true) && rowOutcome.get(rowIndexFor(index)) === index) marks.push({
|
|
9641
10134
|
kind: "toolFailed",
|
|
9642
10135
|
itemIndex: index,
|
|
@@ -9950,6 +10443,7 @@ function nearestMember(cluster, y) {
|
|
|
9950
10443
|
const LANE = {
|
|
9951
10444
|
user: "l",
|
|
9952
10445
|
subagent: "l",
|
|
10446
|
+
shell: "l",
|
|
9953
10447
|
turn: "r",
|
|
9954
10448
|
turnFailed: "r",
|
|
9955
10449
|
toolFailed: "r",
|
|
@@ -9967,11 +10461,13 @@ const LOUDNESS = {
|
|
|
9967
10461
|
turn: 2,
|
|
9968
10462
|
bookmark: 1,
|
|
9969
10463
|
subagent: 1,
|
|
10464
|
+
shell: 1,
|
|
9970
10465
|
recap: 0
|
|
9971
10466
|
};
|
|
9972
10467
|
const KIND_NAME = {
|
|
9973
10468
|
user: "you",
|
|
9974
10469
|
subagent: "sub-agent",
|
|
10470
|
+
shell: "shell",
|
|
9975
10471
|
turn: "response · turn end",
|
|
9976
10472
|
turnFailed: "turn failed",
|
|
9977
10473
|
toolFailed: "tool failed",
|
|
@@ -9989,6 +10485,7 @@ function excerpt(item) {
|
|
|
9989
10485
|
case "assistant_text":
|
|
9990
10486
|
case "thinking":
|
|
9991
10487
|
case "notice": return item.text;
|
|
10488
|
+
case "shell": return item.shell.command;
|
|
9992
10489
|
case "tool_call": return `${item.name}(${toolInputPreview(item.input)})`;
|
|
9993
10490
|
case "turn_result": return doneLine(item);
|
|
9994
10491
|
case "file_delivered": return item.path;
|
|
@@ -10031,6 +10528,10 @@ function buildMarks(items, { frameParentId, bookmarks = [], recapItemIndex } = {
|
|
|
10031
10528
|
kind: "error",
|
|
10032
10529
|
itemIndex: index
|
|
10033
10530
|
});
|
|
10531
|
+
else if (item.kind === "shell") marks.push({
|
|
10532
|
+
kind: "shell",
|
|
10533
|
+
itemIndex: index
|
|
10534
|
+
});
|
|
10034
10535
|
else if (item.kind === "tool_call" && parentOf(item) === frameParentId && (item.status === "failed" || item.result?.isError === true)) marks.push({
|
|
10035
10536
|
kind: "toolFailed",
|
|
10036
10537
|
itemIndex: index
|
|
@@ -10463,6 +10964,7 @@ function TerminalItemView({ item, fileUrl }) {
|
|
|
10463
10964
|
item,
|
|
10464
10965
|
href: fileUrl?.(item.path)
|
|
10465
10966
|
});
|
|
10967
|
+
case "shell": return /* @__PURE__ */ jsx(ShellRow, { item });
|
|
10466
10968
|
default: return null;
|
|
10467
10969
|
}
|
|
10468
10970
|
}
|
|
@@ -10988,9 +11490,80 @@ function TranscriptItemView({ item, fileUrl, attachmentUrl, hostImage, terminal
|
|
|
10988
11490
|
item,
|
|
10989
11491
|
href: fileUrl?.(item.path)
|
|
10990
11492
|
});
|
|
11493
|
+
case "shell": return /* @__PURE__ */ jsx(ShellCard, { item });
|
|
10991
11494
|
default: return null;
|
|
10992
11495
|
}
|
|
10993
11496
|
}
|
|
11497
|
+
function ShellCard({ item }) {
|
|
11498
|
+
const [open, setOpen] = useState(false);
|
|
11499
|
+
const actions = useShellActions();
|
|
11500
|
+
const running = item.shell.status === "running";
|
|
11501
|
+
const failed = shellFailed(item);
|
|
11502
|
+
const lines = shellBodyLines(item, open);
|
|
11503
|
+
const footer = shellFooterText(item, open, lines.length);
|
|
11504
|
+
const shellId = item.shell.id;
|
|
11505
|
+
const verify = actions.verify;
|
|
11506
|
+
useEffect(() => {
|
|
11507
|
+
if (running) verify(shellId);
|
|
11508
|
+
}, [
|
|
11509
|
+
running,
|
|
11510
|
+
shellId,
|
|
11511
|
+
verify
|
|
11512
|
+
]);
|
|
11513
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
11514
|
+
"data-slot": "shell",
|
|
11515
|
+
className: "overflow-hidden rounded-md border border-border bg-surface",
|
|
11516
|
+
children: [
|
|
11517
|
+
/* @__PURE__ */ jsxs("div", {
|
|
11518
|
+
className: "flex items-center gap-2 px-3 py-1.5",
|
|
11519
|
+
children: [
|
|
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")
|
|
11559
|
+
}) : null,
|
|
11560
|
+
footer ? /* @__PURE__ */ jsx("div", {
|
|
11561
|
+
className: "px-3 pb-2 text-label text-fg-4",
|
|
11562
|
+
children: footer
|
|
11563
|
+
}) : null
|
|
11564
|
+
]
|
|
11565
|
+
});
|
|
11566
|
+
}
|
|
10994
11567
|
function CompactionRow({ item }) {
|
|
10995
11568
|
return /* @__PURE__ */ jsxs("div", {
|
|
10996
11569
|
"data-slot": "compaction",
|
|
@@ -11822,7 +12395,7 @@ const INTERACTIVE = [
|
|
|
11822
12395
|
"[role=\"radio\"]",
|
|
11823
12396
|
"[role=\"tab\"]"
|
|
11824
12397
|
].join(",");
|
|
11825
|
-
function SessionPanel({ client, sessionId, header, panelSurface = "internal", statusSurface = "internal", statusPlacement = "top", onOpenPanel, onVitals, transcriptVariant = "cards", transcriptDensity = "comfortable", transcriptFont = "sans", affordances, terminalMetrics, scrubber = false, bookmarks, peerMentions = true, onToggleBookmark, reveal, subagents, openSubagent, onSubagentChange, stickyPrompt = false, controlsSurface = "internal", onControls, focusComposerOnClick = false, unseen, readOnly = false, approvalPrompts, toolHost, clientTools, cacheTranscript, emptyState, onLinkClick, onOpenFile, fontSize, className }) {
|
|
12398
|
+
function SessionPanel({ client, sessionId, header, panelSurface = "internal", statusSurface = "internal", statusPlacement = "top", onOpenPanel, onVitals, transcriptVariant = "cards", transcriptDensity = "comfortable", 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 }) {
|
|
11826
12399
|
const effectiveTermFontSize = terminalMetrics?.fontSize ?? fontSize;
|
|
11827
12400
|
const effectiveTermLineHeight = terminalMetrics?.lineHeight ?? (fontSize !== void 0 ? Math.round(fontSize * (18 / 13)) : void 0);
|
|
11828
12401
|
const external = panelSurface === "external";
|
|
@@ -11833,10 +12406,30 @@ function SessionPanel({ client, sessionId, header, panelSurface = "internal", st
|
|
|
11833
12406
|
const [panel, setPanel] = useState();
|
|
11834
12407
|
const [showCompletedTasks, setShowCompletedTasks] = useState(false);
|
|
11835
12408
|
const [taskReveal, setTaskReveal] = useState();
|
|
11836
|
-
const { state, connection, replaying, protocolMismatch, shell, pricing, models, effectiveModel, handle, send, runShell, approve, deny, interrupt, clearContext, setModel, setPermissionMode, reconnectNow, loadFullResult } = useClaudeSession(client, sessionId, {
|
|
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, {
|
|
11837
12410
|
onProtocolError: setProtocolError,
|
|
11838
12411
|
cacheTranscript
|
|
11839
12412
|
});
|
|
12413
|
+
const { shellId: framedShellId, enterShell, leaveShell, returnReveal: shellReturnReveal, shell: framedShell, label: framedShellLabel } = useShellFrame({
|
|
12414
|
+
sessionId,
|
|
12415
|
+
items: state.items,
|
|
12416
|
+
session: state.session,
|
|
12417
|
+
shells,
|
|
12418
|
+
reveal,
|
|
12419
|
+
openShell,
|
|
12420
|
+
onShellChange
|
|
12421
|
+
});
|
|
12422
|
+
const shellActions = useMemo(() => ({
|
|
12423
|
+
loadOutput: loadShellOutput,
|
|
12424
|
+
verify: verifyShell,
|
|
12425
|
+
kill: killShell,
|
|
12426
|
+
open: enterShell
|
|
12427
|
+
}), [
|
|
12428
|
+
loadShellOutput,
|
|
12429
|
+
verifyShell,
|
|
12430
|
+
killShell,
|
|
12431
|
+
enterShell
|
|
12432
|
+
]);
|
|
11840
12433
|
useEffect(() => setProtocolError(void 0), [sessionId]);
|
|
11841
12434
|
const { subagentId, enterSubagent, leaveSubagent, returnReveal, frameItems: subagentFrameItems, task: subagentTask, fallbackLabel: subagentFallbackLabel } = useSubagentFrame({
|
|
11842
12435
|
sessionId,
|
|
@@ -11846,6 +12439,10 @@ function SessionPanel({ client, sessionId, header, panelSurface = "internal", st
|
|
|
11846
12439
|
openSubagent,
|
|
11847
12440
|
onSubagentChange
|
|
11848
12441
|
});
|
|
12442
|
+
const frameReturnReveal = useMemo(() => {
|
|
12443
|
+
if (returnReveal && shellReturnReveal) return returnReveal.nonce >= shellReturnReveal.nonce ? returnReveal : shellReturnReveal;
|
|
12444
|
+
return returnReveal ?? shellReturnReveal;
|
|
12445
|
+
}, [returnReveal, shellReturnReveal]);
|
|
11849
12446
|
const [caughtUp, setCaughtUp] = useState(false);
|
|
11850
12447
|
useEffect(() => {
|
|
11851
12448
|
setCaughtUp(false);
|
|
@@ -12171,229 +12768,245 @@ function SessionPanel({ client, sessionId, header, panelSurface = "internal", st
|
|
|
12171
12768
|
value: fileLinks,
|
|
12172
12769
|
children: /* @__PURE__ */ jsx(ToolResultFetchProvider, {
|
|
12173
12770
|
value: loadFullResult,
|
|
12174
|
-
children: /* @__PURE__ */ jsx(
|
|
12175
|
-
value:
|
|
12176
|
-
children: /* @__PURE__ */ jsx(
|
|
12177
|
-
value:
|
|
12178
|
-
children: /* @__PURE__ */
|
|
12179
|
-
|
|
12180
|
-
|
|
12181
|
-
|
|
12182
|
-
|
|
12183
|
-
|
|
12184
|
-
|
|
12185
|
-
|
|
12186
|
-
|
|
12187
|
-
|
|
12188
|
-
|
|
12189
|
-
|
|
12190
|
-
|
|
12191
|
-
|
|
12192
|
-
protocolMismatch,
|
|
12193
|
-
", this build renders v",
|
|
12194
|
-
PROTOCOL_VERSION,
|
|
12195
|
-
". Some events may not render."
|
|
12196
|
-
]
|
|
12197
|
-
}) : null,
|
|
12198
|
-
protocolError ? /* @__PURE__ */ jsx(Notice, {
|
|
12199
|
-
level: "error",
|
|
12200
|
-
onDismiss: () => setProtocolError(void 0),
|
|
12201
|
-
children: protocolError
|
|
12202
|
-
}) : null,
|
|
12203
|
-
subagentId !== void 0 ? /* @__PURE__ */ jsx(SubagentStrip, {
|
|
12204
|
-
task: subagentTask,
|
|
12205
|
-
items: subagentFrameItems,
|
|
12206
|
-
label: subagentFallbackLabel,
|
|
12207
|
-
onBack: leaveSubagent,
|
|
12208
|
-
terminal,
|
|
12209
|
-
fontSize: effectiveTermFontSize,
|
|
12210
|
-
lineHeight: effectiveTermLineHeight
|
|
12211
|
-
}) : null,
|
|
12212
|
-
/* @__PURE__ */ jsx(BookmarkProvider, {
|
|
12213
|
-
value: bookmarkHandle,
|
|
12214
|
-
children: /* @__PURE__ */ jsx(Transcript, {
|
|
12215
|
-
state,
|
|
12216
|
-
fileUrl: sessionId ? (path) => client.sessionFileUrl(sessionId, path) : void 0,
|
|
12217
|
-
attachmentUrl: sessionId ? (id) => client.attachmentUrl(sessionId, id) : void 0,
|
|
12218
|
-
canBrowseFiles: hostFiles.available,
|
|
12219
|
-
sessionNames: peers.names,
|
|
12220
|
-
hostImage,
|
|
12221
|
-
variant: transcriptVariant,
|
|
12222
|
-
density: transcriptDensity,
|
|
12223
|
-
fontSize: effectiveTermFontSize,
|
|
12224
|
-
lineHeight: effectiveTermLineHeight,
|
|
12225
|
-
affordances,
|
|
12226
|
-
stickyPrompt,
|
|
12227
|
-
scrubber,
|
|
12228
|
-
bookmarks,
|
|
12229
|
-
replaying,
|
|
12230
|
-
catchUp: catchUp && newCount > 0 ? {
|
|
12231
|
-
from: catchUp.itemCount,
|
|
12232
|
-
since: catchUp.since
|
|
12233
|
-
} : void 0,
|
|
12234
|
-
reveal: taskReveal ?? returnReveal ?? reveal,
|
|
12235
|
-
frame: subagentId === void 0 ? void 0 : { parentToolUseId: subagentId },
|
|
12236
|
-
onOpenSubagent: enterSubagent,
|
|
12237
|
-
emptyState,
|
|
12238
|
-
jumpToRecapRef: jumpToRecap,
|
|
12239
|
-
repinRef: repinTranscript
|
|
12240
|
-
}, subagentId ?? "session")
|
|
12241
|
-
}),
|
|
12242
|
-
catchUp && newCount > 0 && !replaying && subagentId === void 0 ? /* @__PURE__ */ jsx("div", {
|
|
12243
|
-
className: "px-3 pb-1",
|
|
12244
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
12245
|
-
"data-slot": "catch-up",
|
|
12246
|
-
className: "mx-auto flex w-full max-w-[var(--wd-transcript-max-width)] items-center gap-2 text-label text-fg-3",
|
|
12771
|
+
children: /* @__PURE__ */ jsx(ShellActionsProvider, {
|
|
12772
|
+
value: shellActions,
|
|
12773
|
+
children: /* @__PURE__ */ jsx(ToolTitleProvider, {
|
|
12774
|
+
value: state.toolTitles,
|
|
12775
|
+
children: /* @__PURE__ */ jsx(ToolResultImageProvider, {
|
|
12776
|
+
value: resultImages,
|
|
12777
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
12778
|
+
ref: panelRef,
|
|
12779
|
+
"data-slot": "session-panel",
|
|
12780
|
+
"data-agent-font": transcriptFont,
|
|
12781
|
+
onClick: handleClick,
|
|
12782
|
+
className: cn("flex h-full min-h-0 flex-col overflow-hidden bg-bg", className),
|
|
12783
|
+
style: fontSize !== void 0 ? { "--wd-font-size": `${Math.round(fontSize)}px` } : void 0,
|
|
12784
|
+
children: [
|
|
12785
|
+
headerTakesActions ? header({ actions: menu }) : header,
|
|
12786
|
+
statusPlacement === "top" ? statusBar : null,
|
|
12787
|
+
protocolMismatch !== void 0 ? /* @__PURE__ */ jsxs(Notice, {
|
|
12788
|
+
level: "warning",
|
|
12247
12789
|
children: [
|
|
12248
|
-
|
|
12249
|
-
|
|
12250
|
-
|
|
12251
|
-
|
|
12252
|
-
|
|
12253
|
-
/* @__PURE__ */ jsxs("span", {
|
|
12254
|
-
className: "min-w-0 flex-1 truncate",
|
|
12255
|
-
children: [
|
|
12256
|
-
newCount,
|
|
12257
|
-
" new ",
|
|
12258
|
-
newCount === 1 ? "row" : "rows",
|
|
12259
|
-
catchUp.since !== void 0 ? ` since you were last here` : ""
|
|
12260
|
-
]
|
|
12261
|
-
}),
|
|
12262
|
-
/* @__PURE__ */ jsx("button", {
|
|
12263
|
-
type: "button",
|
|
12264
|
-
onClick: () => jumpToRecap.current?.(),
|
|
12265
|
-
className: "shrink-0 underline-offset-2 hover:text-fg-1 hover:underline",
|
|
12266
|
-
children: "jump"
|
|
12267
|
-
}),
|
|
12268
|
-
/* @__PURE__ */ jsx("button", {
|
|
12269
|
-
type: "button",
|
|
12270
|
-
onClick: () => setCaughtUp(true),
|
|
12271
|
-
className: "shrink-0 underline-offset-2 hover:text-fg-1 hover:underline",
|
|
12272
|
-
children: "dismiss"
|
|
12273
|
-
})
|
|
12790
|
+
"Server speaks protocol v",
|
|
12791
|
+
protocolMismatch,
|
|
12792
|
+
", this build renders v",
|
|
12793
|
+
PROTOCOL_VERSION,
|
|
12794
|
+
". Some events may not render."
|
|
12274
12795
|
]
|
|
12275
|
-
})
|
|
12276
|
-
|
|
12277
|
-
|
|
12278
|
-
|
|
12279
|
-
|
|
12796
|
+
}) : null,
|
|
12797
|
+
protocolError ? /* @__PURE__ */ jsx(Notice, {
|
|
12798
|
+
level: "error",
|
|
12799
|
+
onDismiss: () => setProtocolError(void 0),
|
|
12800
|
+
children: protocolError
|
|
12801
|
+
}) : null,
|
|
12802
|
+
framedShellId !== void 0 ? /* @__PURE__ */ jsx(ShellStrip, {
|
|
12803
|
+
shell: framedShell,
|
|
12804
|
+
label: framedShellLabel,
|
|
12805
|
+
onBack: leaveShell,
|
|
12806
|
+
onKill: () => void killShell(framedShellId),
|
|
12280
12807
|
terminal,
|
|
12281
|
-
|
|
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,
|
|
12816
|
+
terminal,
|
|
12817
|
+
fontSize: effectiveTermFontSize,
|
|
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,
|
|
12282
12835
|
fontSize: effectiveTermFontSize,
|
|
12283
|
-
lineHeight: effectiveTermLineHeight
|
|
12284
|
-
|
|
12285
|
-
|
|
12286
|
-
|
|
12287
|
-
|
|
12288
|
-
|
|
12289
|
-
|
|
12290
|
-
|
|
12291
|
-
|
|
12292
|
-
},
|
|
12293
|
-
|
|
12294
|
-
|
|
12295
|
-
|
|
12296
|
-
|
|
12297
|
-
|
|
12298
|
-
|
|
12299
|
-
|
|
12300
|
-
onApprove: approve,
|
|
12301
|
-
onDeny: deny
|
|
12302
|
-
}, request.id);
|
|
12303
|
-
return isQuestion ? /* @__PURE__ */ jsx(QuestionPrompt, {
|
|
12304
|
-
request,
|
|
12305
|
-
onAnswer: approve,
|
|
12306
|
-
onDismiss: (id) => deny(id, "Question dismissed by user")
|
|
12307
|
-
}, request.id) : /* @__PURE__ */ jsx(PermissionPrompt, {
|
|
12308
|
-
request,
|
|
12309
|
-
onApprove: approve,
|
|
12310
|
-
onDeny: deny
|
|
12311
|
-
}, request.id);
|
|
12312
|
-
})
|
|
12313
|
-
})
|
|
12314
|
-
}) : null,
|
|
12315
|
-
readOnly || subagentId !== void 0 ? null : /* @__PURE__ */ jsx(Fragment$1, { children: /* @__PURE__ */ jsx(Composer, {
|
|
12316
|
-
ref: composerRef,
|
|
12317
|
-
onSend: handleSend,
|
|
12318
|
-
onInterrupt: interrupt,
|
|
12319
|
-
busy,
|
|
12320
|
-
disabled: ended || !sessionId,
|
|
12321
|
-
commands: capabilities.slashCommands ? state.commands : void 0,
|
|
12322
|
-
skills: capabilities.skillsList ? state.skills : void 0,
|
|
12323
|
-
clientCommands,
|
|
12324
|
-
attachments,
|
|
12325
|
-
draft,
|
|
12326
|
-
onSearchFiles: hostFiles.available ? searchComposerFiles : void 0,
|
|
12327
|
-
peers: peers.peers,
|
|
12328
|
-
onShellCommand: shell ? runShell : void 0,
|
|
12329
|
-
layout: controlsExternal ? "inline" : "stacked",
|
|
12330
|
-
toolbar: controlsExternal ? void 0 : sessionControls,
|
|
12331
|
-
fontSize: effectiveTermFontSize,
|
|
12332
|
-
lineHeight: effectiveTermLineHeight,
|
|
12333
|
-
affordances
|
|
12334
|
-
}) }),
|
|
12335
|
-
statusPlacement === "bottom" ? statusBar : null,
|
|
12336
|
-
!external ? /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
12337
|
-
/* @__PURE__ */ jsx(SessionInfoDialog, {
|
|
12338
|
-
state,
|
|
12339
|
-
client,
|
|
12340
|
-
sessionId,
|
|
12341
|
-
open: panel === "info",
|
|
12342
|
-
onOpenChange: (next) => setPanel(next ? "info" : void 0)
|
|
12343
|
-
}),
|
|
12344
|
-
/* @__PURE__ */ jsx(ContextDialog, {
|
|
12345
|
-
usage: state.contextUsage,
|
|
12346
|
-
engine: state.engine ?? "claude",
|
|
12347
|
-
open: panel === "context",
|
|
12348
|
-
onOpenChange: (next) => setPanel(next ? "context" : void 0)
|
|
12349
|
-
}),
|
|
12350
|
-
/* @__PURE__ */ jsx(UsageDialog, {
|
|
12351
|
-
rateLimits: windows,
|
|
12352
|
-
subscriptionType: state.subscriptionType,
|
|
12353
|
-
engine: state.engine ?? "claude",
|
|
12354
|
-
totalCostUsd: state.totalCostUsd,
|
|
12355
|
-
costUsd: state.costUsd,
|
|
12356
|
-
usageByModel: state.usageByModel,
|
|
12357
|
-
pricing,
|
|
12358
|
-
spend: profileSpend,
|
|
12359
|
-
updatedAt: usageUpdatedAt,
|
|
12360
|
-
open: panel === "usage",
|
|
12361
|
-
onOpenChange: (next) => setPanel(next ? "usage" : void 0)
|
|
12362
|
-
}),
|
|
12363
|
-
/* @__PURE__ */ jsx(McpDialog, {
|
|
12364
|
-
client,
|
|
12365
|
-
sessionId,
|
|
12366
|
-
canManageServers: capabilities.mcpServerActions,
|
|
12367
|
-
open: panel === "mcp",
|
|
12368
|
-
onOpenChange: (next) => setPanel(next ? "mcp" : void 0)
|
|
12836
|
+
lineHeight: effectiveTermLineHeight,
|
|
12837
|
+
affordances,
|
|
12838
|
+
stickyPrompt,
|
|
12839
|
+
scrubber,
|
|
12840
|
+
bookmarks,
|
|
12841
|
+
replaying,
|
|
12842
|
+
catchUp: catchUp && newCount > 0 ? {
|
|
12843
|
+
from: catchUp.itemCount,
|
|
12844
|
+
since: catchUp.since
|
|
12845
|
+
} : void 0,
|
|
12846
|
+
reveal: taskReveal ?? frameReturnReveal ?? reveal,
|
|
12847
|
+
frame: subagentId === void 0 ? void 0 : { parentToolUseId: subagentId },
|
|
12848
|
+
onOpenSubagent: enterSubagent,
|
|
12849
|
+
emptyState,
|
|
12850
|
+
jumpToRecapRef: jumpToRecap,
|
|
12851
|
+
repinRef: repinTranscript
|
|
12852
|
+
}, subagentId ?? "session")
|
|
12369
12853
|
}),
|
|
12370
|
-
/* @__PURE__ */ jsx(
|
|
12371
|
-
|
|
12372
|
-
|
|
12373
|
-
|
|
12374
|
-
|
|
12375
|
-
|
|
12376
|
-
|
|
12377
|
-
|
|
12378
|
-
|
|
12379
|
-
|
|
12380
|
-
|
|
12381
|
-
|
|
12382
|
-
|
|
12383
|
-
|
|
12384
|
-
|
|
12385
|
-
|
|
12386
|
-
|
|
12387
|
-
|
|
12388
|
-
|
|
12389
|
-
|
|
12390
|
-
|
|
12391
|
-
|
|
12392
|
-
|
|
12393
|
-
|
|
12394
|
-
|
|
12395
|
-
|
|
12396
|
-
|
|
12854
|
+
catchUp && newCount > 0 && !replaying && subagentId === void 0 && framedShellId === void 0 ? /* @__PURE__ */ jsx("div", {
|
|
12855
|
+
className: "px-3 pb-1",
|
|
12856
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
12857
|
+
"data-slot": "catch-up",
|
|
12858
|
+
className: "mx-auto flex w-full max-w-[var(--wd-transcript-max-width)] items-center gap-2 text-label text-fg-3",
|
|
12859
|
+
children: [
|
|
12860
|
+
/* @__PURE__ */ jsx("span", {
|
|
12861
|
+
"aria-hidden": true,
|
|
12862
|
+
className: cn("select-none", terminal ? "text-fg-3" : "text-accent"),
|
|
12863
|
+
children: "※"
|
|
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)
|
|
13006
|
+
})
|
|
13007
|
+
] }) : null
|
|
13008
|
+
]
|
|
13009
|
+
})
|
|
12397
13010
|
})
|
|
12398
13011
|
})
|
|
12399
13012
|
})
|
|
@@ -12566,6 +13179,6 @@ function resolveAgainstCwd(path, cwd) {
|
|
|
12566
13179
|
return parseFileLink(path, cwd)?.path ?? path;
|
|
12567
13180
|
}
|
|
12568
13181
|
//#endregion
|
|
12569
|
-
export {
|
|
13182
|
+
export { useToolTitle as $, DialogContent as $t, ShellTerminal as A, rankComposerRows as At, SkillsDialog as B, segmentsToPlainText as Bt, SessionInfoDialog as C, toolIcon as Ct, QuestionPrompt as D, useTranscriptVariant as Dt, QUESTION_BEHAVIORS as E, useTranscriptDensity as Et, PERMISSION_MODES as F, launchTrigger as Ft, TaskList as G, CopyButton as Gt, HostFilesDialog as H, Splitter as Ht, PermissionModeSelect as I, mentionTrigger as It, Composer as J, TooltipContent as Jt, ContextDialog as K, copyText as Kt, permissionModeChoices as L, usePromptAreaState as Lt, SubagentStrip as M, skillPrompt as Mt, PermissionPrompt as N, commandTrigger as Nt, parseUserQuestions as O, matchClientCommand as Ot, Response as P, hashtagTrigger as Pt, ToolTitleProvider as Q, DialogClose as Qt, permissionModeMeta as R, PromptArea as Rt, STATUS_META as S, isMutatingTool as St, TerminalPermissionPrompt as T, TranscriptVariantProvider as Tt, EntryIcon as U, CodeBlock as Ut, McpDialog as V, ProgressRing as Vt, TasksDialog as W, Spinner as Wt, ShellActionsProvider as X, Dialog$1 as Xt, TerminalSurface as Y, TooltipProvider as Yt, useShellActions as Z, DialogBody as Zt, Loader as _, Badge as _n, shellInfoStatusText as _t, UsageDialog as a, MenuItem as an, previewPatch as at, ConversationScrollButton as b, buttonVariants as bn, SessionNamesProvider as bt, Transcript as c, Select$1 as cn, Ink as ct, Message as d, SelectItemText as dn, WithActions as dt, DialogHeader as en, TerminalMarkdown as et, MessageContent as f, SelectTrigger as fn, useAffordances as ft, SessionEmptyState as g, Input as gn, shellInfoLabel as gt, TerminalTranscript as h, Textarea as hn, shellInfoFailed as ht, SessionPanel as i, MenuContent as in, TerminalDiff as it, ShellStrip as j, rankPeerSessions as jt, useShellFrame as k, mergeComposerRows as kt, ToolCallCard as l, SelectContent as ln, Row as lt, TerminalItemView as m, PortalScope as mn, SHELL_KILL_GLYPH as mt, usePathLinks as n, DialogTrigger as nn, useFileLinks as nt, UsageMeters as o, MenuSeparator as on, Band as ot, FileCard as p, SelectValue as pn, SHELL_GLYPH as pt, contextNote as q, Tip as qt, matchPath as r, Menu$1 as rn, parseFileLink as rt, useMinuteClock as s, MenuTrigger as sn, Blank as st, resolveAgainstCwd as t, DialogRow as tn, FileLinkProvider as tt, Reasoning as u, SelectItem as un, CopyAction as ut, Conversation as v, badgeVariants as vn, shellTitle as vt, TerminalQuestionPrompt as w, TranscriptDensityProvider as wt, StatusBar as x, cn as xn, SkillNamesProvider as xt, ConversationContent as y, Button as yn, PromptTokenText as yt, ModelSelect as z, plainTextToSegments as zt };
|
|
12570
13183
|
|
|
12571
|
-
//# sourceMappingURL=use-path-links-
|
|
13184
|
+
//# sourceMappingURL=use-path-links-BgWXmfAS.mjs.map
|