@workerdeck/ui 2.13.0 → 2.15.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.
Files changed (36) hide show
  1. package/build/{SessionPanel-CJwp5B3q.d.mts → SessionPanel-BVKqPs_3.d.mts} +9 -3
  2. package/build/index.d.mts +84 -6
  3. package/build/index.mjs +83 -37
  4. package/build/index.mjs.map +1 -1
  5. package/build/scoped.css +24 -3
  6. package/build/{use-path-links-CepFsMdW.mjs → use-path-links-BgWXmfAS.mjs} +849 -236
  7. package/build/use-path-links-BgWXmfAS.mjs.map +1 -0
  8. package/build/workspace.d.mts +19 -4
  9. package/build/workspace.mjs +7 -4
  10. package/build/workspace.mjs.map +1 -1
  11. package/package.json +16 -6
  12. package/src/components/agent/Composer.tsx +18 -13
  13. package/src/components/agent/SessionBrowser.tsx +24 -1
  14. package/src/components/agent/SessionItem.tsx +13 -3
  15. package/src/components/agent/SessionPanel.tsx +264 -211
  16. package/src/components/agent/SessionSteps.tsx +78 -27
  17. package/src/components/agent/SessionWorkspace.tsx +10 -1
  18. package/src/components/agent/ShellStrip.tsx +71 -0
  19. package/src/components/agent/ShellTerminal.tsx +170 -0
  20. package/src/components/agent/SubagentToggle.tsx +7 -1
  21. package/src/components/agent/TranscriptItemView.tsx +74 -1
  22. package/src/components/agent/scrubber-marks.ts +9 -1
  23. package/src/components/agent/shell-actions.tsx +25 -0
  24. package/src/components/agent/use-shell-frame.ts +111 -0
  25. package/src/components/terminal/TerminalTranscript.tsx +4 -0
  26. package/src/components/terminal/affordances.tsx +37 -0
  27. package/src/components/terminal/height.ts +14 -0
  28. package/src/components/terminal/items.tsx +72 -3
  29. package/src/components/terminal/press.tsx +5 -3
  30. package/src/components/terminal/scrubber.tsx +9 -1
  31. package/src/components/terminal/shell-row.ts +106 -0
  32. package/src/index.ts +12 -1
  33. package/src/styles/terminal.css +11 -0
  34. package/src/styles/theme.css +3 -0
  35. package/src/workspace.ts +1 -0
  36. 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 = "! shell mode · esc to exit";
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(ToolTitleProvider, {
12175
- value: state.toolTitles,
12176
- children: /* @__PURE__ */ jsx(ToolResultImageProvider, {
12177
- value: resultImages,
12178
- children: /* @__PURE__ */ jsxs("div", {
12179
- ref: panelRef,
12180
- "data-slot": "session-panel",
12181
- "data-agent-font": transcriptFont,
12182
- onClick: handleClick,
12183
- className: cn("flex h-full min-h-0 flex-col overflow-hidden bg-bg", className),
12184
- style: fontSize !== void 0 ? { "--wd-font-size": `${Math.round(fontSize)}px` } : void 0,
12185
- children: [
12186
- headerTakesActions ? header({ actions: menu }) : header,
12187
- statusPlacement === "top" ? statusBar : null,
12188
- protocolMismatch !== void 0 ? /* @__PURE__ */ jsxs(Notice, {
12189
- level: "warning",
12190
- children: [
12191
- "Server speaks protocol v",
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
- /* @__PURE__ */ jsx("span", {
12249
- "aria-hidden": true,
12250
- className: cn("select-none", terminal ? "text-fg-3" : "text-accent"),
12251
- children: "※"
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
- }) : null,
12277
- !readOnly && capabilities.interactiveApprovals && state.pendingApprovals.length > 0 ? /* @__PURE__ */ jsx("div", {
12278
- className: cn(terminal ? "pb-2" : "px-3 pb-2"),
12279
- children: /* @__PURE__ */ jsx(PromptSurface, {
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
- metrics: {
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
- affordances,
12286
- children: state.pendingApprovals.map((request) => {
12287
- const HostPrompt = approvalPrompts?.[request.toolName];
12288
- if (HostPrompt) return /* @__PURE__ */ jsx(HostPrompt, {
12289
- request,
12290
- onApprove: approve,
12291
- onDeny: deny
12292
- }, request.id);
12293
- const isQuestion = request.toolName === "AskUserQuestion" && parseUserQuestions(request.input).length > 0;
12294
- if (terminal) return isQuestion ? /* @__PURE__ */ jsx(TerminalQuestionPrompt, {
12295
- request,
12296
- onAnswer: approve,
12297
- onDismiss: (id) => deny(id, "Question dismissed by user")
12298
- }, request.id) : /* @__PURE__ */ jsx(TerminalPermissionPrompt, {
12299
- request,
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(TasksDialog, {
12371
- tasks,
12372
- showCompleted: showCompletedTasks,
12373
- onShowCompletedChange: setShowCompletedTasks,
12374
- onSelectTask: (task) => {
12375
- if (task.toolUseId) setTaskReveal({
12376
- toolUseId: task.toolUseId,
12377
- nonce: Date.now()
12378
- });
12379
- },
12380
- open: panel === "tasks",
12381
- onOpenChange: (next) => setPanel(next ? "tasks" : void 0)
12382
- }),
12383
- /* @__PURE__ */ jsx(SkillsDialog, {
12384
- skills: state.skills,
12385
- open: panel === "skills",
12386
- onOpenChange: (next) => setPanel(next ? "skills" : void 0),
12387
- onUse: (skill) => composerRef.current?.insertText(skillPrompt(skill))
12388
- }),
12389
- /* @__PURE__ */ jsx(HostFilesDialog, {
12390
- client,
12391
- cwd: state.cwd,
12392
- open: panel === "files",
12393
- onOpenChange: (next) => setPanel(next ? "files" : void 0)
12394
- })
12395
- ] }) : null
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 { TerminalDiff as $, SelectItem as $t, PermissionPrompt as A, ProgressRing as At, EntryIcon as B, DialogBody as Bt, SessionInfoDialog as C, hashtagTrigger as Ct, QuestionPrompt as D, PromptArea as Dt, QUESTION_BEHAVIORS as E, usePromptAreaState as Et, permissionModeMeta as F, copyText as Ft, Composer as G, DialogTrigger as Gt, TaskList as H, DialogContent as Ht, ModelSelect as I, Tip as It, useToolTitle as J, MenuItem as Jt, TerminalSurface as K, Menu$1 as Kt, SkillsDialog as L, TooltipContent as Lt, PERMISSION_MODES as M, CodeBlock as Mt, PermissionModeSelect as N, Spinner as Nt, parseUserQuestions as O, plainTextToSegments as Ot, permissionModeChoices as P, CopyButton as Pt, parseFileLink as Q, SelectContent as Qt, McpDialog as R, TooltipProvider as Rt, STATUS_META as S, commandTrigger as St, TerminalPermissionPrompt as T, mentionTrigger as Tt, ContextDialog as U, DialogHeader as Ut, TasksDialog as V, DialogClose as Vt, contextNote as W, DialogRow as Wt, FileLinkProvider as X, MenuTrigger as Xt, TerminalMarkdown as Y, MenuSeparator as Yt, useFileLinks as Z, Select$1 as Zt, Loader as _, matchClientCommand as _t, UsageDialog as a, Input as an, CopyAction as at, ConversationScrollButton as b, rankPeerSessions as bt, Transcript as c, Button as cn, PromptTokenText as ct, Message as d, isMutatingTool as dt, SelectItemText as en, previewPatch as et, MessageContent as f, toolIcon as ft, SessionEmptyState as g, useTranscriptVariant as gt, TerminalTranscript as h, useTranscriptDensity as ht, SessionPanel as i, Textarea as in, Row as it, Response as j, Splitter as jt, SubagentStrip as k, segmentsToPlainText as kt, ToolCallCard as l, buttonVariants as ln, SessionNamesProvider as lt, TerminalItemView as m, TranscriptVariantProvider as mt, usePathLinks as n, SelectValue as nn, Blank as nt, UsageMeters as o, Badge as on, WithActions as ot, FileCard as p, TranscriptDensityProvider as pt, ToolTitleProvider as q, MenuContent as qt, matchPath as r, PortalScope as rn, Ink as rt, useMinuteClock as s, badgeVariants as sn, useAffordances as st, resolveAgainstCwd as t, SelectTrigger as tn, Band as tt, Reasoning as u, cn as un, SkillNamesProvider as ut, Conversation as v, mergeComposerRows as vt, TerminalQuestionPrompt as w, launchTrigger as wt, StatusBar as x, skillPrompt as xt, ConversationContent as y, rankComposerRows as yt, HostFilesDialog as z, Dialog$1 as zt };
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-CepFsMdW.mjs.map
13184
+ //# sourceMappingURL=use-path-links-BgWXmfAS.mjs.map