@cofy-x/dsh-console 0.1.0-alpha.5 → 0.1.0-alpha.7

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.
@@ -52,6 +52,7 @@ import {
52
52
  pickDefaultThemeName,
53
53
  resolveColor,
54
54
  sanitizeForDisplay,
55
+ sanitizeMultilineForDisplay,
55
56
  setGlobalProxy,
56
57
  shortenPath,
57
58
  shouldEnterAlternateScreen,
@@ -65,7 +66,7 @@ import {
65
66
  unescapePath,
66
67
  writeToStderr,
67
68
  writeToStdout
68
- } from "./chunk-N3EQS35J.js";
69
+ } from "./chunk-4L2DX7CL.js";
69
70
 
70
71
  // src/dsh/index.ts
71
72
  import { randomUUID as randomUUID3 } from "node:crypto";
@@ -2432,9 +2433,9 @@ function computeTerminalTitle({
2432
2433
 
2433
2434
  // src/ui/app-container.tsx
2434
2435
  import {
2435
- useMemo as useMemo36,
2436
+ useMemo as useMemo38,
2436
2437
  useState as useState54,
2437
- useCallback as useCallback46,
2438
+ useCallback as useCallback47,
2438
2439
  useEffect as useEffect55,
2439
2440
  useRef as useRef31,
2440
2441
  useLayoutEffect as useLayoutEffect3,
@@ -2475,7 +2476,7 @@ var useStreamingContext = () => {
2475
2476
  import { Box as Box26 } from "ink";
2476
2477
 
2477
2478
  // src/ui/components/session/history-item-display.tsx
2478
- import { useMemo as useMemo6 } from "react";
2479
+ import { useMemo as useMemo7 } from "react";
2479
2480
 
2480
2481
  // src/ui/components/messages/user-message.tsx
2481
2482
  import { Text as Text2, Box as Box2 } from "ink";
@@ -3528,6 +3529,7 @@ import {
3528
3529
  useCallback as useCallback3,
3529
3530
  useContext as useContext5,
3530
3531
  useEffect as useEffect2,
3532
+ useMemo as useMemo3,
3531
3533
  useRef as useRef2
3532
3534
  } from "react";
3533
3535
 
@@ -3810,7 +3812,15 @@ function MouseProvider({
3810
3812
  stdin.removeListener("data", handleData);
3811
3813
  };
3812
3814
  }, [stdin, mouseEventsEnabled, subscribers, debugKeystrokeLogging]);
3813
- return /* @__PURE__ */ jsx10(MouseContext.Provider, { value: { subscribe, unsubscribe }, children });
3815
+ const contextValue = useMemo3(
3816
+ () => ({
3817
+ subscribe,
3818
+ unsubscribe,
3819
+ mouseEventsEnabled: mouseEventsEnabled === true
3820
+ }),
3821
+ [mouseEventsEnabled, subscribe, unsubscribe]
3822
+ );
3823
+ return /* @__PURE__ */ jsx10(MouseContext.Provider, { value: contextValue, children });
3814
3824
  }
3815
3825
 
3816
3826
  // src/ui/hooks/input/use-mouse-click.ts
@@ -4043,7 +4053,7 @@ var ErrorMessage = ({ text }) => {
4043
4053
  };
4044
4054
 
4045
4055
  // src/ui/components/messages/tool-group-message.tsx
4046
- import { useCallback as useCallback7, useMemo as useMemo4, useState as useState7 } from "react";
4056
+ import { useCallback as useCallback7, useMemo as useMemo5, useState as useState7 } from "react";
4047
4057
  import { Box as Box19, Text as Text18 } from "ink";
4048
4058
 
4049
4059
  // src/ui/components/messages/tool-message.tsx
@@ -4122,7 +4132,7 @@ import React9 from "react";
4122
4132
  import { Box as Box15, Text as Text15 } from "ink";
4123
4133
 
4124
4134
  // src/ui/components/messages/diff-renderer.tsx
4125
- import { useMemo as useMemo3 } from "react";
4135
+ import { useMemo as useMemo4 } from "react";
4126
4136
  import { Box as Box13, Text as Text13, useIsScreenReaderEnabled } from "ink";
4127
4137
  import crypto from "node:crypto";
4128
4138
  import { Fragment as Fragment4, jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
@@ -4190,19 +4200,19 @@ var DiffRenderer = ({
4190
4200
  }) => {
4191
4201
  const settings = useSettings();
4192
4202
  const screenReaderEnabled = useIsScreenReaderEnabled();
4193
- const parsedLines = useMemo3(() => {
4203
+ const parsedLines = useMemo4(() => {
4194
4204
  if (!diffContent || typeof diffContent !== "string") {
4195
4205
  return [];
4196
4206
  }
4197
4207
  return parseDiffWithLineNumbers(diffContent);
4198
4208
  }, [diffContent]);
4199
- const isNewFile = useMemo3(() => {
4209
+ const isNewFile = useMemo4(() => {
4200
4210
  if (parsedLines.length === 0) return false;
4201
4211
  return parsedLines.every(
4202
4212
  (line) => line.type === "add" || line.type === "hunk" || line.type === "other" || line.content.startsWith("diff --git") || line.content.startsWith("new file mode")
4203
4213
  );
4204
4214
  }, [parsedLines]);
4205
- const renderedOutput = useMemo3(() => {
4215
+ const renderedOutput = useMemo4(() => {
4206
4216
  if (!diffContent || typeof diffContent !== "string") {
4207
4217
  return /* @__PURE__ */ jsx16(Text13, { color: theme.status.warning, children: "No diff content." });
4208
4218
  }
@@ -4882,6 +4892,27 @@ var useInactivityTimer = (isActive, trigger, delayMs = 5e3) => {
4882
4892
  // src/ui/components/messages/tool-shared.tsx
4883
4893
  import { Fragment as Fragment5, jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
4884
4894
  var STATUS_INDICATOR_WIDTH = 3;
4895
+ function truncateWithSpacedEllipsis(value, maxWidth) {
4896
+ if (maxWidth <= 1) return "\u2026";
4897
+ const contentWidth = maxWidth - getCachedStringWidth(" \u2026");
4898
+ if (getCachedStringWidth(value) <= contentWidth) return `${value} \u2026`;
4899
+ let width = 0;
4900
+ let truncated = "";
4901
+ for (const character of Array.from(value)) {
4902
+ const characterWidth = getCachedStringWidth(character);
4903
+ if (width + characterWidth > contentWidth) break;
4904
+ truncated += character;
4905
+ width += characterWidth;
4906
+ }
4907
+ return `${truncated.trimEnd()} \u2026`;
4908
+ }
4909
+ function isToolTitleCollapsible(title, terminalWidth) {
4910
+ const headerContentWidth = Math.max(
4911
+ 1,
4912
+ terminalWidth - STATUS_INDICATOR_WIDTH - 4
4913
+ );
4914
+ return getCachedStringWidth(title) > headerContentWidth;
4915
+ }
4885
4916
  function isShellTool(name2) {
4886
4917
  return name2 === SHELL_COMMAND_NAME || name2 === SHELL_NAME || name2 === SHELL_TOOL_NAME;
4887
4918
  }
@@ -4942,7 +4973,10 @@ var ToolInfo = ({
4942
4973
  name: name2,
4943
4974
  description,
4944
4975
  status,
4945
- emphasis
4976
+ emphasis,
4977
+ hideDescription = false,
4978
+ maxNameWidth,
4979
+ expandTitle = false
4946
4980
  }) => {
4947
4981
  const nameColor = React10.useMemo(() => {
4948
4982
  switch (emphasis) {
@@ -4963,13 +4997,30 @@ var ToolInfo = ({
4963
4997
  "Error" /* Error */,
4964
4998
  "Canceled" /* Canceled */
4965
4999
  ].includes(status);
4966
- return /* @__PURE__ */ jsx21(Box16, { overflow: "hidden", height: 1, flexGrow: 1, flexShrink: 1, children: /* @__PURE__ */ jsxs16(Text17, { strikethrough: status === "Canceled" /* Canceled */, wrap: "truncate", children: [
4967
- /* @__PURE__ */ jsx21(Text17, { color: nameColor, bold: true, children: name2 }),
4968
- !isCompletedAskUser && /* @__PURE__ */ jsxs16(Fragment5, { children: [
4969
- " ",
4970
- /* @__PURE__ */ jsx21(Text17, { color: theme.text.secondary, children: description })
4971
- ] })
4972
- ] }) });
5000
+ const displayName = maxNameWidth === void 0 ? name2 : truncateWithSpacedEllipsis(name2, maxNameWidth);
5001
+ return /* @__PURE__ */ jsx21(
5002
+ Box16,
5003
+ {
5004
+ overflow: expandTitle ? "visible" : "hidden",
5005
+ height: expandTitle ? void 0 : 1,
5006
+ flexGrow: 1,
5007
+ flexShrink: 1,
5008
+ children: /* @__PURE__ */ jsxs16(
5009
+ Text17,
5010
+ {
5011
+ strikethrough: status === "Canceled" /* Canceled */,
5012
+ wrap: expandTitle ? "wrap" : "truncate",
5013
+ children: [
5014
+ /* @__PURE__ */ jsx21(Text17, { color: nameColor, bold: true, children: displayName }),
5015
+ !isCompletedAskUser && !hideDescription && /* @__PURE__ */ jsxs16(Fragment5, { children: [
5016
+ " ",
5017
+ /* @__PURE__ */ jsx21(Text17, { color: theme.text.secondary, children: description })
5018
+ ] })
5019
+ ]
5020
+ }
5021
+ )
5022
+ }
5023
+ );
4973
5024
  };
4974
5025
  var TrailingIndicator = () => /* @__PURE__ */ jsxs16(Text17, { color: theme.text.primary, wrap: "truncate", children: [
4975
5026
  " ",
@@ -5697,6 +5748,7 @@ import { Fragment as Fragment6, jsx as jsx23, jsxs as jsxs17 } from "react/jsx-r
5697
5748
  var ToolMessage = ({
5698
5749
  name: name2,
5699
5750
  description,
5751
+ arguments: argumentsText,
5700
5752
  resultDisplay: resultDisplay2,
5701
5753
  status,
5702
5754
  availableTerminalHeight,
@@ -5714,7 +5766,26 @@ var ToolMessage = ({
5714
5766
  resultCollapsible = false,
5715
5767
  onToggleResult
5716
5768
  }) => {
5769
+ const { mouseEventsEnabled } = useMouseContext();
5770
+ const title = React11.useMemo(
5771
+ () => escapeAnsiCtrlCodes(
5772
+ argumentsText === void 0 && description ? `${name2} ${description}` : name2
5773
+ ),
5774
+ [argumentsText, description, name2]
5775
+ );
5776
+ const detailsCollapsible = isToolTitleCollapsible(title, terminalWidth);
5777
+ const [detailsExpandedByUser, setDetailsExpandedByUser] = React11.useState(false);
5778
+ const detailsExpanded = detailsCollapsible && (!mouseEventsEnabled || detailsExpandedByUser);
5779
+ const headerRef = React11.useRef(null);
5717
5780
  const contentRef = React11.useRef(null);
5781
+ const handleHeaderClick = React11.useCallback(() => {
5782
+ if (detailsCollapsible && mouseEventsEnabled) {
5783
+ setDetailsExpandedByUser((expanded) => !expanded);
5784
+ }
5785
+ }, [detailsCollapsible, mouseEventsEnabled]);
5786
+ useMouseClick(headerRef, handleHeaderClick, {
5787
+ isActive: detailsCollapsible && mouseEventsEnabled
5788
+ });
5718
5789
  useMouseClick(contentRef, () => onToggleResult?.(), {
5719
5790
  isActive: resultCollapsible && onToggleResult !== void 0
5720
5791
  });
@@ -5743,15 +5814,19 @@ var ToolMessage = ({
5743
5814
  isFirst,
5744
5815
  borderColor,
5745
5816
  borderDimColor,
5817
+ containerRef: headerRef,
5746
5818
  children: [
5747
5819
  /* @__PURE__ */ jsx23(ToolStatusIndicator, { status, name: name2 }),
5748
5820
  /* @__PURE__ */ jsx23(
5749
5821
  ToolInfo,
5750
5822
  {
5751
- name: name2,
5823
+ name: title,
5752
5824
  status,
5753
- description,
5754
- emphasis
5825
+ description: "",
5826
+ emphasis,
5827
+ hideDescription: true,
5828
+ maxNameWidth: detailsCollapsible && mouseEventsEnabled && !detailsExpanded ? Math.max(1, terminalWidth - STATUS_INDICATOR_WIDTH - 4) : void 0,
5829
+ expandTitle: detailsExpanded
5755
5830
  }
5756
5831
  ),
5757
5832
  /* @__PURE__ */ jsx23(
@@ -5780,7 +5855,7 @@ var ToolMessage = ({
5780
5855
  paddingX: 1,
5781
5856
  flexDirection: "column",
5782
5857
  children: [
5783
- /* @__PURE__ */ jsx23(
5858
+ /* @__PURE__ */ jsx23(Box17, { flexDirection: "column", children: /* @__PURE__ */ jsx23(
5784
5859
  ToolResultDisplay,
5785
5860
  {
5786
5861
  resultDisplay: resultDisplay2,
@@ -5790,7 +5865,7 @@ var ToolMessage = ({
5790
5865
  collapsed: resultCollapsible && !resultExpanded,
5791
5866
  canToggle: resultCollapsible
5792
5867
  }
5793
- ),
5868
+ ) }),
5794
5869
  isThisShellFocused2 && config && /* @__PURE__ */ jsx23(Box17, { paddingLeft: STATUS_INDICATOR_WIDTH, marginTop: 1, children: /* @__PURE__ */ jsx23(
5795
5870
  ShellInputPrompt,
5796
5871
  {
@@ -5825,6 +5900,7 @@ import { Fragment as Fragment7, jsx as jsx24, jsxs as jsxs18 } from "react/jsx-r
5825
5900
  var ShellToolMessage = ({
5826
5901
  name: name2,
5827
5902
  description,
5903
+ arguments: argumentsText,
5828
5904
  resultDisplay: resultDisplay2,
5829
5905
  status,
5830
5906
  availableTerminalHeight,
@@ -5842,6 +5918,15 @@ var ShellToolMessage = ({
5842
5918
  resultCollapsible = false,
5843
5919
  onToggleResult
5844
5920
  }) => {
5921
+ const { mouseEventsEnabled } = useMouseContext();
5922
+ const title = React12.useMemo(
5923
+ () => escapeAnsiCtrlCodes(
5924
+ argumentsText === void 0 && description ? `${name2} ${description}` : name2
5925
+ ),
5926
+ [argumentsText, description, name2]
5927
+ );
5928
+ const commandCollapsible = isToolTitleCollapsible(title, terminalWidth);
5929
+ const [commandExpandedByUser, setCommandExpandedByUser] = React12.useState(false);
5845
5930
  const isThisShellFocused2 = isThisShellFocused(
5846
5931
  name2,
5847
5932
  status,
@@ -5853,18 +5938,35 @@ var ShellToolMessage = ({
5853
5938
  const headerRef = React12.useRef(null);
5854
5939
  const contentRef = React12.useRef(null);
5855
5940
  const isThisShellFocusable2 = isThisShellFocusable(name2, status, config);
5856
- const handleFocus = () => {
5941
+ const commandExpanded = commandCollapsible && !isThisShellFocusable2 && (!mouseEventsEnabled || commandExpandedByUser);
5942
+ const handleFocus = React12.useCallback(() => {
5857
5943
  if (isThisShellFocusable2) {
5858
5944
  setEmbeddedShellFocused(true);
5859
5945
  }
5860
- };
5946
+ }, [isThisShellFocusable2, setEmbeddedShellFocused]);
5947
+ const handleHeaderClick = React12.useCallback(() => {
5948
+ if (isThisShellFocusable2) {
5949
+ handleFocus();
5950
+ return;
5951
+ }
5952
+ if (commandCollapsible && mouseEventsEnabled) {
5953
+ setCommandExpandedByUser((expanded) => !expanded);
5954
+ }
5955
+ }, [
5956
+ commandCollapsible,
5957
+ handleFocus,
5958
+ isThisShellFocusable2,
5959
+ mouseEventsEnabled
5960
+ ]);
5861
5961
  const handleContentClick = () => {
5862
5962
  if (isThisShellFocusable2) {
5863
5963
  handleFocus();
5864
5964
  }
5865
5965
  onToggleResult?.();
5866
5966
  };
5867
- useMouseClick(headerRef, handleFocus, { isActive: !!isThisShellFocusable2 });
5967
+ useMouseClick(headerRef, handleHeaderClick, {
5968
+ isActive: !!isThisShellFocusable2 || commandCollapsible && mouseEventsEnabled
5969
+ });
5868
5970
  useMouseClick(contentRef, handleContentClick, {
5869
5971
  isActive: !!isThisShellFocusable2 || resultCollapsible
5870
5972
  });
@@ -5898,10 +6000,13 @@ var ShellToolMessage = ({
5898
6000
  /* @__PURE__ */ jsx24(
5899
6001
  ToolInfo,
5900
6002
  {
5901
- name: name2,
6003
+ name: title,
5902
6004
  status,
5903
- description,
5904
- emphasis
6005
+ description: "",
6006
+ emphasis,
6007
+ hideDescription: true,
6008
+ maxNameWidth: commandCollapsible && !commandExpanded ? Math.max(1, terminalWidth - STATUS_INDICATOR_WIDTH - 4) : void 0,
6009
+ expandTitle: commandExpanded
5905
6010
  }
5906
6011
  ),
5907
6012
  /* @__PURE__ */ jsx24(
@@ -5930,7 +6035,7 @@ var ShellToolMessage = ({
5930
6035
  paddingX: 1,
5931
6036
  flexDirection: "column",
5932
6037
  children: [
5933
- /* @__PURE__ */ jsx24(
6038
+ /* @__PURE__ */ jsx24(Box18, { flexDirection: "column", children: /* @__PURE__ */ jsx24(
5934
6039
  ToolResultDisplay,
5935
6040
  {
5936
6041
  resultDisplay: resultDisplay2,
@@ -5940,7 +6045,7 @@ var ShellToolMessage = ({
5940
6045
  collapsed: resultCollapsible && !resultExpanded,
5941
6046
  canToggle: resultCollapsible
5942
6047
  }
5943
- ),
6048
+ ) }),
5944
6049
  isThisShellFocused2 && config && /* @__PURE__ */ jsx24(Box18, { paddingLeft: STATUS_INDICATOR_WIDTH, marginTop: 1, children: /* @__PURE__ */ jsx24(
5945
6050
  ShellInputPrompt,
5946
6051
  {
@@ -5964,17 +6069,17 @@ var ToolGroupMessage = ({
5964
6069
  activeShellPtyId,
5965
6070
  embeddedShellFocused
5966
6071
  }) => {
5967
- const toolCalls = useMemo4(
6072
+ const toolCalls = useMemo5(
5968
6073
  () => allToolCalls.filter((t) => !isAskUserInProgress(t)),
5969
6074
  [allToolCalls]
5970
6075
  );
5971
6076
  const config = useConfig();
5972
- const visibleToolCalls = useMemo4(() => toolCalls.filter((t) => t.status !== "Pending" /* Pending */), [toolCalls]);
6077
+ const visibleToolCalls = useMemo5(() => toolCalls.filter((t) => t.status !== "Pending" /* Pending */), [toolCalls]);
5973
6078
  const [expandedCallIds, setExpandedCallIds] = useState7(
5974
6079
  () => /* @__PURE__ */ new Set()
5975
6080
  );
5976
6081
  const resultWidth = Math.max(1, terminalWidth - 4);
5977
- const collapsibleCallIds = useMemo4(
6082
+ const collapsibleCallIds = useMemo5(
5978
6083
  () => visibleToolCalls.filter(
5979
6084
  (tool) => isToolResultCollapsible(tool.resultDisplay, resultWidth)
5980
6085
  ).map((tool) => tool.callId),
@@ -6155,7 +6260,7 @@ import { Box as Box25 } from "ink";
6155
6260
  import { Box as Box21, Text as Text20 } from "ink";
6156
6261
 
6157
6262
  // src/generated/git-commit.ts
6158
- var GIT_COMMIT_INFO = "7fa332d";
6263
+ var GIT_COMMIT_INFO = "52d0684";
6159
6264
 
6160
6265
  // src/ui/components/dialogs/about-box.tsx
6161
6266
  import { jsx as jsx27, jsxs as jsxs21 } from "react/jsx-runtime";
@@ -6226,7 +6331,7 @@ import {
6226
6331
  useCallback as useCallback8,
6227
6332
  useContext as useContext8,
6228
6333
  useEffect as useEffect10,
6229
- useMemo as useMemo5,
6334
+ useMemo as useMemo6,
6230
6335
  useState as useState8
6231
6336
  } from "react";
6232
6337
  import { jsx as jsx29 } from "react/jsx-runtime";
@@ -6259,7 +6364,7 @@ var SessionStatsProvider = ({ children, conversationRuntime }) => {
6259
6364
  () => stats.promptCount,
6260
6365
  [stats.promptCount]
6261
6366
  );
6262
- const value = useMemo5(
6367
+ const value = useMemo6(
6263
6368
  () => ({ stats, startNewPrompt, getPromptCount }),
6264
6369
  [stats, startNewPrompt, getPromptCount]
6265
6370
  );
@@ -6687,7 +6792,7 @@ var HistoryItemDisplay = ({
6687
6792
  embeddedShellFocused,
6688
6793
  availableTerminalHeightAgent
6689
6794
  }) => {
6690
- const itemForDisplay = useMemo6(() => escapeAnsiCtrlCodes(item), [item]);
6795
+ const itemForDisplay = useMemo7(() => escapeAnsiCtrlCodes(item), [item]);
6691
6796
  return /* @__PURE__ */ jsxs25(
6692
6797
  Box25,
6693
6798
  {
@@ -6950,7 +7055,7 @@ var compactDshLogo = `\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2
6950
7055
  var tinyDshLogo = "DSH CONSOLE";
6951
7056
 
6952
7057
  // src/ui/hooks/visual/use-snow-fall.ts
6953
- import { useState as useState11, useEffect as useEffect13, useMemo as useMemo7 } from "react";
7058
+ import { useState as useState11, useEffect as useEffect13, useMemo as useMemo8 } from "react";
6954
7059
  var SNOW_CHARS = ["*", ".", "\xB7", "+"];
6955
7060
  var FRAME_RATE = 150;
6956
7061
  var addHolidayTrees = (art) => {
@@ -7001,7 +7106,7 @@ var useSnowfall = (displayTitle, terminalWidth) => {
7001
7106
  return () => clearTimeout(timer);
7002
7107
  }, [historyRemountKey]);
7003
7108
  const showAnimation = isHolidaySeason && currentTheme.name === Holiday.name && terminalWidth >= displayTitleWidth && !containsAnsi && !hasStartedChat && showSnow;
7004
- const displayArt = useMemo7(() => {
7109
+ const displayArt = useMemo8(() => {
7005
7110
  if (showAnimation) {
7006
7111
  return addHolidayTrees(displayTitle);
7007
7112
  }
@@ -7095,7 +7200,7 @@ var VerticalHeader = ({
7095
7200
  };
7096
7201
 
7097
7202
  // src/ui/components/layout/horizontal-header.tsx
7098
- import { useMemo as useMemo8 } from "react";
7203
+ import { useMemo as useMemo9 } from "react";
7099
7204
  import { Box as Box30, Text as Text27 } from "ink";
7100
7205
 
7101
7206
  // src/ui/components/layout/resources/quotes.ts
@@ -7259,15 +7364,15 @@ var HorizontalHeader = ({
7259
7364
  version,
7260
7365
  art
7261
7366
  }) => {
7262
- const randomQuote = useMemo8(
7367
+ const randomQuote = useMemo9(
7263
7368
  () => QUOTES[Math.floor(Math.random() * QUOTES.length)],
7264
7369
  []
7265
7370
  );
7266
- const startupQuest = useMemo8(
7371
+ const startupQuest = useMemo9(
7267
7372
  () => STARTUP_QUESTS[Math.floor(Math.random() * STARTUP_QUESTS.length)],
7268
7373
  []
7269
7374
  );
7270
- const artHeight = useMemo8(() => art.trimEnd().split("\n").length, [art]);
7375
+ const artHeight = useMemo9(() => art.trimEnd().split("\n").length, [art]);
7271
7376
  return /* @__PURE__ */ jsxs28(Box30, { flexDirection: "row", paddingBottom: 1, alignItems: "flex-start", children: [
7272
7377
  /* @__PURE__ */ jsx39(Box30, { paddingRight: 2, marginRight: 1, flexShrink: 0, children: /* @__PURE__ */ jsx39(Text27, { children: art }) }),
7273
7378
  /* @__PURE__ */ jsxs28(
@@ -7390,7 +7495,7 @@ var Header = ({
7390
7495
  };
7391
7496
 
7392
7497
  // src/ui/components/layout/app-header.tsx
7393
- import { useMemo as useMemo9 } from "react";
7498
+ import { useMemo as useMemo10 } from "react";
7394
7499
  import { jsx as jsx42 } from "react/jsx-runtime";
7395
7500
  var AppHeader = ({ version }) => {
7396
7501
  const settings = useSettings();
@@ -7401,13 +7506,13 @@ var AppHeader = ({ version }) => {
7401
7506
  const artResourcesPath = settings.merged.ui.header.artResourcesPath;
7402
7507
  const customAsciiArtPath = settings.merged.ui.header.customAsciiArtPath;
7403
7508
  const pokemonNumber = config.getPokemonNumber();
7404
- const customAsciiArt = useMemo9(() => {
7509
+ const customAsciiArt = useMemo10(() => {
7405
7510
  if (pokemonNumber === void 0 && customAsciiArtPath) {
7406
7511
  return loadCustomAsciiArt(customAsciiArtPath);
7407
7512
  }
7408
7513
  return void 0;
7409
7514
  }, [customAsciiArtPath, pokemonNumber]);
7410
- const headerArt = useMemo9(() => {
7515
+ const headerArt = useMemo10(() => {
7411
7516
  if (customAsciiArt) {
7412
7517
  return null;
7413
7518
  }
@@ -7441,7 +7546,7 @@ import {
7441
7546
  forwardRef,
7442
7547
  useImperativeHandle,
7443
7548
  useEffect as useEffect16,
7444
- useMemo as useMemo10,
7549
+ useMemo as useMemo11,
7445
7550
  useCallback as useCallback10
7446
7551
  } from "react";
7447
7552
 
@@ -7514,7 +7619,7 @@ function VirtualizedList(props, ref) {
7514
7619
  const itemRefs = useRef6([]);
7515
7620
  const [heights, setHeights] = useState13([]);
7516
7621
  const isInitialScrollSet = useRef6(false);
7517
- const { totalHeight, offsets } = useMemo10(() => {
7622
+ const { totalHeight, offsets } = useMemo11(() => {
7518
7623
  const offsets2 = [0];
7519
7624
  let totalHeight2 = 0;
7520
7625
  for (let i = 0; i < data.length; i++) {
@@ -7575,7 +7680,7 @@ function VirtualizedList(props, ref) {
7575
7680
  },
7576
7681
  []
7577
7682
  );
7578
- const scrollTop = useMemo10(() => {
7683
+ const scrollTop = useMemo11(() => {
7579
7684
  const offset = offsets[scrollAnchor.index];
7580
7685
  if (typeof offset !== "number") {
7581
7686
  return 0;
@@ -7818,7 +7923,7 @@ import {
7818
7923
  forwardRef as forwardRef2,
7819
7924
  useImperativeHandle as useImperativeHandle2,
7820
7925
  useCallback as useCallback13,
7821
- useMemo as useMemo12,
7926
+ useMemo as useMemo13,
7822
7927
  useEffect as useEffect20
7823
7928
  } from "react";
7824
7929
 
@@ -7828,7 +7933,7 @@ import {
7828
7933
  useCallback as useCallback11,
7829
7934
  useContext as useContext10,
7830
7935
  useEffect as useEffect18,
7831
- useMemo as useMemo11,
7936
+ useMemo as useMemo12,
7832
7937
  useRef as useRef7,
7833
7938
  useState as useState14
7834
7939
  } from "react";
@@ -8064,7 +8169,7 @@ var ScrollProvider = ({
8064
8169
  },
8065
8170
  { isActive: true }
8066
8171
  );
8067
- const contextValue = useMemo11(
8172
+ const contextValue = useMemo12(
8068
8173
  () => ({ register, unregister }),
8069
8174
  [register, unregister]
8070
8175
  );
@@ -8521,7 +8626,7 @@ function ScrollableList(props, ref) {
8521
8626
  { isActive: hasFocus }
8522
8627
  );
8523
8628
  const hasFocusCallback = useCallback13(() => hasFocus, [hasFocus]);
8524
- const scrollableEntry = useMemo12(
8629
+ const scrollableEntry = useMemo13(
8525
8630
  () => ({
8526
8631
  ref: containerRef,
8527
8632
  getScrollState,
@@ -8561,7 +8666,7 @@ function ScrollableList(props, ref) {
8561
8666
  var ScrollableListWithForwardRef = forwardRef2(ScrollableList);
8562
8667
 
8563
8668
  // src/ui/components/layout/main-content.tsx
8564
- import { useMemo as useMemo13, memo, useCallback as useCallback14 } from "react";
8669
+ import { useMemo as useMemo14, memo, useCallback as useCallback14 } from "react";
8565
8670
 
8566
8671
  // src/ui/components/indicators/constants.ts
8567
8672
  var MAX_AGENT_MESSAGE_LINES = 65536;
@@ -8588,7 +8693,7 @@ var MainContent = () => {
8588
8693
  staticAreaMaxItemHeight,
8589
8694
  availableTerminalHeight
8590
8695
  } = uiState;
8591
- const historyItems = useMemo13(
8696
+ const historyItems = useMemo14(
8592
8697
  () => uiState.history.map((h, index) => /* @__PURE__ */ jsx46(
8593
8698
  MemoizedHistoryItemDisplay,
8594
8699
  {
@@ -8612,7 +8717,7 @@ var MainContent = () => {
8612
8717
  uiState.slashCommands
8613
8718
  ]
8614
8719
  );
8615
- const pendingItems = useMemo13(
8720
+ const pendingItems = useMemo14(
8616
8721
  () => /* @__PURE__ */ jsx46(OverflowProvider, { children: /* @__PURE__ */ jsxs32(Box36, { flexDirection: "column", children: [
8617
8722
  pendingHistoryItems.map((item, i) => /* @__PURE__ */ jsx46(
8618
8723
  HistoryItemDisplay,
@@ -8645,7 +8750,7 @@ var MainContent = () => {
8645
8750
  uiState.embeddedShellFocused
8646
8751
  ]
8647
8752
  );
8648
- const virtualizedData = useMemo13(
8753
+ const virtualizedData = useMemo14(
8649
8754
  () => [
8650
8755
  { type: "header" },
8651
8756
  ...uiState.history.map((item, index) => ({
@@ -9700,7 +9805,7 @@ def fibonacci(n):
9700
9805
  }
9701
9806
 
9702
9807
  // src/ui/components/dialogs/settings-dialog.tsx
9703
- import { useState as useState21, useEffect as useEffect26, useMemo as useMemo15, useCallback as useCallback21 } from "react";
9808
+ import { useState as useState21, useEffect as useEffect26, useMemo as useMemo16, useCallback as useCallback21 } from "react";
9704
9809
  import { Text as Text35 } from "ink";
9705
9810
  import { AsyncFzf } from "fzf";
9706
9811
 
@@ -9760,7 +9865,7 @@ import { spawnSync } from "node:child_process";
9760
9865
  import fs7 from "node:fs";
9761
9866
  import os2 from "node:os";
9762
9867
  import pathMod from "node:path";
9763
- import { useState as useState19, useCallback as useCallback18, useEffect as useEffect24, useMemo as useMemo14, useReducer as useReducer2 } from "react";
9868
+ import { useState as useState19, useCallback as useCallback18, useEffect as useEffect24, useMemo as useMemo15, useReducer as useReducer2 } from "react";
9764
9869
 
9765
9870
  // src/terminal/clipboard/parser.ts
9766
9871
  var PATH_PREFIX_PATTERN = /^([/~.]|[a-zA-Z]:|\\\\)/;
@@ -12290,7 +12395,7 @@ function useTextBuffer({
12290
12395
  singleLine = false,
12291
12396
  getPreferredEditor
12292
12397
  }) {
12293
- const initialState3 = useMemo14(() => {
12398
+ const initialState3 = useMemo15(() => {
12294
12399
  const lines2 = initialText.split("\n");
12295
12400
  const [initialCursorRow, initialCursorCol] = calculateInitialCursorPosition(
12296
12401
  lines2.length === 0 ? [""] : lines2,
@@ -12336,8 +12441,8 @@ function useTextBuffer({
12336
12441
  pastedContent,
12337
12442
  expandedPaste
12338
12443
  } = state;
12339
- const text = useMemo14(() => lines.join("\n"), [lines]);
12340
- const visualCursor = useMemo14(
12444
+ const text = useMemo15(() => lines.join("\n"), [lines]);
12445
+ const visualCursor = useMemo15(
12341
12446
  () => calculateVisualCursorFromLayout(visualLayout, [cursorRow, cursorCol]),
12342
12447
  [visualLayout, cursorRow, cursorCol]
12343
12448
  );
@@ -12715,14 +12820,14 @@ function useTextBuffer({
12715
12820
  singleLine
12716
12821
  ]
12717
12822
  );
12718
- const visualScrollRow = useMemo14(() => {
12823
+ const visualScrollRow = useMemo15(() => {
12719
12824
  const totalVisualLines = visualLines.length;
12720
12825
  return Math.min(
12721
12826
  scrollRowState,
12722
12827
  Math.max(0, totalVisualLines - viewport.height)
12723
12828
  );
12724
12829
  }, [visualLines.length, scrollRowState, viewport.height]);
12725
- const renderedVisualLines = useMemo14(
12830
+ const renderedVisualLines = useMemo15(
12726
12831
  () => visualLines.slice(visualScrollRow, visualScrollRow + viewport.height),
12727
12832
  [visualLines, visualScrollRow, viewport.height]
12728
12833
  );
@@ -12854,7 +12959,7 @@ function useTextBuffer({
12854
12959
  (lineIndex) => getExpandedPasteAtLine(lineIndex, expandedPaste),
12855
12960
  [expandedPaste]
12856
12961
  );
12857
- const returnValue = useMemo14(
12962
+ const returnValue = useMemo15(
12858
12963
  () => ({
12859
12964
  lines,
12860
12965
  text,
@@ -13465,7 +13570,7 @@ function SettingsDialog({
13465
13570
  const [filteredKeys, setFilteredKeys] = useState21(
13466
13571
  () => getDialogSettingKeys()
13467
13572
  );
13468
- const { fzfInstance, searchMap } = useMemo15(() => {
13573
+ const { fzfInstance, searchMap } = useMemo16(() => {
13469
13574
  const keys = getDialogSettingKeys();
13470
13575
  const map = /* @__PURE__ */ new Map();
13471
13576
  const searchItems = [];
@@ -13533,7 +13638,7 @@ function SettingsDialog({
13533
13638
  setRestartRequiredSettings(newRestartRequired);
13534
13639
  setShowRestartPrompt(newRestartRequired.size > 0);
13535
13640
  }, [selectedScope, settings, globalPendingChanges]);
13536
- const maxLabelOrDescriptionWidth = useMemo15(() => {
13641
+ const maxLabelOrDescriptionWidth = useMemo16(() => {
13537
13642
  const allKeys = getDialogSettingKeys();
13538
13643
  let max = 0;
13539
13644
  for (const key of allKeys) {
@@ -13566,7 +13671,7 @@ function SettingsDialog({
13566
13671
  onChange: (text) => setSearchQuery(text)
13567
13672
  });
13568
13673
  const settingKeys = searchQuery ? filteredKeys : getDialogSettingKeys();
13569
- const items = useMemo15(() => {
13674
+ const items = useMemo16(() => {
13570
13675
  const scopeSettings = settings.forScope(selectedScope).settings;
13571
13676
  const mergedSettings = settings.merged;
13572
13677
  return settingKeys.map((key) => {
@@ -13857,7 +13962,7 @@ function SettingsDialog({
13857
13962
  },
13858
13963
  [showRestartPrompt, onRestartRequest, saveRestartRequiredSettings]
13859
13964
  );
13860
- const { effectiveMaxItemsToShow, showScopeSelection, showSearch } = useMemo15(() => {
13965
+ const { effectiveMaxItemsToShow, showScopeSelection, showSearch } = useMemo16(() => {
13861
13966
  const hasWorkspace = settings.workspace.path !== void 0;
13862
13967
  const shouldShowSearch = !showRestartPrompt;
13863
13968
  if (!availableTerminalHeight) {
@@ -14399,7 +14504,7 @@ var RawMarkdownIndicator = () => {
14399
14504
 
14400
14505
  // src/ui/components/input/input-prompt.tsx
14401
14506
  import clipboardy2 from "clipboardy";
14402
- import { useCallback as useCallback29, useEffect as useEffect33, useState as useState30, useRef as useRef15, useMemo as useMemo20 } from "react";
14507
+ import { useCallback as useCallback29, useEffect as useEffect33, useState as useState30, useRef as useRef15, useMemo as useMemo21 } from "react";
14403
14508
  import { Box as Box50, Text as Text44, useStdout as useStdout2 } from "ink";
14404
14509
 
14405
14510
  // src/ui/components/input/suggestions-display.tsx
@@ -14798,7 +14903,7 @@ function useShellHistory(projectRoot, storage) {
14798
14903
  }
14799
14904
 
14800
14905
  // src/ui/hooks/completion/use-reverse-search-completion.tsx
14801
- import { useState as useState26, useEffect as useEffect28, useMemo as useMemo16, useCallback as useCallback26, useRef as useRef12 } from "react";
14906
+ import { useState as useState26, useEffect as useEffect28, useMemo as useMemo17, useCallback as useCallback26, useRef as useRef12 } from "react";
14802
14907
 
14803
14908
  // src/ui/hooks/completion/use-completion.ts
14804
14909
  import { useState as useState25, useCallback as useCallback25 } from "react";
@@ -14920,7 +15025,7 @@ function useReverseSearchCompletion(buffer, history, reverseSearchActive) {
14920
15025
  },
14921
15026
  []
14922
15027
  );
14923
- const matches = useMemo16(() => {
15028
+ const matches = useMemo17(() => {
14924
15029
  if (!reverseSearchActive) return [];
14925
15030
  if (debouncedQuery.length === 0)
14926
15031
  return history.map((cmd) => ({
@@ -14977,7 +15082,7 @@ function useReverseSearchCompletion(buffer, history, reverseSearchActive) {
14977
15082
  }
14978
15083
 
14979
15084
  // src/ui/hooks/completion/use-command-completion.tsx
14980
- import { useCallback as useCallback28, useMemo as useMemo19, useEffect as useEffect32 } from "react";
15085
+ import { useCallback as useCallback28, useMemo as useMemo20, useEffect as useEffect32 } from "react";
14981
15086
 
14982
15087
  // src/ui/hooks/completion/use-at-completion.ts
14983
15088
  import { useEffect as useEffect29, useReducer as useReducer3, useRef as useRef13 } from "react";
@@ -15155,7 +15260,7 @@ function useAtCompletion(props) {
15155
15260
  }
15156
15261
 
15157
15262
  // src/ui/hooks/completion/use-slash-completion.ts
15158
- import { useState as useState27, useEffect as useEffect30, useMemo as useMemo17 } from "react";
15263
+ import { useState as useState27, useEffect as useEffect30, useMemo as useMemo18 } from "react";
15159
15264
  import { AsyncFzf as AsyncFzf2 } from "fzf";
15160
15265
  function logErrorSafely(error, context) {
15161
15266
  if (error instanceof Error) {
@@ -15168,7 +15273,7 @@ function matchesCommand(cmd, query) {
15168
15273
  return cmd.name.toLowerCase() === query.toLowerCase() || cmd.altNames?.some((alt) => alt.toLowerCase() === query.toLowerCase()) || false;
15169
15274
  }
15170
15275
  function useCommandParser(query, slashCommands) {
15171
- return useMemo17(() => {
15276
+ return useMemo18(() => {
15172
15277
  if (!query) {
15173
15278
  return {
15174
15279
  hasTrailingSpace: false,
@@ -15378,7 +15483,7 @@ function useCommandSuggestions(query, parserResult, commandContext, getFzfForCom
15378
15483
  return { suggestions, isLoading };
15379
15484
  }
15380
15485
  function useCompletionPositions(query, parserResult) {
15381
- return useMemo17(() => {
15486
+ return useMemo18(() => {
15382
15487
  if (!query) {
15383
15488
  return { start: -1, end: -1 };
15384
15489
  }
@@ -15399,7 +15504,7 @@ function useCompletionPositions(query, parserResult) {
15399
15504
  }, [query, parserResult]);
15400
15505
  }
15401
15506
  function usePerfectMatch(parserResult) {
15402
- return useMemo17(() => {
15507
+ return useMemo18(() => {
15403
15508
  const { hasTrailingSpace, partial, leafCommand, currentLevel } = parserResult;
15404
15509
  if (hasTrailingSpace) {
15405
15510
  return { isPerfectMatch: false };
@@ -15440,11 +15545,11 @@ function useSlashCompletion(props) {
15440
15545
  } = props;
15441
15546
  const [completionStart, setCompletionStart] = useState27(-1);
15442
15547
  const [completionEnd, setCompletionEnd] = useState27(-1);
15443
- const fzfInstanceCache = useMemo17(
15548
+ const fzfInstanceCache = useMemo18(
15444
15549
  () => /* @__PURE__ */ new WeakMap(),
15445
15550
  []
15446
15551
  );
15447
- const getFzfForCommands = useMemo17(
15552
+ const getFzfForCommands = useMemo18(
15448
15553
  () => (commands) => {
15449
15554
  if (!commands || commands.length === 0) {
15450
15555
  return null;
@@ -15488,7 +15593,7 @@ function useSlashCompletion(props) {
15488
15593
  },
15489
15594
  [fzfInstanceCache]
15490
15595
  );
15491
- const getPrefixSuggestions = useMemo17(
15596
+ const getPrefixSuggestions = useMemo18(
15492
15597
  () => (commands, partial) => commands.filter(
15493
15598
  (cmd) => cmd.description && !cmd.hidden && (cmd.name.toLowerCase().startsWith(partial.toLowerCase()) || cmd.altNames?.some(
15494
15599
  (alt) => alt.toLowerCase().startsWith(partial.toLowerCase())
@@ -15549,7 +15654,7 @@ function useSlashCompletion(props) {
15549
15654
  }
15550
15655
 
15551
15656
  // src/ui/hooks/completion/use-prompt-completion.ts
15552
- import { useState as useState28, useCallback as useCallback27, useRef as useRef14, useEffect as useEffect31, useMemo as useMemo18 } from "react";
15657
+ import { useState as useState28, useCallback as useCallback27, useRef as useRef14, useEffect as useEffect31, useMemo as useMemo19 } from "react";
15553
15658
  var PROMPT_COMPLETION_MIN_LENGTH = 5;
15554
15659
  var PROMPT_COMPLETION_DEBOUNCE_MS = 250;
15555
15660
  function usePromptCompletion({
@@ -15676,7 +15781,7 @@ function usePromptCompletion({
15676
15781
  }
15677
15782
  }, [buffer.text, buffer.cursor, ghostText, clearGhostText, isCursorAtEnd]);
15678
15783
  useEffect31(() => () => abortControllerRef.current?.abort(), []);
15679
- const isActive = useMemo18(() => {
15784
+ const isActive = useMemo19(() => {
15680
15785
  if (!isPromptCompletionEnabled) return false;
15681
15786
  if (!isCursorAtEnd()) return false;
15682
15787
  const trimmedText = buffer.text.trim();
@@ -15713,7 +15818,7 @@ function useCommandCompletion(buffer, cwd, slashCommands, commandContext, revers
15713
15818
  } = useCompletion();
15714
15819
  const cursorRow = buffer.cursor[0];
15715
15820
  const cursorCol = buffer.cursor[1];
15716
- const { completionMode, query, completionStart, completionEnd } = useMemo19(() => {
15821
+ const { completionMode, query, completionStart, completionEnd } = useMemo20(() => {
15717
15822
  const currentLine = buffer.lines[cursorRow] || "";
15718
15823
  const codePoints = toCodePoints(currentLine);
15719
15824
  for (let i = cursorCol - 1; i >= 0; i--) {
@@ -16818,7 +16923,7 @@ var InputPrompt = ({
16818
16923
  const useBackgroundColor = config.getUseBackgroundColor();
16819
16924
  const isLowColor = isLowColorDepth();
16820
16925
  const terminalBg = terminalBackgroundColor || "black";
16821
- const useLineFallback = useMemo20(() => {
16926
+ const useLineFallback = useMemo21(() => {
16822
16927
  if (!useBackgroundColor) {
16823
16928
  return true;
16824
16929
  }
@@ -17462,10 +17567,10 @@ var CommandInitDisplay = ({
17462
17567
 
17463
17568
  // src/ui/components/messages/todo.tsx
17464
17569
  import { Box as Box57, Text as Text52 } from "ink";
17465
- import { useMemo as useMemo21 } from "react";
17570
+ import { useMemo as useMemo22 } from "react";
17466
17571
  import { jsx as jsx72, jsxs as jsxs56 } from "react/jsx-runtime";
17467
17572
  var TodoTitleDisplay = ({ todos, isWorking, compact = false }) => {
17468
- const score = useMemo21(() => {
17573
+ const score = useMemo22(() => {
17469
17574
  let total = 0;
17470
17575
  let completed = 0;
17471
17576
  let unfinished = 0;
@@ -17530,13 +17635,13 @@ var TodoTray = () => {
17530
17635
  const uiState = useUIState();
17531
17636
  const todos = uiState.todos ?? null;
17532
17637
  const isWorking = uiState.streamingState === "responding" /* Responding */;
17533
- const inProgress = useMemo21(() => {
17638
+ const inProgress = useMemo22(() => {
17534
17639
  if (todos === null) {
17535
17640
  return null;
17536
17641
  }
17537
17642
  return todos.todos.find((todo) => todo.status === "in_progress") || null;
17538
17643
  }, [todos]);
17539
- const hasActiveTodos = useMemo21(() => {
17644
+ const hasActiveTodos = useMemo22(() => {
17540
17645
  if (!todos || !todos.todos) return false;
17541
17646
  return todos.todos.some(
17542
17647
  (todo) => todo.status === "pending" || todo.status === "in_progress"
@@ -17737,7 +17842,7 @@ function useFlickerDetector(rootUiRef, terminalHeight) {
17737
17842
  import {
17738
17843
  createContext as createContext12,
17739
17844
  useContext as useContext13,
17740
- useMemo as useMemo22,
17845
+ useMemo as useMemo23,
17741
17846
  useSyncExternalStore
17742
17847
  } from "react";
17743
17848
  import { jsx as jsx76 } from "react/jsx-runtime";
@@ -17750,7 +17855,7 @@ var ApprovalRuntimeProvider = ({ runtime, children }) => {
17750
17855
  runtime.getSnapshot,
17751
17856
  runtime.getSnapshot
17752
17857
  );
17753
- const value = useMemo22(() => ({ runtime, snapshot }), [runtime, snapshot]);
17858
+ const value = useMemo23(() => ({ runtime, snapshot }), [runtime, snapshot]);
17754
17859
  return /* @__PURE__ */ jsx76(ApprovalContext.Provider, { value, children });
17755
17860
  };
17756
17861
  function useApprovalRuntime() {
@@ -17767,7 +17872,7 @@ function useApprovalRuntime() {
17767
17872
  import {
17768
17873
  createContext as createContext13,
17769
17874
  useContext as useContext14,
17770
- useMemo as useMemo23,
17875
+ useMemo as useMemo24,
17771
17876
  useSyncExternalStore as useSyncExternalStore2
17772
17877
  } from "react";
17773
17878
  import { jsx as jsx77 } from "react/jsx-runtime";
@@ -17778,7 +17883,7 @@ var UserQuestionRuntimeProvider = ({ runtime, children }) => {
17778
17883
  runtime.getSnapshot,
17779
17884
  runtime.getSnapshot
17780
17885
  );
17781
- const value = useMemo23(() => ({ runtime, snapshot }), [runtime, snapshot]);
17886
+ const value = useMemo24(() => ({ runtime, snapshot }), [runtime, snapshot]);
17782
17887
  return /* @__PURE__ */ jsx77(UserQuestionContext.Provider, { value, children });
17783
17888
  };
17784
17889
  function useUserQuestionRuntime() {
@@ -17796,7 +17901,7 @@ import { Box as Box61, Text as Text56 } from "ink";
17796
17901
 
17797
17902
  // src/ui/components/messages/tool-confirmation-message.tsx
17798
17903
  import { Box as Box60, Text as Text55 } from "ink";
17799
- import { useMemo as useMemo24 } from "react";
17904
+ import { useMemo as useMemo25 } from "react";
17800
17905
  import { jsx as jsx78, jsxs as jsxs59 } from "react/jsx-runtime";
17801
17906
  var ToolConfirmationMessage = ({ request, respond, isFocused }) => {
17802
17907
  useKeypress(
@@ -17807,7 +17912,7 @@ var ToolConfirmationMessage = ({ request, respond, isFocused }) => {
17807
17912
  },
17808
17913
  { isActive: isFocused }
17809
17914
  );
17810
- const options = useMemo24(
17915
+ const options = useMemo25(
17811
17916
  () => [
17812
17917
  {
17813
17918
  label: "Allow once",
@@ -17877,12 +17982,12 @@ var ToolConfirmationQueue = ({ request, index, total, terminalWidth, respond })
17877
17982
  );
17878
17983
 
17879
17984
  // src/ui/components/dialogs/user-question-queue.tsx
17880
- import { useMemo as useMemo26 } from "react";
17985
+ import { useMemo as useMemo28 } from "react";
17881
17986
 
17882
17987
  // src/ui/components/dialogs/ask-user-dialog.tsx
17883
17988
  import {
17884
17989
  useCallback as useCallback30,
17885
- useMemo as useMemo25,
17990
+ useMemo as useMemo26,
17886
17991
  useRef as useRef16,
17887
17992
  useEffect as useEffect37,
17888
17993
  useReducer as useReducer4,
@@ -17935,7 +18040,7 @@ function TabHeader({
17935
18040
  }
17936
18041
 
17937
18042
  // src/ui/components/dialogs/ask-user-dialog.tsx
17938
- import { jsx as jsx81, jsxs as jsxs62 } from "react/jsx-runtime";
18043
+ import { Fragment as Fragment15, jsx as jsx81, jsxs as jsxs62 } from "react/jsx-runtime";
17939
18044
  var initialState2 = {
17940
18045
  currentQuestionIndex: 0,
17941
18046
  answers: {},
@@ -18025,6 +18130,75 @@ function askUserDialogReducerLogic(state, action) {
18025
18130
  }
18026
18131
  }
18027
18132
  var ASK_USER_ANSWER_SEPARATOR = "";
18133
+ var QuestionPrompt = ({ question, presentation }) => {
18134
+ const uiState = useContext15(UIStateContext);
18135
+ const { stdout } = useStdout3();
18136
+ const terminalWidth = Math.max(
18137
+ 20,
18138
+ (uiState?.terminalWidth ?? stdout?.columns ?? 80) - 6
18139
+ );
18140
+ const terminalHeight = uiState?.terminalHeight ?? stdout?.rows ?? 24;
18141
+ const planViewportHeight = Math.max(5, Math.min(24, terminalHeight - 14));
18142
+ const planDetail = useMemo26(
18143
+ () => question.detail === void 0 ? [] : [question.detail],
18144
+ [question.detail]
18145
+ );
18146
+ const estimatePlanHeight = useCallback30(
18147
+ () => Math.max(
18148
+ 1,
18149
+ question.detail?.split(/\r?\n/).reduce((height, line) => {
18150
+ const wrappedLines2 = Math.max(
18151
+ 1,
18152
+ Math.ceil(
18153
+ getCachedStringWidth(line) / Math.max(1, terminalWidth - 4)
18154
+ )
18155
+ );
18156
+ return height + wrappedLines2;
18157
+ }, 0) ?? 1
18158
+ ),
18159
+ [question.detail, terminalWidth]
18160
+ );
18161
+ const planKeyExtractor = useCallback30(() => "plan-review-detail", []);
18162
+ const renderPlanDetail = useCallback30(
18163
+ ({ item }) => /* @__PURE__ */ jsx81(Box63, { flexDirection: "column", children: /* @__PURE__ */ jsx81(
18164
+ MarkdownDisplay,
18165
+ {
18166
+ availableTerminalHeight: planViewportHeight - 2,
18167
+ isPending: false,
18168
+ text: item,
18169
+ terminalWidth: terminalWidth - 2
18170
+ }
18171
+ ) }),
18172
+ [planViewportHeight, terminalWidth]
18173
+ );
18174
+ return /* @__PURE__ */ jsxs62(Fragment15, { children: [
18175
+ presentation === "plan-review" && /* @__PURE__ */ jsx81(Box63, { marginBottom: 1, children: /* @__PURE__ */ jsx81(Text58, { bold: true, color: theme.text.accent, children: "Plan Review" }) }),
18176
+ /* @__PURE__ */ jsx81(Box63, { marginBottom: 1, children: /* @__PURE__ */ jsx81(Text58, { bold: true, color: theme.text.primary, children: question.question }) }),
18177
+ question.detail && (presentation === "plan-review" ? /* @__PURE__ */ jsx81(
18178
+ Box63,
18179
+ {
18180
+ flexDirection: "column",
18181
+ borderStyle: "single",
18182
+ borderColor: theme.border.default,
18183
+ paddingX: 1,
18184
+ marginBottom: 1,
18185
+ height: planViewportHeight,
18186
+ overflow: "hidden",
18187
+ children: /* @__PURE__ */ jsx81(
18188
+ ScrollableListWithForwardRef,
18189
+ {
18190
+ data: planDetail,
18191
+ hasFocus: true,
18192
+ width: "100%",
18193
+ estimatedItemHeight: estimatePlanHeight,
18194
+ keyExtractor: planKeyExtractor,
18195
+ renderItem: renderPlanDetail
18196
+ }
18197
+ )
18198
+ }
18199
+ ) : /* @__PURE__ */ jsx81(Box63, { marginBottom: 1, children: /* @__PURE__ */ jsx81(Text58, { color: theme.text.secondary, children: question.detail }) }))
18200
+ ] });
18201
+ };
18028
18202
  function formatAnswerForReview(question, answer) {
18029
18203
  return answer.split(ASK_USER_ANSWER_SEPARATOR).map((value) => {
18030
18204
  const option = question.options?.find(
@@ -18083,7 +18257,8 @@ var TextQuestionView = ({
18083
18257
  onCursorEdgeChange,
18084
18258
  initialAnswer,
18085
18259
  progressHeader,
18086
- keyboardHints
18260
+ keyboardHints,
18261
+ presentation
18087
18262
  }) => {
18088
18263
  const uiState = useContext15(UIStateContext);
18089
18264
  const { stdout } = useStdout3();
@@ -18144,8 +18319,7 @@ var TextQuestionView = ({
18144
18319
  borderColor: theme.border.default,
18145
18320
  children: [
18146
18321
  progressHeader,
18147
- /* @__PURE__ */ jsx81(Box63, { marginBottom: 1, children: /* @__PURE__ */ jsx81(Text58, { bold: true, color: theme.text.primary, children: question.question }) }),
18148
- question.detail && /* @__PURE__ */ jsx81(Box63, { marginBottom: 1, children: /* @__PURE__ */ jsx81(Text58, { color: theme.text.secondary, children: question.detail }) }),
18322
+ /* @__PURE__ */ jsx81(QuestionPrompt, { question, presentation }),
18149
18323
  /* @__PURE__ */ jsxs62(Box63, { flexDirection: "row", marginBottom: 1, children: [
18150
18324
  /* @__PURE__ */ jsx81(Text58, { color: theme.text.accent, children: "> " }),
18151
18325
  /* @__PURE__ */ jsx81(
@@ -18215,16 +18389,17 @@ var ChoiceQuestionView = ({
18215
18389
  onCursorEdgeChange,
18216
18390
  initialAnswer,
18217
18391
  progressHeader,
18218
- keyboardHints
18392
+ keyboardHints,
18393
+ presentation
18219
18394
  }) => {
18220
18395
  const uiState = useContext15(UIStateContext);
18221
18396
  const { stdout } = useStdout3();
18222
18397
  const terminalWidth = uiState?.terminalWidth ?? stdout?.columns ?? 80;
18223
- const questionOptions = useMemo25(
18398
+ const questionOptions = useMemo26(
18224
18399
  () => question.options ?? [],
18225
18400
  [question.options]
18226
18401
  );
18227
- const initialReducerState = useMemo25(() => {
18402
+ const initialReducerState = useMemo26(() => {
18228
18403
  if (!initialAnswer) {
18229
18404
  return {
18230
18405
  selectedIndices: /* @__PURE__ */ new Set(),
@@ -18267,7 +18442,7 @@ var ChoiceQuestionView = ({
18267
18442
  initialReducerState
18268
18443
  );
18269
18444
  const { selectedIndices, isCustomOptionSelected, isCustomOptionFocused } = state;
18270
- const initialCustomText = useMemo25(() => {
18445
+ const initialCustomText = useMemo26(() => {
18271
18446
  if (!initialAnswer) return "";
18272
18447
  if (question.multiSelect) {
18273
18448
  const answers = initialAnswer.split(ASK_USER_ANSWER_SEPARATOR);
@@ -18348,7 +18523,7 @@ var ChoiceQuestionView = ({
18348
18523
  [isCustomOptionFocused, customBuffer, onEditingCustomOption]
18349
18524
  );
18350
18525
  useKeypress(handleExtraKeys, { isActive: true });
18351
- const selectionItems = useMemo25(() => {
18526
+ const selectionItems = useMemo26(() => {
18352
18527
  const list = questionOptions.map(
18353
18528
  (opt, i) => {
18354
18529
  const item = {
@@ -18383,6 +18558,13 @@ var ChoiceQuestionView = ({
18383
18558
  }
18384
18559
  return list;
18385
18560
  }, [questionOptions, question.multiSelect, question.type, customOptionText]);
18561
+ const preferredIndex = useMemo26(() => {
18562
+ if (question.preferredValue === void 0) return 0;
18563
+ const index = questionOptions.findIndex(
18564
+ (option) => (option.value ?? option.label) === question.preferredValue
18565
+ );
18566
+ return index < 0 ? 0 : index;
18567
+ }, [question.preferredValue, questionOptions]);
18386
18568
  const handleHighlight = useCallback30(
18387
18569
  (itemValue) => {
18388
18570
  const nowFocusingCustomOption = itemValue.type === "other";
@@ -18418,7 +18600,7 @@ var ChoiceQuestionView = ({
18418
18600
  }
18419
18601
  } else {
18420
18602
  if (itemValue.type === "option") {
18421
- onAnswer(itemValue.label);
18603
+ onAnswer(questionOptions[itemValue.index]?.value ?? itemValue.label);
18422
18604
  } else if (itemValue.type === "other") {
18423
18605
  if (customOptionText.trim()) {
18424
18606
  onAnswer(customOptionText.trim());
@@ -18432,7 +18614,8 @@ var ChoiceQuestionView = ({
18432
18614
  isCustomOptionSelected,
18433
18615
  customOptionText,
18434
18616
  onAnswer,
18435
- buildAnswerString
18617
+ buildAnswerString,
18618
+ questionOptions
18436
18619
  ]
18437
18620
  );
18438
18621
  useEffect37(() => {
@@ -18452,8 +18635,7 @@ var ChoiceQuestionView = ({
18452
18635
  borderColor: theme.border.default,
18453
18636
  children: [
18454
18637
  progressHeader,
18455
- /* @__PURE__ */ jsx81(Box63, { marginBottom: 1, children: /* @__PURE__ */ jsx81(Text58, { bold: true, color: theme.text.primary, children: question.question }) }),
18456
- question.detail && /* @__PURE__ */ jsx81(Box63, { marginBottom: 1, children: /* @__PURE__ */ jsx81(Text58, { color: theme.text.secondary, children: question.detail }) }),
18638
+ /* @__PURE__ */ jsx81(QuestionPrompt, { question, presentation }),
18457
18639
  question.multiSelect && /* @__PURE__ */ jsxs62(Text58, { color: theme.text.secondary, italic: true, children: [
18458
18640
  " ",
18459
18641
  "(Select all that apply)"
@@ -18462,6 +18644,7 @@ var ChoiceQuestionView = ({
18462
18644
  BaseSelectionList,
18463
18645
  {
18464
18646
  items: selectionItems,
18647
+ initialIndex: preferredIndex,
18465
18648
  onSelect: handleSelect,
18466
18649
  onHighlight: handleHighlight,
18467
18650
  focusKey: isCustomOptionFocused ? "other" : void 0,
@@ -18469,8 +18652,9 @@ var ChoiceQuestionView = ({
18469
18652
  const optionItem = item.value;
18470
18653
  const isChecked = selectedIndices.has(optionItem.index) || optionItem.type === "other" && isCustomOptionSelected;
18471
18654
  const showCheck = question.multiSelect && (optionItem.type === "option" || optionItem.type === "other");
18655
+ const isPreferred = optionItem.type === "option" && (questionOptions[optionItem.index]?.value ?? questionOptions[optionItem.index]?.label) === question.preferredValue;
18472
18656
  if (optionItem.type === "other") {
18473
- const placeholder = "Enter a custom value";
18657
+ const placeholder = presentation === "plan-review" ? context.isSelected ? "Describe what should change" : "Request changes..." : "Enter a custom value";
18474
18658
  return /* @__PURE__ */ jsxs62(Box63, { flexDirection: "row", children: [
18475
18659
  showCheck && /* @__PURE__ */ jsxs62(
18476
18660
  Text58,
@@ -18496,7 +18680,7 @@ var ChoiceQuestionView = ({
18496
18680
  isChecked && !question.multiSelect && /* @__PURE__ */ jsx81(Text58, { color: theme.status.success, children: " \u2713" })
18497
18681
  ] });
18498
18682
  }
18499
- const labelColor = isChecked && !question.multiSelect ? theme.status.success : context.isSelected ? context.titleColor : theme.text.primary;
18683
+ const labelColor = isChecked && !question.multiSelect ? theme.status.success : isPreferred ? theme.status.success : context.isSelected ? context.titleColor : theme.text.primary;
18500
18684
  return /* @__PURE__ */ jsxs62(Box63, { flexDirection: "column", children: [
18501
18685
  /* @__PURE__ */ jsxs62(Box63, { flexDirection: "row", children: [
18502
18686
  showCheck && /* @__PURE__ */ jsxs62(
@@ -18533,7 +18717,8 @@ var AskUserDialog = ({
18533
18717
  questions,
18534
18718
  onSubmit,
18535
18719
  onCancel,
18536
- onActiveTextInputChange
18720
+ onActiveTextInputChange,
18721
+ presentation = "default"
18537
18722
  }) => {
18538
18723
  const [state, dispatch] = useReducer4(askUserDialogReducerLogic, initialState2);
18539
18724
  const {
@@ -18544,6 +18729,7 @@ var AskUserDialog = ({
18544
18729
  submitted
18545
18730
  } = state;
18546
18731
  const isEditingCustomOptionRef = useRef16(false);
18732
+ const submissionDeliveredRef = useRef16(false);
18547
18733
  isEditingCustomOptionRef.current = isEditingCustomOption;
18548
18734
  const handleEditingCustomOption = useCallback30((isEditing) => {
18549
18735
  dispatch({ type: "SET_EDITING_CUSTOM", payload: { isEditing } });
@@ -18604,7 +18790,8 @@ var AskUserDialog = ({
18604
18790
  isActive: questions.length > 1 && !submitted
18605
18791
  });
18606
18792
  useEffect37(() => {
18607
- if (submitted) {
18793
+ if (submitted && !submissionDeliveredRef.current) {
18794
+ submissionDeliveredRef.current = true;
18608
18795
  const structuredAnswers = Object.fromEntries(
18609
18796
  Object.entries(answers).map(([index, raw]) => {
18610
18797
  const question = questions[Number(index)];
@@ -18664,12 +18851,12 @@ var AskUserDialog = ({
18664
18851
  },
18665
18852
  [submitted]
18666
18853
  );
18667
- const answeredIndices = useMemo25(
18854
+ const answeredIndices = useMemo26(
18668
18855
  () => new Set(Object.keys(answers).map(Number)),
18669
18856
  [answers]
18670
18857
  );
18671
18858
  const currentQuestion = questions[currentQuestionIndex];
18672
- const effectiveQuestion = useMemo25(() => {
18859
+ const effectiveQuestion = useMemo26(() => {
18673
18860
  if (currentQuestion?.type === "yesno") {
18674
18861
  return {
18675
18862
  ...currentQuestion,
@@ -18682,7 +18869,7 @@ var AskUserDialog = ({
18682
18869
  }
18683
18870
  return currentQuestion;
18684
18871
  }, [currentQuestion]);
18685
- const tabs = useMemo25(() => {
18872
+ const tabs = useMemo26(() => {
18686
18873
  const questionTabs = questions.map((q, i) => ({
18687
18874
  key: String(i),
18688
18875
  header: q.header
@@ -18716,7 +18903,7 @@ var AskUserDialog = ({
18716
18903
  );
18717
18904
  }
18718
18905
  if (!currentQuestion) return null;
18719
- const keyboardHints = /* @__PURE__ */ jsx81(Box63, { marginTop: 1, children: /* @__PURE__ */ jsx81(Text58, { color: theme.text.secondary, children: currentQuestion.type === "text" || isEditingCustomOption ? questions.length > 1 ? "Enter to submit \xB7 Tab/Shift+Tab to switch questions \xB7 Esc to cancel" : "Enter to submit \xB7 Esc to cancel" : questions.length > 1 ? "Enter to select \xB7 \u2190/\u2192 to switch questions \xB7 Esc to cancel" : "Enter to select \xB7 \u2191/\u2193 to navigate \xB7 Esc to cancel" }) });
18906
+ const keyboardHints = /* @__PURE__ */ jsx81(Box63, { marginTop: 1, children: /* @__PURE__ */ jsx81(Text58, { color: theme.text.secondary, children: presentation === "plan-review" ? "Enter to select \xB7 \u2191/\u2193 options \xB7 Shift+\u2191/\u2193 or PgUp/PgDn scroll plan \xB7 Esc to cancel" : currentQuestion.type === "text" || isEditingCustomOption ? questions.length > 1 ? "Enter to submit \xB7 Tab/Shift+Tab to switch questions \xB7 Esc to cancel" : "Enter to submit \xB7 Esc to cancel" : questions.length > 1 ? "Enter to select \xB7 \u2190/\u2192 to switch questions \xB7 Esc to cancel" : "Enter to select \xB7 \u2191/\u2193 to navigate \xB7 Esc to cancel" }) });
18720
18907
  if (currentQuestion.type === "text") {
18721
18908
  return /* @__PURE__ */ jsx81(
18722
18909
  TextQuestionView,
@@ -18728,7 +18915,8 @@ var AskUserDialog = ({
18728
18915
  onCursorEdgeChange: handleCursorEdgeChange,
18729
18916
  initialAnswer: answers[currentQuestionIndex],
18730
18917
  progressHeader,
18731
- keyboardHints
18918
+ keyboardHints,
18919
+ presentation
18732
18920
  },
18733
18921
  currentQuestionIndex
18734
18922
  );
@@ -18743,18 +18931,74 @@ var AskUserDialog = ({
18743
18931
  onCursorEdgeChange: handleCursorEdgeChange,
18744
18932
  initialAnswer: answers[currentQuestionIndex],
18745
18933
  progressHeader,
18746
- keyboardHints
18934
+ keyboardHints,
18935
+ presentation
18747
18936
  },
18748
18937
  currentQuestionIndex
18749
18938
  );
18750
18939
  };
18751
18940
 
18752
- // src/ui/components/dialogs/user-question-queue.tsx
18941
+ // src/ui/components/dialogs/plan-review-dialog.tsx
18942
+ import { useCallback as useCallback31, useMemo as useMemo27 } from "react";
18753
18943
  import { jsx as jsx82 } from "react/jsx-runtime";
18944
+ function PlanReviewDialog({
18945
+ question,
18946
+ onSubmit,
18947
+ onCancel
18948
+ }) {
18949
+ const presented = useMemo27(
18950
+ () => ({
18951
+ id: question.id,
18952
+ header: question.header ?? "Plan Review",
18953
+ question: question.question,
18954
+ ...question.detail === void 0 ? {} : { detail: question.detail },
18955
+ type: "choice" /* CHOICE */,
18956
+ ...question.options === void 0 ? {} : {
18957
+ options: question.options.map((option) => ({
18958
+ value: option.value,
18959
+ label: option.label,
18960
+ description: option.description ?? (option.value === question.intent?.approveValue ? "Approve this plan and continue." : "")
18961
+ }))
18962
+ },
18963
+ multiSelect: false,
18964
+ ...question.intent === void 0 ? {} : { preferredValue: question.intent.approveValue }
18965
+ }),
18966
+ [question]
18967
+ );
18968
+ const presentedQuestions = useMemo27(() => [presented], [presented]);
18969
+ const handleSubmit = useCallback31(
18970
+ (answers) => {
18971
+ const answer = answers[0] ?? { selected: [] };
18972
+ onSubmit({
18973
+ id: question.id,
18974
+ selected: answer.selected,
18975
+ ...answer.custom === void 0 ? {} : { custom: answer.custom }
18976
+ });
18977
+ },
18978
+ [onSubmit, question.id]
18979
+ );
18980
+ return /* @__PURE__ */ jsx82(
18981
+ AskUserDialog,
18982
+ {
18983
+ questions: presentedQuestions,
18984
+ presentation: "plan-review",
18985
+ onCancel,
18986
+ onSubmit: handleSubmit
18987
+ }
18988
+ );
18989
+ }
18990
+
18991
+ // src/ui/components/dialogs/user-question-queue.tsx
18992
+ import { jsx as jsx83 } from "react/jsx-runtime";
18993
+ function isPlanReview(question) {
18994
+ return question.intent?.kind === "plan-review" && question.detail !== void 0 && question.multiSelect === false && question.options?.some(
18995
+ (option) => option.value === question.intent?.approveValue
18996
+ ) === true;
18997
+ }
18754
18998
  var UserQuestionQueue = () => {
18755
18999
  const { runtime, snapshot } = useUserQuestionRuntime();
18756
19000
  const request = snapshot.pending[0];
18757
- const questions = useMemo26(
19001
+ const questions = useMemo28(
18758
19002
  () => request?.questions.map((question) => ({
18759
19003
  id: question.id,
18760
19004
  question: question.question,
@@ -18773,7 +19017,19 @@ var UserQuestionQueue = () => {
18773
19017
  [request]
18774
19018
  );
18775
19019
  if (request === void 0) return null;
18776
- return /* @__PURE__ */ jsx82(
19020
+ const planReview = request.questions.length === 1 && isPlanReview(request.questions[0]) ? request.questions[0] : void 0;
19021
+ if (planReview !== void 0) {
19022
+ return /* @__PURE__ */ jsx83(
19023
+ PlanReviewDialog,
19024
+ {
19025
+ question: planReview,
19026
+ onCancel: () => runtime.cancel(request.id),
19027
+ onSubmit: (answer) => runtime.answer(request.id, [answer])
19028
+ },
19029
+ request.id
19030
+ );
19031
+ }
19032
+ return /* @__PURE__ */ jsx83(
18777
19033
  AskUserDialog,
18778
19034
  {
18779
19035
  questions: [...questions],
@@ -18791,12 +19047,13 @@ var UserQuestionQueue = () => {
18791
19047
  })
18792
19048
  );
18793
19049
  }
18794
- }
19050
+ },
19051
+ request.id
18795
19052
  );
18796
19053
  };
18797
19054
 
18798
19055
  // src/ui/components/layout/screen-reader-app-layout.tsx
18799
- import { jsx as jsx83, jsxs as jsxs63 } from "react/jsx-runtime";
19056
+ import { jsx as jsx84, jsxs as jsxs63 } from "react/jsx-runtime";
18800
19057
  var ScreenReaderAppLayout = () => {
18801
19058
  const uiState = useUIState();
18802
19059
  const { rootUiRef, terminalHeight } = uiState;
@@ -18813,10 +19070,10 @@ var ScreenReaderAppLayout = () => {
18813
19070
  height: "100%",
18814
19071
  ref: uiState.rootUiRef,
18815
19072
  children: [
18816
- /* @__PURE__ */ jsx83(Notifications, {}),
18817
- /* @__PURE__ */ jsx83(Footer, {}),
18818
- /* @__PURE__ */ jsx83(Box64, { flexGrow: 1, overflow: "hidden", children: /* @__PURE__ */ jsx83(MainContent, {}) }),
18819
- pendingApproval !== void 0 ? /* @__PURE__ */ jsx83(
19073
+ /* @__PURE__ */ jsx84(Notifications, {}),
19074
+ /* @__PURE__ */ jsx84(Footer, {}),
19075
+ /* @__PURE__ */ jsx84(Box64, { flexGrow: 1, overflow: "hidden", children: /* @__PURE__ */ jsx84(MainContent, {}) }),
19076
+ pendingApproval !== void 0 ? /* @__PURE__ */ jsx84(
18820
19077
  ToolConfirmationQueue,
18821
19078
  {
18822
19079
  request: pendingApproval,
@@ -18825,13 +19082,13 @@ var ScreenReaderAppLayout = () => {
18825
19082
  terminalWidth: uiState.terminalWidth,
18826
19083
  respond: (response) => approvalRuntime.respond(pendingApproval.id, response)
18827
19084
  }
18828
- ) : pendingUserQuestion !== void 0 ? /* @__PURE__ */ jsx83(UserQuestionQueue, {}) : uiState.dialogsVisible ? /* @__PURE__ */ jsx83(
19085
+ ) : pendingUserQuestion !== void 0 ? /* @__PURE__ */ jsx84(UserQuestionQueue, {}) : uiState.dialogsVisible ? /* @__PURE__ */ jsx84(
18829
19086
  DialogManager,
18830
19087
  {
18831
19088
  terminalWidth: uiState.terminalWidth
18832
19089
  }
18833
- ) : /* @__PURE__ */ jsx83(Composer, {}),
18834
- /* @__PURE__ */ jsx83(ExitWarning, {})
19090
+ ) : /* @__PURE__ */ jsx84(Composer, {}),
19091
+ /* @__PURE__ */ jsx84(ExitWarning, {})
18835
19092
  ]
18836
19093
  }
18837
19094
  );
@@ -18842,17 +19099,17 @@ import { Box as Box66 } from "ink";
18842
19099
 
18843
19100
  // src/ui/components/dialogs/copy-mode-warning.tsx
18844
19101
  import { Box as Box65, Text as Text59 } from "ink";
18845
- import { jsx as jsx84 } from "react/jsx-runtime";
19102
+ import { jsx as jsx85 } from "react/jsx-runtime";
18846
19103
  var CopyModeWarning = () => {
18847
19104
  const { copyModeEnabled } = useUIState();
18848
19105
  if (!copyModeEnabled) {
18849
19106
  return null;
18850
19107
  }
18851
- return /* @__PURE__ */ jsx84(Box65, { children: /* @__PURE__ */ jsx84(Text59, { color: theme.status.warning, children: "In Copy Mode. Press any key to exit." }) });
19108
+ return /* @__PURE__ */ jsx85(Box65, { children: /* @__PURE__ */ jsx85(Text59, { color: theme.status.warning, children: "In Copy Mode. Press any key to exit." }) });
18852
19109
  };
18853
19110
 
18854
19111
  // src/ui/components/layout/default-app-layout.tsx
18855
- import { Fragment as Fragment15, jsx as jsx85, jsxs as jsxs64 } from "react/jsx-runtime";
19112
+ import { Fragment as Fragment16, jsx as jsx86, jsxs as jsxs64 } from "react/jsx-runtime";
18856
19113
  var DefaultAppLayout = () => {
18857
19114
  const uiState = useUIState();
18858
19115
  const isAlternateBuffer = useAlternateBuffer();
@@ -18874,7 +19131,7 @@ var DefaultAppLayout = () => {
18874
19131
  overflow: "hidden",
18875
19132
  ref: uiState.rootUiRef,
18876
19133
  children: [
18877
- /* @__PURE__ */ jsx85(MainContent, {}),
19134
+ /* @__PURE__ */ jsx86(MainContent, {}),
18878
19135
  /* @__PURE__ */ jsxs64(
18879
19136
  Box66,
18880
19137
  {
@@ -18884,10 +19141,10 @@ var DefaultAppLayout = () => {
18884
19141
  flexGrow: 0,
18885
19142
  width: uiState.terminalWidth,
18886
19143
  children: [
18887
- /* @__PURE__ */ jsx85(Notifications, {}),
18888
- /* @__PURE__ */ jsx85(CopyModeWarning, {}),
18889
- pendingApproval !== void 0 ? /* @__PURE__ */ jsxs64(Fragment15, { children: [
18890
- /* @__PURE__ */ jsx85(
19144
+ /* @__PURE__ */ jsx86(Notifications, {}),
19145
+ /* @__PURE__ */ jsx86(CopyModeWarning, {}),
19146
+ pendingApproval !== void 0 ? /* @__PURE__ */ jsxs64(Fragment16, { children: [
19147
+ /* @__PURE__ */ jsx86(
18891
19148
  ToolConfirmationQueue,
18892
19149
  {
18893
19150
  request: pendingApproval,
@@ -18897,14 +19154,14 @@ var DefaultAppLayout = () => {
18897
19154
  respond: (response) => approvalRuntime.respond(pendingApproval.id, response)
18898
19155
  }
18899
19156
  ),
18900
- /* @__PURE__ */ jsx85(Composer, { isFocused: false })
18901
- ] }) : pendingUserQuestion !== void 0 ? /* @__PURE__ */ jsx85(UserQuestionQueue, {}) : uiState.customDialog ? uiState.customDialog : uiState.dialogsVisible ? /* @__PURE__ */ jsx85(
19157
+ /* @__PURE__ */ jsx86(Composer, { isFocused: false })
19158
+ ] }) : pendingUserQuestion !== void 0 ? /* @__PURE__ */ jsx86(UserQuestionQueue, {}) : uiState.customDialog ? uiState.customDialog : uiState.dialogsVisible ? /* @__PURE__ */ jsx86(
18902
19159
  DialogManager,
18903
19160
  {
18904
19161
  terminalWidth: uiState.terminalWidth
18905
19162
  }
18906
- ) : /* @__PURE__ */ jsx85(Composer, { isFocused: true }),
18907
- /* @__PURE__ */ jsx85(ExitWarning, {})
19163
+ ) : /* @__PURE__ */ jsx86(Composer, { isFocused: true }),
19164
+ /* @__PURE__ */ jsx86(ExitWarning, {})
18908
19165
  ]
18909
19166
  }
18910
19167
  )
@@ -18915,7 +19172,7 @@ var DefaultAppLayout = () => {
18915
19172
 
18916
19173
  // src/ui/components/indicators/alternate-buffer-quitting-display.tsx
18917
19174
  import { Box as Box67, Text as Text60 } from "ink";
18918
- import { jsx as jsx86, jsxs as jsxs65 } from "react/jsx-runtime";
19175
+ import { jsx as jsx87, jsxs as jsxs65 } from "react/jsx-runtime";
18919
19176
  var AlternateBufferQuittingDisplay = () => {
18920
19177
  const { version } = useAppContext();
18921
19178
  const uiState = useUIState();
@@ -18929,8 +19186,8 @@ var AlternateBufferQuittingDisplay = () => {
18929
19186
  flexGrow: 0,
18930
19187
  width: uiState.terminalWidth,
18931
19188
  children: [
18932
- /* @__PURE__ */ jsx86(AppHeader, { version }, "app-header"),
18933
- uiState.history.map((h) => /* @__PURE__ */ jsx86(
19189
+ /* @__PURE__ */ jsx87(AppHeader, { version }, "app-header"),
19190
+ uiState.history.map((h) => /* @__PURE__ */ jsx87(
18934
19191
  HistoryItemDisplay,
18935
19192
  {
18936
19193
  terminalWidth: uiState.mainAreaWidth,
@@ -18942,7 +19199,7 @@ var AlternateBufferQuittingDisplay = () => {
18942
19199
  },
18943
19200
  h.id
18944
19201
  )),
18945
- uiState.pendingHistoryItems.map((item, i) => /* @__PURE__ */ jsx86(
19202
+ uiState.pendingHistoryItems.map((item, i) => /* @__PURE__ */ jsx87(
18946
19203
  HistoryItemDisplay,
18947
19204
  {
18948
19205
  availableTerminalHeight: void 0,
@@ -18956,48 +19213,48 @@ var AlternateBufferQuittingDisplay = () => {
18956
19213
  i
18957
19214
  )),
18958
19215
  pendingApproval !== void 0 && /* @__PURE__ */ jsxs65(Box67, { flexDirection: "column", marginTop: 1, marginBottom: 1, children: [
18959
- /* @__PURE__ */ jsx86(Text60, { color: theme.status.warning, bold: true, children: "Action Required (was prompted):" }),
18960
- /* @__PURE__ */ jsx86(Text60, { color: theme.text.primary, children: pendingApproval.toolName }),
18961
- pendingApproval.reason !== void 0 && /* @__PURE__ */ jsx86(Text60, { color: theme.text.secondary, children: pendingApproval.reason })
19216
+ /* @__PURE__ */ jsx87(Text60, { color: theme.status.warning, bold: true, children: "Action Required (was prompted):" }),
19217
+ /* @__PURE__ */ jsx87(Text60, { color: theme.text.primary, children: pendingApproval.toolName }),
19218
+ pendingApproval.reason !== void 0 && /* @__PURE__ */ jsx87(Text60, { color: theme.text.secondary, children: pendingApproval.reason })
18962
19219
  ] }),
18963
- /* @__PURE__ */ jsx86(QuittingDisplay, {})
19220
+ /* @__PURE__ */ jsx87(QuittingDisplay, {})
18964
19221
  ]
18965
19222
  }
18966
19223
  );
18967
19224
  };
18968
19225
 
18969
19226
  // src/ui/app.tsx
18970
- import { jsx as jsx87 } from "react/jsx-runtime";
19227
+ import { jsx as jsx88 } from "react/jsx-runtime";
18971
19228
  var App = () => {
18972
19229
  const uiState = useUIState();
18973
19230
  const isAlternateBuffer = useAlternateBuffer();
18974
19231
  const isScreenReaderEnabled = useIsScreenReaderEnabled5();
18975
19232
  if (uiState.quittingMessages) {
18976
19233
  if (isAlternateBuffer) {
18977
- return /* @__PURE__ */ jsx87(StreamingContext.Provider, { value: uiState.streamingState, children: /* @__PURE__ */ jsx87(AlternateBufferQuittingDisplay, {}) });
19234
+ return /* @__PURE__ */ jsx88(StreamingContext.Provider, { value: uiState.streamingState, children: /* @__PURE__ */ jsx88(AlternateBufferQuittingDisplay, {}) });
18978
19235
  } else {
18979
- return /* @__PURE__ */ jsx87(QuittingDisplay, {});
19236
+ return /* @__PURE__ */ jsx88(QuittingDisplay, {});
18980
19237
  }
18981
19238
  }
18982
- return /* @__PURE__ */ jsx87(StreamingContext.Provider, { value: uiState.streamingState, children: isScreenReaderEnabled ? /* @__PURE__ */ jsx87(ScreenReaderAppLayout, {}) : /* @__PURE__ */ jsx87(DefaultAppLayout, {}) });
19239
+ return /* @__PURE__ */ jsx88(StreamingContext.Provider, { value: uiState.streamingState, children: isScreenReaderEnabled ? /* @__PURE__ */ jsx88(ScreenReaderAppLayout, {}) : /* @__PURE__ */ jsx88(DefaultAppLayout, {}) });
18983
19240
  };
18984
19241
 
18985
19242
  // src/ui/app-container.tsx
18986
19243
  import process8 from "node:process";
18987
19244
 
18988
19245
  // src/ui/hooks/session/use-history-manager.ts
18989
- import { useState as useState34, useRef as useRef17, useCallback as useCallback31, useMemo as useMemo27 } from "react";
19246
+ import { useState as useState34, useRef as useRef17, useCallback as useCallback32, useMemo as useMemo29 } from "react";
18990
19247
  function useHistory() {
18991
19248
  const [history, setHistory] = useState34([]);
18992
19249
  const messageIdCounterRef = useRef17(0);
18993
- const getNextMessageId = useCallback31((baseTimestamp) => {
19250
+ const getNextMessageId = useCallback32((baseTimestamp) => {
18994
19251
  messageIdCounterRef.current += 1;
18995
19252
  return baseTimestamp + messageIdCounterRef.current;
18996
19253
  }, []);
18997
- const loadHistory = useCallback31((newHistory) => {
19254
+ const loadHistory = useCallback32((newHistory) => {
18998
19255
  setHistory(newHistory);
18999
19256
  }, []);
19000
- const addItem = useCallback31(
19257
+ const addItem = useCallback32(
19001
19258
  (itemData, baseTimestamp = Date.now()) => {
19002
19259
  const id = getNextMessageId(baseTimestamp);
19003
19260
  const newItem = { ...itemData, id };
@@ -19014,7 +19271,7 @@ function useHistory() {
19014
19271
  },
19015
19272
  [getNextMessageId]
19016
19273
  );
19017
- const updateItem = useCallback31(
19274
+ const updateItem = useCallback32(
19018
19275
  (id, updates) => {
19019
19276
  setHistory(
19020
19277
  (prevHistory) => prevHistory.map((item) => {
@@ -19028,11 +19285,11 @@ function useHistory() {
19028
19285
  },
19029
19286
  []
19030
19287
  );
19031
- const clearItems = useCallback31(() => {
19288
+ const clearItems = useCallback32(() => {
19032
19289
  setHistory([]);
19033
19290
  messageIdCounterRef.current = 0;
19034
19291
  }, []);
19035
- return useMemo27(
19292
+ return useMemo29(
19036
19293
  () => ({
19037
19294
  history,
19038
19295
  addItem,
@@ -19045,7 +19302,7 @@ function useHistory() {
19045
19302
  }
19046
19303
 
19047
19304
  // src/ui/hooks/commands/use-slash-command-processor.ts
19048
- import { useCallback as useCallback36, useMemo as useMemo34, useEffect as useEffect44, useRef as useRef22, useState as useState42 } from "react";
19305
+ import { useCallback as useCallback37, useMemo as useMemo36, useEffect as useEffect44, useRef as useRef22, useState as useState42 } from "react";
19049
19306
 
19050
19307
  // src/services/command-service.ts
19051
19308
  var CommandService = class _CommandService {
@@ -19228,13 +19485,13 @@ var vimCommand = {
19228
19485
  import React16 from "react";
19229
19486
 
19230
19487
  // src/ui/components/dialogs/model-dialog.tsx
19231
- import { useCallback as useCallback32, useEffect as useEffect39, useMemo as useMemo28, useRef as useRef19, useState as useState36 } from "react";
19488
+ import { useCallback as useCallback33, useEffect as useEffect39, useMemo as useMemo30, useRef as useRef19, useState as useState36 } from "react";
19232
19489
  import { Box as Box69, Text as Text62 } from "ink";
19233
19490
 
19234
19491
  // src/ui/components/dialogs/provider-setup-dialog.tsx
19235
19492
  import { useEffect as useEffect38, useRef as useRef18, useState as useState35 } from "react";
19236
19493
  import { Box as Box68, Text as Text61 } from "ink";
19237
- import { jsx as jsx88, jsxs as jsxs66 } from "react/jsx-runtime";
19494
+ import { jsx as jsx89, jsxs as jsxs66 } from "react/jsx-runtime";
19238
19495
  function ProviderSetupDialog({
19239
19496
  runtime,
19240
19497
  provider,
@@ -19352,39 +19609,39 @@ function ProviderSetupDialog({
19352
19609
  label
19353
19610
  ] }),
19354
19611
  /* @__PURE__ */ jsxs66(Text61, { color: theme.text.secondary, children: [
19355
- /* @__PURE__ */ jsx88(Text61, { bold: true, color: theme.text.primary, children: "Esc" }),
19612
+ /* @__PURE__ */ jsx89(Text61, { bold: true, color: theme.text.primary, children: "Esc" }),
19356
19613
  " ",
19357
19614
  reason === "first-run" ? "Cancel" : "Close"
19358
19615
  ] })
19359
19616
  ] }),
19360
19617
  /* @__PURE__ */ jsxs66(Box68, { marginTop: 1, flexDirection: "column", children: [
19361
- /* @__PURE__ */ jsx88(Text61, { color: theme.text.primary, children: reason === "first-run" ? `Enter your ${label} API key to continue.` : `Enter a replacement credential for ${label}.` }),
19618
+ /* @__PURE__ */ jsx89(Text61, { color: theme.text.primary, children: reason === "first-run" ? `Enter your ${label} API key to continue.` : `Enter a replacement credential for ${label}.` }),
19362
19619
  /* @__PURE__ */ jsxs66(Text61, { color: theme.text.secondary, children: [
19363
19620
  "Alternatively, set ",
19364
19621
  credential,
19365
19622
  " before starting DSH Console."
19366
19623
  ] })
19367
19624
  ] }),
19368
- !view && !error && /* @__PURE__ */ jsx88(Box68, { marginTop: 1, children: /* @__PURE__ */ jsx88(Text61, { color: theme.text.secondary, children: "Checking provider setup..." }) }),
19369
- view?.status === "configured" && /* @__PURE__ */ jsx88(Box68, { marginTop: 1, children: /* @__PURE__ */ jsxs66(Text61, { color: theme.status.success, children: [
19625
+ !view && !error && /* @__PURE__ */ jsx89(Box68, { marginTop: 1, children: /* @__PURE__ */ jsx89(Text61, { color: theme.text.secondary, children: "Checking provider setup..." }) }),
19626
+ view?.status === "configured" && /* @__PURE__ */ jsx89(Box68, { marginTop: 1, children: /* @__PURE__ */ jsxs66(Text61, { color: theme.status.success, children: [
19370
19627
  "Configured from ",
19371
19628
  view.source ?? "DSH credential storage",
19372
19629
  "."
19373
19630
  ] }) }),
19374
- (view?.status === "unsupported" || view?.status === "error") && view.message && /* @__PURE__ */ jsx88(Box68, { marginTop: 1, children: /* @__PURE__ */ jsx88(Text61, { color: theme.status.warning, children: view.message }) }),
19375
- isReadOnly && /* @__PURE__ */ jsx88(Box68, { marginTop: 1, children: /* @__PURE__ */ jsxs66(Text61, { color: theme.status.warning, children: [
19631
+ (view?.status === "unsupported" || view?.status === "error") && view.message && /* @__PURE__ */ jsx89(Box68, { marginTop: 1, children: /* @__PURE__ */ jsx89(Text61, { color: theme.status.warning, children: view.message }) }),
19632
+ isReadOnly && /* @__PURE__ */ jsx89(Box68, { marginTop: 1, children: /* @__PURE__ */ jsxs66(Text61, { color: theme.status.warning, children: [
19376
19633
  credential,
19377
19634
  " is supplied by a read-only source. Change that source and restart DSH Console."
19378
19635
  ] }) }),
19379
19636
  canWrite && /* @__PURE__ */ jsxs66(Box68, { marginTop: 1, flexDirection: "column", children: [
19380
- /* @__PURE__ */ jsx88(Text61, { bold: true, color: theme.text.primary, children: fieldLabel }),
19381
- /* @__PURE__ */ jsx88(
19637
+ /* @__PURE__ */ jsx89(Text61, { bold: true, color: theme.text.primary, children: fieldLabel }),
19638
+ /* @__PURE__ */ jsx89(
19382
19639
  Box68,
19383
19640
  {
19384
19641
  borderStyle: "single",
19385
19642
  borderColor: saving ? theme.border.default : theme.text.accent,
19386
19643
  paddingX: 1,
19387
- children: /* @__PURE__ */ jsx88(Text61, { color: theme.text.primary, children: secret.length === 0 ? /* @__PURE__ */ jsxs66(Text61, { color: theme.text.secondary, children: [
19644
+ children: /* @__PURE__ */ jsx89(Text61, { color: theme.text.primary, children: secret.length === 0 ? /* @__PURE__ */ jsxs66(Text61, { color: theme.text.secondary, children: [
19388
19645
  "Paste your ",
19389
19646
  label,
19390
19647
  " API key"
@@ -19392,37 +19649,37 @@ function ProviderSetupDialog({
19392
19649
  }
19393
19650
  )
19394
19651
  ] }),
19395
- error && /* @__PURE__ */ jsx88(Box68, { marginTop: 1, children: /* @__PURE__ */ jsx88(Text61, { color: theme.status.error, children: error }) }),
19652
+ error && /* @__PURE__ */ jsx89(Box68, { marginTop: 1, children: /* @__PURE__ */ jsx89(Text61, { color: theme.status.error, children: error }) }),
19396
19653
  canWrite ? /* @__PURE__ */ jsxs66(Box68, { marginTop: 1, flexDirection: "column", children: [
19397
- /* @__PURE__ */ jsx88(Text61, { color: theme.text.secondary, children: "Stored through the configured DSH credential service. Never added to prompts, sessions, history, or logs." }),
19654
+ /* @__PURE__ */ jsx89(Text61, { color: theme.text.secondary, children: "Stored through the configured DSH credential service. Never added to prompts, sessions, history, or logs." }),
19398
19655
  /* @__PURE__ */ jsxs66(Box68, { marginTop: 1, children: [
19399
- /* @__PURE__ */ jsx88(Text61, { bold: true, color: theme.text.accent, children: "Enter" }),
19400
- /* @__PURE__ */ jsx88(Text61, { color: theme.text.primary, children: " Save and continue" }),
19401
- /* @__PURE__ */ jsx88(Text61, { color: theme.text.secondary, children: " " }),
19402
- /* @__PURE__ */ jsx88(Text61, { bold: true, color: theme.text.primary, children: "Esc" }),
19656
+ /* @__PURE__ */ jsx89(Text61, { bold: true, color: theme.text.accent, children: "Enter" }),
19657
+ /* @__PURE__ */ jsx89(Text61, { color: theme.text.primary, children: " Save and continue" }),
19658
+ /* @__PURE__ */ jsx89(Text61, { color: theme.text.secondary, children: " " }),
19659
+ /* @__PURE__ */ jsx89(Text61, { bold: true, color: theme.text.primary, children: "Esc" }),
19403
19660
  /* @__PURE__ */ jsxs66(Text61, { color: theme.text.secondary, children: [
19404
19661
  " ",
19405
19662
  reason === "first-run" ? "Cancel" : "Close"
19406
19663
  ] }),
19407
- /* @__PURE__ */ jsx88(Text61, { color: theme.text.secondary, children: " " }),
19408
- /* @__PURE__ */ jsx88(Text61, { bold: true, color: theme.text.primary, children: "Ctrl+C" }),
19664
+ /* @__PURE__ */ jsx89(Text61, { color: theme.text.secondary, children: " " }),
19665
+ /* @__PURE__ */ jsx89(Text61, { bold: true, color: theme.text.primary, children: "Ctrl+C" }),
19409
19666
  /* @__PURE__ */ jsxs66(Text61, { color: theme.text.secondary, children: [
19410
19667
  " ",
19411
19668
  secret.length > 0 ? "Clear" : "Cancel"
19412
19669
  ] })
19413
19670
  ] })
19414
19671
  ] }) : /* @__PURE__ */ jsxs66(Box68, { marginTop: 1, children: [
19415
- /* @__PURE__ */ jsx88(Text61, { bold: true, color: theme.text.primary, children: "Esc" }),
19416
- /* @__PURE__ */ jsx88(Text61, { color: theme.text.secondary, children: " Close" })
19672
+ /* @__PURE__ */ jsx89(Text61, { bold: true, color: theme.text.primary, children: "Esc" }),
19673
+ /* @__PURE__ */ jsx89(Text61, { color: theme.text.secondary, children: " Close" })
19417
19674
  ] }),
19418
- saving && /* @__PURE__ */ jsx88(Text61, { bold: true, color: theme.text.accent, children: "Saving credential..." })
19675
+ saving && /* @__PURE__ */ jsx89(Text61, { bold: true, color: theme.text.accent, children: "Saving credential..." })
19419
19676
  ]
19420
19677
  }
19421
19678
  );
19422
19679
  }
19423
19680
 
19424
19681
  // src/ui/components/dialogs/model-dialog.tsx
19425
- import { Fragment as Fragment16, jsx as jsx89, jsxs as jsxs67 } from "react/jsx-runtime";
19682
+ import { Fragment as Fragment17, jsx as jsx90, jsxs as jsxs67 } from "react/jsx-runtime";
19426
19683
  function capabilityLabel(model) {
19427
19684
  return model.inputModalities.includes("image") ? "Text + Vision" : "Text";
19428
19685
  }
@@ -19477,7 +19734,7 @@ function ModelDialog({
19477
19734
  (model) => model.provider === current.provider && model.model === current.model
19478
19735
  )
19479
19736
  );
19480
- const items = useMemo28(
19737
+ const items = useMemo30(
19481
19738
  () => models.map((model) => ({
19482
19739
  key: modelSelectionLabel(model),
19483
19740
  value: model,
@@ -19485,7 +19742,7 @@ function ModelDialog({
19485
19742
  })),
19486
19743
  [models]
19487
19744
  );
19488
- const switchModel = useCallback32(
19745
+ const switchModel = useCallback33(
19489
19746
  async (selection) => {
19490
19747
  setSwitching(true);
19491
19748
  setError(void 0);
@@ -19505,7 +19762,7 @@ function ModelDialog({
19505
19762
  },
19506
19763
  [onSwitched, runtime]
19507
19764
  );
19508
- const finishSelection = useCallback32(
19765
+ const finishSelection = useCallback33(
19509
19766
  (selection) => {
19510
19767
  if (selection.provider === current.provider && selection.model === current.model && selection.reasoning?.selectedEffort === current.reasoning?.selectedEffort) {
19511
19768
  onClose();
@@ -19526,7 +19783,7 @@ function ModelDialog({
19526
19783
  switchModel
19527
19784
  ]
19528
19785
  );
19529
- const continueSelection = useCallback32(
19786
+ const continueSelection = useCallback33(
19530
19787
  (selection) => {
19531
19788
  if (selection.reasoning?.efforts.length) {
19532
19789
  setReasoningSelection(selection);
@@ -19536,7 +19793,7 @@ function ModelDialog({
19536
19793
  },
19537
19794
  [finishSelection]
19538
19795
  );
19539
- const selectModel = useCallback32(
19796
+ const selectModel = useCallback33(
19540
19797
  async (selection) => {
19541
19798
  if (providerSetupRuntime) {
19542
19799
  providerCheckRef.current?.abort();
@@ -19590,7 +19847,7 @@ function ModelDialog({
19590
19847
  { isActive: setupSelection === void 0 }
19591
19848
  );
19592
19849
  if (setupSelection) {
19593
- return /* @__PURE__ */ jsx89(
19850
+ return /* @__PURE__ */ jsx90(
19594
19851
  ProviderSetupDialog,
19595
19852
  {
19596
19853
  runtime: providerSetupRuntime,
@@ -19637,11 +19894,11 @@ function ModelDialog({
19637
19894
  width: "100%",
19638
19895
  children: [
19639
19896
  /* @__PURE__ */ jsxs67(Box69, { justifyContent: "space-between", children: [
19640
- /* @__PURE__ */ jsx89(Text62, { bold: true, color: theme.text.primary, children: "Select Reasoning Effort" }),
19641
- /* @__PURE__ */ jsx89(Text62, { color: theme.text.secondary, children: "Esc to models" })
19897
+ /* @__PURE__ */ jsx90(Text62, { bold: true, color: theme.text.primary, children: "Select Reasoning Effort" }),
19898
+ /* @__PURE__ */ jsx90(Text62, { color: theme.text.secondary, children: "Esc to models" })
19642
19899
  ] }),
19643
19900
  /* @__PURE__ */ jsxs67(Box69, { marginTop: 1, flexDirection: "row", children: [
19644
- /* @__PURE__ */ jsx89(Box69, { width: "55%", paddingRight: 2, flexDirection: "column", children: /* @__PURE__ */ jsx89(
19901
+ /* @__PURE__ */ jsx90(Box69, { width: "55%", paddingRight: 2, flexDirection: "column", children: /* @__PURE__ */ jsx90(
19645
19902
  RadioButtonSelect,
19646
19903
  {
19647
19904
  items: effortItems,
@@ -19661,19 +19918,19 @@ function ModelDialog({
19661
19918
  }
19662
19919
  ) }),
19663
19920
  /* @__PURE__ */ jsxs67(Box69, { width: "45%", paddingLeft: 2, flexDirection: "column", children: [
19664
- /* @__PURE__ */ jsx89(Text62, { bold: true, color: theme.text.primary, children: reasoningSelection.name }),
19921
+ /* @__PURE__ */ jsx90(Text62, { bold: true, color: theme.text.primary, children: reasoningSelection.name }),
19665
19922
  /* @__PURE__ */ jsxs67(Box69, { marginTop: 1, flexDirection: "column", children: [
19666
- /* @__PURE__ */ jsx89(Text62, { color: theme.text.secondary, children: "Current choice" }),
19667
- /* @__PURE__ */ jsx89(Text62, { children: modelReasoningEffortLabel({
19923
+ /* @__PURE__ */ jsx90(Text62, { color: theme.text.secondary, children: "Current choice" }),
19924
+ /* @__PURE__ */ jsx90(Text62, { children: modelReasoningEffortLabel({
19668
19925
  ...reasoningSelection,
19669
19926
  reasoning: { ...reasoning, selectedEffort }
19670
19927
  }) }),
19671
- /* @__PURE__ */ jsx89(Text62, { color: theme.text.secondary, children: "Behavior" }),
19672
- /* @__PURE__ */ jsx89(Text62, { wrap: "wrap", children: "Provider default follows the model adapter. An explicit effort remains fixed for this Agent and future Sessions." })
19928
+ /* @__PURE__ */ jsx90(Text62, { color: theme.text.secondary, children: "Behavior" }),
19929
+ /* @__PURE__ */ jsx90(Text62, { wrap: "wrap", children: "Provider default follows the model adapter. An explicit effort remains fixed for this Agent and future Sessions." })
19673
19930
  ] })
19674
19931
  ] })
19675
19932
  ] }),
19676
- /* @__PURE__ */ jsx89(Box69, { marginTop: 1, children: /* @__PURE__ */ jsx89(Text62, { color: theme.text.secondary, children: "Use \u2191/\u2193 to navigate and Enter to select." }) })
19933
+ /* @__PURE__ */ jsx90(Box69, { marginTop: 1, children: /* @__PURE__ */ jsx90(Text62, { color: theme.text.secondary, children: "Use \u2191/\u2193 to navigate and Enter to select." }) })
19677
19934
  ]
19678
19935
  }
19679
19936
  );
@@ -19689,12 +19946,12 @@ function ModelDialog({
19689
19946
  width: "100%",
19690
19947
  children: [
19691
19948
  /* @__PURE__ */ jsxs67(Box69, { justifyContent: "space-between", children: [
19692
- /* @__PURE__ */ jsx89(Text62, { bold: true, color: theme.text.primary, children: "Select DSH Model" }),
19693
- /* @__PURE__ */ jsx89(Text62, { color: theme.text.secondary, children: "Esc to close" })
19949
+ /* @__PURE__ */ jsx90(Text62, { bold: true, color: theme.text.primary, children: "Select DSH Model" }),
19950
+ /* @__PURE__ */ jsx90(Text62, { color: theme.text.secondary, children: "Esc to close" })
19694
19951
  ] }),
19695
- error && /* @__PURE__ */ jsx89(Box69, { marginTop: 1, children: /* @__PURE__ */ jsx89(Text62, { color: theme.status.error, children: error }) }),
19696
- loading ? /* @__PURE__ */ jsx89(Box69, { marginTop: 1, children: /* @__PURE__ */ jsx89(Text62, { color: theme.text.secondary, children: "Loading models..." }) }) : models.length === 0 ? /* @__PURE__ */ jsx89(Box69, { marginTop: 1, children: /* @__PURE__ */ jsx89(Text62, { color: theme.status.warning, children: "No DSH models are available." }) }) : /* @__PURE__ */ jsxs67(Box69, { flexDirection: "row", marginTop: 1, children: [
19697
- /* @__PURE__ */ jsx89(Box69, { width: "55%", paddingRight: 2, flexDirection: "column", children: /* @__PURE__ */ jsx89(
19952
+ error && /* @__PURE__ */ jsx90(Box69, { marginTop: 1, children: /* @__PURE__ */ jsx90(Text62, { color: theme.status.error, children: error }) }),
19953
+ loading ? /* @__PURE__ */ jsx90(Box69, { marginTop: 1, children: /* @__PURE__ */ jsx90(Text62, { color: theme.text.secondary, children: "Loading models..." }) }) : models.length === 0 ? /* @__PURE__ */ jsx90(Box69, { marginTop: 1, children: /* @__PURE__ */ jsx90(Text62, { color: theme.status.warning, children: "No DSH models are available." }) }) : /* @__PURE__ */ jsxs67(Box69, { flexDirection: "row", marginTop: 1, children: [
19954
+ /* @__PURE__ */ jsx90(Box69, { width: "55%", paddingRight: 2, flexDirection: "column", children: /* @__PURE__ */ jsx90(
19698
19955
  RadioButtonSelect,
19699
19956
  {
19700
19957
  items,
@@ -19710,25 +19967,25 @@ function ModelDialog({
19710
19967
  return /* @__PURE__ */ jsxs67(Text62, { color: titleColor, wrap: "truncate", children: [
19711
19968
  model.name,
19712
19969
  " ",
19713
- /* @__PURE__ */ jsx89(Text62, { color: theme.text.secondary, children: model.provider }),
19714
- model.inputModalities.includes("image") && /* @__PURE__ */ jsx89(Text62, { color: theme.status.success, children: " Vision" }),
19715
- isCurrent && /* @__PURE__ */ jsx89(Text62, { color: theme.text.accent, children: " Current" })
19970
+ /* @__PURE__ */ jsx90(Text62, { color: theme.text.secondary, children: model.provider }),
19971
+ model.inputModalities.includes("image") && /* @__PURE__ */ jsx90(Text62, { color: theme.status.success, children: " Vision" }),
19972
+ isCurrent && /* @__PURE__ */ jsx90(Text62, { color: theme.text.accent, children: " Current" })
19716
19973
  ] });
19717
19974
  }
19718
19975
  },
19719
19976
  items.map((item) => item.key).join("|")
19720
19977
  ) }),
19721
- /* @__PURE__ */ jsx89(Box69, { width: "45%", paddingLeft: 2, flexDirection: "column", children: pending ? /* @__PURE__ */ jsxs67(Fragment16, { children: [
19722
- /* @__PURE__ */ jsx89(Text62, { bold: true, color: theme.status.warning, children: "Start a new Session?" }),
19978
+ /* @__PURE__ */ jsx90(Box69, { width: "45%", paddingLeft: 2, flexDirection: "column", children: pending ? /* @__PURE__ */ jsxs67(Fragment17, { children: [
19979
+ /* @__PURE__ */ jsx90(Text62, { bold: true, color: theme.status.warning, children: "Start a new Session?" }),
19723
19980
  /* @__PURE__ */ jsxs67(Box69, { marginTop: 1, flexDirection: "column", children: [
19724
19981
  /* @__PURE__ */ jsxs67(Text62, { children: [
19725
19982
  "Changing to ",
19726
19983
  pending.name,
19727
19984
  " creates a new DSH Agent and Session."
19728
19985
  ] }),
19729
- /* @__PURE__ */ jsx89(Text62, { color: theme.text.secondary, children: "The existing transcript remains visible but is not sent to the new model." })
19986
+ /* @__PURE__ */ jsx90(Text62, { color: theme.text.secondary, children: "The existing transcript remains visible but is not sent to the new model." })
19730
19987
  ] }),
19731
- /* @__PURE__ */ jsx89(Box69, { marginTop: 1, children: /* @__PURE__ */ jsx89(
19988
+ /* @__PURE__ */ jsx90(Box69, { marginTop: 1, children: /* @__PURE__ */ jsx90(
19732
19989
  RadioButtonSelect,
19733
19990
  {
19734
19991
  items: [
@@ -19743,23 +20000,23 @@ function ModelDialog({
19743
20000
  showNumbers: false
19744
20001
  }
19745
20002
  ) })
19746
- ] }) : /* @__PURE__ */ jsxs67(Fragment16, { children: [
19747
- /* @__PURE__ */ jsx89(Text62, { bold: true, color: theme.text.primary, children: highlighted.name }),
20003
+ ] }) : /* @__PURE__ */ jsxs67(Fragment17, { children: [
20004
+ /* @__PURE__ */ jsx90(Text62, { bold: true, color: theme.text.primary, children: highlighted.name }),
19748
20005
  /* @__PURE__ */ jsxs67(Box69, { marginTop: 1, flexDirection: "column", children: [
19749
- /* @__PURE__ */ jsx89(Text62, { color: theme.text.secondary, children: "Provider" }),
19750
- /* @__PURE__ */ jsx89(Text62, { children: highlighted.provider }),
19751
- /* @__PURE__ */ jsx89(Text62, { color: theme.text.secondary, children: "Model ID" }),
19752
- /* @__PURE__ */ jsx89(Text62, { wrap: "wrap", children: highlighted.model }),
19753
- /* @__PURE__ */ jsx89(Text62, { color: theme.text.secondary, children: "Input" }),
19754
- /* @__PURE__ */ jsx89(Text62, { color: highlighted.inputModalities.includes("image") ? theme.status.success : theme.text.primary, children: capabilityLabel(highlighted) }),
19755
- /* @__PURE__ */ jsx89(Text62, { color: theme.text.secondary, children: "Context window" }),
19756
- /* @__PURE__ */ jsx89(Text62, { children: highlighted.contextWindow === void 0 ? "Not disclosed" : `${formatTokenCount(highlighted.contextWindow)} tokens` })
20006
+ /* @__PURE__ */ jsx90(Text62, { color: theme.text.secondary, children: "Provider" }),
20007
+ /* @__PURE__ */ jsx90(Text62, { children: highlighted.provider }),
20008
+ /* @__PURE__ */ jsx90(Text62, { color: theme.text.secondary, children: "Model ID" }),
20009
+ /* @__PURE__ */ jsx90(Text62, { wrap: "wrap", children: highlighted.model }),
20010
+ /* @__PURE__ */ jsx90(Text62, { color: theme.text.secondary, children: "Input" }),
20011
+ /* @__PURE__ */ jsx90(Text62, { color: highlighted.inputModalities.includes("image") ? theme.status.success : theme.text.primary, children: capabilityLabel(highlighted) }),
20012
+ /* @__PURE__ */ jsx90(Text62, { color: theme.text.secondary, children: "Context window" }),
20013
+ /* @__PURE__ */ jsx90(Text62, { children: highlighted.contextWindow === void 0 ? "Not disclosed" : `${formatTokenCount(highlighted.contextWindow)} tokens` })
19757
20014
  ] }),
19758
- switching && /* @__PURE__ */ jsx89(Box69, { marginTop: 1, children: /* @__PURE__ */ jsx89(Text62, { color: theme.text.accent, children: "Creating new Agent..." }) }),
19759
- checkingProvider && /* @__PURE__ */ jsx89(Box69, { marginTop: 1, children: /* @__PURE__ */ jsx89(Text62, { color: theme.text.accent, children: "Checking provider setup..." }) })
20015
+ switching && /* @__PURE__ */ jsx90(Box69, { marginTop: 1, children: /* @__PURE__ */ jsx90(Text62, { color: theme.text.accent, children: "Creating new Agent..." }) }),
20016
+ checkingProvider && /* @__PURE__ */ jsx90(Box69, { marginTop: 1, children: /* @__PURE__ */ jsx90(Text62, { color: theme.text.accent, children: "Checking provider setup..." }) })
19760
20017
  ] }) })
19761
20018
  ] }),
19762
- /* @__PURE__ */ jsx89(Box69, { marginTop: 1, children: /* @__PURE__ */ jsx89(Text62, { color: theme.text.secondary, children: "Use \u2191/\u2193 to navigate and Enter to select." }) })
20019
+ /* @__PURE__ */ jsx90(Box69, { marginTop: 1, children: /* @__PURE__ */ jsx90(Text62, { color: theme.text.secondary, children: "Use \u2191/\u2193 to navigate and Enter to select." }) })
19763
20020
  ]
19764
20021
  }
19765
20022
  );
@@ -19812,9 +20069,9 @@ var modelCommand = {
19812
20069
  import React17 from "react";
19813
20070
 
19814
20071
  // src/ui/components/dialogs/provider-dialog.tsx
19815
- import { useEffect as useEffect40, useMemo as useMemo29, useState as useState37 } from "react";
20072
+ import { useEffect as useEffect40, useMemo as useMemo31, useState as useState37 } from "react";
19816
20073
  import { Box as Box70, Text as Text63 } from "ink";
19817
- import { Fragment as Fragment17, jsx as jsx90, jsxs as jsxs68 } from "react/jsx-runtime";
20074
+ import { Fragment as Fragment18, jsx as jsx91, jsxs as jsxs68 } from "react/jsx-runtime";
19818
20075
  function statusLabel(status) {
19819
20076
  switch (status) {
19820
20077
  case "configured":
@@ -19889,7 +20146,7 @@ function ProviderDialog({
19889
20146
  },
19890
20147
  { isActive: editing === void 0 }
19891
20148
  );
19892
- const items = useMemo29(
20149
+ const items = useMemo31(
19893
20150
  () => providers.map((provider) => ({
19894
20151
  key: provider.provider,
19895
20152
  label: provider.displayName,
@@ -19905,7 +20162,7 @@ function ProviderDialog({
19905
20162
  );
19906
20163
  const currentProvider = runtime.getSnapshot().current.provider;
19907
20164
  if (editing) {
19908
- return /* @__PURE__ */ jsx90(
20165
+ return /* @__PURE__ */ jsx91(
19909
20166
  ProviderSetupDialog,
19910
20167
  {
19911
20168
  runtime,
@@ -19934,17 +20191,17 @@ function ProviderDialog({
19934
20191
  width: "100%",
19935
20192
  children: [
19936
20193
  /* @__PURE__ */ jsxs68(Box70, { justifyContent: "space-between", children: [
19937
- /* @__PURE__ */ jsx90(Text63, { bold: true, color: theme.text.accent, children: "DSH Providers" }),
20194
+ /* @__PURE__ */ jsx91(Text63, { bold: true, color: theme.text.accent, children: "DSH Providers" }),
19938
20195
  /* @__PURE__ */ jsxs68(Text63, { color: theme.text.secondary, children: [
19939
- /* @__PURE__ */ jsx90(Text63, { bold: true, color: theme.text.primary, children: "Esc" }),
20196
+ /* @__PURE__ */ jsx91(Text63, { bold: true, color: theme.text.primary, children: "Esc" }),
19940
20197
  " Close"
19941
20198
  ] })
19942
20199
  ] }),
19943
- error && /* @__PURE__ */ jsx90(Box70, { marginTop: 1, children: /* @__PURE__ */ jsx90(Text63, { color: theme.status.error, children: error }) }),
19944
- loading && /* @__PURE__ */ jsx90(Box70, { marginTop: 1, children: /* @__PURE__ */ jsx90(Text63, { color: theme.text.secondary, children: "Loading providers..." }) }),
19945
- !loading && providers.length === 0 && /* @__PURE__ */ jsx90(Box70, { marginTop: 1, children: /* @__PURE__ */ jsx90(Text63, { color: theme.status.warning, children: "No DSH-managed providers are available." }) }),
20200
+ error && /* @__PURE__ */ jsx91(Box70, { marginTop: 1, children: /* @__PURE__ */ jsx91(Text63, { color: theme.status.error, children: error }) }),
20201
+ loading && /* @__PURE__ */ jsx91(Box70, { marginTop: 1, children: /* @__PURE__ */ jsx91(Text63, { color: theme.text.secondary, children: "Loading providers..." }) }),
20202
+ !loading && providers.length === 0 && /* @__PURE__ */ jsx91(Box70, { marginTop: 1, children: /* @__PURE__ */ jsx91(Text63, { color: theme.status.warning, children: "No DSH-managed providers are available." }) }),
19946
20203
  providers.length > 0 && highlighted && /* @__PURE__ */ jsxs68(Box70, { marginTop: 1, children: [
19947
- /* @__PURE__ */ jsx90(Box70, { width: "55%", paddingRight: 2, children: /* @__PURE__ */ jsx90(
20204
+ /* @__PURE__ */ jsx91(Box70, { width: "55%", paddingRight: 2, children: /* @__PURE__ */ jsx91(
19948
20205
  RadioButtonSelect,
19949
20206
  {
19950
20207
  items,
@@ -19960,33 +20217,33 @@ function ProviderDialog({
19960
20217
  renderItem: (item, { titleColor }) => /* @__PURE__ */ jsxs68(Text63, { color: titleColor, wrap: "truncate", children: [
19961
20218
  item.value.displayName,
19962
20219
  " ",
19963
- /* @__PURE__ */ jsx90(Text63, { color: statusColor(item.value.status), children: statusLabel(item.value.status) }),
19964
- item.value.provider === currentProvider && /* @__PURE__ */ jsx90(Text63, { color: theme.text.accent, children: " Current" })
20220
+ /* @__PURE__ */ jsx91(Text63, { color: statusColor(item.value.status), children: statusLabel(item.value.status) }),
20221
+ item.value.provider === currentProvider && /* @__PURE__ */ jsx91(Text63, { color: theme.text.accent, children: " Current" })
19965
20222
  ] })
19966
20223
  }
19967
20224
  ) }),
19968
20225
  /* @__PURE__ */ jsxs68(Box70, { width: "45%", paddingLeft: 2, flexDirection: "column", children: [
19969
- /* @__PURE__ */ jsx90(Text63, { bold: true, color: theme.text.primary, children: highlighted.displayName }),
20226
+ /* @__PURE__ */ jsx91(Text63, { bold: true, color: theme.text.primary, children: highlighted.displayName }),
19970
20227
  /* @__PURE__ */ jsxs68(Box70, { marginTop: 1, flexDirection: "column", children: [
19971
- /* @__PURE__ */ jsx90(Text63, { color: theme.text.secondary, children: "Provider" }),
19972
- /* @__PURE__ */ jsx90(Text63, { children: highlighted.provider }),
19973
- /* @__PURE__ */ jsx90(Text63, { color: theme.text.secondary, children: "Status" }),
19974
- /* @__PURE__ */ jsx90(Text63, { color: statusColor(highlighted.status), children: statusLabel(highlighted.status) }),
19975
- highlighted.credentialLabel && /* @__PURE__ */ jsxs68(Fragment17, { children: [
19976
- /* @__PURE__ */ jsx90(Text63, { color: theme.text.secondary, children: "Credential" }),
19977
- /* @__PURE__ */ jsx90(Text63, { children: highlighted.credentialLabel })
20228
+ /* @__PURE__ */ jsx91(Text63, { color: theme.text.secondary, children: "Provider" }),
20229
+ /* @__PURE__ */ jsx91(Text63, { children: highlighted.provider }),
20230
+ /* @__PURE__ */ jsx91(Text63, { color: theme.text.secondary, children: "Status" }),
20231
+ /* @__PURE__ */ jsx91(Text63, { color: statusColor(highlighted.status), children: statusLabel(highlighted.status) }),
20232
+ highlighted.credentialLabel && /* @__PURE__ */ jsxs68(Fragment18, { children: [
20233
+ /* @__PURE__ */ jsx91(Text63, { color: theme.text.secondary, children: "Credential" }),
20234
+ /* @__PURE__ */ jsx91(Text63, { children: highlighted.credentialLabel })
19978
20235
  ] }),
19979
- highlighted.source && /* @__PURE__ */ jsxs68(Fragment17, { children: [
19980
- /* @__PURE__ */ jsx90(Text63, { color: theme.text.secondary, children: "Source" }),
19981
- /* @__PURE__ */ jsx90(Text63, { children: highlighted.source })
20236
+ highlighted.source && /* @__PURE__ */ jsxs68(Fragment18, { children: [
20237
+ /* @__PURE__ */ jsx91(Text63, { color: theme.text.secondary, children: "Source" }),
20238
+ /* @__PURE__ */ jsx91(Text63, { children: highlighted.source })
19982
20239
  ] }),
19983
- highlighted.message && /* @__PURE__ */ jsx90(Box70, { marginTop: 1, children: /* @__PURE__ */ jsx90(Text63, { color: theme.status.warning, children: highlighted.message }) }),
19984
- !highlighted.writable && highlighted.status !== "unsupported" && highlighted.status !== "error" && /* @__PURE__ */ jsx90(Box70, { marginTop: 1, children: /* @__PURE__ */ jsx90(Text63, { color: theme.status.warning, children: "This credential comes from a read-only source. Update it outside DSH Console." }) })
20240
+ highlighted.message && /* @__PURE__ */ jsx91(Box70, { marginTop: 1, children: /* @__PURE__ */ jsx91(Text63, { color: theme.status.warning, children: highlighted.message }) }),
20241
+ !highlighted.writable && highlighted.status !== "unsupported" && highlighted.status !== "error" && /* @__PURE__ */ jsx91(Box70, { marginTop: 1, children: /* @__PURE__ */ jsx91(Text63, { color: theme.status.warning, children: "This credential comes from a read-only source. Update it outside DSH Console." }) })
19985
20242
  ] })
19986
20243
  ] })
19987
20244
  ] }),
19988
- providers.length > 0 && highlighted && /* @__PURE__ */ jsx90(Box70, { marginTop: 1, children: highlighted.writable && highlighted.status !== "unsupported" ? /* @__PURE__ */ jsxs68(Fragment17, { children: [
19989
- /* @__PURE__ */ jsx90(Text63, { bold: true, color: theme.text.accent, children: "Enter" }),
20245
+ providers.length > 0 && highlighted && /* @__PURE__ */ jsx91(Box70, { marginTop: 1, children: highlighted.writable && highlighted.status !== "unsupported" ? /* @__PURE__ */ jsxs68(Fragment18, { children: [
20246
+ /* @__PURE__ */ jsx91(Text63, { bold: true, color: theme.text.accent, children: "Enter" }),
19990
20247
  /* @__PURE__ */ jsxs68(Text63, { color: theme.text.primary, children: [
19991
20248
  " ",
19992
20249
  highlighted.status === "configured" ? "Replace credential" : "Configure provider"
@@ -19995,7 +20252,7 @@ function ProviderDialog({
19995
20252
  " ",
19996
20253
  "Use \u2191/\u2193 to navigate"
19997
20254
  ] })
19998
- ] }) : /* @__PURE__ */ jsx90(Text63, { color: theme.text.secondary, children: "Use \u2191/\u2193 to inspect providers. This credential cannot be changed here." }) })
20255
+ ] }) : /* @__PURE__ */ jsx91(Text63, { color: theme.text.secondary, children: "Use \u2191/\u2193 to inspect providers. This credential cannot be changed here." }) })
19999
20256
  ]
20000
20257
  }
20001
20258
  );
@@ -20047,9 +20304,9 @@ var providerCommand = {
20047
20304
  import React18 from "react";
20048
20305
 
20049
20306
  // src/ui/components/dialogs/session-dialog.tsx
20050
- import { useCallback as useCallback33, useEffect as useEffect41, useMemo as useMemo30, useRef as useRef20, useState as useState38 } from "react";
20307
+ import { useCallback as useCallback34, useEffect as useEffect41, useMemo as useMemo32, useRef as useRef20, useState as useState38 } from "react";
20051
20308
  import { Box as Box71, Text as Text64 } from "ink";
20052
- import { Fragment as Fragment18, jsx as jsx91, jsxs as jsxs69 } from "react/jsx-runtime";
20309
+ import { Fragment as Fragment19, jsx as jsx92, jsxs as jsxs69 } from "react/jsx-runtime";
20053
20310
  function shortId(id) {
20054
20311
  const start2 = id.startsWith("dsh-console-") ? "dsh-console-".length : 0;
20055
20312
  return id.slice(start2, start2 + 12);
@@ -20066,7 +20323,7 @@ function SessionDialog({ runtime, onClose }) {
20066
20323
  const [error, setError] = useState38();
20067
20324
  const switchingRef = useRef20(false);
20068
20325
  const titleRequestsRef = useRef20(/* @__PURE__ */ new Map());
20069
- const resolveTitles = useCallback33((candidates) => {
20326
+ const resolveTitles = useCallback34((candidates) => {
20070
20327
  const sessionsToResolve = candidates.filter((session) => !session.title && !titleRequestsRef.current.has(session.id));
20071
20328
  if (sessionsToResolve.length === 0) return;
20072
20329
  const controller = new AbortController();
@@ -20113,17 +20370,17 @@ function SessionDialog({ runtime, onClose }) {
20113
20370
  titleRequests.clear();
20114
20371
  };
20115
20372
  }, [resolveTitles, runtime]);
20116
- const items = useMemo30(() => sessions.map((session) => ({
20373
+ const items = useMemo32(() => sessions.map((session) => ({
20117
20374
  key: session.id,
20118
20375
  value: session,
20119
20376
  label: sessionLabel(session)
20120
20377
  })), [sessions]);
20121
20378
  const initialIndex = Math.max(0, sessions.findIndex((session) => session.current));
20122
- const highlight = useCallback33((session) => {
20379
+ const highlight = useCallback34((session) => {
20123
20380
  setHighlighted(session);
20124
20381
  resolveTitles([session]);
20125
20382
  }, [resolveTitles]);
20126
- const resume = useCallback33(async (session) => {
20383
+ const resume = useCallback34(async (session) => {
20127
20384
  if (switchingRef.current) return;
20128
20385
  switchingRef.current = true;
20129
20386
  setSwitching(true);
@@ -20139,7 +20396,7 @@ function SessionDialog({ runtime, onClose }) {
20139
20396
  setSwitching(false);
20140
20397
  }
20141
20398
  }, [onClose, runtime]);
20142
- const select = useCallback33((session) => {
20399
+ const select = useCallback34((session) => {
20143
20400
  if (session.current) {
20144
20401
  onClose();
20145
20402
  return;
@@ -20158,12 +20415,12 @@ function SessionDialog({ runtime, onClose }) {
20158
20415
  }, { isActive: true });
20159
20416
  return /* @__PURE__ */ jsxs69(Box71, { borderStyle: "round", borderColor: theme.border.default, flexDirection: "column", paddingX: 1, paddingY: 1, width: "100%", children: [
20160
20417
  /* @__PURE__ */ jsxs69(Box71, { justifyContent: "space-between", children: [
20161
- /* @__PURE__ */ jsx91(Text64, { bold: true, color: theme.text.primary, children: "DSH Sessions" }),
20162
- /* @__PURE__ */ jsx91(Text64, { color: theme.text.secondary, children: "Esc to close" })
20418
+ /* @__PURE__ */ jsx92(Text64, { bold: true, color: theme.text.primary, children: "DSH Sessions" }),
20419
+ /* @__PURE__ */ jsx92(Text64, { color: theme.text.secondary, children: "Esc to close" })
20163
20420
  ] }),
20164
- error && /* @__PURE__ */ jsx91(Box71, { marginTop: 1, children: /* @__PURE__ */ jsx91(Text64, { color: theme.status.error, children: error }) }),
20165
- loading ? /* @__PURE__ */ jsx91(Box71, { marginTop: 1, children: /* @__PURE__ */ jsx91(Text64, { color: theme.text.secondary, children: "Loading Sessions..." }) }) : sessions.length === 0 ? /* @__PURE__ */ jsx91(Box71, { marginTop: 1, children: /* @__PURE__ */ jsx91(Text64, { color: theme.text.secondary, children: "No resumable Sessions." }) }) : /* @__PURE__ */ jsxs69(Box71, { flexDirection: "row", marginTop: 1, children: [
20166
- /* @__PURE__ */ jsx91(Box71, { width: "55%", paddingRight: 2, flexDirection: "column", children: /* @__PURE__ */ jsx91(
20421
+ error && /* @__PURE__ */ jsx92(Box71, { marginTop: 1, children: /* @__PURE__ */ jsx92(Text64, { color: theme.status.error, children: error }) }),
20422
+ loading ? /* @__PURE__ */ jsx92(Box71, { marginTop: 1, children: /* @__PURE__ */ jsx92(Text64, { color: theme.text.secondary, children: "Loading Sessions..." }) }) : sessions.length === 0 ? /* @__PURE__ */ jsx92(Box71, { marginTop: 1, children: /* @__PURE__ */ jsx92(Text64, { color: theme.text.secondary, children: "No resumable Sessions." }) }) : /* @__PURE__ */ jsxs69(Box71, { flexDirection: "row", marginTop: 1, children: [
20423
+ /* @__PURE__ */ jsx92(Box71, { width: "55%", paddingRight: 2, flexDirection: "column", children: /* @__PURE__ */ jsx92(
20167
20424
  RadioButtonSelect,
20168
20425
  {
20169
20426
  items,
@@ -20175,18 +20432,18 @@ function SessionDialog({ runtime, onClose }) {
20175
20432
  maxItemsToShow: 12,
20176
20433
  renderItem: (item, { titleColor }) => /* @__PURE__ */ jsxs69(Text64, { color: titleColor, wrap: "truncate", children: [
20177
20434
  sessionLabel(item.value),
20178
- item.value.current && /* @__PURE__ */ jsx91(Text64, { color: theme.text.accent, children: " Current" }),
20179
- !item.value.current && !item.value.resumable && /* @__PURE__ */ jsx91(Text64, { color: theme.status.warning, children: " Not resumable" })
20435
+ item.value.current && /* @__PURE__ */ jsx92(Text64, { color: theme.text.accent, children: " Current" }),
20436
+ !item.value.current && !item.value.resumable && /* @__PURE__ */ jsx92(Text64, { color: theme.status.warning, children: " Not resumable" })
20180
20437
  ] })
20181
20438
  }
20182
20439
  ) }),
20183
- /* @__PURE__ */ jsx91(Box71, { width: "45%", paddingLeft: 2, flexDirection: "column", children: pending ? /* @__PURE__ */ jsxs69(Fragment18, { children: [
20184
- /* @__PURE__ */ jsx91(Text64, { bold: true, color: theme.status.warning, children: "Resume this Session?" }),
20440
+ /* @__PURE__ */ jsx92(Box71, { width: "45%", paddingLeft: 2, flexDirection: "column", children: pending ? /* @__PURE__ */ jsxs69(Fragment19, { children: [
20441
+ /* @__PURE__ */ jsx92(Text64, { bold: true, color: theme.status.warning, children: "Resume this Session?" }),
20185
20442
  /* @__PURE__ */ jsxs69(Box71, { marginTop: 1, flexDirection: "column", children: [
20186
- /* @__PURE__ */ jsx91(Text64, { children: sessionLabel(pending) }),
20187
- /* @__PURE__ */ jsx91(Text64, { color: theme.text.secondary, children: "The current transcript will be replaced." })
20443
+ /* @__PURE__ */ jsx92(Text64, { children: sessionLabel(pending) }),
20444
+ /* @__PURE__ */ jsx92(Text64, { color: theme.text.secondary, children: "The current transcript will be replaced." })
20188
20445
  ] }),
20189
- /* @__PURE__ */ jsx91(Box71, { marginTop: 1, children: /* @__PURE__ */ jsx91(
20446
+ /* @__PURE__ */ jsx92(Box71, { marginTop: 1, children: /* @__PURE__ */ jsx92(
20190
20447
  RadioButtonSelect,
20191
20448
  {
20192
20449
  items: [
@@ -20198,21 +20455,21 @@ function SessionDialog({ runtime, onClose }) {
20198
20455
  showNumbers: false
20199
20456
  }
20200
20457
  ) })
20201
- ] }) : highlighted ? /* @__PURE__ */ jsxs69(Fragment18, { children: [
20202
- /* @__PURE__ */ jsx91(Text64, { bold: true, children: sessionLabel(highlighted) }),
20458
+ ] }) : highlighted ? /* @__PURE__ */ jsxs69(Fragment19, { children: [
20459
+ /* @__PURE__ */ jsx92(Text64, { bold: true, children: sessionLabel(highlighted) }),
20203
20460
  /* @__PURE__ */ jsxs69(Box71, { marginTop: 1, flexDirection: "column", children: [
20204
- /* @__PURE__ */ jsx91(Text64, { color: theme.text.secondary, children: "Created" }),
20205
- /* @__PURE__ */ jsx91(Text64, { children: new Date(highlighted.createdAt).toLocaleString() }),
20206
- !highlighted.resumable && highlighted.resumeUnavailableReason && /* @__PURE__ */ jsxs69(Fragment18, { children: [
20207
- /* @__PURE__ */ jsx91(Text64, { color: theme.text.secondary, children: "Resume status" }),
20208
- /* @__PURE__ */ jsx91(Text64, { color: theme.status.warning, children: highlighted.resumeUnavailableReason })
20461
+ /* @__PURE__ */ jsx92(Text64, { color: theme.text.secondary, children: "Created" }),
20462
+ /* @__PURE__ */ jsx92(Text64, { children: new Date(highlighted.createdAt).toLocaleString() }),
20463
+ !highlighted.resumable && highlighted.resumeUnavailableReason && /* @__PURE__ */ jsxs69(Fragment19, { children: [
20464
+ /* @__PURE__ */ jsx92(Text64, { color: theme.text.secondary, children: "Resume status" }),
20465
+ /* @__PURE__ */ jsx92(Text64, { color: theme.status.warning, children: highlighted.resumeUnavailableReason })
20209
20466
  ] }),
20210
- /* @__PURE__ */ jsx91(Text64, { color: theme.text.secondary, children: "Session ID" }),
20211
- /* @__PURE__ */ jsx91(Text64, { wrap: "wrap", children: highlighted.id })
20467
+ /* @__PURE__ */ jsx92(Text64, { color: theme.text.secondary, children: "Session ID" }),
20468
+ /* @__PURE__ */ jsx92(Text64, { wrap: "wrap", children: highlighted.id })
20212
20469
  ] })
20213
20470
  ] }) : null })
20214
20471
  ] }),
20215
- /* @__PURE__ */ jsx91(Box71, { marginTop: 1, children: /* @__PURE__ */ jsx91(Text64, { color: theme.text.secondary, children: "Use \u2191/\u2193 to navigate and Enter to resume." }) })
20472
+ /* @__PURE__ */ jsx92(Box71, { marginTop: 1, children: /* @__PURE__ */ jsx92(Text64, { color: theme.text.secondary, children: "Use \u2191/\u2193 to navigate and Enter to resume." }) })
20216
20473
  ] });
20217
20474
  }
20218
20475
 
@@ -20318,12 +20575,12 @@ var statsCommand = {
20318
20575
  import React19 from "react";
20319
20576
 
20320
20577
  // src/ui/components/dialogs/tools-dialog.tsx
20321
- import { useEffect as useEffect42, useMemo as useMemo31, useState as useState39, useSyncExternalStore as useSyncExternalStore3 } from "react";
20578
+ import { useEffect as useEffect42, useMemo as useMemo33, useState as useState39, useSyncExternalStore as useSyncExternalStore3 } from "react";
20322
20579
  import { Box as Box73, Text as Text66 } from "ink";
20323
20580
 
20324
20581
  // src/ui/components/shared/descriptive-radio-button-select.tsx
20325
20582
  import { Text as Text65, Box as Box72 } from "ink";
20326
- import { jsx as jsx92, jsxs as jsxs70 } from "react/jsx-runtime";
20583
+ import { jsx as jsx93, jsxs as jsxs70 } from "react/jsx-runtime";
20327
20584
  function DescriptiveRadioButtonSelect({
20328
20585
  items,
20329
20586
  initialIndex = 0,
@@ -20334,7 +20591,7 @@ function DescriptiveRadioButtonSelect({
20334
20591
  showScrollArrows = false,
20335
20592
  maxItemsToShow = 10
20336
20593
  }) {
20337
- return /* @__PURE__ */ jsx92(
20594
+ return /* @__PURE__ */ jsx93(
20338
20595
  BaseSelectionList,
20339
20596
  {
20340
20597
  items,
@@ -20346,15 +20603,15 @@ function DescriptiveRadioButtonSelect({
20346
20603
  showScrollArrows,
20347
20604
  maxItemsToShow,
20348
20605
  renderItem: (item, { titleColor }) => /* @__PURE__ */ jsxs70(Box72, { flexDirection: "column", children: [
20349
- /* @__PURE__ */ jsx92(Text65, { color: titleColor, children: item.title }),
20350
- item.description && /* @__PURE__ */ jsx92(Text65, { color: theme.text.secondary, children: item.description })
20606
+ /* @__PURE__ */ jsx93(Text65, { color: titleColor, children: item.title }),
20607
+ item.description && /* @__PURE__ */ jsx93(Text65, { color: theme.text.secondary, children: item.description })
20351
20608
  ] }, item.key)
20352
20609
  }
20353
20610
  );
20354
20611
  }
20355
20612
 
20356
20613
  // src/ui/components/dialogs/tools-dialog.tsx
20357
- import { Fragment as Fragment19, jsx as jsx93, jsxs as jsxs71 } from "react/jsx-runtime";
20614
+ import { Fragment as Fragment20, jsx as jsx94, jsxs as jsxs71 } from "react/jsx-runtime";
20358
20615
  function summary(description) {
20359
20616
  const line = description.replace(/\s+/g, " ").trim();
20360
20617
  return line.length > 90 ? `${line.slice(0, 89)}...` : line;
@@ -20376,7 +20633,7 @@ function ToolsDialog({ runtime, onClose }) {
20376
20633
  },
20377
20634
  { isActive: true }
20378
20635
  );
20379
- const items = useMemo31(
20636
+ const items = useMemo33(
20380
20637
  () => snapshot.tools.map((tool) => ({
20381
20638
  key: tool.name,
20382
20639
  value: tool.name,
@@ -20401,10 +20658,10 @@ function ToolsDialog({ runtime, onClose }) {
20401
20658
  snapshot.tools.length,
20402
20659
  ")"
20403
20660
  ] }),
20404
- /* @__PURE__ */ jsx93(Text66, { color: theme.text.secondary, children: "Esc to close" })
20661
+ /* @__PURE__ */ jsx94(Text66, { color: theme.text.secondary, children: "Esc to close" })
20405
20662
  ] }),
20406
- snapshot.tools.length === 0 ? /* @__PURE__ */ jsx93(Box73, { marginTop: 1, children: /* @__PURE__ */ jsx93(Text66, { color: theme.text.secondary, children: "No tools are visible to the current Agent." }) }) : /* @__PURE__ */ jsxs71(Box73, { flexDirection: "row", marginTop: 1, children: [
20407
- /* @__PURE__ */ jsx93(Box73, { width: "55%", paddingRight: 2, flexDirection: "column", children: /* @__PURE__ */ jsx93(
20663
+ snapshot.tools.length === 0 ? /* @__PURE__ */ jsx94(Box73, { marginTop: 1, children: /* @__PURE__ */ jsx94(Text66, { color: theme.text.secondary, children: "No tools are visible to the current Agent." }) }) : /* @__PURE__ */ jsxs71(Box73, { flexDirection: "row", marginTop: 1, children: [
20664
+ /* @__PURE__ */ jsx94(Box73, { width: "55%", paddingRight: 2, flexDirection: "column", children: /* @__PURE__ */ jsx94(
20408
20665
  DescriptiveRadioButtonSelect,
20409
20666
  {
20410
20667
  items,
@@ -20415,12 +20672,12 @@ function ToolsDialog({ runtime, onClose }) {
20415
20672
  maxItemsToShow: 10
20416
20673
  }
20417
20674
  ) }),
20418
- /* @__PURE__ */ jsx93(Box73, { width: "45%", paddingLeft: 2, flexDirection: "column", children: selected && /* @__PURE__ */ jsxs71(Fragment19, { children: [
20419
- /* @__PURE__ */ jsx93(Text66, { bold: true, color: theme.text.accent, children: selected.name }),
20420
- /* @__PURE__ */ jsx93(Box73, { marginTop: 1, children: /* @__PURE__ */ jsx93(Text66, { wrap: "wrap", children: selected.description }) }),
20675
+ /* @__PURE__ */ jsx94(Box73, { width: "45%", paddingLeft: 2, flexDirection: "column", children: selected && /* @__PURE__ */ jsxs71(Fragment20, { children: [
20676
+ /* @__PURE__ */ jsx94(Text66, { bold: true, color: theme.text.accent, children: selected.name }),
20677
+ /* @__PURE__ */ jsx94(Box73, { marginTop: 1, children: /* @__PURE__ */ jsx94(Text66, { wrap: "wrap", children: selected.description }) }),
20421
20678
  /* @__PURE__ */ jsxs71(Box73, { marginTop: 1, flexDirection: "column", children: [
20422
- /* @__PURE__ */ jsx93(Text66, { bold: true, color: theme.text.primary, children: "Parameters" }),
20423
- selected.parameters.length === 0 ? /* @__PURE__ */ jsx93(Text66, { color: theme.text.secondary, children: "None" }) : selected.parameters.map((parameter) => /* @__PURE__ */ jsxs71(Box73, { flexDirection: "column", children: [
20679
+ /* @__PURE__ */ jsx94(Text66, { bold: true, color: theme.text.primary, children: "Parameters" }),
20680
+ selected.parameters.length === 0 ? /* @__PURE__ */ jsx94(Text66, { color: theme.text.secondary, children: "None" }) : selected.parameters.map((parameter) => /* @__PURE__ */ jsxs71(Box73, { flexDirection: "column", children: [
20424
20681
  /* @__PURE__ */ jsxs71(Text66, { color: theme.text.link, children: [
20425
20682
  parameter.name,
20426
20683
  " ",
@@ -20429,12 +20686,12 @@ function ToolsDialog({ runtime, onClose }) {
20429
20686
  parameter.required ? " required" : " optional"
20430
20687
  ] })
20431
20688
  ] }),
20432
- parameter.description && /* @__PURE__ */ jsx93(Text66, { color: theme.text.secondary, children: parameter.description })
20689
+ parameter.description && /* @__PURE__ */ jsx94(Text66, { color: theme.text.secondary, children: parameter.description })
20433
20690
  ] }, parameter.name))
20434
20691
  ] })
20435
20692
  ] }) })
20436
20693
  ] }),
20437
- snapshot.tools.length > 0 && /* @__PURE__ */ jsx93(Box73, { marginTop: 1, children: /* @__PURE__ */ jsx93(Text66, { color: theme.text.secondary, children: "Use Up/Down to inspect the current Agent's tool catalog." }) })
20694
+ snapshot.tools.length > 0 && /* @__PURE__ */ jsx94(Box73, { marginTop: 1, children: /* @__PURE__ */ jsx94(Text66, { color: theme.text.secondary, children: "Use Up/Down to inspect the current Agent's tool catalog." }) })
20438
20695
  ]
20439
20696
  }
20440
20697
  );
@@ -20476,9 +20733,9 @@ var toolsCommand = {
20476
20733
  import React20 from "react";
20477
20734
 
20478
20735
  // src/ui/components/dialogs/permission-dialog.tsx
20479
- import { useCallback as useCallback34, useMemo as useMemo32, useState as useState40, useSyncExternalStore as useSyncExternalStore4 } from "react";
20736
+ import { useCallback as useCallback35, useMemo as useMemo34, useState as useState40, useSyncExternalStore as useSyncExternalStore4 } from "react";
20480
20737
  import { Box as Box74, Text as Text67 } from "ink";
20481
- import { Fragment as Fragment20, jsx as jsx94, jsxs as jsxs72 } from "react/jsx-runtime";
20738
+ import { Fragment as Fragment21, jsx as jsx95, jsxs as jsxs72 } from "react/jsx-runtime";
20482
20739
  function PermissionDialog({
20483
20740
  runtime,
20484
20741
  onClose,
@@ -20493,7 +20750,7 @@ function PermissionDialog({
20493
20750
  const [pending, setPending] = useState40();
20494
20751
  const [error, setError] = useState40();
20495
20752
  const selected = highlighted ?? snapshot.options.find((option) => option.value === snapshot.currentValue) ?? snapshot.options[0];
20496
- const items = useMemo32(
20753
+ const items = useMemo34(
20497
20754
  () => snapshot.options.map((option) => ({
20498
20755
  key: option.value,
20499
20756
  value: option,
@@ -20505,7 +20762,7 @@ function PermissionDialog({
20505
20762
  0,
20506
20763
  snapshot.options.findIndex((option) => option.value === snapshot.currentValue)
20507
20764
  );
20508
- const switchPermission = useCallback34(
20765
+ const switchPermission = useCallback35(
20509
20766
  async (option) => {
20510
20767
  setError(void 0);
20511
20768
  try {
@@ -20518,7 +20775,7 @@ function PermissionDialog({
20518
20775
  },
20519
20776
  [onSwitched, runtime]
20520
20777
  );
20521
- const selectPermission = useCallback34(
20778
+ const selectPermission = useCallback35(
20522
20779
  (option) => {
20523
20780
  if (option.value === snapshot.currentValue) {
20524
20781
  onClose();
@@ -20551,12 +20808,12 @@ function PermissionDialog({
20551
20808
  width: "100%",
20552
20809
  children: [
20553
20810
  /* @__PURE__ */ jsxs72(Box74, { justifyContent: "space-between", children: [
20554
- /* @__PURE__ */ jsx94(Text67, { bold: true, color: theme.text.primary, children: "Select DSH Permission" }),
20555
- /* @__PURE__ */ jsx94(Text67, { color: theme.text.secondary, children: "Esc to close" })
20811
+ /* @__PURE__ */ jsx95(Text67, { bold: true, color: theme.text.primary, children: "Select DSH Permission" }),
20812
+ /* @__PURE__ */ jsx95(Text67, { color: theme.text.secondary, children: "Esc to close" })
20556
20813
  ] }),
20557
- error && /* @__PURE__ */ jsx94(Box74, { marginTop: 1, children: /* @__PURE__ */ jsx94(Text67, { color: theme.status.error, children: error }) }),
20558
- !snapshot.available ? /* @__PURE__ */ jsx94(Box74, { marginTop: 1, children: /* @__PURE__ */ jsx94(Text67, { color: theme.status.warning, children: "DSH permission presets are unavailable." }) }) : snapshot.options.length === 0 ? /* @__PURE__ */ jsx94(Box74, { marginTop: 1, children: /* @__PURE__ */ jsx94(Text67, { color: theme.status.warning, children: "No permission presets are available." }) }) : /* @__PURE__ */ jsxs72(Box74, { flexDirection: "row", marginTop: 1, children: [
20559
- /* @__PURE__ */ jsx94(Box74, { width: "50%", paddingRight: 2, flexDirection: "column", children: /* @__PURE__ */ jsx94(
20814
+ error && /* @__PURE__ */ jsx95(Box74, { marginTop: 1, children: /* @__PURE__ */ jsx95(Text67, { color: theme.status.error, children: error }) }),
20815
+ !snapshot.available ? /* @__PURE__ */ jsx95(Box74, { marginTop: 1, children: /* @__PURE__ */ jsx95(Text67, { color: theme.status.warning, children: "DSH permission presets are unavailable." }) }) : snapshot.options.length === 0 ? /* @__PURE__ */ jsx95(Box74, { marginTop: 1, children: /* @__PURE__ */ jsx95(Text67, { color: theme.status.warning, children: "No permission presets are available." }) }) : /* @__PURE__ */ jsxs72(Box74, { flexDirection: "row", marginTop: 1, children: [
20816
+ /* @__PURE__ */ jsx95(Box74, { width: "50%", paddingRight: 2, flexDirection: "column", children: /* @__PURE__ */ jsx95(
20560
20817
  RadioButtonSelect,
20561
20818
  {
20562
20819
  items,
@@ -20567,15 +20824,15 @@ function PermissionDialog({
20567
20824
  showNumbers: false,
20568
20825
  renderItem: (item, { titleColor }) => /* @__PURE__ */ jsxs72(Text67, { color: titleColor, wrap: "truncate", children: [
20569
20826
  item.value.name,
20570
- item.value.value === snapshot.currentValue && /* @__PURE__ */ jsx94(Text67, { color: theme.text.accent, children: " Current" })
20827
+ item.value.value === snapshot.currentValue && /* @__PURE__ */ jsx95(Text67, { color: theme.text.accent, children: " Current" })
20571
20828
  ] })
20572
20829
  },
20573
20830
  items.map((item) => item.key).join("|")
20574
20831
  ) }),
20575
- /* @__PURE__ */ jsx94(Box74, { width: "50%", paddingLeft: 2, flexDirection: "column", children: pending ? /* @__PURE__ */ jsxs72(Fragment20, { children: [
20576
- /* @__PURE__ */ jsx94(Text67, { bold: true, color: theme.status.warning, children: "Enable Full access?" }),
20577
- /* @__PURE__ */ jsx94(Box74, { marginTop: 1, children: /* @__PURE__ */ jsx94(Text67, { children: "This allows commands to run without workspace sandbox restrictions or approval prompts." }) }),
20578
- /* @__PURE__ */ jsx94(Box74, { marginTop: 1, children: /* @__PURE__ */ jsx94(
20832
+ /* @__PURE__ */ jsx95(Box74, { width: "50%", paddingLeft: 2, flexDirection: "column", children: pending ? /* @__PURE__ */ jsxs72(Fragment21, { children: [
20833
+ /* @__PURE__ */ jsx95(Text67, { bold: true, color: theme.status.warning, children: "Enable Full access?" }),
20834
+ /* @__PURE__ */ jsx95(Box74, { marginTop: 1, children: /* @__PURE__ */ jsx95(Text67, { children: "This allows commands to run without workspace sandbox restrictions or approval prompts." }) }),
20835
+ /* @__PURE__ */ jsx95(Box74, { marginTop: 1, children: /* @__PURE__ */ jsx95(
20579
20836
  RadioButtonSelect,
20580
20837
  {
20581
20838
  items: [
@@ -20590,14 +20847,14 @@ function PermissionDialog({
20590
20847
  showNumbers: false
20591
20848
  }
20592
20849
  ) })
20593
- ] }) : selected ? /* @__PURE__ */ jsxs72(Fragment20, { children: [
20594
- /* @__PURE__ */ jsx94(Text67, { bold: true, color: theme.text.primary, children: selected.name }),
20595
- /* @__PURE__ */ jsx94(Text67, { color: theme.text.secondary, children: selected.value }),
20596
- /* @__PURE__ */ jsx94(Box74, { marginTop: 1, children: /* @__PURE__ */ jsx94(Text67, { children: selected.description ?? "No description is available for this preset." }) }),
20597
- snapshot.busy && /* @__PURE__ */ jsx94(Box74, { marginTop: 1, children: /* @__PURE__ */ jsx94(Text67, { color: theme.text.accent, children: "Applying permission..." }) })
20850
+ ] }) : selected ? /* @__PURE__ */ jsxs72(Fragment21, { children: [
20851
+ /* @__PURE__ */ jsx95(Text67, { bold: true, color: theme.text.primary, children: selected.name }),
20852
+ /* @__PURE__ */ jsx95(Text67, { color: theme.text.secondary, children: selected.value }),
20853
+ /* @__PURE__ */ jsx95(Box74, { marginTop: 1, children: /* @__PURE__ */ jsx95(Text67, { children: selected.description ?? "No description is available for this preset." }) }),
20854
+ snapshot.busy && /* @__PURE__ */ jsx95(Box74, { marginTop: 1, children: /* @__PURE__ */ jsx95(Text67, { color: theme.text.accent, children: "Applying permission..." }) })
20598
20855
  ] }) : null })
20599
20856
  ] }),
20600
- /* @__PURE__ */ jsx94(Box74, { marginTop: 1, children: /* @__PURE__ */ jsx94(Text67, { color: theme.text.secondary, children: "Changes apply to the current DSH Session immediately. No restart required." }) })
20857
+ /* @__PURE__ */ jsx95(Box74, { marginTop: 1, children: /* @__PURE__ */ jsx95(Text67, { color: theme.text.secondary, children: "Changes apply to the current DSH Session immediately. No restart required." }) })
20601
20858
  ]
20602
20859
  }
20603
20860
  );
@@ -20752,9 +21009,9 @@ import React21 from "react";
20752
21009
 
20753
21010
  // src/ui/components/dialogs/agents-dialog.tsx
20754
21011
  import {
20755
- useCallback as useCallback35,
21012
+ useCallback as useCallback36,
20756
21013
  useEffect as useEffect43,
20757
- useMemo as useMemo33,
21014
+ useMemo as useMemo35,
20758
21015
  useRef as useRef21,
20759
21016
  useState as useState41,
20760
21017
  useSyncExternalStore as useSyncExternalStore5
@@ -20784,6 +21041,7 @@ function conversationMessageToHistoryItem(message, visibleToolCallIds) {
20784
21041
  callId: message.callId,
20785
21042
  name: message.presentation?.kind === "card" ? message.presentation.title ?? message.name : message.name,
20786
21043
  description: message.presentation?.kind === "compact" ? "" : message.presentation?.description ?? message.arguments,
21044
+ arguments: message.arguments,
20787
21045
  resultDisplay: message.presentation?.kind === "compact" ? void 0 : message.presentation?.resultDisplay ?? (message.result === void 0 ? void 0 : {
20788
21046
  type: "dsh-content",
20789
21047
  content: message.result.content,
@@ -20822,6 +21080,7 @@ function conversationMessageFingerprint(message, item) {
20822
21080
  if (message.role === "tool") {
20823
21081
  return JSON.stringify([
20824
21082
  message.status,
21083
+ message.arguments,
20825
21084
  message.result,
20826
21085
  message.presentation
20827
21086
  ]);
@@ -20836,7 +21095,7 @@ function conversationMessageFingerprint(message, item) {
20836
21095
  }
20837
21096
 
20838
21097
  // src/ui/components/dialogs/agents-dialog.tsx
20839
- import { Fragment as Fragment21, jsx as jsx95, jsxs as jsxs73 } from "react/jsx-runtime";
21098
+ import { Fragment as Fragment22, jsx as jsx96, jsxs as jsxs73 } from "react/jsx-runtime";
20840
21099
  function shortId2(id) {
20841
21100
  return id.slice(-8);
20842
21101
  }
@@ -20887,7 +21146,7 @@ function AgentsDialog({ runtime, onClose }) {
20887
21146
  },
20888
21147
  { isActive: true }
20889
21148
  );
20890
- const openTranscript = useCallback35(
21149
+ const openTranscript = useCallback36(
20891
21150
  async (sessionId) => {
20892
21151
  const item = snapshot.items.find(
20893
21152
  (candidate) => candidate.id === sessionId && candidate.kind === "agent"
@@ -20925,7 +21184,7 @@ function AgentsDialog({ runtime, onClose }) {
20925
21184
  },
20926
21185
  [runtime, snapshot.items]
20927
21186
  );
20928
- const closeTranscript = useCallback35(() => {
21187
+ const closeTranscript = useCallback36(() => {
20929
21188
  openController.current?.abort();
20930
21189
  openController.current = void 0;
20931
21190
  openingRef.current = false;
@@ -20935,7 +21194,7 @@ function AgentsDialog({ runtime, onClose }) {
20935
21194
  setTranscriptSessionId(void 0);
20936
21195
  setOpenError(void 0);
20937
21196
  }, []);
20938
- const items = useMemo33(
21197
+ const items = useMemo35(
20939
21198
  () => snapshot.items.map((item) => ({
20940
21199
  key: item.id,
20941
21200
  value: item.id,
@@ -20948,7 +21207,7 @@ function AgentsDialog({ runtime, onClose }) {
20948
21207
  const item = snapshot.items.find(
20949
21208
  (candidate) => candidate.id === transcriptSessionId
20950
21209
  );
20951
- return /* @__PURE__ */ jsx95(
21210
+ return /* @__PURE__ */ jsx96(
20952
21211
  AgentTranscriptView,
20953
21212
  {
20954
21213
  runtime: transcript,
@@ -20973,10 +21232,10 @@ function AgentsDialog({ runtime, onClose }) {
20973
21232
  snapshot.items.length,
20974
21233
  ")"
20975
21234
  ] }),
20976
- /* @__PURE__ */ jsx95(Text68, { color: theme.text.secondary, children: "R refresh \xB7 Esc close" })
21235
+ /* @__PURE__ */ jsx96(Text68, { color: theme.text.secondary, children: "R refresh \xB7 Esc close" })
20977
21236
  ] }),
20978
- snapshot.status === "loading" && snapshot.items.length === 0 ? /* @__PURE__ */ jsx95(Box75, { marginTop: 1, children: /* @__PURE__ */ jsx95(Text68, { color: theme.text.secondary, children: "Loading delegated Agents..." }) }) : snapshot.status === "error" && snapshot.items.length === 0 ? /* @__PURE__ */ jsx95(Box75, { marginTop: 1, children: /* @__PURE__ */ jsx95(Text68, { color: theme.status.error, children: snapshot.error }) }) : snapshot.items.length === 0 ? /* @__PURE__ */ jsx95(Box75, { marginTop: 1, children: /* @__PURE__ */ jsx95(Text68, { color: theme.text.secondary, children: "The Main Agent has not delegated any subagents in this Session." }) }) : /* @__PURE__ */ jsxs73(Box75, { flexDirection: "row", marginTop: 1, children: [
20979
- /* @__PURE__ */ jsx95(Box75, { width: "55%", paddingRight: 2, flexDirection: "column", children: /* @__PURE__ */ jsx95(
21237
+ snapshot.status === "loading" && snapshot.items.length === 0 ? /* @__PURE__ */ jsx96(Box75, { marginTop: 1, children: /* @__PURE__ */ jsx96(Text68, { color: theme.text.secondary, children: "Loading delegated Agents..." }) }) : snapshot.status === "error" && snapshot.items.length === 0 ? /* @__PURE__ */ jsx96(Box75, { marginTop: 1, children: /* @__PURE__ */ jsx96(Text68, { color: theme.status.error, children: snapshot.error }) }) : snapshot.items.length === 0 ? /* @__PURE__ */ jsx96(Box75, { marginTop: 1, children: /* @__PURE__ */ jsx96(Text68, { color: theme.text.secondary, children: "The Main Agent has not delegated any subagents in this Session." }) }) : /* @__PURE__ */ jsxs73(Box75, { flexDirection: "row", marginTop: 1, children: [
21238
+ /* @__PURE__ */ jsx96(Box75, { width: "55%", paddingRight: 2, flexDirection: "column", children: /* @__PURE__ */ jsx96(
20980
21239
  DescriptiveRadioButtonSelect,
20981
21240
  {
20982
21241
  items,
@@ -20987,13 +21246,13 @@ function AgentsDialog({ runtime, onClose }) {
20987
21246
  maxItemsToShow: 10
20988
21247
  }
20989
21248
  ) }),
20990
- /* @__PURE__ */ jsx95(Box75, { width: "45%", paddingLeft: 2, flexDirection: "column", children: selected?.kind === "agent" ? /* @__PURE__ */ jsxs73(Fragment21, { children: [
20991
- /* @__PURE__ */ jsx95(Text68, { bold: true, color: theme.text.accent, children: selected.label }),
21249
+ /* @__PURE__ */ jsx96(Box75, { width: "45%", paddingLeft: 2, flexDirection: "column", children: selected?.kind === "agent" ? /* @__PURE__ */ jsxs73(Fragment22, { children: [
21250
+ /* @__PURE__ */ jsx96(Text68, { bold: true, color: theme.text.accent, children: selected.label }),
20992
21251
  /* @__PURE__ */ jsxs73(Box75, { marginTop: 1, flexDirection: "column", children: [
20993
21252
  /* @__PURE__ */ jsxs73(Text68, { color: theme.text.secondary, children: [
20994
21253
  "Status",
20995
21254
  " ",
20996
- /* @__PURE__ */ jsx95(
21255
+ /* @__PURE__ */ jsx96(
20997
21256
  Text68,
20998
21257
  {
20999
21258
  color: selected.activity === "running" ? theme.status.success : theme.text.primary,
@@ -21003,33 +21262,33 @@ function AgentsDialog({ runtime, onClose }) {
21003
21262
  ] }),
21004
21263
  /* @__PURE__ */ jsxs73(Text68, { color: theme.text.secondary, children: [
21005
21264
  "Mode ",
21006
- /* @__PURE__ */ jsx95(Text68, { color: theme.text.primary, children: selected.mode })
21265
+ /* @__PURE__ */ jsx96(Text68, { color: theme.text.primary, children: selected.mode })
21007
21266
  ] }),
21008
21267
  /* @__PURE__ */ jsxs73(Text68, { color: theme.text.secondary, children: [
21009
21268
  "Depth ",
21010
- /* @__PURE__ */ jsx95(Text68, { color: theme.text.primary, children: selected.depth })
21269
+ /* @__PURE__ */ jsx96(Text68, { color: theme.text.primary, children: selected.depth })
21011
21270
  ] }),
21012
21271
  /* @__PURE__ */ jsxs73(Text68, { color: theme.text.secondary, children: [
21013
21272
  "Session ",
21014
- /* @__PURE__ */ jsx95(Text68, { color: theme.text.primary, children: shortId2(selected.id) })
21273
+ /* @__PURE__ */ jsx96(Text68, { color: theme.text.primary, children: shortId2(selected.id) })
21015
21274
  ] })
21016
21275
  ] })
21017
- ] }) : selected ? /* @__PURE__ */ jsxs73(Fragment21, { children: [
21018
- /* @__PURE__ */ jsx95(Text68, { bold: true, color: theme.status.warning, children: "Unavailable Agent" }),
21276
+ ] }) : selected ? /* @__PURE__ */ jsxs73(Fragment22, { children: [
21277
+ /* @__PURE__ */ jsx96(Text68, { bold: true, color: theme.status.warning, children: "Unavailable Agent" }),
21019
21278
  /* @__PURE__ */ jsxs73(Box75, { marginTop: 1, flexDirection: "column", children: [
21020
21279
  /* @__PURE__ */ jsxs73(Text68, { color: theme.text.secondary, children: [
21021
21280
  "Reason ",
21022
- /* @__PURE__ */ jsx95(Text68, { color: theme.text.primary, children: selected.reason })
21281
+ /* @__PURE__ */ jsx96(Text68, { color: theme.text.primary, children: selected.reason })
21023
21282
  ] }),
21024
21283
  /* @__PURE__ */ jsxs73(Text68, { color: theme.text.secondary, children: [
21025
21284
  "Session ",
21026
- /* @__PURE__ */ jsx95(Text68, { color: theme.text.primary, children: shortId2(selected.id) })
21285
+ /* @__PURE__ */ jsx96(Text68, { color: theme.text.primary, children: shortId2(selected.id) })
21027
21286
  ] })
21028
21287
  ] })
21029
21288
  ] }) : null })
21030
21289
  ] }),
21031
- (opening || openError !== void 0) && /* @__PURE__ */ jsx95(Box75, { marginTop: 1, children: /* @__PURE__ */ jsx95(Text68, { color: openError === void 0 ? theme.text.secondary : theme.status.error, children: openError ?? "Opening canonical Agent history..." }) }),
21032
- snapshot.items.length > 0 && /* @__PURE__ */ jsx95(Box75, { marginTop: 1, children: /* @__PURE__ */ jsx95(Text68, { color: theme.text.secondary, children: "Enter opens read-only history. Agent conversations remain DSH-owned." }) })
21290
+ (opening || openError !== void 0) && /* @__PURE__ */ jsx96(Box75, { marginTop: 1, children: /* @__PURE__ */ jsx96(Text68, { color: openError === void 0 ? theme.text.secondary : theme.status.error, children: openError ?? "Opening canonical Agent history..." }) }),
21291
+ snapshot.items.length > 0 && /* @__PURE__ */ jsx96(Box75, { marginTop: 1, children: /* @__PURE__ */ jsx96(Text68, { color: theme.text.secondary, children: "Enter opens read-only history. Agent conversations remain DSH-owned." }) })
21033
21292
  ]
21034
21293
  }
21035
21294
  );
@@ -21046,7 +21305,7 @@ function AgentTranscriptView({
21046
21305
  runtime.getSnapshot
21047
21306
  );
21048
21307
  const listRef = useRef21(null);
21049
- const history = useMemo33(() => transcriptItems(snapshot.messages), [snapshot.messages]);
21308
+ const history = useMemo35(() => transcriptItems(snapshot.messages), [snapshot.messages]);
21050
21309
  const completed = snapshot.todos.filter((todo) => todo.status === "completed").length;
21051
21310
  useEffect43(() => {
21052
21311
  listRef.current?.scrollToEnd();
@@ -21072,26 +21331,26 @@ function AgentTranscriptView({
21072
21331
  children: [
21073
21332
  /* @__PURE__ */ jsxs73(Box75, { justifyContent: "space-between", children: [
21074
21333
  /* @__PURE__ */ jsxs73(Box75, { children: [
21075
- /* @__PURE__ */ jsx95(Text68, { bold: true, color: theme.text.primary, children: label }),
21334
+ /* @__PURE__ */ jsx96(Text68, { bold: true, color: theme.text.primary, children: label }),
21076
21335
  item?.kind === "agent" && /* @__PURE__ */ jsxs73(Text68, { color: theme.text.secondary, children: [
21077
21336
  " ",
21078
21337
  "\xB7 ",
21079
21338
  item.mode,
21080
21339
  " \xB7",
21081
21340
  " ",
21082
- /* @__PURE__ */ jsx95(Text68, { color: item.activity === "running" ? theme.status.success : theme.text.secondary, children: item.activity })
21341
+ /* @__PURE__ */ jsx96(Text68, { color: item.activity === "running" ? theme.status.success : theme.text.secondary, children: item.activity })
21083
21342
  ] })
21084
21343
  ] }),
21085
- /* @__PURE__ */ jsx95(Text68, { color: theme.text.secondary, children: "Read only \xB7 Esc back" })
21344
+ /* @__PURE__ */ jsx96(Text68, { color: theme.text.secondary, children: "Read only \xB7 Esc back" })
21086
21345
  ] }),
21087
- snapshot.todos.length > 0 && /* @__PURE__ */ jsx95(Box75, { marginTop: 1, children: /* @__PURE__ */ jsxs73(Text68, { color: theme.text.secondary, children: [
21346
+ snapshot.todos.length > 0 && /* @__PURE__ */ jsx96(Box75, { marginTop: 1, children: /* @__PURE__ */ jsxs73(Text68, { color: theme.text.secondary, children: [
21088
21347
  "Todo ",
21089
21348
  completed,
21090
21349
  "/",
21091
21350
  snapshot.todos.length,
21092
21351
  " completed"
21093
21352
  ] }) }),
21094
- /* @__PURE__ */ jsx95(Box75, { flexGrow: 1, marginTop: 1, overflow: "hidden", children: history.length === 0 ? /* @__PURE__ */ jsx95(Text68, { color: theme.text.secondary, children: "This Agent has no conversation events yet." }) : /* @__PURE__ */ jsx95(
21353
+ /* @__PURE__ */ jsx96(Box75, { flexGrow: 1, marginTop: 1, overflow: "hidden", children: history.length === 0 ? /* @__PURE__ */ jsx96(Text68, { color: theme.text.secondary, children: "This Agent has no conversation events yet." }) : /* @__PURE__ */ jsx96(
21095
21354
  ScrollableListWithForwardRef,
21096
21355
  {
21097
21356
  ref: listRef,
@@ -21101,7 +21360,7 @@ function AgentTranscriptView({
21101
21360
  keyExtractor: (entry) => entry.key,
21102
21361
  estimatedItemHeight: () => 3,
21103
21362
  initialScrollIndex: history.length - 1,
21104
- renderItem: ({ item: entry, index }) => /* @__PURE__ */ jsx95(
21363
+ renderItem: ({ item: entry, index }) => /* @__PURE__ */ jsx96(
21105
21364
  HistoryItemDisplay,
21106
21365
  {
21107
21366
  item: { ...entry.item, id: index },
@@ -21247,11 +21506,11 @@ var useSlashCommandProcessor = (addItem, clearItems, loadHistory, refreshStatic,
21247
21506
  );
21248
21507
  const [reloadTrigger, setReloadTrigger] = useState42(0);
21249
21508
  const commandAbortRef = useRef22(void 0);
21250
- const reloadCommands = useCallback36(() => {
21509
+ const reloadCommands = useCallback37(() => {
21251
21510
  setReloadTrigger((v) => v + 1);
21252
21511
  }, []);
21253
21512
  const [confirmationRequest, setConfirmationRequest] = useState42(null);
21254
- const commandContext = useMemo34(
21513
+ const commandContext = useMemo36(
21255
21514
  () => ({
21256
21515
  services: {
21257
21516
  modelSelection,
@@ -21308,7 +21567,10 @@ var useSlashCommandProcessor = (addItem, clearItems, loadHistory, refreshStatic,
21308
21567
  ...dshCommands === void 0 ? [] : [new DshCommandLoader(dshCommands)],
21309
21568
  new BuiltinCommandLoader(enableProfiler)
21310
21569
  ];
21311
- const commandService = await CommandService.create(loaders, controller.signal);
21570
+ const commandService = await CommandService.create(
21571
+ loaders,
21572
+ controller.signal
21573
+ );
21312
21574
  setCommands(commandService.getCommands());
21313
21575
  })();
21314
21576
  return () => {
@@ -21319,11 +21581,8 @@ var useSlashCommandProcessor = (addItem, clearItems, loadHistory, refreshStatic,
21319
21581
  () => dshCommands?.subscribe(reloadCommands),
21320
21582
  [dshCommands, reloadCommands]
21321
21583
  );
21322
- useEffect44(
21323
- () => () => commandAbortRef.current?.abort(),
21324
- []
21325
- );
21326
- const handleSlashCommand = useCallback36(
21584
+ useEffect44(() => () => commandAbortRef.current?.abort(), []);
21585
+ const handleSlashCommand = useCallback37(
21327
21586
  async (rawQuery, overwriteConfirmed, addToHistory = true) => {
21328
21587
  if (!commands) {
21329
21588
  return false;
@@ -21441,6 +21700,22 @@ ${commandToExecute.subCommands.map((sc) => ` - ${sc.name}: ${sc.description ||
21441
21700
  return { type: "handled" };
21442
21701
  }
21443
21702
  }
21703
+ if (dshCommands !== void 0) {
21704
+ const result = await dshCommands.execute(
21705
+ trimmed,
21706
+ commandController.signal
21707
+ );
21708
+ if (result.text !== void 0) {
21709
+ addItem(
21710
+ {
21711
+ type: result.kind === "error" ? "error" /* ERROR */ : "info" /* INFO */,
21712
+ text: result.text
21713
+ },
21714
+ Date.now()
21715
+ );
21716
+ }
21717
+ return { type: "handled" };
21718
+ }
21444
21719
  addItem(
21445
21720
  { type: "error" /* ERROR */, text: `Unknown command: ${trimmed}` },
21446
21721
  Date.now()
@@ -21467,6 +21742,7 @@ ${commandToExecute.subCommands.map((sc) => ` - ${sc.name}: ${sc.description ||
21467
21742
  actions,
21468
21743
  commands,
21469
21744
  commandContext,
21745
+ dshCommands,
21470
21746
  setIsProcessing,
21471
21747
  setConfirmationRequest,
21472
21748
  setCustomDialog
@@ -21488,13 +21764,13 @@ import * as fs12 from "node:fs";
21488
21764
  import { basename as basename3, join as join5 } from "node:path";
21489
21765
 
21490
21766
  // src/ui/hooks/commands/use-settings-command.ts
21491
- import { useState as useState43, useCallback as useCallback37 } from "react";
21767
+ import { useState as useState43, useCallback as useCallback38 } from "react";
21492
21768
  function useSettingsCommand() {
21493
21769
  const [isSettingsDialogOpen, setIsSettingsDialogOpen] = useState43(false);
21494
- const openSettingsDialog = useCallback37(() => {
21770
+ const openSettingsDialog = useCallback38(() => {
21495
21771
  setIsSettingsDialogOpen(true);
21496
21772
  }, []);
21497
- const closeSettingsDialog = useCallback37(() => {
21773
+ const closeSettingsDialog = useCallback38(() => {
21498
21774
  setIsSettingsDialogOpen(false);
21499
21775
  }, []);
21500
21776
  return {
@@ -21505,11 +21781,11 @@ function useSettingsCommand() {
21505
21781
  }
21506
21782
 
21507
21783
  // src/ui/hooks/commands/use-theme-command.ts
21508
- import { useState as useState44, useCallback as useCallback38 } from "react";
21784
+ import { useState as useState44, useCallback as useCallback39 } from "react";
21509
21785
  import process6 from "node:process";
21510
21786
  var useThemeCommand = (loadedSettings, setThemeError, addItem, initialThemeError) => {
21511
21787
  const [isThemeDialogOpen, setIsThemeDialogOpen] = useState44(!!initialThemeError);
21512
- const openThemeDialog = useCallback38(() => {
21788
+ const openThemeDialog = useCallback39(() => {
21513
21789
  if (process6.env["NO_COLOR"]) {
21514
21790
  addItem(
21515
21791
  {
@@ -21522,7 +21798,7 @@ var useThemeCommand = (loadedSettings, setThemeError, addItem, initialThemeError
21522
21798
  }
21523
21799
  setIsThemeDialogOpen(true);
21524
21800
  }, [addItem]);
21525
- const applyTheme = useCallback38(
21801
+ const applyTheme = useCallback39(
21526
21802
  (themeName) => {
21527
21803
  if (!themeManager.setActiveTheme(themeName)) {
21528
21804
  setIsThemeDialogOpen(true);
@@ -21533,17 +21809,17 @@ var useThemeCommand = (loadedSettings, setThemeError, addItem, initialThemeError
21533
21809
  },
21534
21810
  [setThemeError]
21535
21811
  );
21536
- const handleThemeHighlight = useCallback38(
21812
+ const handleThemeHighlight = useCallback39(
21537
21813
  (themeName) => {
21538
21814
  applyTheme(themeName);
21539
21815
  },
21540
21816
  [applyTheme]
21541
21817
  );
21542
- const closeThemeDialog = useCallback38(() => {
21818
+ const closeThemeDialog = useCallback39(() => {
21543
21819
  applyTheme(loadedSettings.merged.ui.theme);
21544
21820
  setIsThemeDialogOpen(false);
21545
21821
  }, [applyTheme, loadedSettings]);
21546
- const handleThemeSelect = useCallback38(
21822
+ const handleThemeSelect = useCallback39(
21547
21823
  (themeName, scope) => {
21548
21824
  try {
21549
21825
  const mergedCustomThemes = {
@@ -21579,7 +21855,7 @@ var useThemeCommand = (loadedSettings, setThemeError, addItem, initialThemeError
21579
21855
  };
21580
21856
 
21581
21857
  // src/ui/hooks/input/use-vim.ts
21582
- import { useCallback as useCallback39, useReducer as useReducer5, useEffect as useEffect45, useRef as useRef23 } from "react";
21858
+ import { useCallback as useCallback40, useReducer as useReducer5, useEffect as useEffect45, useRef as useRef23 } from "react";
21583
21859
  var DIGIT_MULTIPLIER = 10;
21584
21860
  var DEFAULT_COUNT = 1;
21585
21861
  var DIGIT_1_TO_9 = /^[1-9]$/;
@@ -21648,18 +21924,18 @@ function useVim(buffer, onSubmit) {
21648
21924
  useEffect45(() => {
21649
21925
  dispatch({ type: "SET_MODE", mode: vimMode });
21650
21926
  }, [vimMode]);
21651
- const updateMode = useCallback39(
21927
+ const updateMode = useCallback40(
21652
21928
  (mode) => {
21653
21929
  setVimMode(mode);
21654
21930
  dispatch({ type: "SET_MODE", mode });
21655
21931
  },
21656
21932
  [setVimMode]
21657
21933
  );
21658
- const getCurrentCount = useCallback39(
21934
+ const getCurrentCount = useCallback40(
21659
21935
  () => state.count || DEFAULT_COUNT,
21660
21936
  [state.count]
21661
21937
  );
21662
- const checkDoubleEscape = useCallback39(() => {
21938
+ const checkDoubleEscape = useCallback40(() => {
21663
21939
  const now = Date.now();
21664
21940
  const lastEscape = lastEscapeTimestampRef.current;
21665
21941
  lastEscapeTimestampRef.current = now;
@@ -21669,7 +21945,7 @@ function useVim(buffer, onSubmit) {
21669
21945
  }
21670
21946
  return false;
21671
21947
  }, []);
21672
- const executeCommand = useCallback39(
21948
+ const executeCommand = useCallback40(
21673
21949
  (cmdType, count) => {
21674
21950
  switch (cmdType) {
21675
21951
  case CMD_TYPES.DELETE_WORD_FORWARD: {
@@ -21745,7 +22021,7 @@ function useVim(buffer, onSubmit) {
21745
22021
  },
21746
22022
  [buffer, updateMode]
21747
22023
  );
21748
- const handleInsertModeInput = useCallback39(
22024
+ const handleInsertModeInput = useCallback40(
21749
22025
  (normalizedKey) => {
21750
22026
  if (keyMatchers["basic.cancel" /* ESCAPE */](normalizedKey)) {
21751
22027
  checkDoubleEscape();
@@ -21777,7 +22053,7 @@ function useVim(buffer, onSubmit) {
21777
22053
  },
21778
22054
  [buffer, dispatch, updateMode, onSubmit, checkDoubleEscape]
21779
22055
  );
21780
- const normalizeKey = useCallback39(
22056
+ const normalizeKey = useCallback40(
21781
22057
  (key) => ({
21782
22058
  name: key.name || "",
21783
22059
  sequence: key.sequence || "",
@@ -21789,7 +22065,7 @@ function useVim(buffer, onSubmit) {
21789
22065
  }),
21790
22066
  []
21791
22067
  );
21792
- const handleChangeMovement = useCallback39(
22068
+ const handleChangeMovement = useCallback40(
21793
22069
  (movement) => {
21794
22070
  const count = getCurrentCount();
21795
22071
  dispatch({ type: "CLEAR_COUNT" });
@@ -21810,7 +22086,7 @@ function useVim(buffer, onSubmit) {
21810
22086
  },
21811
22087
  [getCurrentCount, dispatch, buffer, updateMode]
21812
22088
  );
21813
- const handleOperatorMotion = useCallback39(
22089
+ const handleOperatorMotion = useCallback40(
21814
22090
  (operator, motion) => {
21815
22091
  const count = getCurrentCount();
21816
22092
  const commandMap = {
@@ -21837,7 +22113,7 @@ function useVim(buffer, onSubmit) {
21837
22113
  },
21838
22114
  [getCurrentCount, executeCommand, dispatch]
21839
22115
  );
21840
- const handleInput = useCallback39(
22116
+ const handleInput = useCallback40(
21841
22117
  (key) => {
21842
22118
  if (!vimEnabled) {
21843
22119
  return false;
@@ -22144,13 +22420,13 @@ function useVim(buffer, onSubmit) {
22144
22420
  }
22145
22421
 
22146
22422
  // src/ui/hooks/session/use-git-branch-name.ts
22147
- import { useState as useState45, useEffect as useEffect46, useCallback as useCallback40 } from "react";
22423
+ import { useState as useState45, useEffect as useEffect46, useCallback as useCallback41 } from "react";
22148
22424
  import fs9 from "node:fs";
22149
22425
  import fsPromises2 from "node:fs/promises";
22150
22426
  import path11 from "node:path";
22151
22427
  function useGitBranchName(cwd) {
22152
22428
  const [branchName, setBranchName] = useState45(void 0);
22153
- const fetchBranchName = useCallback40(async () => {
22429
+ const fetchBranchName = useCallback41(async () => {
22154
22430
  try {
22155
22431
  const { stdout } = await spawnAsync(
22156
22432
  "git",
@@ -22199,7 +22475,7 @@ function useGitBranchName(cwd) {
22199
22475
  }
22200
22476
 
22201
22477
  // src/ui/hooks/settings/use-editor-settings.ts
22202
- import { useState as useState46, useCallback as useCallback41 } from "react";
22478
+ import { useState as useState46, useCallback as useCallback42 } from "react";
22203
22479
 
22204
22480
  // src/config/setting-paths.ts
22205
22481
  var SettingPaths = {
@@ -22211,10 +22487,10 @@ var SettingPaths = {
22211
22487
  // src/ui/hooks/settings/use-editor-settings.ts
22212
22488
  var useEditorSettings = (loadedSettings, setEditorError, addItem) => {
22213
22489
  const [isEditorDialogOpen, setIsEditorDialogOpen] = useState46(false);
22214
- const openEditorDialog = useCallback41(() => {
22490
+ const openEditorDialog = useCallback42(() => {
22215
22491
  setIsEditorDialogOpen(true);
22216
22492
  }, []);
22217
- const handleEditorSelect = useCallback41(
22493
+ const handleEditorSelect = useCallback42(
22218
22494
  (editorType, scope) => {
22219
22495
  if (editorType && !checkHasEditorType(editorType)) {
22220
22496
  return;
@@ -22240,7 +22516,7 @@ var useEditorSettings = (loadedSettings, setEditorError, addItem) => {
22240
22516
  },
22241
22517
  [loadedSettings, setEditorError, addItem]
22242
22518
  );
22243
- const exitEditorDialog = useCallback41(() => {
22519
+ const exitEditorDialog = useCallback42(() => {
22244
22520
  setIsEditorDialogOpen(false);
22245
22521
  }, []);
22246
22522
  return {
@@ -22277,7 +22553,7 @@ var useMemoryMonitor = ({ addItem }) => {
22277
22553
 
22278
22554
  // src/ui/hooks/visual/use-console-messages.ts
22279
22555
  import {
22280
- useCallback as useCallback42,
22556
+ useCallback as useCallback43,
22281
22557
  useEffect as useEffect48,
22282
22558
  useReducer as useReducer6,
22283
22559
  useRef as useRef24,
@@ -22311,7 +22587,7 @@ function useConsoleMessages() {
22311
22587
  const messageQueueRef = useRef24([]);
22312
22588
  const timeoutRef = useRef24(null);
22313
22589
  const [, startTransition] = useTransition();
22314
- const processQueue = useCallback42(() => {
22590
+ const processQueue = useCallback43(() => {
22315
22591
  if (messageQueueRef.current.length > 0) {
22316
22592
  const messagesToProcess = messageQueueRef.current;
22317
22593
  messageQueueRef.current = [];
@@ -22321,7 +22597,7 @@ function useConsoleMessages() {
22321
22597
  }
22322
22598
  timeoutRef.current = null;
22323
22599
  }, []);
22324
- const handleNewMessage = useCallback42(
22600
+ const handleNewMessage = useCallback43(
22325
22601
  (message) => {
22326
22602
  messageQueueRef.current.push(message);
22327
22603
  if (!timeoutRef.current) {
@@ -22349,7 +22625,7 @@ function useConsoleMessages() {
22349
22625
  coreEvents.off(CoreEvent.Output, handleOutput);
22350
22626
  };
22351
22627
  }, [handleNewMessage]);
22352
- const clearConsoleMessages = useCallback42(() => {
22628
+ const clearConsoleMessages = useCallback43(() => {
22353
22629
  if (timeoutRef.current) {
22354
22630
  clearTimeout(timeoutRef.current);
22355
22631
  timeoutRef.current = null;
@@ -22636,18 +22912,18 @@ var useLoadingIndicator = ({
22636
22912
  };
22637
22913
 
22638
22914
  // src/ui/hooks/session/use-message-queue.ts
22639
- import { useCallback as useCallback43, useEffect as useEffect52, useMemo as useMemo35, useState as useState50 } from "react";
22915
+ import { useCallback as useCallback44, useEffect as useEffect52, useMemo as useMemo37, useState as useState50 } from "react";
22640
22916
  function useMessageQueue({
22641
22917
  queueKey,
22642
22918
  streamingState,
22643
22919
  submitQuery
22644
22920
  }) {
22645
22921
  const [queuedMessages, setQueuedMessages] = useState50([]);
22646
- const messageQueue = useMemo35(
22922
+ const messageQueue = useMemo37(
22647
22923
  () => queuedMessages.filter((entry) => entry.key === queueKey).map((entry) => entry.message),
22648
22924
  [queueKey, queuedMessages]
22649
22925
  );
22650
- const addMessage = useCallback43((message) => {
22926
+ const addMessage = useCallback44((message) => {
22651
22927
  const trimmedMessage = message.trim();
22652
22928
  if (trimmedMessage.length > 0) {
22653
22929
  setQueuedMessages((previous) => [
@@ -22656,16 +22932,16 @@ function useMessageQueue({
22656
22932
  ]);
22657
22933
  }
22658
22934
  }, [queueKey]);
22659
- const clearQueue = useCallback43(() => {
22935
+ const clearQueue = useCallback44(() => {
22660
22936
  setQueuedMessages(
22661
22937
  (previous) => previous.filter((entry) => entry.key !== queueKey)
22662
22938
  );
22663
22939
  }, [queueKey]);
22664
- const getQueuedMessagesText = useCallback43(() => {
22940
+ const getQueuedMessagesText = useCallback44(() => {
22665
22941
  if (messageQueue.length === 0) return "";
22666
22942
  return messageQueue.join("\n\n");
22667
22943
  }, [messageQueue]);
22668
- const popAllMessages = useCallback43(() => {
22944
+ const popAllMessages = useCallback44(() => {
22669
22945
  if (messageQueue.length === 0) {
22670
22946
  return void 0;
22671
22947
  }
@@ -22694,7 +22970,7 @@ function useMessageQueue({
22694
22970
  }
22695
22971
 
22696
22972
  // src/ui/hooks/input/use-input-history-store.ts
22697
- import { useCallback as useCallback44, useRef as useRef28, useState as useState51 } from "react";
22973
+ import { useCallback as useCallback45, useRef as useRef28, useState as useState51 } from "react";
22698
22974
  function deduplicateConsecutive(messages) {
22699
22975
  return messages.filter(
22700
22976
  (message, index) => index === 0 || message !== messages[index - 1]
@@ -22703,7 +22979,7 @@ function deduplicateConsecutive(messages) {
22703
22979
  function useInputHistoryStore() {
22704
22980
  const [inputHistory, setInputHistory] = useState51([]);
22705
22981
  const initializationStarted = useRef28(false);
22706
- const initializeFromHistory = useCallback44(
22982
+ const initializeFromHistory = useCallback45(
22707
22983
  async (history) => {
22708
22984
  if (initializationStarted.current) return;
22709
22985
  initializationStarted.current = true;
@@ -22724,7 +23000,7 @@ function useInputHistoryStore() {
22724
23000
  },
22725
23001
  []
22726
23002
  );
22727
- const addInput = useCallback44(
23003
+ const addInput = useCallback45(
22728
23004
  (input) => {
22729
23005
  const trimmedInput = input.trim();
22730
23006
  if (!trimmedInput) return;
@@ -22888,7 +23164,7 @@ var useShellInactivityStatus = ({
22888
23164
  };
22889
23165
 
22890
23166
  // src/ui/hooks/input/use-local-shell-command.ts
22891
- import { useCallback as useCallback45, useEffect as useEffect54, useRef as useRef30, useState as useState53 } from "react";
23167
+ import { useCallback as useCallback46, useEffect as useEffect54, useRef as useRef30, useState as useState53 } from "react";
22892
23168
  import crypto2 from "node:crypto";
22893
23169
  import fs11 from "node:fs";
22894
23170
  import os3 from "node:os";
@@ -22910,7 +23186,7 @@ function useLocalShellCommand({
22910
23186
  const [isExecuting, setIsExecuting] = useState53(false);
22911
23187
  const [activePtyId, setActivePtyId] = useState53(void 0);
22912
23188
  const [lastOutputTime, setLastOutputTime] = useState53(0);
22913
- const cancel = useCallback45(() => controllerRef.current?.abort(), []);
23189
+ const cancel = useCallback46(() => controllerRef.current?.abort(), []);
22914
23190
  useEffect54(() => {
22915
23191
  mountedRef.current = true;
22916
23192
  return () => {
@@ -22918,7 +23194,7 @@ function useLocalShellCommand({
22918
23194
  controllerRef.current?.abort();
22919
23195
  };
22920
23196
  }, []);
22921
- const execute = useCallback45(
23197
+ const execute = useCallback46(
22922
23198
  (rawCommand) => {
22923
23199
  const command = rawCommand.trim();
22924
23200
  if (command.length === 0 || controllerRef.current !== void 0) {
@@ -23051,7 +23327,9 @@ function useLocalShellCommand({
23051
23327
  fs11.unlinkSync(pwdFilePath);
23052
23328
  } catch (error) {
23053
23329
  if (error.code !== "ENOENT") {
23054
- onDebugMessage(`Unable to remove shell state file: ${String(error)}`);
23330
+ onDebugMessage(
23331
+ `Unable to remove shell state file: ${String(error)}`
23332
+ );
23055
23333
  }
23056
23334
  }
23057
23335
  }
@@ -23115,7 +23393,7 @@ ${output}`;
23115
23393
  }
23116
23394
 
23117
23395
  // src/ui/app-container.tsx
23118
- import { jsx as jsx96 } from "react/jsx-runtime";
23396
+ import { jsx as jsx97 } from "react/jsx-runtime";
23119
23397
  var SHELL_WIDTH_FRACTION = 0.89;
23120
23398
  var SHELL_HEIGHT_PADDING = 10;
23121
23399
  var noopExternalStoreSubscribe = () => () => {
@@ -23257,7 +23535,7 @@ var AppContainer = (props) => {
23257
23535
  const [queueErrorMessage, setQueueErrorMessage] = useState54(
23258
23536
  null
23259
23537
  );
23260
- const toggleDebugProfiler = useCallback46(
23538
+ const toggleDebugProfiler = useCallback47(
23261
23539
  () => setShowDebugProfiler((visible) => !visible),
23262
23540
  []
23263
23541
  );
@@ -23278,7 +23556,7 @@ var AppContainer = (props) => {
23278
23556
  providerSetupRuntime?.getSnapshot ?? emptyProviderSetupSnapshot
23279
23557
  );
23280
23558
  const [providerSetupDismissed, setProviderSetupDismissed] = useState54(false);
23281
- const promptHistory = useMemo36(
23559
+ const promptHistory = useMemo38(
23282
23560
  () => new PromptHistoryStore(
23283
23561
  join5(config.storage.getProjectTempDir(), "prompt_history.json")
23284
23562
  ),
@@ -23314,19 +23592,19 @@ var AppContainer = (props) => {
23314
23592
  }, []);
23315
23593
  const { consoleMessages, clearConsoleMessages: clearConsoleMessagesState } = useConsoleMessages();
23316
23594
  const mainAreaWidth = calculateMainAreaWidth(terminalWidth, settings);
23317
- const { inputWidth, suggestionsWidth } = useMemo36(() => {
23595
+ const { inputWidth, suggestionsWidth } = useMemo38(() => {
23318
23596
  const { inputWidth: inputWidth2, suggestionsWidth: suggestionsWidth2 } = calculatePromptWidths(mainAreaWidth);
23319
23597
  return { inputWidth: inputWidth2, suggestionsWidth: suggestionsWidth2 };
23320
23598
  }, [mainAreaWidth]);
23321
23599
  const staticAreaMaxItemHeight = Math.max(terminalHeight * 4, 100);
23322
- const isValidPath = useCallback46((filePath) => {
23600
+ const isValidPath = useCallback47((filePath) => {
23323
23601
  try {
23324
23602
  return fs12.existsSync(filePath) && fs12.statSync(filePath).isFile();
23325
23603
  } catch (_e) {
23326
23604
  return false;
23327
23605
  }
23328
23606
  }, []);
23329
- const getPreferredEditor = useCallback46(
23607
+ const getPreferredEditor = useCallback47(
23330
23608
  () => settings.merged.general.preferredEditor,
23331
23609
  [settings.merged.general.preferredEditor]
23332
23610
  );
@@ -23342,13 +23620,13 @@ var AppContainer = (props) => {
23342
23620
  useEffect55(() => {
23343
23621
  initializeFromHistory(promptHistory);
23344
23622
  }, [initializeFromHistory, promptHistory]);
23345
- const refreshStatic = useCallback46(() => {
23623
+ const refreshStatic = useCallback47(() => {
23346
23624
  if (!isAlternateBuffer) {
23347
23625
  stdout.write(ansiEscapes.clearTerminal);
23348
23626
  }
23349
23627
  setHistoryRemountKey((prev) => prev + 1);
23350
23628
  }, [setHistoryRemountKey, isAlternateBuffer, stdout]);
23351
- const handleEditorClose = useCallback46(() => {
23629
+ const handleEditorClose = useCallback47(() => {
23352
23630
  if (shouldEnterAlternateScreen(isAlternateBuffer, config.getScreenReader())) {
23353
23631
  enterAlternateScreen();
23354
23632
  enableMouseEvents();
@@ -23385,7 +23663,7 @@ var AppContainer = (props) => {
23385
23663
  } = useEditorSettings(settings, setEditorError, historyManager.addItem);
23386
23664
  const { isSettingsDialogOpen, openSettingsDialog, closeSettingsDialog } = useSettingsCommand();
23387
23665
  const { toggleVimEnabled } = useVimMode();
23388
- const slashCommandActions = useMemo36(
23666
+ const slashCommandActions = useMemo38(
23389
23667
  () => ({
23390
23668
  openThemeDialog,
23391
23669
  openEditorDialog,
@@ -23434,6 +23712,24 @@ var AppContainer = (props) => {
23434
23712
  sideConversationRuntime,
23435
23713
  subagentCatalogRuntime
23436
23714
  );
23715
+ const commandPreparationRef = useRef31(void 0);
23716
+ useEffect55(() => {
23717
+ if (!isSlashCommand(buffer.text.trim()) || commandPreparationRef.current !== void 0) {
23718
+ return;
23719
+ }
23720
+ const controller = new AbortController();
23721
+ commandPreparationRef.current = controller;
23722
+ void commandRuntime.prepare(controller.signal).catch((error) => {
23723
+ if (!(error instanceof Error && error.name === "AbortError")) {
23724
+ debugLogger.debug(`Unable to prepare DSH commands: ${String(error)}`);
23725
+ }
23726
+ }).finally(() => {
23727
+ if (commandPreparationRef.current === controller) {
23728
+ commandPreparationRef.current = void 0;
23729
+ }
23730
+ });
23731
+ }, [buffer.text, commandRuntime]);
23732
+ useEffect55(() => () => commandPreparationRef.current?.abort(), []);
23437
23733
  const cancelHandlerRef = useRef31(
23438
23734
  () => {
23439
23735
  }
@@ -23451,7 +23747,7 @@ var AppContainer = (props) => {
23451
23747
  }
23452
23748
  }, [pendingRestorePrompt, inputHistory, historyManager.history]);
23453
23749
  const initError = initializationResult.initError;
23454
- const todos = useMemo36(
23750
+ const todos = useMemo38(
23455
23751
  () => ({
23456
23752
  todos: conversationSnapshot.todos.map((todo) => ({
23457
23753
  description: todo.content,
@@ -23476,7 +23772,7 @@ var AppContainer = (props) => {
23476
23772
  terminalHeight
23477
23773
  });
23478
23774
  const streamingState = conversationSnapshot.busy || promptInputPreparing || localShellExecuting || isProcessing ? "responding" /* Responding */ : "idle" /* Idle */;
23479
- const submitQuery = useCallback46(
23775
+ const submitQuery = useCallback47(
23480
23776
  (query) => {
23481
23777
  if (isSlashCommand(query.trim())) {
23482
23778
  void handleSlashCommand(query);
@@ -23529,7 +23825,7 @@ var AppContainer = (props) => {
23529
23825
  buffer
23530
23826
  ]
23531
23827
  );
23532
- const cancelOngoingRequest = useCallback46(() => {
23828
+ const cancelOngoingRequest = useCallback47(() => {
23533
23829
  cancelCommand();
23534
23830
  cancelLocalShell();
23535
23831
  promptInputAbortRef.current?.abort();
@@ -23565,7 +23861,7 @@ var AppContainer = (props) => {
23565
23861
  streamingState,
23566
23862
  submitQuery
23567
23863
  });
23568
- cancelHandlerRef.current = useCallback46(
23864
+ cancelHandlerRef.current = useCallback47(
23569
23865
  (shouldRestorePrompt = true) => {
23570
23866
  const lastUserMessage = inputHistory.at(-1);
23571
23867
  let textToSet = shouldRestorePrompt ? lastUserMessage || "" : "";
@@ -23582,7 +23878,7 @@ ${queuedText}` : queuedText;
23582
23878
  },
23583
23879
  [buffer, inputHistory, getQueuedMessagesText, clearQueue]
23584
23880
  );
23585
- const handleFinalSubmit = useCallback46(
23881
+ const handleFinalSubmit = useCallback47(
23586
23882
  (submittedValue) => {
23587
23883
  if (shellModeActive) {
23588
23884
  executeLocalShell(submittedValue);
@@ -23617,7 +23913,7 @@ ${queuedText}` : queuedText;
23617
23913
  streamingState
23618
23914
  ]
23619
23915
  );
23620
- const handleClearScreen = useCallback46(() => {
23916
+ const handleClearScreen = useCallback47(() => {
23621
23917
  historyManager.clearItems();
23622
23918
  clearConsoleMessagesState();
23623
23919
  refreshStatic();
@@ -23648,7 +23944,7 @@ ${queuedText}` : queuedText;
23648
23944
  sanitizationConfig: config.sanitizationConfig
23649
23945
  });
23650
23946
  const isFocused = useFocus();
23651
- const initialPrompt = useMemo36(
23947
+ const initialPrompt = useMemo38(
23652
23948
  () => props.initialPrompt ?? config.getQuestion(),
23653
23949
  [config, props.initialPrompt]
23654
23950
  );
@@ -23659,7 +23955,7 @@ ${queuedText}` : queuedText;
23659
23955
  return;
23660
23956
  }
23661
23957
  setCustomDialog(
23662
- /* @__PURE__ */ jsx96(
23958
+ /* @__PURE__ */ jsx97(
23663
23959
  ProviderSetupDialog,
23664
23960
  {
23665
23961
  runtime: providerSetupRuntime,
@@ -23731,7 +24027,7 @@ ${queuedText}` : queuedText;
23731
24027
  const isInitialMount = useRef31(true);
23732
24028
  const warningTimeoutRef = useRef31(null);
23733
24029
  const tabFocusTimeoutRef = useRef31(null);
23734
- const handleWarning = useCallback46((message) => {
24030
+ const handleWarning = useCallback47((message) => {
23735
24031
  setWarningMessage(message);
23736
24032
  if (warningTimeoutRef.current) {
23737
24033
  clearTimeout(warningTimeoutRef.current);
@@ -23819,7 +24115,7 @@ ${queuedText}` : queuedText;
23819
24115
  }, WARNING_PROMPT_DURATION_MS);
23820
24116
  }
23821
24117
  }, [ctrlDPressCount, config, setCtrlDPressCount, handleSlashCommand]);
23822
- const handleEscapePromptChange = useCallback46((showPrompt) => {
24118
+ const handleEscapePromptChange = useCallback47((showPrompt) => {
23823
24119
  setShowEscapePrompt(showPrompt);
23824
24120
  }, []);
23825
24121
  const { elapsedTime, currentLoadingPhrase } = useLoadingIndicator({
@@ -23827,7 +24123,7 @@ ${queuedText}` : queuedText;
23827
24123
  shouldShowFocusHint,
23828
24124
  customWittyPhrases: settings.merged.ui.customWittyPhrases
23829
24125
  });
23830
- const handleGlobalKeypress = useCallback46(
24126
+ const handleGlobalKeypress = useCallback47(
23831
24127
  (key) => {
23832
24128
  if (copyModeEnabled) {
23833
24129
  setCopyModeEnabled(false);
@@ -24018,23 +24314,23 @@ ${queuedText}` : queuedText;
24018
24314
  coreEvents.off(CoreEvent.UserFeedback, handleUserFeedback);
24019
24315
  };
24020
24316
  }, [historyManager]);
24021
- const filteredConsoleMessages = useMemo36(() => {
24317
+ const filteredConsoleMessages = useMemo38(() => {
24022
24318
  if (config.getDebugMode()) {
24023
24319
  return consoleMessages;
24024
24320
  }
24025
24321
  return consoleMessages.filter((msg) => msg.type !== "debug");
24026
24322
  }, [consoleMessages, config]);
24027
- const errorCount = useMemo36(
24323
+ const errorCount = useMemo38(
24028
24324
  () => filteredConsoleMessages.filter((msg) => msg.type === "error").reduce((total, msg) => total + msg.count, 0),
24029
24325
  [filteredConsoleMessages]
24030
24326
  );
24031
24327
  const nightly = props.version.includes("nightly");
24032
24328
  const dialogsVisible = pendingUserQuestion !== void 0 || !!confirmationRequest || !!customDialog || isThemeDialogOpen || isSettingsDialogOpen || isEditorDialogOpen;
24033
- const pendingHistoryItems = useMemo36(
24329
+ const pendingHistoryItems = useMemo38(
24034
24330
  () => pendingShellHistoryItem ? [pendingShellHistoryItem] : [],
24035
24331
  [pendingShellHistoryItem]
24036
24332
  );
24037
- const uiState = useMemo36(
24333
+ const uiState = useMemo38(
24038
24334
  () => ({
24039
24335
  history: historyManager.history,
24040
24336
  isThemeDialogOpen,
@@ -24162,7 +24458,7 @@ ${queuedText}` : queuedText;
24162
24458
  subagentCatalogSnapshot
24163
24459
  ]
24164
24460
  );
24165
- const uiActions = useMemo36(
24461
+ const uiActions = useMemo38(
24166
24462
  () => ({
24167
24463
  handleThemeSelect,
24168
24464
  closeThemeDialog,
@@ -24204,14 +24500,14 @@ ${queuedText}` : queuedText;
24204
24500
  setEmbeddedShellFocused
24205
24501
  ]
24206
24502
  );
24207
- return /* @__PURE__ */ jsx96(UIStateContext.Provider, { value: uiState, children: /* @__PURE__ */ jsx96(UIActionsContext.Provider, { value: uiActions, children: /* @__PURE__ */ jsx96(ConfigContext.Provider, { value: config, children: /* @__PURE__ */ jsx96(
24503
+ return /* @__PURE__ */ jsx97(UIStateContext.Provider, { value: uiState, children: /* @__PURE__ */ jsx97(UIActionsContext.Provider, { value: uiActions, children: /* @__PURE__ */ jsx97(ConfigContext.Provider, { value: config, children: /* @__PURE__ */ jsx97(
24208
24504
  AppContext.Provider,
24209
24505
  {
24210
24506
  value: {
24211
24507
  version: props.version,
24212
24508
  startupWarnings: props.startupWarnings || []
24213
24509
  },
24214
- children: /* @__PURE__ */ jsx96(ApprovalRuntimeProvider, { runtime: approvalRuntime, children: /* @__PURE__ */ jsx96(UserQuestionRuntimeProvider, { runtime: userQuestionRuntime, children: /* @__PURE__ */ jsx96(ShellFocusContext.Provider, { value: isFocused, children: /* @__PURE__ */ jsx96(App, {}) }) }) })
24510
+ children: /* @__PURE__ */ jsx97(ApprovalRuntimeProvider, { runtime: approvalRuntime, children: /* @__PURE__ */ jsx97(UserQuestionRuntimeProvider, { runtime: userQuestionRuntime, children: /* @__PURE__ */ jsx97(ShellFocusContext.Provider, { value: isFocused, children: /* @__PURE__ */ jsx97(App, {}) }) }) })
24215
24511
  }
24216
24512
  ) }) }) });
24217
24513
  };
@@ -24219,7 +24515,7 @@ ${queuedText}` : queuedText;
24219
24515
  // src/ui/root.tsx
24220
24516
  import React22 from "react";
24221
24517
  import { render } from "ink";
24222
- import { jsx as jsx97 } from "react/jsx-runtime";
24518
+ import { jsx as jsx98 } from "react/jsx-runtime";
24223
24519
  var SLOW_RENDER_MS = 200;
24224
24520
  function validateDnsResolutionOrder(order) {
24225
24521
  const defaultValue = "ipv4first";
@@ -24267,17 +24563,17 @@ async function startInteractiveUI(config, settings, startupWarnings, workspaceRo
24267
24563
  const version = await getVersion();
24268
24564
  const AppWrapper = () => {
24269
24565
  useKittyKeyboardProtocol();
24270
- return /* @__PURE__ */ jsx97(SettingsContext.Provider, { value: settings, children: /* @__PURE__ */ jsx97(
24566
+ return /* @__PURE__ */ jsx98(SettingsContext.Provider, { value: settings, children: /* @__PURE__ */ jsx98(
24271
24567
  KeypressProvider,
24272
24568
  {
24273
24569
  config,
24274
24570
  debugKeystrokeLogging: settings.merged.general.debugKeystrokeLogging,
24275
- children: /* @__PURE__ */ jsx97(
24571
+ children: /* @__PURE__ */ jsx98(
24276
24572
  MouseProvider,
24277
24573
  {
24278
24574
  mouseEventsEnabled,
24279
24575
  debugKeystrokeLogging: settings.merged.general.debugKeystrokeLogging,
24280
- children: /* @__PURE__ */ jsx97(ScrollProvider, { children: /* @__PURE__ */ jsx97(SessionStatsProvider, { conversationRuntime, children: /* @__PURE__ */ jsx97(VimModeProvider, { settings, children: /* @__PURE__ */ jsx97(
24576
+ children: /* @__PURE__ */ jsx98(ScrollProvider, { children: /* @__PURE__ */ jsx98(SessionStatsProvider, { conversationRuntime, children: /* @__PURE__ */ jsx98(VimModeProvider, { settings, children: /* @__PURE__ */ jsx98(
24281
24577
  AppContainer,
24282
24578
  {
24283
24579
  config,
@@ -24307,7 +24603,7 @@ async function startInteractiveUI(config, settings, startupWarnings, workspaceRo
24307
24603
  };
24308
24604
  const { stdout: inkStdout, stderr: inkStderr } = createWorkingStdio();
24309
24605
  const instance = render(
24310
- process.env["DEBUG"] ? /* @__PURE__ */ jsx97(React22.StrictMode, { children: /* @__PURE__ */ jsx97(AppWrapper, {}) }) : /* @__PURE__ */ jsx97(AppWrapper, {}),
24606
+ process.env["DEBUG"] ? /* @__PURE__ */ jsx98(React22.StrictMode, { children: /* @__PURE__ */ jsx98(AppWrapper, {}) }) : /* @__PURE__ */ jsx98(AppWrapper, {}),
24311
24607
  {
24312
24608
  stdout: inkStdout,
24313
24609
  stderr: inkStderr,
@@ -25146,7 +25442,8 @@ function isWithin(root, candidate) {
25146
25442
  function parseReferences(text) {
25147
25443
  const references = [];
25148
25444
  for (let index = 0; index < text.length; index += 1) {
25149
- if (text[index] !== "@" || index > 0 && !/\s/.test(text[index - 1])) continue;
25445
+ if (text[index] !== "@" || index > 0 && !/\s/.test(text[index - 1]))
25446
+ continue;
25150
25447
  let cursor = index + 1;
25151
25448
  let value = "";
25152
25449
  let escaped = false;
@@ -25156,7 +25453,9 @@ function parseReferences(text) {
25156
25453
  value += character;
25157
25454
  escaped = false;
25158
25455
  } else if (character === "\\") {
25159
- escaped = true;
25456
+ const next = text[cursor + 1];
25457
+ if (next !== void 0 && /[,\s;!()[\]{}]/.test(next)) escaped = true;
25458
+ else value += character;
25160
25459
  } else if (/[,\s;!?()[\]{}]/.test(character)) {
25161
25460
  break;
25162
25461
  } else {
@@ -25174,13 +25473,18 @@ async function resolveReference(value, workspaceRoots, clipboardRoots) {
25174
25473
  const isAllowedLexically = candidates.some(
25175
25474
  (candidate) => workspaceRoots.some((root) => isWithin(root, candidate)) || clipboardRoots.some((root) => isWithin(root, candidate))
25176
25475
  );
25177
- if (!isAllowedLexically) throw new Error(`File reference is outside the workspace: @${value}`);
25476
+ if (!isAllowedLexically)
25477
+ throw new Error(`File reference is outside the workspace: @${value}`);
25178
25478
  for (const candidate of candidates) {
25179
25479
  try {
25180
25480
  const realCandidate = await fs13.realpath(candidate);
25181
- const workspaceRoot = workspaceRoots.find((root) => isWithin(root, realCandidate));
25481
+ const workspaceRoot = workspaceRoots.find(
25482
+ (root) => isWithin(root, realCandidate)
25483
+ );
25182
25484
  if (workspaceRoot) return { path: realCandidate, kind: "workspace-file" };
25183
- const clipboardRoot = clipboardRoots.find((root) => isWithin(root, realCandidate));
25485
+ const clipboardRoot = clipboardRoots.find(
25486
+ (root) => isWithin(root, realCandidate)
25487
+ );
25184
25488
  if (clipboardRoot) return { path: realCandidate, kind: "clipboard-file" };
25185
25489
  throw new Error(`File reference is outside the workspace: @${value}`);
25186
25490
  } catch (error) {
@@ -25196,7 +25500,8 @@ async function collectFiles(candidate, root, signal, output) {
25196
25500
  const stats = await fs13.lstat(candidate);
25197
25501
  if (stats.isSymbolicLink()) return;
25198
25502
  if (stats.isFile()) {
25199
- if (!IMAGE_MEDIA_TYPES.has(path14.extname(candidate).toLowerCase())) output.push(candidate);
25503
+ if (!IMAGE_MEDIA_TYPES.has(path14.extname(candidate).toLowerCase()))
25504
+ output.push(candidate);
25200
25505
  return;
25201
25506
  }
25202
25507
  if (!stats.isDirectory()) return;
@@ -25224,23 +25529,33 @@ var WorkspacePromptInputRuntime = class {
25224
25529
  clipboardImageRoots,
25225
25530
  signal
25226
25531
  }) {
25227
- if (this.disposed) throw new Error("Prompt input runtime has been disposed.");
25532
+ if (this.disposed)
25533
+ throw new Error("Prompt input runtime has been disposed.");
25228
25534
  throwIfAborted(signal);
25229
- const roots = await Promise.all(workspaceRoots.map((root) => fs13.realpath(root)));
25230
- const clipboardRoots = await Promise.all(clipboardImageRoots.map(async (root) => {
25231
- try {
25232
- return await fs13.realpath(root);
25233
- } catch (error) {
25234
- if (error.code === "ENOENT") return path14.resolve(root);
25235
- throw error;
25236
- }
25237
- }));
25535
+ const roots = await Promise.all(
25536
+ workspaceRoots.map((root) => fs13.realpath(root))
25537
+ );
25538
+ const clipboardRoots = await Promise.all(
25539
+ clipboardImageRoots.map(async (root) => {
25540
+ try {
25541
+ return await fs13.realpath(root);
25542
+ } catch (error) {
25543
+ if (error.code === "ENOENT")
25544
+ return path14.resolve(root);
25545
+ throw error;
25546
+ }
25547
+ })
25548
+ );
25238
25549
  const references = parseReferences(text);
25239
25550
  const images = /* @__PURE__ */ new Map();
25240
25551
  const textFiles = [];
25241
25552
  for (const reference of references) {
25242
25553
  throwIfAborted(signal);
25243
- const resolved = await resolveReference(reference.value, roots, clipboardRoots);
25554
+ const resolved = await resolveReference(
25555
+ reference.value,
25556
+ roots,
25557
+ clipboardRoots
25558
+ );
25244
25559
  if (!resolved) continue;
25245
25560
  const stats = await fs13.stat(resolved.path);
25246
25561
  const extension = path14.extname(resolved.path).toLowerCase();
@@ -25255,16 +25570,27 @@ var WorkspacePromptInputRuntime = class {
25255
25570
  continue;
25256
25571
  }
25257
25572
  if (stats.isFile() && UNSUPPORTED_ATTACHMENT_EXTENSIONS.has(extension)) {
25258
- throw new Error(`Unsupported attachment type: ${extension.slice(1) || "binary file"}`);
25573
+ throw new Error(
25574
+ `Unsupported attachment type: ${extension.slice(1) || "binary file"}`
25575
+ );
25259
25576
  }
25260
25577
  if (resolved.kind === "clipboard-file") {
25261
- throw new Error("Clipboard attachments must be PNG, JPEG, WebP, or GIF images.");
25578
+ throw new Error(
25579
+ "Clipboard attachments must be PNG, JPEG, WebP, or GIF images."
25580
+ );
25262
25581
  }
25263
- const root = roots.find((candidate) => isWithin(candidate, resolved.path));
25264
- if (!root) throw new Error(`File reference is outside the workspace: @${reference.value}`);
25582
+ const root = roots.find(
25583
+ (candidate) => isWithin(candidate, resolved.path)
25584
+ );
25585
+ if (!root)
25586
+ throw new Error(
25587
+ `File reference is outside the workspace: @${reference.value}`
25588
+ );
25265
25589
  if (stats.isFile()) {
25266
25590
  if (stats.size > MAX_FILE_BYTES) {
25267
- throw new Error(`Referenced text file is too large: @${reference.value}`);
25591
+ throw new Error(
25592
+ `Referenced text file is too large: @${reference.value}`
25593
+ );
25268
25594
  }
25269
25595
  const candidate = await fs13.readFile(resolved.path, { signal });
25270
25596
  try {
@@ -25288,14 +25614,18 @@ var WorkspacePromptInputRuntime = class {
25288
25614
  cursor = reference.end;
25289
25615
  }
25290
25616
  appendText(displayContent, text.slice(cursor));
25291
- if (displayContent.length === 0) displayContent.push({ type: "text", text });
25292
- const uniqueFiles = [...new Map(textFiles.map((entry) => [entry.file, entry])).values()].slice(0, MAX_FILES);
25617
+ if (displayContent.length === 0)
25618
+ displayContent.push({ type: "text", text });
25619
+ const uniqueFiles = [
25620
+ ...new Map(textFiles.map((entry) => [entry.file, entry])).values()
25621
+ ].slice(0, MAX_FILES);
25293
25622
  const sections = [];
25294
25623
  let totalBytes = 0;
25295
25624
  for (const { file, root } of uniqueFiles) {
25296
25625
  throwIfAborted(signal);
25297
25626
  const stats = await fs13.stat(file);
25298
- if (stats.size > MAX_FILE_BYTES || totalBytes + stats.size > MAX_TOTAL_BYTES) continue;
25627
+ if (stats.size > MAX_FILE_BYTES || totalBytes + stats.size > MAX_TOTAL_BYTES)
25628
+ continue;
25299
25629
  const buffer = await fs13.readFile(file, { signal });
25300
25630
  if (buffer.includes(0)) continue;
25301
25631
  let content2;
@@ -25309,13 +25639,18 @@ var WorkspacePromptInputRuntime = class {
25309
25639
  sections.push(`Content from @${label}:
25310
25640
  ${content2}`);
25311
25641
  }
25312
- const content = displayContent.map((part) => part.type === "text" ? { ...part } : part);
25642
+ const content = displayContent.map(
25643
+ (part) => part.type === "text" ? { ...part } : part
25644
+ );
25313
25645
  if (sections.length > 0) {
25314
- appendText(content, `
25646
+ appendText(
25647
+ content,
25648
+ `
25315
25649
 
25316
25650
  ${REFERENCE_START}
25317
25651
  ${sections.join("\n\n")}
25318
- ${REFERENCE_END}`);
25652
+ ${REFERENCE_END}`
25653
+ );
25319
25654
  }
25320
25655
  return { content, displayContent };
25321
25656
  }
@@ -25744,27 +26079,37 @@ var DshSessionManagementRuntime = class {
25744
26079
  hasConversation = () => this.callbacks.hasConversation();
25745
26080
  isBusy = () => this.switching || this.callbacks.isBusy();
25746
26081
  async listSessions(signal) {
25747
- const records = await this.query.filterSessions([
25748
- { kind: "cwd", values: [this.cwd] },
25749
- { kind: "parent", values: [null] }
25750
- ], signal);
26082
+ const records = await this.query.filterSessions(
26083
+ [
26084
+ { kind: "cwd", values: [this.cwd] },
26085
+ { kind: "parent", values: [null] }
26086
+ ],
26087
+ signal
26088
+ );
25751
26089
  signal?.throwIfAborted();
25752
26090
  return records.filter((record) => {
25753
26091
  const id = String(record.header.id);
25754
26092
  return isConsoleSession(id) && (record.persisted || id === this.snapshot.currentSessionId);
25755
- }).map((record) => ({
25756
- id: String(record.header.id),
25757
- createdAt: record.header.createdAt,
25758
- current: String(record.header.id) === this.snapshot.currentSessionId,
25759
- persisted: record.persisted,
25760
- resumable: record.persisted
25761
- }));
26093
+ }).map(
26094
+ (record) => ({
26095
+ id: String(record.header.id),
26096
+ createdAt: record.header.createdAt,
26097
+ current: String(record.header.id) === this.snapshot.currentSessionId,
26098
+ persisted: record.persisted,
26099
+ resumable: record.persisted
26100
+ })
26101
+ );
25762
26102
  }
25763
26103
  async resolveSessionTitles(sessionIds, signal) {
25764
26104
  if (sessionIds.length === 0) return [];
25765
- const results = await this.query.readTitleSnapshots(sessionIds.map(SessionId2), signal);
26105
+ const results = await this.query.readTitleSnapshots(
26106
+ sessionIds.map(SessionId2),
26107
+ signal
26108
+ );
25766
26109
  signal?.throwIfAborted();
25767
- return results.flatMap((result) => result.status === "fulfilled" && result.value.title ? [{ id: String(result.sessionId), title: result.value.title.title }] : []);
26110
+ return results.flatMap(
26111
+ (result) => result.status === "fulfilled" && result.value.title ? [{ id: String(result.sessionId), title: result.value.title.title }] : []
26112
+ );
25768
26113
  }
25769
26114
  async createNew(signal) {
25770
26115
  this.beginSwitch();
@@ -25780,56 +26125,101 @@ var DshSessionManagementRuntime = class {
25780
26125
  this.switching = false;
25781
26126
  }
25782
26127
  }
25783
- async resumeSession(sessionId, signal) {
25784
- if (sessionId === this.snapshot.currentSessionId) return;
25785
- if (!isConsoleSession(sessionId)) throw new Error("Session is not a dsh-console conversation.");
26128
+ async resumeLatest(signal) {
25786
26129
  this.beginSwitch();
25787
26130
  try {
25788
- const id = SessionId2(sessionId);
25789
- const records = await this.query.filterSessions([
25790
- { kind: "id", values: [id] },
25791
- { kind: "cwd", values: [this.cwd] },
25792
- { kind: "parent", values: [null] },
25793
- { kind: "availability", values: ["persisted"] }
25794
- ], signal);
25795
- signal?.throwIfAborted();
25796
- if (records.length !== 1) throw new Error("Session is unavailable or belongs to another workspace.");
25797
- const log = await this.query.readSession(id);
25798
- signal?.throwIfAborted();
25799
- const header = foldRequestHeader(log.events);
25800
- if (header === void 0) {
25801
- throw new Error(
25802
- hasConversationEvents(log.events) ? "This Session predates model-route persistence and cannot be resumed safely." : "This Session is empty and cannot be resumed."
25803
- );
25804
- }
25805
- const resolved = await this.llm.resolveModelInfo(
25806
- header.config.provider,
25807
- header.config.model,
26131
+ const records = await this.query.filterSessions(
26132
+ [
26133
+ { kind: "cwd", values: [this.cwd] },
26134
+ { kind: "parent", values: [null] },
26135
+ { kind: "availability", values: ["persisted"] }
26136
+ ],
25808
26137
  signal
25809
26138
  );
25810
26139
  signal?.throwIfAborted();
25811
- const explicitReasoningEffort = header.adapterDefaults?.reasoningEffort ? void 0 : header.config.reasoningEffort;
25812
- const selected = modelSelectionView(
25813
- resolved,
25814
- explicitReasoningEffort === void 0 ? void 0 : String(explicitReasoningEffort)
26140
+ const candidates = records.filter((record) => {
26141
+ const id = String(record.header.id);
26142
+ return record.persisted && id !== this.snapshot.currentSessionId && isConsoleSession(id);
26143
+ }).sort((left, right) => right.header.createdAt - left.header.createdAt);
26144
+ for (const record of candidates) {
26145
+ const resumed = await this.resumePersistedSession(
26146
+ record.header.id,
26147
+ signal,
26148
+ true
26149
+ );
26150
+ if (resumed) return;
26151
+ }
26152
+ throw new Error(
26153
+ "No resumable dsh-console Session exists for this directory."
25815
26154
  );
25816
- const resumedSessionId = await this.callbacks.resume(
25817
- id,
25818
- modelSelectionFromView(selected),
26155
+ } finally {
26156
+ this.switching = false;
26157
+ }
26158
+ }
26159
+ async resumeSession(sessionId, signal) {
26160
+ if (sessionId === this.snapshot.currentSessionId) return;
26161
+ if (!isConsoleSession(sessionId))
26162
+ throw new Error("Session is not a dsh-console conversation.");
26163
+ this.beginSwitch();
26164
+ try {
26165
+ const id = SessionId2(sessionId);
26166
+ const records = await this.query.filterSessions(
26167
+ [
26168
+ { kind: "id", values: [id] },
26169
+ { kind: "cwd", values: [this.cwd] },
26170
+ { kind: "parent", values: [null] },
26171
+ { kind: "availability", values: ["persisted"] }
26172
+ ],
25819
26173
  signal
25820
26174
  );
25821
- this.callbacks.adoptCurrentModel(selected);
25822
- this.commitCurrentSession(resumedSessionId);
26175
+ signal?.throwIfAborted();
26176
+ if (records.length !== 1)
26177
+ throw new Error(
26178
+ "Session is unavailable or belongs to another workspace."
26179
+ );
26180
+ await this.resumePersistedSession(id, signal, false);
25823
26181
  } finally {
25824
26182
  this.switching = false;
25825
26183
  }
25826
26184
  }
26185
+ async resumePersistedSession(id, signal, skipMissingRoute) {
26186
+ const log = await this.query.readSession(id);
26187
+ signal?.throwIfAborted();
26188
+ const header = foldRequestHeader(log.events);
26189
+ if (header === void 0) {
26190
+ if (skipMissingRoute) return false;
26191
+ throw new Error(
26192
+ hasConversationEvents(log.events) ? "This Session predates model-route persistence and cannot be resumed safely." : "This Session is empty and cannot be resumed."
26193
+ );
26194
+ }
26195
+ const resolved = await this.llm.resolveModelInfo(
26196
+ header.config.provider,
26197
+ header.config.model,
26198
+ signal
26199
+ );
26200
+ signal?.throwIfAborted();
26201
+ const explicitReasoningEffort = header.adapterDefaults?.reasoningEffort ? void 0 : header.config.reasoningEffort;
26202
+ const selected = modelSelectionView(
26203
+ resolved,
26204
+ explicitReasoningEffort === void 0 ? void 0 : String(explicitReasoningEffort)
26205
+ );
26206
+ const resumedSessionId = await this.callbacks.resume(
26207
+ id,
26208
+ modelSelectionFromView(selected),
26209
+ signal
26210
+ );
26211
+ this.callbacks.adoptCurrentModel(selected);
26212
+ this.commitCurrentSession(resumedSessionId);
26213
+ return true;
26214
+ }
25827
26215
  beginSwitch() {
25828
26216
  if (this.switching) {
25829
26217
  throw new Error("Another Session change is already in progress.");
25830
26218
  }
25831
26219
  if (this.callbacks.isBusy()) {
25832
- throw new Error("Cannot change Session while the current Agent is working.");
26220
+ throw new Error(
26221
+ "Cannot change Session while the current Agent is working."
26222
+ );
25833
26223
  }
25834
26224
  this.switching = true;
25835
26225
  }
@@ -25919,10 +26309,24 @@ var DshApprovalRuntime = class {
25919
26309
  import {
25920
26310
  UserQuestionError
25921
26311
  } from "@deepseek-ai/dsh-user-questions";
26312
+ function createUserQuestionAnswererRegistration(service, registerEventListener, ownsAgent) {
26313
+ return (answerer) => {
26314
+ const registerProvider = service.registerProvider;
26315
+ if (typeof registerProvider === "function") {
26316
+ return registerProvider.call(service, { ask: answerer });
26317
+ }
26318
+ return registerEventListener((request, next) => {
26319
+ if (request.agent !== void 0 && !ownsAgent(request.agent)) {
26320
+ return next();
26321
+ }
26322
+ return answerer(request);
26323
+ });
26324
+ };
26325
+ }
25922
26326
  var DshUserQuestionRuntime = class {
25923
- constructor(service, ownsAgent) {
26327
+ constructor(registerAnswerer, ownsAgent) {
25924
26328
  this.ownsAgent = ownsAgent;
25925
- this.unregister = service.registerProvider(this);
26329
+ this.unregister = registerAnswerer((request) => this.ask(request));
25926
26330
  }
25927
26331
  listeners = /* @__PURE__ */ new Set();
25928
26332
  pending = /* @__PURE__ */ new Map();
@@ -25963,7 +26367,9 @@ var DshUserQuestionRuntime = class {
25963
26367
  id: question.id,
25964
26368
  question: sanitizeForDisplay(question.question, 2e3),
25965
26369
  ...question.header === void 0 ? {} : { header: sanitizeForDisplay(question.header, 160) },
25966
- ...question.detail === void 0 ? {} : { detail: sanitizeForDisplay(question.detail, 2e4) },
26370
+ ...question.detail === void 0 ? {} : {
26371
+ detail: sanitizeMultilineForDisplay(question.detail, 2e4)
26372
+ },
25967
26373
  ...question.options === void 0 ? {} : {
25968
26374
  options: Object.freeze(
25969
26375
  question.options.map(
@@ -25984,7 +26390,7 @@ var DshUserQuestionRuntime = class {
25984
26390
  ...question.intent === void 0 ? {} : {
25985
26391
  intent: Object.freeze({
25986
26392
  kind: question.intent.kind,
25987
- approve: sanitizeForDisplay(question.intent.approve, 500)
26393
+ approveValue: question.intent.approve
25988
26394
  })
25989
26395
  }
25990
26396
  })
@@ -26061,34 +26467,45 @@ var DshUserQuestionRuntime = class {
26061
26467
 
26062
26468
  // src/dsh/command-runtime.ts
26063
26469
  var DshCommandRuntimeAdapter = class {
26064
- constructor(commands, activeAgent, subscribe) {
26470
+ constructor(commands, activeAgent, subscribe, ensureActiveAgent) {
26065
26471
  this.commands = commands;
26066
26472
  this.activeAgent = activeAgent;
26473
+ this.ensureActiveAgent = ensureActiveAgent;
26067
26474
  this.snapshot = this.readSnapshot();
26068
26475
  this.off = subscribe(() => this.refresh());
26069
26476
  }
26070
26477
  listeners = /* @__PURE__ */ new Set();
26071
26478
  snapshot;
26072
26479
  off;
26480
+ preparing;
26073
26481
  getSnapshot = () => this.snapshot;
26074
26482
  subscribe = (listener) => {
26075
26483
  this.listeners.add(listener);
26076
26484
  return () => this.listeners.delete(listener);
26077
26485
  };
26486
+ prepare(signal) {
26487
+ if (this.activeAgent() !== void 0) return Promise.resolve();
26488
+ if (this.preparing !== void 0) return this.preparing;
26489
+ const preparing = this.ensureActiveAgent(signal).then(() => {
26490
+ signal.throwIfAborted();
26491
+ this.refresh();
26492
+ }).finally(() => {
26493
+ if (this.preparing === preparing) this.preparing = void 0;
26494
+ });
26495
+ this.preparing = preparing;
26496
+ return preparing;
26497
+ }
26078
26498
  async execute(line, signal) {
26499
+ await this.prepare(signal);
26500
+ signal.throwIfAborted();
26079
26501
  const agent = this.activeAgent();
26080
26502
  if (agent === void 0) {
26081
26503
  return {
26082
26504
  kind: "error",
26083
- text: "Start a conversation before using DSH commands."
26505
+ text: "Unable to prepare the active conversation for DSH commands."
26084
26506
  };
26085
26507
  }
26086
- const execution = await this.commands.execute(
26087
- agent,
26088
- line,
26089
- [],
26090
- signal
26091
- );
26508
+ const execution = await this.commands.execute(agent, line, [], signal);
26092
26509
  if (execution === void 0) {
26093
26510
  return { kind: "error", text: `Unknown DSH command: ${line.trim()}` };
26094
26511
  }
@@ -26106,7 +26523,8 @@ var DshCommandRuntimeAdapter = class {
26106
26523
  }
26107
26524
  readSnapshot() {
26108
26525
  const agent = this.activeAgent();
26109
- if (agent === void 0) return Object.freeze({ commands: Object.freeze([]) });
26526
+ if (agent === void 0)
26527
+ return Object.freeze({ commands: Object.freeze([]) });
26110
26528
  return Object.freeze({
26111
26529
  commands: Object.freeze(
26112
26530
  this.commands.list(agent).map(
@@ -26683,7 +27101,9 @@ var inject = [
26683
27101
  var Config2 = z2.object({
26684
27102
  prompt: z2.string(),
26685
27103
  debug: z2.boolean().default(false),
26686
- pokemon: z2.number()
27104
+ pokemon: z2.number(),
27105
+ continueSession: z2.boolean().default(false),
27106
+ resumeSessionId: z2.string()
26687
27107
  });
26688
27108
  var CLEANUP_TIMEOUT_MS = 1500;
26689
27109
  var FORCE_EXIT_TIMEOUT_MS = 2500;
@@ -26859,14 +27279,22 @@ async function start(ctx, config) {
26859
27279
  (listener) => ctx.on("approval/request", listener),
26860
27280
  (agent) => agent === mainAgent()
26861
27281
  );
26862
- const userQuestionRuntime = new DshUserQuestionRuntime(
27282
+ const onUserQuestion = ctx.on;
27283
+ const ownsMainAgent = (agent) => agent === mainAgent();
27284
+ const registerUserQuestionAnswerer = createUserQuestionAnswererRegistration(
26863
27285
  userQuestions,
26864
- (agent) => agent === mainAgent()
27286
+ (listener) => onUserQuestion("user-questions/request", listener),
27287
+ ownsMainAgent
27288
+ );
27289
+ const userQuestionRuntime = new DshUserQuestionRuntime(
27290
+ registerUserQuestionAnswerer,
27291
+ ownsMainAgent
26865
27292
  );
26866
27293
  const commandRuntime = new DshCommandRuntimeAdapter(
26867
27294
  commands,
26868
27295
  currentInteractiveAgent,
26869
- (listener) => ctx.on("commands/change", listener)
27296
+ (listener) => ctx.on("commands/change", listener),
27297
+ async (signal) => (await materializeActiveConversation(signal)).handle.agent
26870
27298
  );
26871
27299
  const permissionSelectionRuntime = new DshPermissionSelectionRuntime(
26872
27300
  sessionProjections,
@@ -27104,7 +27532,9 @@ async function start(ctx, config) {
27104
27532
  },
27105
27533
  submit: async (submission) => {
27106
27534
  const ingested = await prepareSubmission(submission, true);
27107
- const conversation = await materializeActiveConversation(submission.signal);
27535
+ const conversation = await materializeActiveConversation(
27536
+ submission.signal
27537
+ );
27108
27538
  await submitToConversation(conversation, ingested, submission.signal);
27109
27539
  },
27110
27540
  cancel: () => {
@@ -27119,7 +27549,9 @@ async function start(ctx, config) {
27119
27549
  mainConversationRuntime,
27120
27550
  async (signal) => {
27121
27551
  if (active.kind !== "materialized") {
27122
- throw new Error("Start the main conversation before opening a Side conversation.");
27552
+ throw new Error(
27553
+ "Start the main conversation before opening a Side conversation."
27554
+ );
27123
27555
  }
27124
27556
  const parent = active.handle.agent;
27125
27557
  const parentEvents = parent.session.events;
@@ -27201,6 +27633,17 @@ async function start(ctx, config) {
27201
27633
  toolCatalogRuntime.activeAgentChanged();
27202
27634
  });
27203
27635
  ctx.effect(() => cleanup, "dsh-console: terminal");
27636
+ const startupResumeSessionId = config.resumeSessionId?.trim();
27637
+ if (config.continueSession && startupResumeSessionId) {
27638
+ throw new Error(
27639
+ "dsh-console startup cannot use both continueSession and resumeSessionId."
27640
+ );
27641
+ }
27642
+ if (startupResumeSessionId) {
27643
+ await sessionManagementRuntime.resumeSession(startupResumeSessionId);
27644
+ } else if (config.continueSession) {
27645
+ await sessionManagementRuntime.resumeLatest();
27646
+ }
27204
27647
  await main({
27205
27648
  conversationRuntime: conversationWorkspace,
27206
27649
  promptCompletionRuntime,