flavor-code 1.4.2 → 1.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/README.md +53 -1
  2. package/README.zh-CN.md +53 -1
  3. package/dist/agent/loop.d.ts +1 -0
  4. package/dist/{app-4CUS3GEJ.js → app-TVY2HM5L.js} +891 -604
  5. package/dist/apply-WOW3QU5I.js +51 -0
  6. package/dist/broker-cli-X5H46FZV.js +15 -0
  7. package/dist/check-CSKTV4O2.js +16 -0
  8. package/dist/chunk-3563SW4X.js +10513 -0
  9. package/dist/chunk-36IDJRLQ.js +630 -0
  10. package/dist/chunk-3UX2CGDW.js +1955 -0
  11. package/dist/chunk-4TMLXZVZ.js +75 -0
  12. package/dist/{chunk-7YFHRORG.js → chunk-5BDKRA6U.js} +412 -172
  13. package/dist/chunk-6F66UXBI.js +48 -0
  14. package/dist/{chunk-KMBDK4SN.js → chunk-6URQ7FIF.js} +24 -88
  15. package/dist/chunk-7Y64WNBB.js +8930 -0
  16. package/dist/chunk-AA4QNKTF.js +501 -0
  17. package/dist/chunk-BDX777JR.js +11 -0
  18. package/dist/chunk-CVP5OUHD.js +103 -0
  19. package/dist/chunk-EWD7FWTH.js +14547 -0
  20. package/dist/{chunk-N5MXHJKD.js → chunk-GTFP2R5I.js} +1 -1
  21. package/dist/{chunk-W2TIY6JY.js → chunk-IKGT4MDT.js} +2028 -516
  22. package/dist/chunk-IQEEFDEE.js +389 -0
  23. package/dist/chunk-IU3UBETC.js +30 -0
  24. package/dist/chunk-JQM2L2YM.js +1003 -0
  25. package/dist/chunk-KRWWCVXA.js +74 -0
  26. package/dist/chunk-OKHV7CTB.js +482 -0
  27. package/dist/chunk-ONRY3C2L.js +196 -0
  28. package/dist/chunk-PULWAH6E.js +474 -0
  29. package/dist/chunk-PZ5NKRVA.js +85 -0
  30. package/dist/chunk-QACFKPZP.js +43704 -0
  31. package/dist/chunk-RBAZLFKB.js +1022 -0
  32. package/dist/chunk-RV3EXUXM.js +30 -0
  33. package/dist/chunk-TIEOVQW6.js +61 -0
  34. package/dist/chunk-WLZUAVVU.js +15 -0
  35. package/dist/chunk-X442CJJH.js +114 -0
  36. package/dist/chunk-X6U6BO5D.js +2130 -0
  37. package/dist/{chunk-RAYH6K2H.js → chunk-Y7EH4NVO.js} +1 -1
  38. package/dist/{chunk-S32JRDZK.js → chunk-ZKKVSR37.js} +6 -1
  39. package/dist/{claude-ink-VQU3C5UL.js → claude-ink-F554I3GJ.js} +9 -4
  40. package/dist/cli-MAWCV2YR.js +163 -0
  41. package/dist/cli-main.js +3805 -473
  42. package/dist/cli.js +50 -4
  43. package/dist/config/load.d.ts +8 -0
  44. package/dist/config/protected-file.d.ts +2 -0
  45. package/dist/config/schema.d.ts +14 -0
  46. package/dist/context/global-instructions.d.ts +12 -0
  47. package/dist/context/manager.d.ts +4 -0
  48. package/dist/desktop/main.js +4943 -1562
  49. package/dist/desktop/preload.cjs +30 -0
  50. package/dist/desktop-renderer/assets/index-BWklSoOO.css +1 -0
  51. package/dist/desktop-renderer/assets/index-CjC0Ibiq.js +153 -0
  52. package/dist/desktop-renderer/assets/{interactive-terminal-ouQQ3brz.js → interactive-terminal-IjIT3Xoa.js} +1 -1
  53. package/dist/desktop-renderer/index.html +2 -2
  54. package/dist/doctor-SEL32R7M.js +20 -0
  55. package/dist/harness/local.d.ts +1 -0
  56. package/dist/load-RHWXNUCS.js +25 -0
  57. package/dist/log-ATFIPRNU.js +19 -0
  58. package/dist/manager-IYBNNKUP.js +191 -0
  59. package/dist/models/anthropic.d.ts +3 -0
  60. package/dist/node-LOIXT44J.js +879 -0
  61. package/dist/plugin-worker-entry.js +1 -1
  62. package/dist/production-TQROFEPV.js +46 -0
  63. package/dist/production.d.ts +28 -1
  64. package/dist/project-3QXE22TG.js +11 -0
  65. package/dist/react-M6JGXSJZ.js +7 -0
  66. package/dist/recorder-FAGJJH3N.js +11 -0
  67. package/dist/sdk/index.js +30 -8
  68. package/dist/server-2KLKPHPL.js +11 -0
  69. package/dist/session/store.d.ts +1 -0
  70. package/dist/store-MZZERW7K.js +18 -0
  71. package/dist/ui/commands.d.ts +11 -3
  72. package/dist/ui/session.d.ts +2 -1
  73. package/dist/usage-summary-G5FBOJLK.js +13 -0
  74. package/dist/write-stream-CGD57URC.js +77 -0
  75. package/package.json +1 -1
  76. package//346/212/200/346/234/257/346/226/271/346/241/210/346/212/245/345/221/212.md +649 -1
  77. package/dist/chunk-B23V72YR.js +0 -170
  78. package/dist/chunk-QKND3FX7.js +0 -26103
  79. package/dist/desktop-renderer/assets/index-Bk6FYhyh.css +0 -1
  80. package/dist/desktop-renderer/assets/index-CPXrzFgv.js +0 -154
  81. package/dist/load-UPOG3XQR.js +0 -19
@@ -1,27 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
3
- import {
4
- statusPresentation
5
- } from "./chunk-RAYH6K2H.js";
6
- import {
7
- COMMAND_DESCRIPTIONS,
8
- MVP_COMMANDS,
9
- charWidth,
10
- checkForUpdate,
11
- createGlobTool,
12
- createProductionRuntime,
13
- createTranscriptState,
14
- isDestructiveTool,
15
- message,
16
- modelContentTranscriptText,
17
- packageVersion,
18
- redactErrorText,
19
- thinkingWindow,
20
- transcriptReducer,
21
- withTimeout
22
- } from "./chunk-QKND3FX7.js";
23
- import "./chunk-N5MXHJKD.js";
24
- import "./chunk-7YFHRORG.js";
2
+ import { createRequire as createFlavorRequire } from "node:module"; const require = createFlavorRequire(import.meta.url);
25
3
  import {
26
4
  Box_default,
27
5
  ClockContext,
@@ -33,37 +11,96 @@ import {
33
11
  Text,
34
12
  instances_default,
35
13
  osc,
14
+ require_jsx_runtime,
36
15
  shiftAnchor,
37
16
  stringWidth,
38
17
  stripAnsi,
39
18
  useStdout,
40
19
  use_app_default,
41
20
  use_input_default
42
- } from "./chunk-W2TIY6JY.js";
21
+ } from "./chunk-IKGT4MDT.js";
22
+ import {
23
+ require_react
24
+ } from "./chunk-PULWAH6E.js";
25
+ import {
26
+ statusPresentation
27
+ } from "./chunk-Y7EH4NVO.js";
28
+ import {
29
+ source_default
30
+ } from "./chunk-AA4QNKTF.js";
31
+ import {
32
+ COMMAND_DESCRIPTIONS,
33
+ MVP_COMMANDS,
34
+ createGlobTool,
35
+ createProductionRuntime,
36
+ isDestructiveTool
37
+ } from "./chunk-QACFKPZP.js";
43
38
  import {
44
- execFileNoThrow,
45
39
  getGraphemeSegmenter
46
- } from "./chunk-B23V72YR.js";
47
- import "./chunk-S32JRDZK.js";
40
+ } from "./chunk-TIEOVQW6.js";
41
+ import "./chunk-OKHV7CTB.js";
42
+ import "./chunk-JQM2L2YM.js";
43
+ import {
44
+ execFileNoThrow
45
+ } from "./chunk-IU3UBETC.js";
46
+ import "./chunk-PZ5NKRVA.js";
47
+ import {
48
+ checkForUpdate
49
+ } from "./chunk-6F66UXBI.js";
50
+ import "./chunk-3UX2CGDW.js";
51
+ import {
52
+ k
53
+ } from "./chunk-7Y64WNBB.js";
54
+ import "./chunk-CVP5OUHD.js";
55
+ import "./chunk-3563SW4X.js";
56
+ import "./chunk-RBAZLFKB.js";
57
+ import "./chunk-36IDJRLQ.js";
58
+ import {
59
+ redactErrorText
60
+ } from "./chunk-WLZUAVVU.js";
61
+ import {
62
+ packageVersion
63
+ } from "./chunk-RV3EXUXM.js";
64
+ import "./chunk-IQEEFDEE.js";
65
+ import "./chunk-GTFP2R5I.js";
66
+ import "./chunk-5BDKRA6U.js";
67
+ import {
68
+ charWidth,
69
+ createTranscriptState,
70
+ modelContentTranscriptText,
71
+ thinkingWindow,
72
+ transcriptReducer,
73
+ withTimeout
74
+ } from "./chunk-X6U6BO5D.js";
75
+ import {
76
+ message
77
+ } from "./chunk-BDX777JR.js";
78
+ import "./chunk-ONRY3C2L.js";
79
+ import "./chunk-EWD7FWTH.js";
80
+ import "./chunk-KRWWCVXA.js";
81
+ import "./chunk-X442CJJH.js";
82
+ import {
83
+ __toESM
84
+ } from "./chunk-ZKKVSR37.js";
48
85
 
49
86
  // src/ui/app.tsx
87
+ var import_react8 = __toESM(require_react(), 1);
50
88
  import { basename as basename3 } from "path";
51
89
  import { homedir } from "os";
52
- import React4, { useEffect as useEffect3, useMemo as useMemo3, useReducer, useRef as useRef4, useState as useState2 } from "react";
53
90
 
54
91
  // src/claude-ink/hooks/use-animation-frame.ts
55
- import { useContext as useContext2, useEffect, useState } from "react";
92
+ var import_react2 = __toESM(require_react(), 1);
56
93
 
57
94
  // src/claude-ink/hooks/use-terminal-viewport.ts
58
- import { useCallback, useContext, useLayoutEffect, useRef } from "react";
95
+ var import_react = __toESM(require_react(), 1);
59
96
  function useTerminalViewport() {
60
- const terminalSize = useContext(TerminalSizeContext);
61
- const elementRef = useRef(null);
62
- const entryRef = useRef({ isVisible: true });
63
- const setElement = useCallback((el) => {
97
+ const terminalSize = (0, import_react.useContext)(TerminalSizeContext);
98
+ const elementRef = (0, import_react.useRef)(null);
99
+ const entryRef = (0, import_react.useRef)({ isVisible: true });
100
+ const setElement = (0, import_react.useCallback)((el) => {
64
101
  elementRef.current = el;
65
102
  }, []);
66
- useLayoutEffect(() => {
103
+ (0, import_react.useLayoutEffect)(() => {
67
104
  const element = elementRef.current;
68
105
  if (!element?.yogaNode || !terminalSize) {
69
106
  return;
@@ -96,11 +133,11 @@ function useTerminalViewport() {
96
133
 
97
134
  // src/claude-ink/hooks/use-animation-frame.ts
98
135
  function useAnimationFrame(intervalMs = 16) {
99
- const clock = useContext2(ClockContext);
136
+ const clock = (0, import_react2.useContext)(ClockContext);
100
137
  const [viewportRef, { isVisible }] = useTerminalViewport();
101
- const [time, setTime] = useState(() => clock?.now() ?? 0);
138
+ const [time, setTime] = (0, import_react2.useState)(() => clock?.now() ?? 0);
102
139
  const active = isVisible && intervalMs !== null;
103
- useEffect(() => {
140
+ (0, import_react2.useEffect)(() => {
104
141
  if (!clock || !active) return;
105
142
  let lastUpdate = clock.now();
106
143
  const onChange = () => {
@@ -116,11 +153,11 @@ function useAnimationFrame(intervalMs = 16) {
116
153
  }
117
154
 
118
155
  // src/claude-ink/hooks/use-selection.ts
119
- import { useContext as useContext3, useMemo, useSyncExternalStore } from "react";
156
+ var import_react3 = __toESM(require_react(), 1);
120
157
  function useSelection() {
121
- useContext3(StdinContext_default);
158
+ (0, import_react3.useContext)(StdinContext_default);
122
159
  const ink = instances_default.get(process.stdout);
123
- return useMemo(() => {
160
+ return (0, import_react3.useMemo)(() => {
124
161
  if (!ink) {
125
162
  return {
126
163
  copySelection: () => "",
@@ -160,10 +197,10 @@ function useSelection() {
160
197
  }
161
198
 
162
199
  // src/claude-ink/hooks/use-terminal-title.ts
163
- import { useContext as useContext4, useEffect as useEffect2 } from "react";
200
+ var import_react4 = __toESM(require_react(), 1);
164
201
  function useTerminalTitle(title) {
165
- const writeRaw = useContext4(TerminalWriteContext);
166
- useEffect2(() => {
202
+ const writeRaw = (0, import_react4.useContext)(TerminalWriteContext);
203
+ (0, import_react4.useEffect)(() => {
167
204
  if (title === null || !writeRaw) return;
168
205
  const clean = stripAnsi(title);
169
206
  writeRaw(osc(OSC.SET_TITLE_AND_ICON, clean));
@@ -171,22 +208,19 @@ function useTerminalTitle(title) {
171
208
  }
172
209
 
173
210
  // src/ui/assistant-text.tsx
174
- import React2 from "react";
211
+ var import_react6 = __toESM(require_react(), 1);
175
212
 
176
213
  // src/ui/markdown.tsx
177
- import React, { useMemo as useMemo2, useRef as useRef2 } from "react";
178
- import chalk2 from "chalk";
179
- import { marked } from "marked";
214
+ var import_react5 = __toESM(require_react(), 1);
180
215
 
181
216
  // src/ui/highlight.ts
182
- import chalk from "chalk";
183
- chalk.level = Math.max(chalk.level, 3);
184
- var KEYWORD = chalk.hex("#c586c0");
185
- var STRING = chalk.hex("#ce9178");
186
- var COMMENT = chalk.gray.italic;
187
- var NUMBER = chalk.hex("#b5cea8");
188
- var FUNCTION = chalk.hex("#dcdcaa");
189
- var ATTRIBUTE = chalk.hex("#d7ba7d");
217
+ source_default.level = Math.max(source_default.level, 3);
218
+ var KEYWORD = source_default.hex("#c586c0");
219
+ var STRING = source_default.hex("#ce9178");
220
+ var COMMENT = source_default.gray.italic;
221
+ var NUMBER = source_default.hex("#b5cea8");
222
+ var FUNCTION = source_default.hex("#dcdcaa");
223
+ var ATTRIBUTE = source_default.hex("#d7ba7d");
190
224
  var KEYWORDS = {
191
225
  javascript: /* @__PURE__ */ new Set([
192
226
  "await",
@@ -613,7 +647,7 @@ function highlightCode(source, language = void 0) {
613
647
  }
614
648
 
615
649
  // src/ui/markdown.tsx
616
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
650
+ var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
617
651
  var CODE_BLOCK_BORDER = {
618
652
  top: "\u2500",
619
653
  bottom: "\u2500",
@@ -625,12 +659,12 @@ var CODE_BLOCK_BORDER = {
625
659
  bottomRight: "\u256F"
626
660
  };
627
661
  function MarkdownViewInner({ text }) {
628
- const stablePrefixRef = useRef2("");
662
+ const stablePrefixRef = (0, import_react5.useRef)("");
629
663
  if (!text.startsWith(stablePrefixRef.current)) stablePrefixRef.current = "";
630
664
  const boundary = stablePrefixRef.current.length;
631
- const suffixTokens = useMemo2(() => {
665
+ const suffixTokens = (0, import_react5.useMemo)(() => {
632
666
  try {
633
- return marked.lexer(text.substring(boundary), { gfm: true, async: false });
667
+ return k.lexer(text.substring(boundary), { gfm: true, async: false });
634
668
  } catch {
635
669
  return [];
636
670
  }
@@ -642,68 +676,68 @@ function MarkdownViewInner({ text }) {
642
676
  if (advance > 0) stablePrefixRef.current = text.substring(0, boundary + advance);
643
677
  const stablePrefix = stablePrefixRef.current;
644
678
  const unstableSuffix = text.substring(stablePrefix.length);
645
- return /* @__PURE__ */ jsxs(Box_default, { flexDirection: "column", width: "100%", children: [
646
- stablePrefix.length > 0 ? /* @__PURE__ */ jsx(MarkdownSegment, { text: stablePrefix }) : null,
647
- unstableSuffix.length > 0 ? /* @__PURE__ */ jsx(MarkdownSegment, { text: unstableSuffix }) : null
679
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", width: "100%", children: [
680
+ stablePrefix.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MarkdownSegment, { text: stablePrefix }) : null,
681
+ unstableSuffix.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MarkdownSegment, { text: unstableSuffix }) : null
648
682
  ] });
649
683
  }
650
- var MarkdownSegment = React.memo(function MarkdownSegment2({ text }) {
651
- const tokens = useMemo2(() => {
684
+ var MarkdownSegment = import_react5.default.memo(function MarkdownSegment2({ text }) {
685
+ const tokens = (0, import_react5.useMemo)(() => {
652
686
  try {
653
- return marked.lexer(text, { gfm: true, async: false });
687
+ return k.lexer(text, { gfm: true, async: false });
654
688
  } catch {
655
689
  return [];
656
690
  }
657
691
  }, [text]);
658
- return /* @__PURE__ */ jsx(Fragment, { children: tokens.map((token, index) => /* @__PURE__ */ jsx(BlockToken, { token }, index)) });
692
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: tokens.map((token, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BlockToken, { token }, index)) });
659
693
  });
660
- var MarkdownView = React.memo(MarkdownViewInner);
661
- var BlockToken = React.memo(function BlockToken2({ token }) {
694
+ var MarkdownView = import_react5.default.memo(MarkdownViewInner);
695
+ var BlockToken = import_react5.default.memo(function BlockToken2({ token }) {
662
696
  switch (token.type) {
663
697
  case "space":
664
- return /* @__PURE__ */ jsx(Box_default, { height: 1 });
698
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { height: 1 });
665
699
  case "heading":
666
- return /* @__PURE__ */ jsx(HeadingView, { token });
700
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(HeadingView, { token });
667
701
  case "paragraph":
668
- return /* @__PURE__ */ jsx(Text, { children: /* @__PURE__ */ jsx(InlineTokens, { tokens: token.tokens ?? [] }) });
702
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InlineTokens, { tokens: token.tokens ?? [] }) });
669
703
  case "code":
670
- return /* @__PURE__ */ jsx(CodeBlock, { token });
704
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(CodeBlock, { token });
671
705
  case "blockquote":
672
- return /* @__PURE__ */ jsx(BlockquoteView, { token });
706
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BlockquoteView, { token });
673
707
  case "list":
674
- return /* @__PURE__ */ jsx(ListView, { token });
708
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ListView, { token });
675
709
  case "hr":
676
- return /* @__PURE__ */ jsx(HrView, {});
710
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(HrView, {});
677
711
  case "table":
678
- return /* @__PURE__ */ jsx(TableView, { token });
712
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TableView, { token });
679
713
  case "html":
680
- return /* @__PURE__ */ jsx(Text, { dimColor: true, children: "[html]" });
714
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { dimColor: true, children: "[html]" });
681
715
  default:
682
716
  if ("text" in token && typeof token.text === "string") {
683
- return /* @__PURE__ */ jsx(Text, { children: token.text });
717
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: token.text });
684
718
  }
685
719
  return null;
686
720
  }
687
721
  });
688
722
  function HeadingView({ token }) {
689
- const styled = useMemo2(() => {
723
+ const styled = (0, import_react5.useMemo)(() => {
690
724
  const inner = renderInlineText(token.tokens);
691
725
  switch (token.depth) {
692
726
  case 1:
693
- return chalk2.bold.hex("#7dd3fc")(inner);
727
+ return source_default.bold.hex("#7dd3fc")(inner);
694
728
  case 2:
695
- return chalk2.bold.hex("#67e8f9")(inner);
729
+ return source_default.bold.hex("#67e8f9")(inner);
696
730
  case 3:
697
- return chalk2.bold.hex("#93c5fd")(inner);
731
+ return source_default.bold.hex("#93c5fd")(inner);
698
732
  default:
699
- return chalk2.italic.hex("#93c5fd")(inner);
733
+ return source_default.italic.hex("#93c5fd")(inner);
700
734
  }
701
735
  }, [token.depth, token.tokens]);
702
- return /* @__PURE__ */ jsx(Text, { children: styled });
736
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: styled });
703
737
  }
704
738
  function CodeBlock({ token }) {
705
- const styledSource = useMemo2(() => highlightCode(token.text, token.lang), [token.text, token.lang]);
706
- const lines = useMemo2(() => styledSource.split("\n"), [styledSource]);
739
+ const styledSource = (0, import_react5.useMemo)(() => highlightCode(token.text, token.lang), [token.text, token.lang]);
740
+ const lines = (0, import_react5.useMemo)(() => styledSource.split("\n"), [styledSource]);
707
741
  const langLabel = token.lang?.trim();
708
742
  const label = langLabel && langLabel.length > 0 ? langLabel : "code";
709
743
  return (
@@ -712,7 +746,7 @@ function CodeBlock({ token }) {
712
746
  // resizes can change that width without changing this memoized token.
713
747
  // Building a line from process.stdout.columns overflows those narrower
714
748
  // parents and desynchronizes the terminal's physical auto-wrap cursor.
715
- /* @__PURE__ */ jsx(
749
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
716
750
  Box_default,
717
751
  {
718
752
  flexDirection: "column",
@@ -722,28 +756,28 @@ function CodeBlock({ token }) {
722
756
  borderColor: "gray",
723
757
  borderText: { content: ` ${label} `, position: "top", align: "start", offset: 1 },
724
758
  opaque: true,
725
- children: /* @__PURE__ */ jsx(Box_default, { flexDirection: "column", paddingX: 1, children: lines.map((line, i) => /* @__PURE__ */ jsx(Text, { color: "gray", wrap: "truncate-end", children: line.length > 0 ? line : " " }, i)) })
759
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { flexDirection: "column", paddingX: 1, children: lines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", wrap: "truncate-end", children: line.length > 0 ? line : " " }, i)) })
726
760
  }
727
761
  )
728
762
  );
729
763
  }
730
764
  function BlockquoteView({ token }) {
731
- return /* @__PURE__ */ jsx(Box_default, { flexDirection: "column", children: token.tokens.map((child, i) => {
765
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { flexDirection: "column", children: token.tokens.map((child, i) => {
732
766
  const inline = "tokens" in child ? child.tokens ?? [] : [];
733
- return /* @__PURE__ */ jsxs(Text, { children: [
734
- /* @__PURE__ */ jsx(Text, { color: "gray", children: "\u2502 " }),
735
- /* @__PURE__ */ jsx(InlineTokens, { tokens: inline })
767
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
768
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", children: "\u2502 " }),
769
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InlineTokens, { tokens: inline })
736
770
  ] }, i);
737
771
  }) });
738
772
  }
739
773
  function HrView() {
740
774
  const { stdout } = useStdout();
741
775
  const width = Math.max(8, (stdout?.columns ?? 80) - 4);
742
- return /* @__PURE__ */ jsx(Text, { color: "gray", children: "\u2500".repeat(width) });
776
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "gray", children: "\u2500".repeat(width) });
743
777
  }
744
778
  function ListView({ token }) {
745
779
  const start = typeof token.start === "number" ? token.start : 1;
746
- return /* @__PURE__ */ jsx(Box_default, { flexDirection: "column", children: token.items.map((item, i) => /* @__PURE__ */ jsx(ListItemView, { item, index: start + i, ordered: token.ordered }, i)) });
780
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { flexDirection: "column", children: token.items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ListItemView, { item, index: start + i, ordered: token.ordered }, i)) });
747
781
  }
748
782
  function ListItemView({
749
783
  item,
@@ -769,28 +803,28 @@ function ListItemView({
769
803
  blockTokens.push(child);
770
804
  }
771
805
  }
772
- return /* @__PURE__ */ jsxs(Box_default, { flexDirection: "column", children: [
773
- /* @__PURE__ */ jsxs(Text, { children: [
774
- /* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
806
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", children: [
807
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
808
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { color: "cyan", children: [
775
809
  bullet,
776
810
  " "
777
811
  ] }),
778
812
  inlineTokens.map((child, i) => {
779
813
  if (child.type === "paragraph") {
780
- return /* @__PURE__ */ jsx(InlineTokens, { tokens: child.tokens ?? [] }, i);
814
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InlineTokens, { tokens: child.tokens ?? [] }, i);
781
815
  }
782
816
  const tokens = child.tokens ?? [];
783
- return tokens.length > 0 ? /* @__PURE__ */ jsx(InlineTokens, { tokens }, i) : /* @__PURE__ */ jsx(Text, { children: child.text }, i);
817
+ return tokens.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InlineTokens, { tokens }, i) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: child.text }, i);
784
818
  })
785
819
  ] }),
786
- blockTokens.map((child, i) => /* @__PURE__ */ jsx(Box_default, { marginLeft: 2, children: /* @__PURE__ */ jsx(BlockToken, { token: child }) }, i))
820
+ blockTokens.map((child, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box_default, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(BlockToken, { token: child }) }, i))
787
821
  ] });
788
822
  }
789
823
  function TableView({ token }) {
790
824
  const { stdout } = useStdout();
791
825
  const maxWidth = stdout?.columns ?? 80;
792
826
  const colCount = token.header.length;
793
- if (colCount === 0) return /* @__PURE__ */ jsx(Text, { dimColor: true, children: "[empty table]" });
827
+ if (colCount === 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { dimColor: true, children: "[empty table]" });
794
828
  const colWidth = Math.max(8, Math.floor((maxWidth - colCount * 3) / colCount));
795
829
  const pad = (value, w, align) => {
796
830
  const stripped = stripAnsi2(value);
@@ -812,33 +846,33 @@ function TableView({ token }) {
812
846
  if (align === "center") return ":" + "\u2500".repeat(colWidth - 2) + ":";
813
847
  return "\u2500".repeat(colWidth);
814
848
  });
815
- return /* @__PURE__ */ jsxs(Box_default, { flexDirection: "column", children: [
816
- /* @__PURE__ */ jsx(Text, { children: token.header.map((cell, i) => pad(cell.text, colWidth, cell.align ?? "left")).join(" \u2502 ") }),
817
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: separator.join(" \u2502 ") }),
818
- token.rows.map((row, ri) => /* @__PURE__ */ jsx(Text, { children: row.map((cell, i) => pad(cell.text, colWidth, token.header[i]?.align ?? "left")).join(" \u2502 ") }, ri))
849
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box_default, { flexDirection: "column", children: [
850
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: token.header.map((cell, i) => pad(cell.text, colWidth, cell.align ?? "left")).join(" \u2502 ") }),
851
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { dimColor: true, children: separator.join(" \u2502 ") }),
852
+ token.rows.map((row, ri) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: row.map((cell, i) => pad(cell.text, colWidth, token.header[i]?.align ?? "left")).join(" \u2502 ") }, ri))
819
853
  ] });
820
854
  }
821
855
  function InlineTokens({ tokens }) {
822
- return /* @__PURE__ */ jsx(Text, { children: tokens.map((token, i) => /* @__PURE__ */ jsx(InlineToken, { token }, i)) });
856
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: tokens.map((token, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(InlineToken, { token }, i)) });
823
857
  }
824
858
  function InlineToken({ token }) {
825
859
  switch (token.type) {
826
860
  case "text":
827
- return /* @__PURE__ */ jsx(Text, { children: token.raw ?? token.text });
861
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: token.raw ?? token.text });
828
862
  case "strong":
829
- return /* @__PURE__ */ jsx(Text, { bold: true, children: renderInlineText(token.tokens) });
863
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { bold: true, children: renderInlineText(token.tokens) });
830
864
  case "em":
831
- return /* @__PURE__ */ jsx(Text, { italic: true, children: renderInlineText(token.tokens) });
865
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { italic: true, children: renderInlineText(token.tokens) });
832
866
  case "del":
833
- return /* @__PURE__ */ jsx(Text, { strikethrough: true, children: renderInlineText(token.tokens) });
867
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { strikethrough: true, children: renderInlineText(token.tokens) });
834
868
  case "codespan":
835
- return /* @__PURE__ */ jsx(Text, { color: "black", backgroundColor: "gray", children: token.text });
869
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { color: "black", backgroundColor: "gray", children: token.text });
836
870
  case "link": {
837
871
  const link = token;
838
872
  const inner = renderInlineText(link.tokens);
839
- return /* @__PURE__ */ jsxs(Text, { children: [
873
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [
840
874
  inner,
841
- /* @__PURE__ */ jsxs(Text, { dimColor: true, color: "blue", children: [
875
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { dimColor: true, color: "blue", children: [
842
876
  " (",
843
877
  link.href,
844
878
  ")"
@@ -847,21 +881,21 @@ function InlineToken({ token }) {
847
881
  }
848
882
  case "image": {
849
883
  const img = token;
850
- return /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
884
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { dimColor: true, children: [
851
885
  "[image: ",
852
886
  img.text,
853
887
  "]"
854
888
  ] });
855
889
  }
856
890
  case "br":
857
- return /* @__PURE__ */ jsx(Text, { children: "\n" });
891
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: "\n" });
858
892
  case "escape":
859
- return /* @__PURE__ */ jsx(Text, { children: token.text });
893
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: token.text });
860
894
  case "html":
861
895
  return null;
862
896
  default:
863
897
  if ("text" in token && typeof token.text === "string") {
864
- return /* @__PURE__ */ jsx(Text, { children: token.text });
898
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: token.text });
865
899
  }
866
900
  return null;
867
901
  }
@@ -882,13 +916,13 @@ function inlineTokenToString(token) {
882
916
  case "text":
883
917
  return token.raw ?? token.text;
884
918
  case "strong":
885
- return chalk2.bold(renderInlineText(token.tokens));
919
+ return source_default.bold(renderInlineText(token.tokens));
886
920
  case "em":
887
- return chalk2.italic(renderInlineText(token.tokens));
921
+ return source_default.italic(renderInlineText(token.tokens));
888
922
  case "del":
889
- return chalk2.strikethrough(renderInlineText(token.tokens));
923
+ return source_default.strikethrough(renderInlineText(token.tokens));
890
924
  case "codespan":
891
- return chalk2.bgGray.black(` ${token.text} `);
925
+ return source_default.bgGray.black(` ${token.text} `);
892
926
  case "escape":
893
927
  return token.text;
894
928
  case "br":
@@ -896,7 +930,7 @@ function inlineTokenToString(token) {
896
930
  case "link": {
897
931
  const link = token;
898
932
  const inner = renderInlineText(link.tokens);
899
- return `${inner} ${chalk2.blue.underline.dim(`(${link.href})`)}`;
933
+ return `${inner} ${source_default.blue.underline.dim(`(${link.href})`)}`;
900
934
  }
901
935
  default:
902
936
  if ("text" in token && typeof token.text === "string") return token.text;
@@ -905,11 +939,11 @@ function inlineTokenToString(token) {
905
939
  }
906
940
 
907
941
  // src/ui/assistant-text.tsx
908
- import { jsx as jsx2 } from "react/jsx-runtime";
942
+ var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
909
943
  function AssistantTextInner({ text }) {
910
- return /* @__PURE__ */ jsx2(MarkdownView, { text });
944
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(MarkdownView, { text });
911
945
  }
912
- var AssistantText = React2.memo(AssistantTextInner);
946
+ var AssistantText = import_react6.default.memo(AssistantTextInner);
913
947
 
914
948
  // src/ui/signals.ts
915
949
  function createSessionInterruptHandler(getSession, shutdown, options) {
@@ -970,8 +1004,8 @@ function wrapPromptInput(input, codePointCursor, options) {
970
1004
  }
971
1005
 
972
1006
  // src/ui/task-progress.tsx
973
- import { useRef as useRef3 } from "react";
974
- import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
1007
+ var import_react7 = __toESM(require_react(), 1);
1008
+ var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1);
975
1009
  function TaskStatusLine({
976
1010
  block,
977
1011
  interactive,
@@ -983,8 +1017,8 @@ function TaskStatusLine({
983
1017
  const { stdout } = useStdout();
984
1018
  const foreground = interactive && (block.activity === "model" || block.task?.role === "main");
985
1019
  const [ref, time] = useAnimationFrame(running && foreground ? 120 : null);
986
- const startedAt = useRef3(void 0);
987
- const previousState = useRef3(block.state);
1020
+ const startedAt = (0, import_react7.useRef)(void 0);
1021
+ const previousState = (0, import_react7.useRef)(block.state);
988
1022
  if (running && (startedAt.current === void 0 || previousState.current !== "running")) startedAt.current = time;
989
1023
  if (!running) startedAt.current = void 0;
990
1024
  previousState.current = block.state;
@@ -1005,14 +1039,17 @@ function TaskStatusLine({
1005
1039
  }
1006
1040
  const thinking = block.thinkingText;
1007
1041
  const thinkingVisible = running && block.activity === "model" && thinking !== void 0 && thinking.length > 0;
1008
- const thinkingScroll = useRef3({ start: 0, lastTime: time });
1042
+ const thinkingScroll = (0, import_react7.useRef)({ start: 0, lastTime: time });
1009
1043
  if (!thinkingVisible) {
1010
1044
  thinkingScroll.current = { start: 0, lastTime: time };
1011
1045
  }
1012
1046
  const thinkingLine = thinkingVisible ? (() => {
1013
1047
  const previous = thinkingScroll.current;
1014
1048
  const state = thinkingWindow(thinking, previous.start, {
1015
- width: Math.max(8, (stdout.columns ?? 80) - 8),
1049
+ // Split task tracks are narrower than the terminal. The rail takes
1050
+ // two cells; measuring against stdout.columns hides the tail behind
1051
+ // the track clip instead of letting the preview advance.
1052
+ width: textWidth === void 0 ? Math.max(8, (stdout.columns ?? 80) - 8) : Math.max(1, textWidth - 2),
1016
1053
  dtMs: time - previous.lastTime
1017
1054
  });
1018
1055
  thinkingScroll.current = { start: state.start, lastTime: time };
@@ -1030,28 +1067,28 @@ function TaskStatusLine({
1030
1067
  ...metaLabel === void 0 ? [] : [{ text: ` ${metaLabel}`, color: metaColor ?? "ansi:blackBright" }]
1031
1068
  ];
1032
1069
  const boundedText = textWidth === void 0 || maxTextLines === void 0 ? void 0 : limitTaskTextSegments(textSegments, textWidth, maxTextLines).segments;
1033
- return /* @__PURE__ */ jsxs2(Box_default, { flexDirection: "column", width: "100%", children: [
1034
- /* @__PURE__ */ jsx3(Box_default, { ref, flexDirection: "row", width: "100%", children: boundedText === void 0 ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
1035
- /* @__PURE__ */ jsxs2(Text, { ...presentation.color === void 0 ? {} : { color: presentation.color }, children: [
1070
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { flexDirection: "column", width: "100%", children: [
1071
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { ref, flexDirection: "row", width: "100%", children: boundedText === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
1072
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { ...presentation.color === void 0 ? {} : { color: presentation.color }, children: [
1036
1073
  presentation.glyph,
1037
1074
  " "
1038
1075
  ] }),
1039
- badge ? /* @__PURE__ */ jsxs2(Text, { color: badgeColor, children: [
1076
+ badge ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { color: badgeColor, children: [
1040
1077
  badge,
1041
1078
  " "
1042
1079
  ] }) : null,
1043
- /* @__PURE__ */ jsx3(Text, { ...presentation.color === void 0 ? {} : { color: presentation.color }, children: before }),
1044
- statusLabel !== void 0 ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
1045
- /* @__PURE__ */ jsx3(Text, { ...presentation.color === void 0 ? {} : { color: presentation.color }, children: " \xB7 " }),
1046
- /* @__PURE__ */ jsx3(Text, { color: statusColor ?? presentation.color, children: statusLabel })
1080
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { ...presentation.color === void 0 ? {} : { color: presentation.color }, children: before }),
1081
+ statusLabel !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
1082
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { ...presentation.color === void 0 ? {} : { color: presentation.color }, children: " \xB7 " }),
1083
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: statusColor ?? presentation.color, children: statusLabel })
1047
1084
  ] }) : null,
1048
- after ? /* @__PURE__ */ jsx3(Text, { ...presentation.color === void 0 ? {} : { color: presentation.color }, children: after }) : null,
1049
- metaLabel === void 0 ? null : /* @__PURE__ */ jsxs2(Text, { color: metaColor ?? "ansi:blackBright", children: [
1085
+ after ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { ...presentation.color === void 0 ? {} : { color: presentation.color }, children: after }) : null,
1086
+ metaLabel === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Text, { color: metaColor ?? "ansi:blackBright", children: [
1050
1087
  " ",
1051
1088
  metaLabel
1052
1089
  ] })
1053
- ] }) : /* @__PURE__ */ jsx3(Text, { children: boundedText.map((segment, index) => /* @__PURE__ */ jsx3(Text, { ...segment.color === void 0 ? {} : { color: segment.color }, children: segment.text }, index)) }) }),
1054
- thinkingLine === void 0 ? null : /* @__PURE__ */ jsx3(ThinkingLineView, { text: thinkingLine })
1090
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { children: boundedText.map((segment, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { ...segment.color === void 0 ? {} : { color: segment.color }, children: segment.text }, index)) }) }),
1091
+ thinkingLine === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(ThinkingLineView, { text: thinkingLine })
1055
1092
  ] });
1056
1093
  }
1057
1094
  function limitTaskTextSegments(segments, width, maxLines = 3) {
@@ -1116,9 +1153,9 @@ function limitTaskTextSegments(segments, width, maxLines = 3) {
1116
1153
  var THINKING_RAIL = "#416f84";
1117
1154
  var THINKING_TEXT = "#91a0a8";
1118
1155
  function ThinkingLineView({ text }) {
1119
- return /* @__PURE__ */ jsxs2(Box_default, { flexDirection: "row", children: [
1120
- /* @__PURE__ */ jsx3(Text, { color: THINKING_RAIL, children: "\u2502 " }),
1121
- /* @__PURE__ */ jsx3(Text, { color: THINKING_TEXT, wrap: "truncate-end", children: text })
1156
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { flexDirection: "row", children: [
1157
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: THINKING_RAIL, children: "\u2502 " }),
1158
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: THINKING_TEXT, wrap: "truncate-end", children: text })
1122
1159
  ] });
1123
1160
  }
1124
1161
  var SPLIT_TRACK_MIN_COLUMNS = 96;
@@ -1142,7 +1179,7 @@ function TaskProgressPanel({
1142
1179
  const hoverProps = (track) => ({
1143
1180
  onMouseEnter: () => onHoverChange?.(track)
1144
1181
  });
1145
- return /* @__PURE__ */ jsx3(
1182
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1146
1183
  Box_default,
1147
1184
  {
1148
1185
  flexDirection: "column",
@@ -1150,7 +1187,7 @@ function TaskProgressPanel({
1150
1187
  width: "100%",
1151
1188
  maxHeight,
1152
1189
  onMouseLeave: () => onHoverChange?.(null),
1153
- children: split ? /* @__PURE__ */ jsx3(
1190
+ children: split ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1154
1191
  SplitTracks,
1155
1192
  {
1156
1193
  taskBlocks,
@@ -1162,7 +1199,7 @@ function TaskProgressPanel({
1162
1199
  subagentScrollRef,
1163
1200
  hoverProps
1164
1201
  }
1165
- ) : hasTasks && hasSubagents ? /* @__PURE__ */ jsx3(
1202
+ ) : hasTasks && hasSubagents ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1166
1203
  StackedTracks,
1167
1204
  {
1168
1205
  taskBlocks,
@@ -1174,7 +1211,7 @@ function TaskProgressPanel({
1174
1211
  subagentScrollRef,
1175
1212
  hoverProps
1176
1213
  }
1177
- ) : /* @__PURE__ */ jsx3(
1214
+ ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1178
1215
  SingleTrack,
1179
1216
  {
1180
1217
  role: hasTasks ? "main" : "subagent",
@@ -1203,14 +1240,14 @@ function SplitTracks({
1203
1240
  const availableWidth = columns - SPLIT_TRACK_GUTTER_COLUMNS;
1204
1241
  const leftWidth = Math.max(1, Math.floor(availableWidth * SPLIT_TRACK_MAIN_RATIO));
1205
1242
  const rightWidth = Math.max(1, availableWidth - leftWidth);
1206
- return /* @__PURE__ */ jsxs2(Fragment2, { children: [
1207
- /* @__PURE__ */ jsxs2(Box_default, { flexDirection: "row", width: "100%", children: [
1208
- /* @__PURE__ */ jsx3(Box_default, { width: leftWidth, ...hoverProps("main"), children: /* @__PURE__ */ jsx3(TrackHeader, { role: "main", count: taskBlocks.length, width: leftWidth }) }),
1209
- /* @__PURE__ */ jsx3(Text, { color: "ansi:white", children: "\u2500\u252C\u2500" }),
1210
- /* @__PURE__ */ jsx3(Box_default, { width: rightWidth, ...hoverProps("subagent"), children: /* @__PURE__ */ jsx3(TrackHeader, { role: "subagent", count: subagentBlocks.length, width: rightWidth }) })
1243
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
1244
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { flexDirection: "row", width: "100%", children: [
1245
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { width: leftWidth, ...hoverProps("main"), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TrackHeader, { role: "main", count: taskBlocks.length, width: leftWidth }) }),
1246
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "ansi:white", children: "\u2500\u252C\u2500" }),
1247
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { width: rightWidth, ...hoverProps("subagent"), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TrackHeader, { role: "subagent", count: subagentBlocks.length, width: rightWidth }) })
1211
1248
  ] }),
1212
- contentHeight <= 0 ? null : /* @__PURE__ */ jsxs2(Box_default, { flexDirection: "row", width: "100%", height: contentHeight, children: [
1213
- /* @__PURE__ */ jsx3(Box_default, { width: leftWidth, minWidth: 0, flexDirection: "column", ...hoverProps("main"), children: /* @__PURE__ */ jsx3(
1249
+ contentHeight <= 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { flexDirection: "row", width: "100%", height: contentHeight, children: [
1250
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { width: leftWidth, minWidth: 0, flexDirection: "column", ...hoverProps("main"), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1214
1251
  TrackScrollBox,
1215
1252
  {
1216
1253
  ref: mainScrollRef,
@@ -1221,8 +1258,8 @@ function SplitTracks({
1221
1258
  maxTextLines: 2
1222
1259
  }
1223
1260
  ) }),
1224
- /* @__PURE__ */ jsx3(TrackDivider, { height: contentHeight }),
1225
- /* @__PURE__ */ jsx3(Box_default, { width: rightWidth, minWidth: 0, flexDirection: "column", ...hoverProps("subagent"), children: /* @__PURE__ */ jsx3(
1261
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TrackDivider, { height: contentHeight }),
1262
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { width: rightWidth, minWidth: 0, flexDirection: "column", ...hoverProps("subagent"), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1226
1263
  TrackScrollBox,
1227
1264
  {
1228
1265
  ref: subagentScrollRef,
@@ -1247,12 +1284,12 @@ function StackedTracks({
1247
1284
  hoverProps
1248
1285
  }) {
1249
1286
  if (height <= 1) {
1250
- return /* @__PURE__ */ jsx3(Box_default, { ...hoverProps("main"), children: /* @__PURE__ */ jsx3(TrackHeader, { role: "main", count: taskBlocks.length, width: columns }) });
1287
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { ...hoverProps("main"), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TrackHeader, { role: "main", count: taskBlocks.length, width: columns }) });
1251
1288
  }
1252
1289
  const mainHeight = Math.ceil(height / 2);
1253
1290
  const subagentHeight = Math.floor(height / 2);
1254
- return /* @__PURE__ */ jsxs2(Fragment2, { children: [
1255
- /* @__PURE__ */ jsx3(
1291
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
1292
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1256
1293
  SingleTrack,
1257
1294
  {
1258
1295
  role: "main",
@@ -1264,7 +1301,7 @@ function StackedTracks({
1264
1301
  hoverProps
1265
1302
  }
1266
1303
  ),
1267
- /* @__PURE__ */ jsx3(
1304
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1268
1305
  SingleTrack,
1269
1306
  {
1270
1307
  role: "subagent",
@@ -1288,9 +1325,9 @@ function SingleTrack({
1288
1325
  hoverProps
1289
1326
  }) {
1290
1327
  const contentHeight = Math.max(0, height - 1);
1291
- return /* @__PURE__ */ jsxs2(Box_default, { flexDirection: "column", width: "100%", height, ...hoverProps(role), children: [
1292
- /* @__PURE__ */ jsx3(TrackHeader, { role, count: blocks.length, width }),
1293
- contentHeight <= 0 ? null : /* @__PURE__ */ jsx3(
1328
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Box_default, { flexDirection: "column", width: "100%", height, ...hoverProps(role), children: [
1329
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TrackHeader, { role, count: blocks.length, width }),
1330
+ contentHeight <= 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1294
1331
  TrackScrollBox,
1295
1332
  {
1296
1333
  ref: scrollRef,
@@ -1311,7 +1348,7 @@ function TrackScrollBox({
1311
1348
  width,
1312
1349
  maxTextLines
1313
1350
  }) {
1314
- return /* @__PURE__ */ jsx3(
1351
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1315
1352
  ScrollBox_default,
1316
1353
  {
1317
1354
  ...ref === void 0 ? {} : { ref },
@@ -1321,7 +1358,7 @@ function TrackScrollBox({
1321
1358
  height,
1322
1359
  maxHeight: height,
1323
1360
  paddingX: 1,
1324
- children: blocks.map((block) => /* @__PURE__ */ jsx3(
1361
+ children: blocks.map((block) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1325
1362
  TaskStatusLine,
1326
1363
  {
1327
1364
  block,
@@ -1339,10 +1376,10 @@ function TrackHeader({ role, count, width }) {
1339
1376
  const label = role === "main" ? `task plan (${count})` : `subagents (${count})`;
1340
1377
  const prefix = `\u2500\u2500 ${label} `;
1341
1378
  const line = prefix.length >= width ? prefix.slice(0, Math.max(0, width)) : `${prefix}${"\u2500".repeat(width - prefix.length)}`;
1342
- return /* @__PURE__ */ jsx3(Text, { color: "ansi:white", wrap: "truncate-end", children: line });
1379
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "ansi:white", wrap: "truncate-end", children: line });
1343
1380
  }
1344
1381
  function TrackDivider({ height }) {
1345
- return /* @__PURE__ */ jsx3(Box_default, { flexDirection: "column", width: SPLIT_TRACK_GUTTER_COLUMNS, flexShrink: 0, children: Array.from({ length: height }, (_, index) => /* @__PURE__ */ jsx3(Text, { color: "ansi:white", children: " \u2502 " }, index)) });
1382
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Box_default, { flexDirection: "column", width: SPLIT_TRACK_GUTTER_COLUMNS, flexShrink: 0, children: Array.from({ length: height }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { color: "ansi:white", children: " \u2502 " }, index)) });
1346
1383
  }
1347
1384
 
1348
1385
  // src/ui/file-diff-style.ts
@@ -1590,7 +1627,7 @@ function comparePaths(left, right) {
1590
1627
  }
1591
1628
 
1592
1629
  // src/ui/welcome.tsx
1593
- import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
1630
+ var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1);
1594
1631
  var WIDE_WELCOME_COLUMNS = 72;
1595
1632
  var FLAVOR_ACCENT = "#67D4FF";
1596
1633
  var FLAVOR_WORDMARK = [
@@ -1603,10 +1640,18 @@ function WelcomeCard({
1603
1640
  serviceName,
1604
1641
  workspaceName,
1605
1642
  updateTo,
1606
- columns
1643
+ columns,
1644
+ availableRows = Number.POSITIVE_INFINITY
1607
1645
  }) {
1608
- const wide = Math.max(1, Math.floor(columns)) >= WIDE_WELCOME_COLUMNS;
1609
- const updateHint = updateTo === void 0 ? null : /* @__PURE__ */ jsxs3(Text, { color: "yellowBright", wrap: "wrap", children: [
1646
+ const wide = Math.max(1, Math.floor(columns)) >= WIDE_WELCOME_COLUMNS && availableRows >= 9 + Math.max(serviceName === void 0 ? 0 : 1, updateTo === void 0 ? 0 : 1);
1647
+ const minimal = availableRows < 6 + (updateTo === void 0 ? 0 : 2);
1648
+ if (minimal) {
1649
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box_default, { width: "100%", flexDirection: "column", children: [
1650
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { bold: true, color: FLAVOR_ACCENT, wrap: "truncate-end", children: "\u25C6 Flavor Code" }),
1651
+ availableRows >= 2 ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { dimColor: true, wrap: "truncate-end", children: updateTo === void 0 ? "/help \xB7 /init" : `\u25B2 Update v${updateTo} \xB7 flavor update` }) : null
1652
+ ] });
1653
+ }
1654
+ const updateHint = updateTo === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { color: "yellowBright", wrap: "wrap", children: [
1610
1655
  "\u25B2 ",
1611
1656
  "Update available: v",
1612
1657
  packageVersion(),
@@ -1616,8 +1661,8 @@ function WelcomeCard({
1616
1661
  updateTo,
1617
1662
  "\nRun: flavor update"
1618
1663
  ] });
1619
- return /* @__PURE__ */ jsx4(Box_default, { width: "100%", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: wide ? /* @__PURE__ */ jsxs3(Box_default, { width: "100%", flexDirection: "row", children: [
1620
- /* @__PURE__ */ jsxs3(
1664
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box_default, { width: "100%", borderStyle: "round", borderColor: "yellow", paddingX: 1, children: wide ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box_default, { width: "100%", flexDirection: "row", children: [
1665
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1621
1666
  Box_default,
1622
1667
  {
1623
1668
  width: "36%",
@@ -1630,55 +1675,55 @@ function WelcomeCard({
1630
1675
  borderColor: "yellow",
1631
1676
  paddingRight: 1,
1632
1677
  children: [
1633
- /* @__PURE__ */ jsx4(Text, { bold: true, color: "yellowBright", children: "Welcome back!" }),
1634
- /* @__PURE__ */ jsx4(Text, { color: FLAVOR_ACCENT, children: FLAVOR_WORDMARK }),
1635
- serviceName === void 0 ? null : /* @__PURE__ */ jsx4(Text, { color: "cyan", wrap: "truncate-end", children: serviceName }),
1636
- /* @__PURE__ */ jsx4(Text, { dimColor: true, wrap: "truncate-end", children: model }),
1637
- /* @__PURE__ */ jsx4(Text, { dimColor: true, wrap: "truncate-end", children: workspaceName }),
1638
- /* @__PURE__ */ jsxs3(Text, { dimColor: true, wrap: "truncate-end", children: [
1678
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { bold: true, color: "yellowBright", children: "Welcome back!" }),
1679
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: FLAVOR_ACCENT, children: FLAVOR_WORDMARK }),
1680
+ serviceName === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "cyan", wrap: "truncate-end", children: serviceName }),
1681
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { dimColor: true, wrap: "truncate-end", children: model }),
1682
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { dimColor: true, wrap: "truncate-end", children: workspaceName }),
1683
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { dimColor: true, wrap: "truncate-end", children: [
1639
1684
  "v",
1640
1685
  packageVersion()
1641
1686
  ] })
1642
1687
  ]
1643
1688
  }
1644
1689
  ),
1645
- /* @__PURE__ */ jsxs3(Box_default, { flexGrow: 1, flexDirection: "column", paddingLeft: 1, children: [
1646
- /* @__PURE__ */ jsx4(Text, { bold: true, color: "yellowBright", children: "Tips for getting started" }),
1647
- /* @__PURE__ */ jsxs3(Text, { children: [
1690
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box_default, { flexGrow: 1, flexDirection: "column", paddingLeft: 1, children: [
1691
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { bold: true, color: "yellowBright", children: "Tips for getting started" }),
1692
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { children: [
1648
1693
  "Run ",
1649
- /* @__PURE__ */ jsx4(Text, { color: "cyan", children: "/init" }),
1694
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "cyan", children: "/init" }),
1650
1695
  " to create or refresh FLAVOR.md"
1651
1696
  ] }),
1652
- /* @__PURE__ */ jsxs3(Text, { children: [
1697
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { children: [
1653
1698
  "Type ",
1654
- /* @__PURE__ */ jsx4(Text, { color: "cyan", children: "@" }),
1699
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "cyan", children: "@" }),
1655
1700
  " to attach a project file"
1656
1701
  ] }),
1657
- /* @__PURE__ */ jsx4(Box_default, { height: 1 }),
1658
- /* @__PURE__ */ jsx4(Text, { bold: true, color: "yellowBright", children: "Quick commands" }),
1659
- /* @__PURE__ */ jsxs3(Text, { children: [
1660
- /* @__PURE__ */ jsx4(Text, { color: "cyan", children: "/help" }),
1702
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box_default, { height: 1 }),
1703
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { bold: true, color: "yellowBright", children: "Quick commands" }),
1704
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { children: [
1705
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "cyan", children: "/help" }),
1661
1706
  " \xB7 ",
1662
- /* @__PURE__ */ jsx4(Text, { color: "cyan", children: "/config" }),
1707
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "cyan", children: "/config" }),
1663
1708
  " \xB7 ",
1664
- /* @__PURE__ */ jsx4(Text, { color: "cyan", children: "/tasks" })
1709
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "cyan", children: "/tasks" })
1665
1710
  ] }),
1666
1711
  updateHint
1667
1712
  ] })
1668
- ] }) : /* @__PURE__ */ jsxs3(Box_default, { width: "100%", flexDirection: "column", children: [
1669
- /* @__PURE__ */ jsx4(Text, { bold: true, color: FLAVOR_ACCENT, children: "\u25C6 Flavor Code" }),
1670
- /* @__PURE__ */ jsx4(Text, { children: "Welcome back!" }),
1671
- /* @__PURE__ */ jsxs3(Text, { dimColor: true, wrap: "truncate-end", children: [
1713
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Box_default, { width: "100%", flexDirection: "column", children: [
1714
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { bold: true, color: FLAVOR_ACCENT, children: "\u25C6 Flavor Code" }),
1715
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { children: "Welcome back!" }),
1716
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { dimColor: true, wrap: "truncate-end", children: [
1672
1717
  model,
1673
1718
  " \xB7 ",
1674
1719
  workspaceName,
1675
1720
  " \xB7 v",
1676
1721
  packageVersion()
1677
1722
  ] }),
1678
- /* @__PURE__ */ jsxs3(Text, { children: [
1679
- /* @__PURE__ */ jsx4(Text, { color: "cyan", children: "/init" }),
1723
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Text, { children: [
1724
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "cyan", children: "/init" }),
1680
1725
  " setup \xB7 ",
1681
- /* @__PURE__ */ jsx4(Text, { color: "cyan", children: "/help" }),
1726
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { color: "cyan", children: "/help" }),
1682
1727
  " commands"
1683
1728
  ] }),
1684
1729
  updateHint
@@ -2014,10 +2059,13 @@ var PromptHistoryStore = class {
2014
2059
  };
2015
2060
 
2016
2061
  // src/ui/app.tsx
2017
- import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
2062
+ var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1);
2018
2063
  var HISTORY_CAP = 200;
2019
2064
  var CLIPBOARD_SHORTCUT_FALLBACK_MS = 300;
2020
- var BUILTIN_SLASH_CANDIDATES = MVP_COMMANDS.map((name) => ({ name, description: COMMAND_DESCRIPTIONS[name] }));
2065
+ var BUILTIN_SLASH_CANDIDATES = [
2066
+ ...MVP_COMMANDS.map((name) => ({ name, description: COMMAND_DESCRIPTIONS[name] })),
2067
+ { name: "queue", description: "Review, edit, or cancel queued follow-ups" }
2068
+ ];
2021
2069
  var PROMPT_HORIZONTAL_PADDING = 1;
2022
2070
  function clonePromptDraft(state) {
2023
2071
  return {
@@ -2074,6 +2122,15 @@ function isOutputToggleShortcut(character, key) {
2074
2122
  function outputToggleShortcut(_platform = process.platform) {
2075
2123
  return "Ctrl+O";
2076
2124
  }
2125
+ function fitFooterActions(columns, actions) {
2126
+ let hint = "";
2127
+ for (const action of actions) {
2128
+ const next = hint.length === 0 ? action : `${hint} \xB7 ${action}`;
2129
+ if (stringWidth(next) > columns) break;
2130
+ hint = next;
2131
+ }
2132
+ return hint || actions[0] || "";
2133
+ }
2077
2134
  function removeLastCliImageOnBackspace(input, cursor, images) {
2078
2135
  if (input.length === 0 && cursor === 0 && images.length > 0) {
2079
2136
  return { handled: true, images: images.slice(0, -1) };
@@ -2175,6 +2232,11 @@ var PendingPromptQueue = class {
2175
2232
  const value = this.#values.pop();
2176
2233
  return value === void 0 ? void 0 : cloneQueuedPrompt(value);
2177
2234
  }
2235
+ removeAt(index) {
2236
+ if (!Number.isInteger(index) || index < 0 || index >= this.#values.length) return void 0;
2237
+ const value = this.#values.splice(index, 1)[0];
2238
+ return value === void 0 ? void 0 : cloneQueuedPrompt(value);
2239
+ }
2178
2240
  take() {
2179
2241
  const value = this.#values.shift();
2180
2242
  return value === void 0 ? void 0 : cloneQueuedPrompt(value);
@@ -2241,65 +2303,71 @@ function appRuntimeOptions(props, output, onApprovalChange) {
2241
2303
  onToolsChange: onApprovalChange
2242
2304
  };
2243
2305
  }
2244
- function App({ workspace, home, resumeSession, instanceId, palAlias }) {
2306
+ function App({ workspace, home, resumeSession, instanceId, palAlias, onSessionEnd }) {
2245
2307
  const { exit } = use_app_default();
2246
- const { stdout } = useStdout();
2247
- const [runtime, setRuntime] = useState2();
2248
- const [input, setInput] = useState2("");
2249
- const [pastedBlocks, setPastedBlocks] = useState2([]);
2250
- const [imageAttachments, setImageAttachments] = useState2([]);
2251
- const [clipboardNotice, setClipboardNotice] = useState2();
2252
- const [history, setHistory] = useState2([]);
2253
- const [historyCursor, setHistoryCursor] = useState2(0);
2254
- const [approvalExpanded, setApprovalExpanded] = useState2(false);
2255
- const [expandedOutput, setExpandedOutput] = useState2(false);
2256
- const [promptCursor, setPromptCursor] = useState2(0);
2257
- const [slashCandidates, setSlashCandidates] = useState2(
2308
+ const terminalSize = (0, import_react8.useContext)(TerminalSizeContext);
2309
+ const [runtime, setRuntime] = (0, import_react8.useState)();
2310
+ const [input, setInput] = (0, import_react8.useState)("");
2311
+ const [pastedBlocks, setPastedBlocks] = (0, import_react8.useState)([]);
2312
+ const [imageAttachments, setImageAttachments] = (0, import_react8.useState)([]);
2313
+ const [clipboardNotice, setClipboardNotice] = (0, import_react8.useState)();
2314
+ const [history, setHistory] = (0, import_react8.useState)([]);
2315
+ const [historyCursor, setHistoryCursor] = (0, import_react8.useState)(0);
2316
+ const [approvalExpanded, setApprovalExpanded] = (0, import_react8.useState)(false);
2317
+ const [expandedOutput, setExpandedOutput] = (0, import_react8.useState)(false);
2318
+ const [promptCursor, setPromptCursor] = (0, import_react8.useState)(0);
2319
+ const [slashCandidates, setSlashCandidates] = (0, import_react8.useState)(
2258
2320
  () => buildSlashCandidates(BUILTIN_SLASH_CANDIDATES, [], [])
2259
2321
  );
2260
- const [slashSelection, setSlashSelection] = useState2(0);
2261
- const [dismissedSlashInput, setDismissedSlashInput] = useState2();
2262
- const [mentionCandidates, setMentionCandidates] = useState2([]);
2263
- const [mentionSelection, setMentionSelection] = useState2(0);
2264
- const [dismissedMentionInput, setDismissedMentionInput] = useState2();
2265
- const [pendingPrompts, setPendingPrompts] = useState2([]);
2266
- const [revision, setRevision] = useState2(0);
2267
- const [ideContext, setIdeContext] = useState2();
2268
- const [questionIndex, setQuestionIndex] = useState2(0);
2269
- const [questionAnswers, setQuestionAnswers] = useState2({});
2270
- const [customQuestionActive, setCustomQuestionActive] = useState2(false);
2271
- const [columns, setColumns] = useState2(stdout?.columns ?? 80);
2272
- const [rows, setRows] = useState2(stdout?.rows ?? 24);
2273
- const [updateTo, setUpdateTo] = useState2();
2274
- const [transcript, dispatch] = useReducer(transcriptReducer, void 0, createTranscriptState);
2275
- const scrollRef = useRef4(null);
2276
- const mainTaskScrollRef = useRef4(null);
2277
- const subagentTaskScrollRef = useRef4(null);
2278
- const hoveredTaskTrack = useRef4(null);
2279
- const runtimeRef = useRef4(void 0);
2280
- const pendingPromptRef = useRef4(void 0);
2322
+ const [slashSelection, setSlashSelection] = (0, import_react8.useState)(0);
2323
+ const [dismissedSlashInput, setDismissedSlashInput] = (0, import_react8.useState)();
2324
+ const [mentionCandidates, setMentionCandidates] = (0, import_react8.useState)([]);
2325
+ const [mentionSelection, setMentionSelection] = (0, import_react8.useState)(0);
2326
+ const [dismissedMentionInput, setDismissedMentionInput] = (0, import_react8.useState)();
2327
+ const [pendingPrompts, setPendingPrompts] = (0, import_react8.useState)([]);
2328
+ const [queueOpen, setQueueOpen] = (0, import_react8.useState)(false);
2329
+ const [queueSelection, setQueueSelection] = (0, import_react8.useState)(0);
2330
+ const queueSelectionRef = (0, import_react8.useRef)(0);
2331
+ const [scrollPosition, setScrollPosition] = (0, import_react8.useState)({ behind: false, newOutput: false });
2332
+ const [revision, setRevision] = (0, import_react8.useState)(0);
2333
+ const [ideContext, setIdeContext] = (0, import_react8.useState)();
2334
+ const [questionIndex, setQuestionIndex] = (0, import_react8.useState)(0);
2335
+ const [questionAnswers, setQuestionAnswers] = (0, import_react8.useState)({});
2336
+ const [customQuestionActive, setCustomQuestionActive] = (0, import_react8.useState)(false);
2337
+ const columns = terminalSize?.columns ?? 80;
2338
+ const rows = terminalSize?.rows ?? 24;
2339
+ const [updateTo, setUpdateTo] = (0, import_react8.useState)();
2340
+ const [transcript, dispatch] = (0, import_react8.useReducer)(transcriptReducer, void 0, createTranscriptState);
2341
+ const scrollRef = (0, import_react8.useRef)(null);
2342
+ const focusScrollRef = (0, import_react8.useRef)(null);
2343
+ const turnElementsRef = (0, import_react8.useRef)(/* @__PURE__ */ new Map());
2344
+ const mainTaskScrollRef = (0, import_react8.useRef)(null);
2345
+ const subagentTaskScrollRef = (0, import_react8.useRef)(null);
2346
+ const hoveredTaskTrack = (0, import_react8.useRef)(null);
2347
+ const runtimeRef = (0, import_react8.useRef)(void 0);
2348
+ const pendingPromptRef = (0, import_react8.useRef)(void 0);
2281
2349
  pendingPromptRef.current ??= new PendingPromptQueue();
2282
- const closing = useRef4(false);
2283
- const clipboardBusy = useRef4(false);
2284
- const clipboardFallbackTimer = useRef4(null);
2285
- const terminalTextPasteRevision = useRef4(0);
2286
- const textBuf = useRef4({ pending: "", timer: null });
2287
- const thinkingBuf = useRef4({ pending: "", timer: null });
2288
- const promptDraftRef = useRef4({
2350
+ const closing = (0, import_react8.useRef)(false);
2351
+ const clipboardBusy = (0, import_react8.useRef)(false);
2352
+ const clipboardFallbackTimer = (0, import_react8.useRef)(null);
2353
+ const terminalTextPasteRevision = (0, import_react8.useRef)(0);
2354
+ const textBuf = (0, import_react8.useRef)({ pending: "", timer: null });
2355
+ const thinkingBuf = (0, import_react8.useRef)({ pending: "", timer: null });
2356
+ const promptDraftRef = (0, import_react8.useRef)({
2289
2357
  text: input,
2290
2358
  cursor: promptCursor,
2291
2359
  pastedBlocks,
2292
2360
  imageAttachments
2293
2361
  });
2294
- const promptEditHistory = useRef4(new PromptEditHistory());
2295
- const historyRef = useRef4([]);
2296
- const historyCursorRef = useRef4(0);
2297
- const historyDraftRef = useRef4(void 0);
2298
- const reverseSearchRef = useRef4(void 0);
2299
- const promptHistoryStoreRef = useRef4(void 0);
2362
+ const promptEditHistory = (0, import_react8.useRef)(new PromptEditHistory());
2363
+ const historyRef = (0, import_react8.useRef)([]);
2364
+ const historyCursorRef = (0, import_react8.useRef)(0);
2365
+ const historyDraftRef = (0, import_react8.useRef)(void 0);
2366
+ const reverseSearchRef = (0, import_react8.useRef)(void 0);
2367
+ const promptHistoryStoreRef = (0, import_react8.useRef)(void 0);
2300
2368
  promptHistoryStoreRef.current ??= new PromptHistoryStore({ home: home ?? homedir(), workspace, maxEntries: HISTORY_CAP });
2301
2369
  promptDraftRef.current = { text: input, cursor: promptCursor, pastedBlocks, imageAttachments };
2302
- useEffect3(() => () => {
2370
+ (0, import_react8.useEffect)(() => () => {
2303
2371
  if (clipboardFallbackTimer.current !== null) clearTimeout(clipboardFallbackTimer.current);
2304
2372
  }, []);
2305
2373
  const commitPromptDraft = (next, recordHistory = true) => {
@@ -2318,7 +2386,7 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
2318
2386
  if (next.imageAttachments !== void 0) setImageAttachments(next.imageAttachments);
2319
2387
  };
2320
2388
  useTerminalTitle("Flavor Code");
2321
- useEffect3(() => {
2389
+ (0, import_react8.useEffect)(() => {
2322
2390
  let disposed = false;
2323
2391
  void promptHistoryStoreRef.current.load().then((entries) => {
2324
2392
  if (disposed) return;
@@ -2339,6 +2407,9 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
2339
2407
  t.timer = null;
2340
2408
  }
2341
2409
  if (t.pending.length > 0) {
2410
+ if (scrollRef.current !== null && !scrollRef.current.isSticky()) {
2411
+ setScrollPosition((previous) => previous.newOutput ? previous : { behind: true, newOutput: true });
2412
+ }
2342
2413
  dispatch({ type: "session", event: { type: "text", text: t.pending } });
2343
2414
  t.pending = "";
2344
2415
  }
@@ -2363,18 +2434,18 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
2363
2434
  closing.current = true;
2364
2435
  await shutdownRuntime(active, exit, (error) => {
2365
2436
  dispatch({ type: "submit-error", message: error });
2366
- });
2437
+ }, { ...onSessionEnd === void 0 ? {} : { onSessionEnd } });
2367
2438
  };
2368
- const shutdownRef = useRef4(shutdown);
2439
+ const shutdownRef = (0, import_react8.useRef)(shutdown);
2369
2440
  shutdownRef.current = shutdown;
2370
- const interruptRef = useRef4(void 0);
2441
+ const interruptRef = (0, import_react8.useRef)(void 0);
2371
2442
  interruptRef.current ??= createSessionInterruptHandler(
2372
2443
  () => runtimeRef.current?.session,
2373
2444
  () => shutdownRef.current(runtimeRef.current),
2374
2445
  { forceExit: () => process.exit(1) }
2375
2446
  );
2376
2447
  const interrupt = interruptRef.current;
2377
- useEffect3(() => {
2448
+ (0, import_react8.useEffect)(() => {
2378
2449
  let disposed = false;
2379
2450
  const FLUSH_MS = 100;
2380
2451
  const receive = (event) => {
@@ -2386,6 +2457,7 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
2386
2457
  if (event.type === "clear") {
2387
2458
  flushStreamBuffers();
2388
2459
  dispatch({ type: "clear" });
2460
+ setScrollPosition({ behind: false, newOutput: false });
2389
2461
  return;
2390
2462
  }
2391
2463
  if (event.type === "text") {
@@ -2401,6 +2473,9 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
2401
2473
  return;
2402
2474
  }
2403
2475
  flushStreamBuffers();
2476
+ if (scrollRef.current !== null && !scrollRef.current.isSticky()) {
2477
+ setScrollPosition((previous) => previous.newOutput ? previous : { behind: true, newOutput: true });
2478
+ }
2404
2479
  dispatch({ type: "session", event });
2405
2480
  };
2406
2481
  void createProductionRuntime(appRuntimeOptions({
@@ -2447,7 +2522,7 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
2447
2522
  `));
2448
2523
  };
2449
2524
  }, [workspace, home, resumeSession, instanceId, palAlias]);
2450
- useEffect3(() => {
2525
+ (0, import_react8.useEffect)(() => {
2451
2526
  if (runtime === void 0) return;
2452
2527
  let disposed = false;
2453
2528
  void runtime.services.skills().then((skills) => {
@@ -2469,8 +2544,8 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
2469
2544
  disposed = true;
2470
2545
  };
2471
2546
  }, [runtime, revision]);
2472
- useEffect3(() => installSigintHandler(process, interrupt), [interrupt]);
2473
- useEffect3(() => {
2547
+ (0, import_react8.useEffect)(() => installSigintHandler(process, interrupt), [interrupt]);
2548
+ (0, import_react8.useEffect)(() => {
2474
2549
  let disposed = false;
2475
2550
  void checkForUpdate(packageVersion()).then((version) => {
2476
2551
  if (version !== void 0 && !disposed) setUpdateTo(version);
@@ -2479,7 +2554,7 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
2479
2554
  disposed = true;
2480
2555
  };
2481
2556
  }, []);
2482
- useEffect3(() => {
2557
+ (0, import_react8.useEffect)(() => {
2483
2558
  if (runtime?.services.ideContext === void 0) {
2484
2559
  setIdeContext(void 0);
2485
2560
  return;
@@ -2509,7 +2584,7 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
2509
2584
  clearInterval(timer);
2510
2585
  };
2511
2586
  }, [runtime]);
2512
- useEffect3(() => {
2587
+ (0, import_react8.useEffect)(() => {
2513
2588
  const controller = new AbortController();
2514
2589
  let disposed = false;
2515
2590
  void createGlobTool(workspace, { defaultLimit: 1e4 }).execute({ pattern: "**", limit: 1e4 }, controller.signal).then((result) => {
@@ -2523,29 +2598,41 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
2523
2598
  controller.abort();
2524
2599
  };
2525
2600
  }, [workspace]);
2526
- useEffect3(() => {
2527
- if (!stdout || typeof stdout.on !== "function") return;
2528
- const onResize = () => {
2529
- setColumns(stdout.columns ?? 80);
2530
- setRows(stdout.rows ?? 24);
2531
- };
2532
- stdout.on("resize", onResize);
2533
- onResize();
2534
- return () => {
2535
- stdout.off("resize", onResize);
2536
- };
2537
- }, [stdout]);
2538
2601
  const approval = runtime?.approvals.pending;
2539
2602
  const questions = runtime?.services.questions.pending;
2540
2603
  const memoryReviews = runtime?.memoryReviews.pending ?? [];
2604
+ const focusedDecision = approval !== void 0 || questions !== void 0 && questions.length > 0;
2605
+ const transcriptVisible = runtime !== void 0 && (transcript.completed.length > 0 || transcript.active !== void 0) && !focusedDecision && !queueOpen;
2606
+ (0, import_react8.useEffect)(() => {
2607
+ if (!transcriptVisible) return;
2608
+ const scroll = scrollRef.current;
2609
+ if (scroll === null) return;
2610
+ const update = () => {
2611
+ const behind = !scroll.isSticky();
2612
+ setScrollPosition((previous) => previous.behind === behind && (behind || !previous.newOutput) ? previous : { behind, newOutput: behind && previous.newOutput });
2613
+ };
2614
+ update();
2615
+ return scroll.subscribe(update);
2616
+ }, [transcriptVisible]);
2617
+ (0, import_react8.useEffect)(() => {
2618
+ if (pendingPrompts.length === 0) setQueueOpen(false);
2619
+ setQueueSelection((previous) => {
2620
+ const next = Math.max(0, Math.min(previous, pendingPrompts.length - 1));
2621
+ queueSelectionRef.current = next;
2622
+ return next;
2623
+ });
2624
+ }, [pendingPrompts.length]);
2625
+ (0, import_react8.useEffect)(() => {
2626
+ if (focusedDecision) focusScrollRef.current?.scrollTo(0);
2627
+ }, [focusedDecision, approval?.id, questionIndex]);
2541
2628
  const memoryAutoDismissSeconds = runtime?.memoryReviews.autoDismissSeconds ?? 0;
2542
- useEffect3(() => {
2629
+ (0, import_react8.useEffect)(() => {
2543
2630
  setQuestionIndex(0);
2544
2631
  setQuestionAnswers({});
2545
2632
  setCustomQuestionActive(false);
2546
2633
  }, [questions]);
2547
- useEffect3(() => setApprovalExpanded(false), [approval?.id]);
2548
- const derivedSlashCompletion = useMemo3(
2634
+ (0, import_react8.useEffect)(() => setApprovalExpanded(false), [approval?.id]);
2635
+ const derivedSlashCompletion = (0, import_react8.useMemo)(
2549
2636
  () => deriveSlashCompletion(input, promptCursor, slashCandidates, slashSelection),
2550
2637
  [input, promptCursor, slashCandidates, slashSelection]
2551
2638
  );
@@ -2618,12 +2705,66 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
2618
2705
  }
2619
2706
  };
2620
2707
  use_input_default((character, key, event) => {
2708
+ if (queueOpen && !focusedDecision) {
2709
+ const queue = pendingPromptRef.current;
2710
+ if (key.escape) {
2711
+ setQueueOpen(false);
2712
+ return;
2713
+ }
2714
+ if (key.upArrow || key.downArrow || key.pageUp || key.pageDown || key.wheelUp || key.wheelDown || key.home || key.end) {
2715
+ const delta = key.upArrow ? -1 : key.downArrow ? 1 : key.pageUp ? -5 : key.pageDown ? 5 : key.wheelUp ? -3 : 3;
2716
+ const target = key.home ? 0 : key.end ? queue.size - 1 : queueSelectionRef.current + delta;
2717
+ const next = Math.max(0, Math.min(queue.size - 1, target));
2718
+ queueSelectionRef.current = next;
2719
+ setQueueSelection(next);
2720
+ return;
2721
+ }
2722
+ if (key.ctrl && character.toLowerCase() === "c") {
2723
+ interrupt();
2724
+ return;
2725
+ }
2726
+ if (key.return || !key.ctrl && !key.meta && character.toLowerCase() === "d") {
2727
+ const removed = queue.removeAt(queueSelectionRef.current);
2728
+ if (removed === void 0) return;
2729
+ setPendingPrompts([...queue.values]);
2730
+ if (key.return) {
2731
+ const restoredDraft = restoreQueuedPrompt(removed);
2732
+ promptEditHistory.current.reset();
2733
+ commitPromptDraft(restoredDraft, false);
2734
+ setQueueOpen(false);
2735
+ setClipboardNotice("Queued message moved to draft; sending it again puts it at the end of the queue.");
2736
+ } else if (queue.size === 0) {
2737
+ setQueueOpen(false);
2738
+ setClipboardNotice("Queued message cancelled.");
2739
+ }
2740
+ const next = Math.max(0, Math.min(queueSelectionRef.current, queue.size - 1));
2741
+ queueSelectionRef.current = next;
2742
+ setQueueSelection(next);
2743
+ return;
2744
+ }
2745
+ return;
2746
+ }
2747
+ const focusScroll = focusedDecision || queueOpen ? focusScrollRef.current : null;
2748
+ if (key.home || key.end) {
2749
+ const scroll = focusScroll ?? scrollRef.current;
2750
+ if (scroll !== null) {
2751
+ if (key.end) scroll.scrollToBottom();
2752
+ else scroll.scrollTo(0);
2753
+ }
2754
+ return;
2755
+ }
2756
+ if (!focusedDecision && !queueOpen && slashCompletion === null && mentionCompletion === null && key.ctrl && (key.upArrow || key.downArrow)) {
2757
+ if (jumpToAdjacentTurn(scrollRef.current, turnElementsRef.current, key.upArrow ? "previous" : "next")) {
2758
+ setScrollPosition({ behind: true, newOutput: false });
2759
+ }
2760
+ return;
2761
+ }
2621
2762
  const terminalAction = classifyTerminalInput(
2622
2763
  key,
2623
- transcript.active !== void 0 && slashCompletion === null && mentionCompletion === null
2764
+ (transcript.active !== void 0 || focusedDecision) && slashCompletion === null && mentionCompletion === null
2624
2765
  );
2625
2766
  if (terminalAction?.type === "scroll") {
2626
- const scroll = selectWheelScrollTarget(
2767
+ const scroll = focusScroll ?? selectWheelScrollTarget(
2627
2768
  scrollRef.current,
2628
2769
  mainTaskScrollRef.current,
2629
2770
  subagentTaskScrollRef.current,
@@ -2636,7 +2777,7 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
2636
2777
  return;
2637
2778
  }
2638
2779
  if (terminalAction?.type === "page") {
2639
- const scroll = scrollRef.current;
2780
+ const scroll = focusScroll ?? scrollRef.current;
2640
2781
  if (scroll !== null) jumpScroll(scroll, Math.floor(scroll.getViewportHeight() * terminalAction.fraction));
2641
2782
  return;
2642
2783
  }
@@ -2831,6 +2972,21 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
2831
2972
  return;
2832
2973
  }
2833
2974
  if (key.return) {
2975
+ if (/^\/queue\s*$/iu.test(input)) {
2976
+ if (imageAttachments.length > 0) {
2977
+ setClipboardNotice("Send or remove image attachments before opening /queue.");
2978
+ return;
2979
+ }
2980
+ setInput("");
2981
+ setPromptCursor(0);
2982
+ if (pendingPromptRef.current.size > 0) {
2983
+ queueSelectionRef.current = 0;
2984
+ setQueueSelection(0);
2985
+ setQueueOpen(true);
2986
+ setClipboardNotice(void 0);
2987
+ } else setClipboardNotice("No queued messages.");
2988
+ return;
2989
+ }
2834
2990
  if (/^\/paste-image\s*$/iu.test(input)) {
2835
2991
  setInput("");
2836
2992
  setPromptCursor(0);
@@ -2860,7 +3016,7 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
2860
3016
  })) return;
2861
3017
  setPendingPrompts([...pendingPromptRef.current.values]);
2862
3018
  }
2863
- scrollRef.current?.scrollToBottom();
3019
+ if (delivery === "prompt" || scrollRef.current?.isSticky()) scrollRef.current?.scrollToBottom();
2864
3020
  const nextHistory = [...historyRef.current, submittedText].slice(-HISTORY_CAP);
2865
3021
  historyRef.current = nextHistory;
2866
3022
  historyCursorRef.current = nextHistory.length;
@@ -2969,7 +3125,7 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
2969
3125
  setDismissedMentionInput(void 0);
2970
3126
  }
2971
3127
  });
2972
- if (runtime === void 0) return /* @__PURE__ */ jsx5(
3128
+ if (runtime === void 0) return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2973
3129
  StartingLayout,
2974
3130
  {
2975
3131
  workspaceName: basename3(workspace),
@@ -2981,7 +3137,7 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
2981
3137
  }
2982
3138
  );
2983
3139
  const llmServiceName = runtime.services.llmServiceName?.();
2984
- return /* @__PURE__ */ jsx5(
3140
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
2985
3141
  TerminalLayout,
2986
3142
  {
2987
3143
  model: runtime.services.mainModel(),
@@ -3002,6 +3158,7 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
3002
3158
  ...ideContext === void 0 ? {} : { ideContext },
3003
3159
  completedSlashTokenLength: completedTokenLength,
3004
3160
  scrollRef,
3161
+ focusScrollRef,
3005
3162
  mainTaskScrollRef,
3006
3163
  subagentTaskScrollRef,
3007
3164
  onTaskPanelHoverChange: (track) => {
@@ -3016,6 +3173,19 @@ function App({ workspace, home, resumeSession, instanceId, palAlias }) {
3016
3173
  memoryReviews,
3017
3174
  memoryAutoDismissSeconds,
3018
3175
  pendingPrompts,
3176
+ queueOpen,
3177
+ queueSelection,
3178
+ onQueueSelectionChange: (index) => {
3179
+ queueSelectionRef.current = index;
3180
+ setQueueSelection(index);
3181
+ },
3182
+ scrollBehind: scrollPosition.behind,
3183
+ newOutput: scrollPosition.newOutput,
3184
+ onJumpToLatest: () => scrollRef.current?.scrollToBottom(),
3185
+ onTurnElement: (id, element) => {
3186
+ if (element === null) turnElementsRef.current.delete(id);
3187
+ else turnElementsRef.current.set(id, element);
3188
+ },
3019
3189
  questionIndex,
3020
3190
  questionAnswers,
3021
3191
  customQuestionActive
@@ -3030,7 +3200,7 @@ function StartingLayout({
3030
3200
  columns,
3031
3201
  rows
3032
3202
  }) {
3033
- return /* @__PURE__ */ jsx5(
3203
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3034
3204
  TerminalLayout,
3035
3205
  {
3036
3206
  model: "starting",
@@ -3050,7 +3220,15 @@ var CLI_VISIBLE_TURN_LIMIT = 40;
3050
3220
  var CLI_VISIBLE_BLOCK_LIMIT = 320;
3051
3221
  var CLI_VISIBLE_BLOCKS_PER_TURN = 80;
3052
3222
  var CLI_VISIBLE_TEXT_CHARS = 32e3;
3053
- function cliRenderBudget(rows, columns) {
3223
+ function cliRenderBudget(rows, columns, expanded = false) {
3224
+ if (expanded) {
3225
+ return {
3226
+ turns: Number.POSITIVE_INFINITY,
3227
+ blocks: Number.POSITIVE_INFINITY,
3228
+ blocksPerTurn: Number.POSITIVE_INFINITY,
3229
+ textChars: Number.POSITIVE_INFINITY
3230
+ };
3231
+ }
3054
3232
  const viewportRows = Math.max(8, Math.floor(rows));
3055
3233
  const viewportColumns = Math.max(20, Math.floor(columns));
3056
3234
  const screenMultiplier = 4;
@@ -3131,6 +3309,9 @@ function boundedCliPresentation(presentation, maxTextChars = CLI_VISIBLE_TEXT_CH
3131
3309
  return presentation;
3132
3310
  }
3133
3311
  function boundedCliTurn(turn, maxBlocks = CLI_VISIBLE_BLOCKS_PER_TURN, maxTextChars = CLI_VISIBLE_TEXT_CHARS) {
3312
+ const uncapped = !Number.isFinite(maxTextChars);
3313
+ const toolTextLimit = uncapped ? maxTextChars : CLI_VISIBLE_TEXT_CHARS;
3314
+ const promptLimit = uncapped ? maxTextChars : 16e3;
3134
3315
  const blockLimit = Math.max(1, Math.floor(maxBlocks));
3135
3316
  const hiddenBlocks = Math.max(0, turn.blocks.length - blockLimit);
3136
3317
  const visible = turn.blocks.slice(-blockLimit).map((block) => block.kind === "text" ? { ...block, text: boundedCliDisplayText(block.text, maxTextChars) } : {
@@ -3138,37 +3319,37 @@ function boundedCliTurn(turn, maxBlocks = CLI_VISIBLE_BLOCKS_PER_TURN, maxTextCh
3138
3319
  ...block.details === void 0 ? {} : {
3139
3320
  details: boundedCliDisplayText(
3140
3321
  block.details,
3141
- block.tool !== void 0 || block.presentation !== void 0 ? CLI_VISIBLE_TEXT_CHARS : maxTextChars
3322
+ block.tool !== void 0 || block.presentation !== void 0 ? toolTextLimit : maxTextChars
3142
3323
  )
3143
3324
  },
3144
3325
  ...block.presentation === void 0 ? {} : {
3145
- presentation: boundedCliPresentation(block.presentation, CLI_VISIBLE_TEXT_CHARS)
3326
+ presentation: boundedCliPresentation(block.presentation, toolTextLimit)
3146
3327
  }
3147
3328
  });
3148
3329
  const blocks = hiddenBlocks === 0 ? visible : [{
3149
3330
  kind: "status",
3150
3331
  id: `display-window:${turn.id}`,
3151
3332
  state: "info",
3152
- text: `\xB7 ${hiddenBlocks} earlier output items hidden to keep the terminal responsive`
3333
+ text: `\xB7 ${hiddenBlocks} earlier output items hidden to keep the terminal responsive \xB7 ${outputToggleShortcut()} to view all`
3153
3334
  }, ...visible];
3154
3335
  return {
3155
3336
  hiddenBlocks,
3156
3337
  turn: {
3157
3338
  ...turn,
3158
- prompt: boundedCliDisplayText(turn.prompt, 16e3),
3339
+ prompt: boundedCliDisplayText(turn.prompt, promptLimit),
3159
3340
  blocks,
3160
3341
  statusLines: blocks.filter((block) => block.kind === "status").map((block) => block.text)
3161
3342
  }
3162
3343
  };
3163
3344
  }
3164
- function cliTranscriptWindow(completed, maxTurns = CLI_VISIBLE_TURN_LIMIT, maxBlocks = CLI_VISIBLE_BLOCK_LIMIT, maxTextChars = CLI_VISIBLE_TEXT_CHARS) {
3345
+ function cliTranscriptWindow(completed, maxTurns = CLI_VISIBLE_TURN_LIMIT, maxBlocks = CLI_VISIBLE_BLOCK_LIMIT, maxTextChars = CLI_VISIBLE_TEXT_CHARS, maxBlocksPerTurn = CLI_VISIBLE_BLOCKS_PER_TURN) {
3165
3346
  const turns = [];
3166
3347
  let remainingBlocks = Math.max(1, Math.floor(maxBlocks));
3167
3348
  let hiddenBlocks = 0;
3168
3349
  for (let index = completed.length - 1; index >= 0 && turns.length < Math.max(1, Math.floor(maxTurns)); index -= 1) {
3169
3350
  const source = completed[index];
3170
3351
  if (remainingBlocks <= 0) break;
3171
- const allowance = Math.min(CLI_VISIBLE_BLOCKS_PER_TURN, remainingBlocks);
3352
+ const allowance = Math.min(maxBlocksPerTurn, remainingBlocks);
3172
3353
  const bounded = boundedCliTurn(source, allowance, maxTextChars);
3173
3354
  turns.push(bounded.turn);
3174
3355
  hiddenBlocks += bounded.hiddenBlocks;
@@ -3204,11 +3385,19 @@ function TerminalLayout({
3204
3385
  questionIndex = 0,
3205
3386
  questionAnswers = {},
3206
3387
  customQuestionActive = false,
3388
+ queueOpen = false,
3389
+ queueSelection = 0,
3390
+ onQueueSelectionChange,
3391
+ scrollBehind = false,
3392
+ newOutput = false,
3393
+ onJumpToLatest,
3394
+ onTurnElement,
3207
3395
  completion,
3208
3396
  mentionCompletion,
3209
3397
  onMentionSelect,
3210
3398
  completedSlashTokenLength: tokenLength = 0,
3211
3399
  scrollRef,
3400
+ focusScrollRef,
3212
3401
  mainTaskScrollRef,
3213
3402
  subagentTaskScrollRef,
3214
3403
  onTaskPanelHoverChange,
@@ -3218,14 +3407,14 @@ function TerminalLayout({
3218
3407
  const dividerWidth = Math.max(1, columns - 1);
3219
3408
  const outputShortcut = outputToggleShortcut();
3220
3409
  const showWelcome = completed.length === 0 && active === void 0;
3221
- const budget = useMemo3(
3222
- () => cliRenderBudget(rows, columns),
3223
- [rows, columns]
3410
+ const budget = (0, import_react8.useMemo)(
3411
+ () => cliRenderBudget(rows, columns, expandedOutput),
3412
+ [rows, columns, expandedOutput]
3224
3413
  );
3225
- const activeTaskBlocks = useMemo3(() => active?.blocks.filter(
3414
+ const activeTaskBlocks = (0, import_react8.useMemo)(() => active?.blocks.filter(
3226
3415
  (block) => block.kind === "status" && block.task !== void 0
3227
3416
  ) ?? [], [active]);
3228
- const activeWithoutTasks = useMemo3(() => {
3417
+ const activeWithoutTasks = (0, import_react8.useMemo)(() => {
3229
3418
  if (active === void 0) return void 0;
3230
3419
  const raw = {
3231
3420
  ...active,
@@ -3233,44 +3422,88 @@ function TerminalLayout({
3233
3422
  };
3234
3423
  return boundedCliTurn(raw, budget.blocksPerTurn, budget.textChars).turn;
3235
3424
  }, [active, budget]);
3236
- const completedWindow = useMemo3(
3237
- () => cliTranscriptWindow(completed, budget.turns, budget.blocks, budget.textChars),
3425
+ const completedWindow = (0, import_react8.useMemo)(
3426
+ () => cliTranscriptWindow(completed, budget.turns, budget.blocks, budget.textChars, budget.blocksPerTurn),
3238
3427
  [completed, budget]
3239
3428
  );
3240
- const questionRows = questions === void 0 ? 0 : 4 + (questions[questionIndex]?.options.length ?? 0) + questions.length * 2;
3241
3429
  const memoryReviewRows = memoryReviews.length === 0 ? 0 : 5;
3242
- const approvalRows = approval === void 0 ? 0 : 3 + (approvalExpanded ? approvalDetailLines(approval).length : 0);
3243
- const fixedBottomRows = approvalRows + questionRows + memoryReviewRows + (pendingPrompts.length === 0 ? 0 : 1) + imageAttachments.length + (clipboardNotice === void 0 ? 0 : 1) + 2;
3430
+ const fixedBottomRows = memoryReviewRows + (pendingPrompts.length === 0 ? 0 : 1) + imageAttachments.length + (clipboardNotice === void 0 ? 0 : 1) + (activeSession ? 1 : 0) + 2;
3244
3431
  const taskPanelRows = taskPanelViewportRows(rows, fixedBottomRows, activeTaskBlocks.length > 0);
3245
3432
  const availableBottomRows = Math.max(1, rows - taskPanelRows - 1);
3246
3433
  const bottomMaxRows = Math.min(availableBottomRows, Math.max(Math.floor(rows / 2), fixedBottomRows + 1));
3247
3434
  const promptMaxLines = Math.max(1, bottomMaxRows - fixedBottomRows);
3248
- return /* @__PURE__ */ jsxs4(Box_default, { height: rows, width: "100%", flexDirection: "column", overflow: "hidden", children: [
3249
- /* @__PURE__ */ jsxs4(ScrollBox_default, { ...scrollRef === void 0 ? {} : { ref: scrollRef }, flexGrow: 1, flexDirection: "column", stickyScroll: true, children: [
3250
- showWelcome ? /* @__PURE__ */ jsx5(WelcomeCard, { model, ...serviceName === void 0 ? {} : { serviceName }, workspaceName, ...updateTo === void 0 ? {} : { updateTo }, columns }) : /* @__PURE__ */ jsxs4(Text, { dimColor: true, children: [
3435
+ let footerHint;
3436
+ if (completion !== void 0 || mentionCompletion !== void 0) {
3437
+ footerHint = columns < 48 ? "\u2191\u2193 select \xB7 Tab choose \xB7 Esc close" : mentionCompletion !== void 0 ? "\u2191/\u2193 select \xB7 Tab complete \xB7 click choose \xB7 Esc close" : "\u2191/\u2193 select \xB7 Tab complete \xB7 Esc close";
3438
+ } else if (activeSession) {
3439
+ footerHint = fitFooterActions(columns, [
3440
+ "Enter queue",
3441
+ `Esc ${pendingPrompts.length > 0 ? "edit" : "stop"}`,
3442
+ "Ctrl+C cancel",
3443
+ "/steer now",
3444
+ "/queue manage",
3445
+ `${outputShortcut} ${expandedOutput ? "collapse" : "expand"}`
3446
+ ]);
3447
+ } else if (columns < 48) {
3448
+ footerHint = "Enter send \xB7 Ctrl+C exit";
3449
+ } else if (columns < 96) {
3450
+ footerHint = `Enter send \xB7 Ctrl+C exit \xB7 \u2191\u2193 history \xB7 ${outputShortcut} output`;
3451
+ } else {
3452
+ footerHint = `Enter send \xB7 \u2191\u2193/Ctrl/Cmd+R history \xB7 ${outputShortcut} ${expandedOutput ? "collapse all output" : "expand all output"} \xB7 Ctrl+C exit`;
3453
+ }
3454
+ if (approval !== void 0 || questions !== void 0 && questions.length > 0 || queueOpen) {
3455
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3456
+ FocusedCliPanel,
3457
+ {
3458
+ rows,
3459
+ columns,
3460
+ input,
3461
+ promptCursor,
3462
+ ...approval === void 0 ? {} : { approval },
3463
+ approvalExpanded,
3464
+ ...questions === void 0 ? {} : { questions },
3465
+ questionIndex,
3466
+ customQuestionActive,
3467
+ pendingPrompts,
3468
+ queueSelection,
3469
+ ...onQueueSelectionChange === void 0 ? {} : { onQueueSelectionChange },
3470
+ ...focusScrollRef === void 0 ? {} : { focusScrollRef }
3471
+ }
3472
+ );
3473
+ }
3474
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { height: rows, width: "100%", flexDirection: "column", overflow: "hidden", children: [
3475
+ showWelcome ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { flexGrow: 1, flexShrink: 1, flexDirection: "column", overflow: "hidden", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(WelcomeCard, { model, ...serviceName === void 0 ? {} : { serviceName }, workspaceName, ...updateTo === void 0 ? {} : { updateTo }, columns, availableRows: Math.max(0, rows - taskPanelRows - fixedBottomRows - 1) }) }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(ScrollBox_default, { ...scrollRef === void 0 ? {} : { ref: scrollRef }, flexGrow: 1, flexDirection: "column", stickyScroll: true, children: [
3476
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { dimColor: true, children: [
3251
3477
  "flavor \xB7 ",
3252
3478
  model,
3253
3479
  " \xB7 ",
3254
3480
  workspaceName
3255
3481
  ] }),
3256
- /* @__PURE__ */ jsx5(Box_default, { height: 1 }),
3257
- completedWindow.hiddenTurns > 0 || completedWindow.hiddenBlocks > 0 ? /* @__PURE__ */ jsxs4(Text, { dimColor: true, children: [
3482
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { height: 1 }),
3483
+ completedWindow.hiddenTurns > 0 || completedWindow.hiddenBlocks > 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { dimColor: true, children: [
3258
3484
  "\u2026 ",
3259
3485
  completedWindow.hiddenTurns,
3260
3486
  " earlier turns and ",
3261
3487
  completedWindow.hiddenBlocks,
3262
- " output items hidden to keep the terminal responsive"
3488
+ " output items hidden to keep the terminal responsive \xB7 ",
3489
+ outputShortcut,
3490
+ " to view all"
3263
3491
  ] }) : null,
3264
- completedWindow.turns.map((turn, index) => /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "column", children: [
3265
- index > 0 ? /* @__PURE__ */ jsx5(TurnSeparator, { width: columns }) : null,
3266
- /* @__PURE__ */ jsx5(TurnView, { turn, interactive: false, workspaceName, expandedOutput })
3492
+ completedWindow.turns.map((turn, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { ref: (element) => onTurnElement?.(turn.id, element), flexDirection: "column", children: [
3493
+ index > 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TurnSeparator, { width: columns }) : null,
3494
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TurnView, { turn, interactive: false, workspaceName, expandedOutput })
3267
3495
  ] }, turn.id)),
3268
- activeWithoutTasks === void 0 ? null : /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "column", children: [
3269
- completedWindow.turns.length > 0 ? /* @__PURE__ */ jsx5(TurnSeparator, { width: columns }) : null,
3270
- /* @__PURE__ */ jsx5(TurnView, { turn: activeWithoutTasks, interactive: activeSession, workspaceName, expandedOutput })
3496
+ activeWithoutTasks === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { ref: (element) => onTurnElement?.(activeWithoutTasks.id, element), flexDirection: "column", children: [
3497
+ completedWindow.turns.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TurnSeparator, { width: columns }) : null,
3498
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TurnView, { turn: activeWithoutTasks, interactive: activeSession, workspaceName, expandedOutput })
3271
3499
  ] })
3272
3500
  ] }),
3273
- /* @__PURE__ */ jsx5(
3501
+ !scrollBehind || showWelcome ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { width: "100%", onClick: onJumpToLatest, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "yellow", wrap: "truncate-end", children: [
3502
+ newOutput ? "\u2193 New output" : "\u2191 Reading earlier output",
3503
+ " \xB7 End latest",
3504
+ columns >= 72 ? " \xB7 Ctrl+\u2191/\u2193 turns" : ""
3505
+ ] }) }),
3506
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3274
3507
  TaskProgressPanel,
3275
3508
  {
3276
3509
  blocks: activeTaskBlocks,
@@ -3282,67 +3515,30 @@ function TerminalLayout({
3282
3515
  ...onTaskPanelHoverChange === void 0 ? {} : { onHoverChange: onTaskPanelHoverChange }
3283
3516
  }
3284
3517
  ),
3285
- /* @__PURE__ */ jsxs4(Box_default, { position: "relative", flexShrink: 0, width: "100%", children: [
3286
- completion === void 0 && mentionCompletion === void 0 ? null : /* @__PURE__ */ jsxs4(Box_default, { position: "absolute", bottom: "100%", left: 0, right: 0, flexDirection: "column", opaque: true, children: [
3287
- completion === void 0 ? null : /* @__PURE__ */ jsx5(SlashMenu, { completion }),
3288
- mentionCompletion === void 0 ? null : /* @__PURE__ */ jsx5(MentionMenu, { completion: mentionCompletion, ...onMentionSelect === void 0 ? {} : { onSelect: onMentionSelect } })
3518
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { position: "relative", flexShrink: 0, width: "100%", children: [
3519
+ completion === void 0 && mentionCompletion === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { position: "absolute", bottom: "100%", left: 0, right: 0, flexDirection: "column", opaque: true, children: [
3520
+ completion === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SlashMenu, { completion }),
3521
+ mentionCompletion === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MentionMenu, { completion: mentionCompletion, ...onMentionSelect === void 0 ? {} : { onSelect: onMentionSelect } })
3289
3522
  ] }),
3290
- /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "column", flexShrink: 0, maxHeight: bottomMaxRows, width: "100%", overflowY: "hidden", children: [
3291
- approval === void 0 ? null : /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "column", marginBottom: 1, children: [
3292
- /* @__PURE__ */ jsxs4(Text, { color: "magenta", children: [
3293
- "\u250C\u2500 approval \xB7 ",
3294
- approval.tool
3295
- ] }),
3296
- /* @__PURE__ */ jsxs4(Text, { wrap: "truncate-end", color: "magentaBright", children: [
3297
- "\u2502 ",
3298
- approval.reason ?? "This action needs permission."
3299
- ] }),
3300
- approvalExpanded ? approvalDetailLines(approval).map((line, index) => /* @__PURE__ */ jsxs4(Text, { color: "magentaBright", wrap: "truncate-end", children: [
3301
- "\u2502 ",
3302
- line
3303
- ] }, `${approval.id}:detail:${index}`)) : null,
3304
- isDestructiveTool(approval.tool) || approval.allowAlways === false ? /* @__PURE__ */ jsxs4(Text, { bold: true, color: "magenta", children: [
3305
- "\u2514\u2500 ",
3306
- /* @__PURE__ */ jsx5(Text, { color: "cyan", children: "v" }),
3307
- "=details / ",
3308
- /* @__PURE__ */ jsx5(Text, { color: "green", children: "y" }),
3309
- "=once / ",
3310
- /* @__PURE__ */ jsx5(Text, { color: "cyan", children: "e" }),
3311
- "=accept edits / ",
3312
- /* @__PURE__ */ jsx5(Text, { color: "red", children: "n" }),
3313
- "=deny"
3314
- ] }) : /* @__PURE__ */ jsxs4(Text, { bold: true, color: "magenta", children: [
3315
- "\u2514\u2500 ",
3316
- /* @__PURE__ */ jsx5(Text, { color: "cyan", children: "v" }),
3317
- "=details / ",
3318
- /* @__PURE__ */ jsx5(Text, { color: "green", children: "y" }),
3319
- "=once / ",
3320
- /* @__PURE__ */ jsx5(Text, { color: "yellow", children: "a" }),
3321
- "=same-type / ",
3322
- /* @__PURE__ */ jsx5(Text, { color: "cyan", children: "e" }),
3323
- "=accept edits / ",
3324
- /* @__PURE__ */ jsx5(Text, { color: "red", children: "n" }),
3325
- "=deny"
3326
- ] })
3327
- ] }),
3328
- !questions || questions.length === 0 ? null : /* @__PURE__ */ jsx5(QuestionCards, { questions, activeIndex: questionIndex, answers: questionAnswers, customActive: customQuestionActive }),
3329
- memoryReviews.length === 0 ? null : /* @__PURE__ */ jsx5(MemoryReviewCards, { reviews: memoryReviews, autoDismissSeconds: memoryAutoDismissSeconds }),
3330
- pendingPrompts.length === 0 ? null : /* @__PURE__ */ jsxs4(Text, { color: "yellow", wrap: "truncate-end", children: [
3523
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "column", flexShrink: 0, maxHeight: bottomMaxRows, width: "100%", overflowY: "hidden", children: [
3524
+ memoryReviews.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MemoryReviewCards, { reviews: memoryReviews, autoDismissSeconds: memoryAutoDismissSeconds }),
3525
+ !activeSession ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "cyan", wrap: "truncate-end", children: columns < 48 ? "Running \xB7 Enter queues \xB7 /queue list" : "Running \xB7 /queue manage \xB7 Enter queues next \xB7 /steer acts now" }),
3526
+ pendingPrompts.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "yellow", wrap: "truncate-end", children: [
3331
3527
  "Pending (",
3332
3528
  pendingPrompts.length,
3333
- ") \xB7 ",
3529
+ ") \xB7 /queue manage \xB7 ",
3334
3530
  queuedPromptLabel(pendingPrompts.at(-1)),
3335
3531
  " \xB7 Esc edit latest"
3336
3532
  ] }),
3337
- /* @__PURE__ */ jsx5(Text, { dimColor: true, children: "\u2500".repeat(dividerWidth) }),
3338
- imageAttachments.map((image, index) => /* @__PURE__ */ jsxs4(Text, { color: "cyan", wrap: "truncate-end", children: [
3533
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { dimColor: true, children: "\u2500".repeat(dividerWidth) }),
3534
+ imageAttachments.map((image, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "cyan", wrap: "truncate-end", children: [
3339
3535
  "[Image #",
3340
3536
  index + 1,
3341
3537
  "] ",
3342
3538
  image.name ?? basename3(image.source.path)
3343
3539
  ] }, `${image.sha256}:${index}`)),
3344
- clipboardNotice === void 0 ? null : /* @__PURE__ */ jsx5(Text, { color: "yellow", wrap: "truncate-end", children: clipboardNotice }),
3345
- /* @__PURE__ */ jsx5(
3540
+ clipboardNotice === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "yellow", wrap: "truncate-end", children: clipboardNotice }),
3541
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3346
3542
  PromptLine,
3347
3543
  {
3348
3544
  input,
@@ -3354,10 +3550,11 @@ function TerminalLayout({
3354
3550
  ...onPromptCursorChange === void 0 ? {} : { onCursorChange: onPromptCursorChange }
3355
3551
  }
3356
3552
  ),
3357
- /* @__PURE__ */ jsx5(
3553
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3358
3554
  FooterStatus,
3359
3555
  {
3360
- hint: completion !== void 0 ? "\u2191/\u2193 select \xB7 Tab complete \xB7 Esc close" : mentionCompletion !== void 0 ? "\u2191/\u2193 select \xB7 Tab complete \xB7 click choose \xB7 Esc close" : activeSession ? `Esc ${pendingPrompts.length > 0 ? "edit latest" : "stop"} \xB7 Ctrl+C cancel \xB7 Enter queue \xB7 Ctrl/Cmd+R history \xB7 ${outputShortcut} ${expandedOutput ? "collapse" : "expand"} tools` : `Enter send \xB7 \u2191\u2193/Ctrl/Cmd+R history \xB7 ${outputShortcut} ${expandedOutput ? "collapse" : "expand"} tools \xB7 Ctrl+C exit`,
3556
+ hint: footerHint,
3557
+ columns,
3361
3558
  ...ideContext === void 0 ? {} : { ideContext }
3362
3559
  }
3363
3560
  )
@@ -3367,12 +3564,14 @@ function TerminalLayout({
3367
3564
  }
3368
3565
  function FooterStatus({
3369
3566
  hint,
3567
+ columns,
3370
3568
  ideContext
3371
3569
  }) {
3372
3570
  const ide = ideFooterPresentation(ideContext);
3373
- return /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "row", width: "100%", justifyContent: "space-between", children: [
3374
- /* @__PURE__ */ jsx5(Box_default, { flexGrow: 1, flexShrink: 1, children: /* @__PURE__ */ jsx5(Text, { dimColor: true, wrap: "truncate-end", children: hint }) }),
3375
- ide === void 0 ? null : /* @__PURE__ */ jsx5(Box_default, { flexShrink: 0, marginLeft: 1, children: /* @__PURE__ */ jsxs4(Text, { color: "cyan", wrap: "truncate-end", children: [
3571
+ const showIde = ide !== void 0 && (columns === void 0 || stringWidth(hint) + stringWidth(ide) + 3 <= columns);
3572
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "row", width: "100%", justifyContent: "space-between", children: [
3573
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { flexGrow: 1, flexShrink: 1, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { dimColor: true, wrap: "truncate-end", children: hint }) }),
3574
+ !showIde ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { flexShrink: 0, marginLeft: 1, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "cyan", wrap: "truncate-end", children: [
3376
3575
  "\u29C9 ",
3377
3576
  ide
3378
3577
  ] }) })
@@ -3385,85 +3584,153 @@ function ideFooterPresentation(context) {
3385
3584
  const count = Math.max(1, endLine - context.selection.start.line + 1);
3386
3585
  return `${count} ${count === 1 ? "line" : "lines"} selected`;
3387
3586
  }
3388
- function QuestionCards({ questions, activeIndex, answers, customActive }) {
3389
- return /* @__PURE__ */ jsx5(Box_default, { flexDirection: "column", marginBottom: 1, children: questions.map((q, qi) => /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "column", marginBottom: qi < questions.length - 1 ? 1 : 0, children: [
3390
- /* @__PURE__ */ jsxs4(Text, { bold: true, color: "cyan", children: [
3391
- "\u250C\u2500 ",
3392
- q.header
3393
- ] }),
3394
- /* @__PURE__ */ jsxs4(Text, { wrap: "truncate-end", color: "cyanBright", children: [
3395
- "\u2502 ",
3396
- q.question
3397
- ] }),
3398
- qi < activeIndex ? /* @__PURE__ */ jsxs4(Text, { color: "green", children: [
3399
- "\u2502 \u2713 ",
3400
- answers[qi]
3401
- ] }) : qi > activeIndex ? null : q.options.map((opt, oi) => /* @__PURE__ */ jsxs4(Text, { color: "cyan", children: [
3402
- "\u2502 ",
3403
- /* @__PURE__ */ jsx5(Text, { bold: true, color: "green", children: oi + 1 }),
3404
- ". ",
3405
- opt.label,
3406
- /* @__PURE__ */ jsxs4(Text, { dimColor: true, children: [
3407
- " ",
3408
- opt.description
3409
- ] })
3410
- ] }, oi)),
3411
- qi === activeIndex ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
3412
- /* @__PURE__ */ jsxs4(Text, { color: "cyan", children: [
3413
- "\u2502 ",
3414
- /* @__PURE__ */ jsx5(Text, { bold: true, color: "green", children: q.options.length + 1 }),
3415
- ". Custom input",
3416
- /* @__PURE__ */ jsx5(Text, { dimColor: true, children: " Type your own answer" })
3587
+ function FocusedCliPanel({
3588
+ rows,
3589
+ columns,
3590
+ input,
3591
+ promptCursor,
3592
+ approval,
3593
+ approvalExpanded,
3594
+ questions,
3595
+ questionIndex,
3596
+ customQuestionActive,
3597
+ pendingPrompts,
3598
+ queueSelection,
3599
+ onQueueSelectionChange,
3600
+ focusScrollRef
3601
+ }) {
3602
+ if (approval !== void 0) {
3603
+ const allowAlways = !isDestructiveTool(approval.tool) && approval.allowAlways !== false;
3604
+ const narrow = columns < 36;
3605
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { height: rows, width: "100%", flexDirection: "column", overflow: "hidden", children: [
3606
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { bold: true, color: "magenta", wrap: "truncate-end", children: [
3607
+ "Approval \xB7 ",
3608
+ approval.tool
3609
+ ] }),
3610
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(ScrollBox_default, { ...focusScrollRef === void 0 ? {} : { ref: focusScrollRef }, flexGrow: 1, flexDirection: "column", children: [
3611
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "magentaBright", wrap: "wrap", children: approval.reason ?? "This action needs permission." }),
3612
+ approvalExpanded ? approvalDetailLines(approval).map((line, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "magentaBright", wrap: "wrap", children: line }, `${approval.id}:detail:${index}`)) : null
3417
3613
  ] }),
3418
- /* @__PURE__ */ jsxs4(Text, { dimColor: true, color: "cyan", children: [
3419
- "\u2514\u2500 ",
3420
- customActive ? "Type below and press Enter; Esc returns to choices" : `Press 1-${q.options.length + 1} to choose; Esc dismisses`
3614
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { bold: true, color: "magenta", wrap: "truncate-end", children: narrow ? "y once \xB7 n deny" : "y=once \xB7 n=deny \xB7 Esc=deny" }),
3615
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "magenta", wrap: "truncate-end", children: [
3616
+ narrow ? "v details \xB7 e edits" : "v=details \xB7 e=accept edits",
3617
+ allowAlways && !narrow ? " \xB7 a=same-type" : ""
3618
+ ] }),
3619
+ allowAlways && narrow && rows >= 5 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "magenta", wrap: "truncate-end", children: "a same-type \xB7 Esc deny" }) : null
3620
+ ] });
3621
+ }
3622
+ const question = questions?.[Math.min(questionIndex, questions.length - 1)];
3623
+ if (question !== void 0) {
3624
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { height: rows, width: "100%", flexDirection: "column", overflow: "hidden", children: [
3625
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { bold: true, color: "cyan", wrap: "truncate-end", children: [
3626
+ "Question ",
3627
+ questionIndex + 1,
3628
+ "/",
3629
+ questions.length,
3630
+ " \xB7 ",
3631
+ question.header
3632
+ ] }),
3633
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(ScrollBox_default, { ...focusScrollRef === void 0 ? {} : { ref: focusScrollRef }, flexGrow: 1, flexDirection: "column", children: [
3634
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "cyanBright", wrap: "wrap", children: question.question }),
3635
+ question.options.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "cyan", wrap: "wrap", children: [
3636
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { bold: true, color: "green", children: [
3637
+ index + 1,
3638
+ ". ",
3639
+ option.label
3640
+ ] }),
3641
+ option.description ? ` ${option.description}` : ""
3642
+ ] }, index)),
3643
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "cyan", children: [
3644
+ question.options.length + 1,
3645
+ ". Custom input"
3646
+ ] })
3647
+ ] }),
3648
+ customQuestionActive ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PromptLine, { input, pastedBlocks: [], cursor: promptCursor, columns, maxVisibleLines: Math.max(1, Math.min(3, Math.floor(rows / 3))) }) : null,
3649
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "cyan", wrap: "truncate-end", children: customQuestionActive ? columns < 40 ? "Enter answer \xB7 Esc choices" : "Enter=answer \xB7 Esc=choices \xB7 PgUp/PgDn=scroll" : columns < 40 ? `1-${question.options.length + 1} choose \xB7 Esc cancel` : `1-${question.options.length + 1}=choose \xB7 Esc=cancel \xB7 PgUp/PgDn=scroll` })
3650
+ ] });
3651
+ }
3652
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { height: rows, width: "100%", flexDirection: "column", overflow: "hidden", children: [
3653
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { bold: true, color: "yellow", wrap: "truncate-end", children: [
3654
+ "Queued messages (",
3655
+ pendingPrompts.length,
3656
+ ")"
3657
+ ] }),
3658
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ScrollBox_default, { ...focusScrollRef === void 0 ? {} : { ref: focusScrollRef }, flexGrow: 1, flexDirection: "column", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3659
+ QueueItems,
3660
+ {
3661
+ items: pendingPrompts,
3662
+ selection: queueSelection,
3663
+ ...focusScrollRef === void 0 ? {} : { scrollRef: focusScrollRef },
3664
+ ...onQueueSelectionChange === void 0 ? {} : { onSelect: onQueueSelectionChange }
3665
+ }
3666
+ ) }),
3667
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { bold: true, color: "yellow", wrap: "truncate-end", children: columns < 48 ? "Enter edit \xB7 d cancel" : "Enter=edit selected \xB7 d=cancel selected" }),
3668
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "yellow", wrap: "truncate-end", children: columns < 48 ? "\u2191\u2193 select \xB7 Esc close" : "\u2191/\u2193=select \xB7 PgUp/PgDn=jump \xB7 Esc=close" })
3669
+ ] });
3670
+ }
3671
+ function QueueItems({ items, selection, scrollRef, onSelect }) {
3672
+ const selectedElement = (0, import_react8.useRef)(null);
3673
+ (0, import_react8.useEffect)(() => {
3674
+ if (selectedElement.current !== null) scrollRef?.current?.scrollToElement(selectedElement.current);
3675
+ }, [selection, items.length, scrollRef]);
3676
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { flexDirection: "column", width: "100%", children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3677
+ Box_default,
3678
+ {
3679
+ ref: index === selection ? selectedElement : void 0,
3680
+ onClick: () => onSelect?.(index),
3681
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: index === selection ? "yellowBright" : void 0, bold: index === selection, wrap: "wrap", children: [
3682
+ index === selection ? "\u276F" : " ",
3683
+ " ",
3684
+ index + 1,
3685
+ ". ",
3686
+ queuedPromptLabel(item)
3421
3687
  ] })
3422
- ] }) : null
3423
- ] }, qi)) });
3688
+ },
3689
+ `${index}:${item.text}`
3690
+ )) });
3424
3691
  }
3425
3692
  function MemoryReviewCards({ reviews, autoDismissSeconds }) {
3426
3693
  const review = reviews[0];
3427
- const [remaining, setRemaining] = useState2(autoDismissSeconds);
3428
- useEffect3(() => {
3694
+ const [remaining, setRemaining] = (0, import_react8.useState)(autoDismissSeconds);
3695
+ (0, import_react8.useEffect)(() => {
3429
3696
  if (autoDismissSeconds <= 0) return;
3430
3697
  setRemaining(autoDismissSeconds);
3431
3698
  const timer = setInterval(() => setRemaining((current) => Math.max(0, current - 1)), 1e3);
3432
3699
  return () => clearInterval(timer);
3433
3700
  }, [review.id, autoDismissSeconds]);
3434
- return /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "column", marginBottom: 1, children: [
3435
- /* @__PURE__ */ jsxs4(Text, { bold: true, color: "yellow", children: [
3701
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "column", marginBottom: 1, children: [
3702
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { bold: true, color: "yellow", children: [
3436
3703
  "\u250C\u2500 Long-term memory requires confirmation (",
3437
3704
  reviews.length,
3438
3705
  ")"
3439
3706
  ] }),
3440
- /* @__PURE__ */ jsxs4(Text, { color: "yellowBright", wrap: "truncate-end", children: [
3707
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "yellowBright", wrap: "truncate-end", children: [
3441
3708
  "\u2502 [",
3442
3709
  review.type,
3443
3710
  "] ",
3444
3711
  review.content
3445
3712
  ] }),
3446
- /* @__PURE__ */ jsx5(Text, { dimColor: true, children: "\u2502 Model-generated content is not stored until you approve it." }),
3447
- /* @__PURE__ */ jsxs4(Text, { color: "yellow", children: [
3713
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { dimColor: true, children: "\u2502 Model-generated content is not stored until you approve it." }),
3714
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "yellow", children: [
3448
3715
  "\u2514\u2500 ",
3449
- /* @__PURE__ */ jsx5(Text, { bold: true, children: "Ctrl+Y" }),
3716
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { bold: true, children: "Ctrl+Y" }),
3450
3717
  " save / ",
3451
- /* @__PURE__ */ jsx5(Text, { bold: true, children: "Ctrl+N" }),
3718
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { bold: true, children: "Ctrl+N" }),
3452
3719
  " ignore",
3453
- autoDismissSeconds > 0 ? /* @__PURE__ */ jsx5(Text, { bold: true, color: "cyanBright", children: ` (auto-dismiss in ${remaining}s)` }) : " (conversation remains available)"
3720
+ autoDismissSeconds > 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { bold: true, color: "cyanBright", children: ` (auto-dismiss in ${remaining}s)` }) : " (conversation remains available)"
3454
3721
  ] })
3455
3722
  ] });
3456
3723
  }
3457
3724
  function SlashMenu({ completion }) {
3458
3725
  const visible = completion.items.slice(completion.windowStart, completion.windowStart + 6);
3459
- return /* @__PURE__ */ jsx5(Box_default, { flexDirection: "column", width: "100%", children: visible.map((candidate, visibleIndex) => {
3726
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { flexDirection: "column", width: "100%", children: visible.map((candidate, visibleIndex) => {
3460
3727
  const index = completion.windowStart + visibleIndex;
3461
3728
  const presentation = slashCandidatePresentation(index === completion.selectedIndex);
3462
- return /* @__PURE__ */ jsxs4(Text, { ...presentation.rowStyle, wrap: "truncate-end", children: [
3729
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { ...presentation.rowStyle, wrap: "truncate-end", children: [
3463
3730
  presentation.marker,
3464
- /* @__PURE__ */ jsx5(HighlightedName, { name: candidate.name, query: completion.query, matchStyle: presentation.matchStyle }),
3465
- candidate.kind === "skill" || candidate.kind === "plugin" ? /* @__PURE__ */ jsx5(Text, { color: candidate.kind === "skill" ? "magentaBright" : "cyanBright", children: ` ${candidate.kind}` }) : null,
3466
- candidate.description === void 0 ? null : /* @__PURE__ */ jsx5(Text, { dimColor: true, children: ` ${normalizeSlashDescription(candidate.description)}` })
3731
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(HighlightedName, { name: candidate.name, query: completion.query, matchStyle: presentation.matchStyle }),
3732
+ candidate.kind === "skill" || candidate.kind === "plugin" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: candidate.kind === "skill" ? "magentaBright" : "cyanBright", children: ` ${candidate.kind}` }) : null,
3733
+ candidate.description === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { dimColor: true, children: ` ${normalizeSlashDescription(candidate.description)}` })
3467
3734
  ] }, `${candidate.kind}:${candidate.name}`);
3468
3735
  }) });
3469
3736
  }
@@ -3472,19 +3739,19 @@ function MentionMenu({
3472
3739
  onSelect
3473
3740
  }) {
3474
3741
  const visible = completion.items.slice(completion.windowStart, completion.windowStart + 6);
3475
- return /* @__PURE__ */ jsx5(Box_default, { flexDirection: "column", width: "100%", children: visible.map((path, visibleIndex) => {
3742
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { flexDirection: "column", width: "100%", children: visible.map((path, visibleIndex) => {
3476
3743
  const index = completion.windowStart + visibleIndex;
3477
3744
  const presentation = mentionCandidatePresentation(index === completion.selectedIndex);
3478
- return /* @__PURE__ */ jsx5(
3745
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3479
3746
  Box_default,
3480
3747
  {
3481
3748
  width: "100%",
3482
3749
  onClick: (event) => {
3483
3750
  if (!event.cellIsBlank) onSelect?.(path);
3484
3751
  },
3485
- children: /* @__PURE__ */ jsxs4(Text, { ...presentation.textStyle, wrap: "truncate-end", children: [
3752
+ children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { ...presentation.textStyle, wrap: "truncate-end", children: [
3486
3753
  presentation.marker,
3487
- presentation.highlightMatches ? /* @__PURE__ */ jsx5(HighlightedName, { name: path, query: completion.query, matchStyle: presentation.matchStyle }) : path
3754
+ presentation.highlightMatches ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(HighlightedName, { name: path, query: completion.query, matchStyle: presentation.matchStyle }) : path
3488
3755
  ] })
3489
3756
  },
3490
3757
  path
@@ -3497,16 +3764,16 @@ function HighlightedName({
3497
3764
  matchStyle
3498
3765
  }) {
3499
3766
  const ranges = matchRanges(name, query);
3500
- if (ranges.length === 0) return /* @__PURE__ */ jsx5(Text, { children: name });
3767
+ if (ranges.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { children: name });
3501
3768
  const parts = [];
3502
3769
  let cursor = 0;
3503
3770
  for (const [start, end] of ranges) {
3504
3771
  if (start > cursor) parts.push(name.slice(cursor, start));
3505
- parts.push(/* @__PURE__ */ jsx5(Text, { ...matchStyle, children: name.slice(start, end) }, `${start}:${end}`));
3772
+ parts.push(/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { ...matchStyle, children: name.slice(start, end) }, `${start}:${end}`));
3506
3773
  cursor = end;
3507
3774
  }
3508
3775
  if (cursor < name.length) parts.push(name.slice(cursor));
3509
- return /* @__PURE__ */ jsx5(Text, { children: parts });
3776
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { children: parts });
3510
3777
  }
3511
3778
  function jumpScroll(scroll, delta) {
3512
3779
  const maximum = Math.max(0, scroll.getScrollHeight() - scroll.getViewportHeight());
@@ -3518,6 +3785,15 @@ function jumpScroll(scroll, delta) {
3518
3785
  scroll.scrollTo(Math.max(0, target));
3519
3786
  }
3520
3787
  }
3788
+ function jumpToAdjacentTurn(scroll, elements, direction) {
3789
+ if (scroll === null) return false;
3790
+ const top = scroll.getScrollTop() + scroll.getPendingDelta();
3791
+ const positions = [...elements.values()].map((element) => ({ element, top: element.yogaNode?.getComputedTop() })).filter((item) => item.top !== void 0).sort((left, right) => left.top - right.top);
3792
+ const target = direction === "previous" ? positions.filter((item) => item.top < top - 1).at(-1) : positions.find((item) => item.top > top + 1);
3793
+ if (target === void 0) return false;
3794
+ scroll.scrollToElement(target.element);
3795
+ return true;
3796
+ }
3521
3797
  function selectWheelScrollTarget(transcript, mainTasks, subagentTasks, hoveredTrack) {
3522
3798
  if (hoveredTrack === "main" && mainTasks !== null) return mainTasks;
3523
3799
  if (hoveredTrack === "subagent" && subagentTasks !== null) return subagentTasks;
@@ -3540,25 +3816,25 @@ function scrollUp(scroll, amount) {
3540
3816
  else scroll.scrollBy(-amount);
3541
3817
  }
3542
3818
  function TurnSeparator({ width }) {
3543
- return /* @__PURE__ */ jsx5(Text, { dimColor: true, children: "\u2500".repeat(Math.max(1, width - 1)) });
3819
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { dimColor: true, children: "\u2500".repeat(Math.max(1, width - 1)) });
3544
3820
  }
3545
- var TurnView = React4.memo(function TurnView2({
3821
+ var TurnView = import_react8.default.memo(function TurnView2({
3546
3822
  turn,
3547
3823
  interactive,
3548
3824
  workspaceName,
3549
3825
  expandedOutput
3550
3826
  }) {
3551
3827
  if (turn.kind === "compaction") {
3552
- return /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "column", marginBottom: 1, borderStyle: "round", borderColor: "ansi:yellowBright", paddingX: 1, children: [
3553
- /* @__PURE__ */ jsx5(Text, { color: "ansi:yellowBright", bold: true, children: turn.prompt }),
3554
- turn.blocks.map((block, index) => block.kind === "status" ? /* @__PURE__ */ jsx5(StatusBlockView, { block, interactive, workspaceName, expandedOutput }, block.id) : /* @__PURE__ */ jsx5(Box_default, { children: /* @__PURE__ */ jsx5(AssistantText, { text: block.text }) }, `${turn.id}-text-${index}`))
3828
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "column", marginBottom: 1, borderStyle: "round", borderColor: "ansi:yellowBright", paddingX: 1, children: [
3829
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "ansi:yellowBright", bold: true, children: turn.prompt }),
3830
+ turn.blocks.map((block, index) => block.kind === "status" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(StatusBlockView, { block, interactive, workspaceName, expandedOutput }, block.id) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AssistantText, { text: block.text }) }, `${turn.id}-text-${index}`))
3555
3831
  ] });
3556
3832
  }
3557
3833
  if (turn.source?.kind === "pal") {
3558
3834
  const context = turn.source.context === void 0 ? "" : ` \xB7 ${turn.source.context}`;
3559
- return /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "column", marginBottom: 1, children: [
3560
- /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [
3561
- /* @__PURE__ */ jsxs4(Text, { color: "cyanBright", bold: true, children: [
3835
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "column", marginBottom: 1, children: [
3836
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, children: [
3837
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "cyanBright", bold: true, children: [
3562
3838
  "PAL \xB7 ",
3563
3839
  turn.source.alias,
3564
3840
  " (",
@@ -3566,20 +3842,20 @@ var TurnView = React4.memo(function TurnView2({
3566
3842
  ")",
3567
3843
  context
3568
3844
  ] }),
3569
- /* @__PURE__ */ jsx5(Text, { color: "ansi:whiteBright", children: turn.prompt })
3845
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "ansi:whiteBright", children: turn.prompt })
3570
3846
  ] }),
3571
- /* @__PURE__ */ jsx5(Box_default, { flexDirection: "column", paddingLeft: 2, marginTop: 1, children: turn.blocks.map((block, index) => block.kind === "status" ? /* @__PURE__ */ jsx5(StatusBlockView, { block, interactive, workspaceName, expandedOutput }, block.id) : /* @__PURE__ */ jsx5(Box_default, { marginBottom: 1, children: /* @__PURE__ */ jsx5(AssistantText, { text: block.text }) }, `${turn.id}-text-${index}`)) })
3847
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { flexDirection: "column", paddingLeft: 2, marginTop: 1, children: turn.blocks.map((block, index) => block.kind === "status" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(StatusBlockView, { block, interactive, workspaceName, expandedOutput }, block.id) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AssistantText, { text: block.text }) }, `${turn.id}-text-${index}`)) })
3572
3848
  ] });
3573
3849
  }
3574
- return /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "column", marginBottom: 1, children: [
3575
- /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "row", backgroundColor: "#3a3a3a", paddingX: 1, paddingY: 0, children: [
3576
- /* @__PURE__ */ jsx5(Text, { color: "ansi:whiteBright", bold: true, backgroundColor: "#3a3a3a", children: "\u276F" }),
3577
- /* @__PURE__ */ jsxs4(Text, { color: "ansi:whiteBright", bold: true, backgroundColor: "#3a3a3a", children: [
3850
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "column", marginBottom: 1, children: [
3851
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "row", backgroundColor: "#3a3a3a", paddingX: 1, paddingY: 0, children: [
3852
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "ansi:whiteBright", bold: true, backgroundColor: "#3a3a3a", children: "\u276F" }),
3853
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "ansi:whiteBright", bold: true, backgroundColor: "#3a3a3a", children: [
3578
3854
  " ",
3579
3855
  turn.prompt
3580
3856
  ] })
3581
3857
  ] }),
3582
- /* @__PURE__ */ jsx5(Box_default, { flexDirection: "column", paddingLeft: 2, marginTop: 1, children: turn.blocks.map((block, index) => block.kind === "status" ? /* @__PURE__ */ jsx5(StatusBlockView, { block, interactive, workspaceName, expandedOutput }, block.id) : /* @__PURE__ */ jsx5(Box_default, { marginBottom: 1, children: /* @__PURE__ */ jsx5(AssistantText, { text: block.text }) }, `${turn.id}-text-${index}`)) })
3858
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { flexDirection: "column", paddingLeft: 2, marginTop: 1, children: turn.blocks.map((block, index) => block.kind === "status" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(StatusBlockView, { block, interactive, workspaceName, expandedOutput }, block.id) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AssistantText, { text: block.text }) }, `${turn.id}-text-${index}`)) })
3583
3859
  ] });
3584
3860
  });
3585
3861
  var DIFF_CONTENT = fileDiffLineStyle("context").contentColor;
@@ -3588,11 +3864,11 @@ var DIFF_ADDED_MARKER = fileDiffLineStyle("added").markerColor;
3588
3864
  function FileDiffView({ presentation, expanded }) {
3589
3865
  const operation = presentation.operation === "create" ? "Create" : presentation.operation === "delete" ? "Delete" : "Update";
3590
3866
  if (presentation.operation === "delete") {
3591
- return /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "row", children: [
3592
- /* @__PURE__ */ jsx5(Text, { color: DIFF_REMOVED_MARKER, children: "\u25CF" }),
3593
- /* @__PURE__ */ jsxs4(Text, { color: DIFF_CONTENT, children: [
3867
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "row", children: [
3868
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: DIFF_REMOVED_MARKER, children: "\u25CF" }),
3869
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: DIFF_CONTENT, children: [
3594
3870
  " ",
3595
- /* @__PURE__ */ jsx5(Text, { bold: true, children: operation }),
3871
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { bold: true, children: operation }),
3596
3872
  "(",
3597
3873
  basename3(presentation.path),
3598
3874
  ")"
@@ -3600,29 +3876,29 @@ function FileDiffView({ presentation, expanded }) {
3600
3876
  ] });
3601
3877
  }
3602
3878
  const lineWidth = Math.max(1, ...presentation.lines.map((line) => Math.max(line.oldLine ?? 0, line.newLine ?? 0))).toString().length;
3603
- return /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "column", width: "100%", children: [
3604
- /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "row", children: [
3605
- /* @__PURE__ */ jsx5(Text, { color: DIFF_ADDED_MARKER, children: "\u25CF" }),
3606
- /* @__PURE__ */ jsxs4(Text, { color: DIFF_CONTENT, children: [
3879
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "column", width: "100%", children: [
3880
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "row", children: [
3881
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: DIFF_ADDED_MARKER, children: "\u25CF" }),
3882
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: DIFF_CONTENT, children: [
3607
3883
  " ",
3608
- /* @__PURE__ */ jsx5(Text, { bold: true, children: operation }),
3884
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { bold: true, children: operation }),
3609
3885
  "(",
3610
3886
  basename3(presentation.path),
3611
3887
  ")"
3612
3888
  ] })
3613
3889
  ] }),
3614
- /* @__PURE__ */ jsxs4(Text, { color: DIFF_CONTENT, children: [
3890
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: DIFF_CONTENT, children: [
3615
3891
  " \u2514 Added ",
3616
3892
  lineCount(presentation.added),
3617
3893
  ", removed ",
3618
3894
  lineCount(presentation.removed)
3619
3895
  ] }),
3620
- (expanded ? presentation.lines : []).map((line, index) => /* @__PURE__ */ jsx5(FileDiffRow, { line, lineWidth }, `${line.kind}:${line.oldLine ?? ""}:${line.newLine ?? ""}:${index}`))
3896
+ (expanded ? presentation.lines : []).map((line, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(FileDiffRow, { line, lineWidth }, `${line.kind}:${line.oldLine ?? ""}:${line.newLine ?? ""}:${index}`))
3621
3897
  ] });
3622
3898
  }
3623
3899
  function FileDiffRow({ line, lineWidth }) {
3624
3900
  if (line.kind === "omitted") {
3625
- return /* @__PURE__ */ jsxs4(Text, { color: DIFF_CONTENT, dimColor: true, children: [
3901
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: DIFF_CONTENT, dimColor: true, children: [
3626
3902
  " ".repeat(lineWidth + 4),
3627
3903
  line.text
3628
3904
  ] });
@@ -3631,14 +3907,14 @@ function FileDiffRow({ line, lineWidth }) {
3631
3907
  const marker = line.kind === "removed" ? "-" : line.kind === "added" ? "+" : " ";
3632
3908
  const { backgroundColor, markerColor, contentColor } = fileDiffLineStyle(line.kind);
3633
3909
  const prefix = `${String(number ?? "").padStart(lineWidth)} ${marker}| `;
3634
- return /* @__PURE__ */ jsxs4(
3910
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
3635
3911
  Box_default,
3636
3912
  {
3637
3913
  flexDirection: "row",
3638
3914
  width: "100%",
3639
3915
  ...backgroundColor === void 0 ? {} : { backgroundColor },
3640
3916
  children: [
3641
- /* @__PURE__ */ jsx5(
3917
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3642
3918
  Text,
3643
3919
  {
3644
3920
  color: markerColor,
@@ -3647,7 +3923,7 @@ function FileDiffRow({ line, lineWidth }) {
3647
3923
  children: prefix
3648
3924
  }
3649
3925
  ),
3650
- /* @__PURE__ */ jsx5(
3926
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3651
3927
  Text,
3652
3928
  {
3653
3929
  color: contentColor,
@@ -3663,18 +3939,18 @@ function lineCount(count) {
3663
3939
  return `${count} ${count === 1 ? "line" : "lines"}`;
3664
3940
  }
3665
3941
  function StatusLine({ block, interactive }) {
3666
- if (block.progress !== void 0) return /* @__PURE__ */ jsx5(CompactProgressLine, { progress: block.progress });
3942
+ if (block.progress !== void 0) return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CompactProgressLine, { progress: block.progress });
3667
3943
  const running = block.state === "running";
3668
3944
  const [ref, time] = useAnimationFrame(running && interactive ? 120 : null);
3669
3945
  const color = statusLineColor(block);
3670
3946
  const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
3671
3947
  const spinner = running && interactive ? frames[Math.floor(Math.max(0, time) / 120) % frames.length] + " " : "";
3672
- return /* @__PURE__ */ jsxs4(Box_default, { ref, flexDirection: "row", children: [
3673
- /* @__PURE__ */ jsxs4(Text, { ...color === void 0 ? { dimColor: true } : { color }, children: [
3948
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { ref, flexDirection: "row", children: [
3949
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { ...color === void 0 ? { dimColor: true } : { color }, children: [
3674
3950
  spinner,
3675
3951
  block.text
3676
3952
  ] }),
3677
- block.hint === void 0 ? null : /* @__PURE__ */ jsxs4(Text, { dimColor: true, wrap: "truncate-end", children: [
3953
+ block.hint === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { dimColor: true, wrap: "truncate-end", children: [
3678
3954
  " (",
3679
3955
  block.hint,
3680
3956
  ")"
@@ -3690,13 +3966,13 @@ function statusLineColor(block) {
3690
3966
  }
3691
3967
  function CompactProgressLine({ progress }) {
3692
3968
  const presentation = compactProgressPresentation(progress);
3693
- return /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "row", children: [
3694
- /* @__PURE__ */ jsx5(Text, { children: "Compacting context " }),
3695
- presentation.cells.map((cell, index) => /* @__PURE__ */ jsxs4(Text, { color: cell.color, children: [
3969
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "row", children: [
3970
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { children: "Compacting context " }),
3971
+ presentation.cells.map((cell, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: cell.color, children: [
3696
3972
  "\u25A0",
3697
3973
  index === presentation.cells.length - 1 ? "" : " "
3698
3974
  ] }, index)),
3699
- /* @__PURE__ */ jsxs4(Text, { dimColor: true, children: [
3975
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { dimColor: true, children: [
3700
3976
  " ",
3701
3977
  presentation.progress,
3702
3978
  "%"
@@ -3727,13 +4003,13 @@ function PromptLine({
3727
4003
  lineStarts.push(nextLineStart);
3728
4004
  nextLineStart += [...line].length;
3729
4005
  }
3730
- return /* @__PURE__ */ jsx5(Box_default, { width: "100%", flexDirection: "column", paddingX: PROMPT_HORIZONTAL_PADDING, children: visibleLines.map((line, visibleIndex) => {
4006
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { width: "100%", flexDirection: "column", paddingX: PROMPT_HORIZONTAL_PADDING, children: visibleLines.map((line, visibleIndex) => {
3731
4007
  const lineIndex = windowStart + visibleIndex;
3732
4008
  const isCursorLine = lineIndex === wrap.cursor.line;
3733
4009
  const points = [...line];
3734
4010
  const cursorCol = wrap.cursor.column;
3735
4011
  const styledCount = Math.max(0, Math.min(points.length, tokenLength - (lineStarts[lineIndex] ?? 0)));
3736
- return /* @__PURE__ */ jsxs4(
4012
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
3737
4013
  Box_default,
3738
4014
  {
3739
4015
  ...onCursorChange === void 0 ? {} : {
@@ -3747,8 +4023,8 @@ function PromptLine({
3747
4023
  }
3748
4024
  },
3749
4025
  children: [
3750
- /* @__PURE__ */ jsx5(Text, { color: "yellow", bold: true, children: lineIndex === 0 ? "\u276F " : " " }),
3751
- /* @__PURE__ */ jsx5(PromptLineContent, { points, cursor: cursorCol, cursorVisible: isCursorLine, styledCount })
4026
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "yellow", bold: true, children: lineIndex === 0 ? "\u276F " : " " }),
4027
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PromptLineContent, { points, cursor: cursorCol, cursorVisible: isCursorLine, styledCount })
3752
4028
  ]
3753
4029
  },
3754
4030
  lineIndex
@@ -3764,14 +4040,14 @@ function StatusBlockView({
3764
4040
  const visibleBlock = cliToolTitle(block);
3765
4041
  const outcome = cliToolOutcome(block);
3766
4042
  const toolOutput = block.tool !== void 0 || block.presentation !== void 0;
3767
- const primary = visibleBlock.activity === "model" || visibleBlock.task !== void 0 ? /* @__PURE__ */ jsx5(TaskStatusLine, { block: visibleBlock, interactive }) : visibleBlock.state === "completed" && visibleBlock.presentation !== void 0 ? /* @__PURE__ */ jsx5(ToolPresentationView, { presentation: visibleBlock.presentation, workspaceName, expandedOutput }) : /* @__PURE__ */ jsx5(StatusLine, { block: visibleBlock, interactive });
3768
- return /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "column", children: [
4043
+ const primary = visibleBlock.activity === "model" || visibleBlock.task !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TaskStatusLine, { block: visibleBlock, interactive }) : visibleBlock.state === "completed" && visibleBlock.presentation !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ToolPresentationView, { presentation: visibleBlock.presentation, workspaceName, expandedOutput }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(StatusLine, { block: visibleBlock, interactive });
4044
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "column", children: [
3769
4045
  primary,
3770
- outcome === void 0 ? null : /* @__PURE__ */ jsx5(Box_default, { paddingLeft: 2, children: /* @__PURE__ */ jsxs4(Text, { dimColor: true, children: [
4046
+ outcome === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { paddingLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { dimColor: true, children: [
3771
4047
  "\u2514 ",
3772
4048
  outcome
3773
4049
  ] }) }),
3774
- block.details === void 0 || block.presentation?.kind === "changeset" || toolOutput && !expandedOutput ? null : /* @__PURE__ */ jsx5(Box_default, { paddingLeft: 2, children: /* @__PURE__ */ jsx5(AssistantText, { text: block.details }) })
4050
+ block.details === void 0 || block.presentation?.kind === "changeset" || toolOutput && !expandedOutput ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { paddingLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AssistantText, { text: block.details }) })
3775
4051
  ] });
3776
4052
  }
3777
4053
  function ToolPresentationView({
@@ -3779,17 +4055,17 @@ function ToolPresentationView({
3779
4055
  workspaceName,
3780
4056
  expandedOutput
3781
4057
  }) {
3782
- if (presentation.kind === "changeset") return /* @__PURE__ */ jsx5(ChangeSetPresentationView, { presentation, workspaceName, expanded: expandedOutput });
3783
- if (presentation.kind === "file-change") return /* @__PURE__ */ jsx5(FileDiffView, { presentation, expanded: expandedOutput });
3784
- if (presentation.kind === "terminal") return /* @__PURE__ */ jsx5(CommandPresentationView, { presentation, expanded: expandedOutput });
3785
- if (presentation.kind === "web") return /* @__PURE__ */ jsx5(WebPresentationView, { presentation, expanded: expandedOutput });
3786
- if (presentation.kind === "job") return /* @__PURE__ */ jsx5(JobPresentationView, { presentation, expanded: expandedOutput });
3787
- return /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "column", paddingLeft: 2, children: [
3788
- /* @__PURE__ */ jsxs4(Text, { children: [
4058
+ if (presentation.kind === "changeset") return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChangeSetPresentationView, { presentation, workspaceName, expanded: expandedOutput });
4059
+ if (presentation.kind === "file-change") return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(FileDiffView, { presentation, expanded: expandedOutput });
4060
+ if (presentation.kind === "terminal") return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CommandPresentationView, { presentation, expanded: expandedOutput });
4061
+ if (presentation.kind === "web") return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(WebPresentationView, { presentation, expanded: expandedOutput });
4062
+ if (presentation.kind === "job") return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(JobPresentationView, { presentation, expanded: expandedOutput });
4063
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 2, children: [
4064
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { children: [
3789
4065
  presentation.title,
3790
4066
  presentation.summary ? ` \xB7 ${presentation.summary}` : ""
3791
4067
  ] }),
3792
- !expandedOutput || presentation.details === void 0 ? null : /* @__PURE__ */ jsx5(AssistantText, { text: presentation.details })
4068
+ !expandedOutput || presentation.details === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AssistantText, { text: presentation.details })
3793
4069
  ] });
3794
4070
  }
3795
4071
  var CHANGESET_TONE = "#b99bf8";
@@ -3803,10 +4079,10 @@ function ChangeSetPresentationView({
3803
4079
  const removed = presentation.files.reduce((total, file) => total + file.removed, 0);
3804
4080
  const fileLabel = presentation.files.length === 1 ? "FILE" : "FILES";
3805
4081
  const showing = presentation.files.length > visibleFiles.length ? ` \xB7 Showing ${visibleFiles.length} of ${presentation.files.length}` : "";
3806
- return /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "column", paddingLeft: 2, marginBottom: 1, children: [
3807
- /* @__PURE__ */ jsxs4(Box_default, { children: [
3808
- /* @__PURE__ */ jsx5(Text, { color: CHANGESET_TONE, children: "\u250C\u2500 " }),
3809
- /* @__PURE__ */ jsxs4(Text, { color: CHANGESET_TONE, bold: true, children: [
4082
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 2, marginBottom: 1, children: [
4083
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4084
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: CHANGESET_TONE, children: "\u250C\u2500 " }),
4085
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: CHANGESET_TONE, bold: true, children: [
3810
4086
  "CHANGESET \xB7 ",
3811
4087
  presentation.files.length,
3812
4088
  " ",
@@ -3816,37 +4092,37 @@ function ChangeSetPresentationView({
3816
4092
  visibleFiles.map((file) => {
3817
4093
  const operation = file.operation.toUpperCase();
3818
4094
  const stats = `+${file.added} -${file.removed}`;
3819
- return /* @__PURE__ */ jsxs4(Box_default, { children: [
3820
- /* @__PURE__ */ jsx5(Text, { color: CHANGESET_TONE, children: "\u2502 " }),
3821
- /* @__PURE__ */ jsx5(Text, { color: changeSetOperationColor(file.operation), bold: true, children: operation.padEnd(8) }),
3822
- /* @__PURE__ */ jsxs4(Text, { children: [
3823
- /* @__PURE__ */ jsxs4(Text, { color: "ansi:green", children: [
4095
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4096
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: CHANGESET_TONE, children: "\u2502 " }),
4097
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: changeSetOperationColor(file.operation), bold: true, children: operation.padEnd(8) }),
4098
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { children: [
4099
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "ansi:green", children: [
3824
4100
  "+",
3825
4101
  file.added
3826
4102
  ] }),
3827
4103
  " ",
3828
- /* @__PURE__ */ jsxs4(Text, { color: "#e06c50", children: [
4104
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "#e06c50", children: [
3829
4105
  "-",
3830
4106
  file.removed
3831
4107
  ] }),
3832
4108
  " ".repeat(Math.max(1, 9 - stats.length))
3833
4109
  ] }),
3834
- /* @__PURE__ */ jsx5(Text, { color: "ansi:whiteBright", wrap: "truncate-end", children: workspaceRelativePath(file.path, workspaceName) })
4110
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "ansi:whiteBright", wrap: "truncate-end", children: workspaceRelativePath(file.path, workspaceName) })
3835
4111
  ] }, `${file.operation}:${file.path}`);
3836
4112
  }),
3837
- /* @__PURE__ */ jsxs4(Box_default, { children: [
3838
- /* @__PURE__ */ jsx5(Text, { color: CHANGESET_TONE, children: "\u2514\u2500 " }),
3839
- /* @__PURE__ */ jsxs4(Text, { children: [
3840
- /* @__PURE__ */ jsxs4(Text, { color: "ansi:green", children: [
4113
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4114
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: CHANGESET_TONE, children: "\u2514\u2500 " }),
4115
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { children: [
4116
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "ansi:green", children: [
3841
4117
  "+",
3842
4118
  added
3843
4119
  ] }),
3844
4120
  " ",
3845
- /* @__PURE__ */ jsxs4(Text, { color: "#e06c50", children: [
4121
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "#e06c50", children: [
3846
4122
  "-",
3847
4123
  removed
3848
4124
  ] }),
3849
- /* @__PURE__ */ jsx5(Text, { dimColor: true, children: showing })
4125
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { dimColor: true, children: showing })
3850
4126
  ] })
3851
4127
  ] })
3852
4128
  ] });
@@ -3875,28 +4151,28 @@ function CommandPresentationView({
3875
4151
  const perStreamLimit = expanded ? Number.POSITIVE_INFINITY : 0;
3876
4152
  const stdout = boundedCommandLines(presentation.stdout ?? "", perStreamLimit);
3877
4153
  const stderr = boundedCommandLines(presentation.stderr ?? "", perStreamLimit);
3878
- return /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "column", paddingLeft: 2, marginBottom: 1, children: [
3879
- /* @__PURE__ */ jsxs4(Box_default, { children: [
3880
- /* @__PURE__ */ jsx5(Text, { color: tone, children: "\u250C\u2500 " }),
3881
- /* @__PURE__ */ jsxs4(Text, { color: tone, bold: true, children: [
4154
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 2, marginBottom: 1, children: [
4155
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4156
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: tone, children: "\u250C\u2500 " }),
4157
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: tone, bold: true, children: [
3882
4158
  label,
3883
4159
  " \xB7 ",
3884
4160
  state.toUpperCase()
3885
4161
  ] })
3886
4162
  ] }),
3887
- /* @__PURE__ */ jsxs4(Box_default, { children: [
3888
- /* @__PURE__ */ jsx5(Text, { color: tone, children: "\u2502 " }),
3889
- /* @__PURE__ */ jsx5(Text, { color: "ansi:whiteBright", bold: true, wrap: "truncate-end", children: presentation.command ?? presentation.title })
4163
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4164
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: tone, children: "\u2502 " }),
4165
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "ansi:whiteBright", bold: true, wrap: "truncate-end", children: presentation.command ?? presentation.title })
3890
4166
  ] }),
3891
- stdout.total === 0 ? null : /* @__PURE__ */ jsx5(CommandOutputSection, { label: "OUTPUT", value: stdout, tone, error: false }),
3892
- stderr.total === 0 ? null : /* @__PURE__ */ jsx5(CommandOutputSection, { label: "ERROR", value: stderr, tone, error: true }),
3893
- !expanded || presentation.diagnostic === void 0 ? null : /* @__PURE__ */ jsxs4(Box_default, { children: [
3894
- /* @__PURE__ */ jsx5(Text, { color: tone, children: "\u2502 " }),
3895
- /* @__PURE__ */ jsx5(Text, { color: tone, children: presentation.diagnostic })
4167
+ stdout.total === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CommandOutputSection, { label: "OUTPUT", value: stdout, tone, error: false }),
4168
+ stderr.total === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CommandOutputSection, { label: "ERROR", value: stderr, tone, error: true }),
4169
+ !expanded || presentation.diagnostic === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4170
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: tone, children: "\u2502 " }),
4171
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: tone, children: presentation.diagnostic })
3896
4172
  ] }),
3897
- /* @__PURE__ */ jsxs4(Box_default, { children: [
3898
- /* @__PURE__ */ jsx5(Text, { color: tone, children: "\u2514\u2500 " }),
3899
- /* @__PURE__ */ jsx5(Text, { dimColor: true, children: commandFooter(presentation, state) })
4173
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4174
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: tone, children: "\u2514\u2500 " }),
4175
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { dimColor: true, children: commandFooter(presentation, state) })
3900
4176
  ] })
3901
4177
  ] });
3902
4178
  }
@@ -3906,17 +4182,17 @@ function CommandOutputSection({
3906
4182
  tone,
3907
4183
  error
3908
4184
  }) {
3909
- return /* @__PURE__ */ jsxs4(Fragment3, { children: [
3910
- /* @__PURE__ */ jsxs4(Box_default, { children: [
3911
- /* @__PURE__ */ jsx5(Text, { color: tone, children: "\u251C\u2500 " }),
3912
- /* @__PURE__ */ jsx5(Text, { color: error ? "#e06c50" : tone, bold: true, children: label }),
3913
- /* @__PURE__ */ jsx5(Text, { dimColor: true, children: ` \xB7 ${value.total} ${value.total === 1 ? "LINE" : "LINES"}` }),
3914
- value.hidden === 0 ? null : /* @__PURE__ */ jsx5(Text, { dimColor: true, children: ` \xB7 ${value.head.length + value.tail.length} SHOWN` })
4185
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
4186
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4187
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: tone, children: "\u251C\u2500 " }),
4188
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: error ? "#e06c50" : tone, bold: true, children: label }),
4189
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { dimColor: true, children: ` \xB7 ${value.total} ${value.total === 1 ? "LINE" : "LINES"}` }),
4190
+ value.hidden === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { dimColor: true, children: ` \xB7 ${value.head.length + value.tail.length} SHOWN` })
3915
4191
  ] }),
3916
- value.head.map((line, index) => /* @__PURE__ */ jsx5(CommandOutputLine, { line, tone, error }, `head:${index}`)),
3917
- value.hidden === 0 ? null : /* @__PURE__ */ jsxs4(Box_default, { children: [
3918
- /* @__PURE__ */ jsx5(Text, { color: tone, children: "\u2502 " }),
3919
- /* @__PURE__ */ jsxs4(Text, { dimColor: true, children: [
4192
+ value.head.map((line, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CommandOutputLine, { line, tone, error }, `head:${index}`)),
4193
+ value.hidden === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4194
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: tone, children: "\u2502 " }),
4195
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { dimColor: true, children: [
3920
4196
  "\u2026 ",
3921
4197
  value.hidden,
3922
4198
  " ",
@@ -3924,13 +4200,13 @@ function CommandOutputSection({
3924
4200
  " hidden"
3925
4201
  ] })
3926
4202
  ] }),
3927
- value.tail.map((line, index) => /* @__PURE__ */ jsx5(CommandOutputLine, { line, tone, error }, `tail:${index}`))
4203
+ value.tail.map((line, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CommandOutputLine, { line, tone, error }, `tail:${index}`))
3928
4204
  ] });
3929
4205
  }
3930
4206
  function CommandOutputLine({ line, tone, error }) {
3931
- return /* @__PURE__ */ jsxs4(Box_default, { children: [
3932
- /* @__PURE__ */ jsx5(Text, { color: tone, children: "\u2502 " }),
3933
- /* @__PURE__ */ jsx5(Text, { color: error ? "#e06c50" : "#b8bcc2", wrap: "truncate-end", children: line === "" ? " " : line })
4207
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4208
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: tone, children: "\u2502 " }),
4209
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: error ? "#e06c50" : "#b8bcc2", wrap: "truncate-end", children: line === "" ? " " : line })
3934
4210
  ] });
3935
4211
  }
3936
4212
  function boundedCommandLines(output, limit) {
@@ -3960,51 +4236,51 @@ function WebPresentationView({
3960
4236
  expanded
3961
4237
  }) {
3962
4238
  const items = presentation.items ?? [];
3963
- if (presentation.items === void 0) return /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "column", paddingLeft: 2, marginBottom: 1, children: [
3964
- /* @__PURE__ */ jsxs4(Box_default, { children: [
3965
- /* @__PURE__ */ jsx5(Text, { color: "#5f87af", children: "\u250C\u2500 " }),
3966
- /* @__PURE__ */ jsx5(Text, { color: "ansi:cyanBright", bold: true, children: "WEB FETCH" }),
3967
- presentation.summary === void 0 ? null : /* @__PURE__ */ jsx5(Text, { dimColor: true, children: ` \xB7 ${presentation.summary}` })
4239
+ if (presentation.items === void 0) return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 2, marginBottom: 1, children: [
4240
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4241
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "#5f87af", children: "\u250C\u2500 " }),
4242
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "ansi:cyanBright", bold: true, children: "WEB FETCH" }),
4243
+ presentation.summary === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { dimColor: true, children: ` \xB7 ${presentation.summary}` })
3968
4244
  ] }),
3969
- /* @__PURE__ */ jsxs4(Box_default, { children: [
3970
- /* @__PURE__ */ jsx5(Text, { color: "#5f87af", children: "\u2502 " }),
3971
- /* @__PURE__ */ jsx5(Text, { color: "ansi:whiteBright", wrap: "truncate-end", children: presentation.url ?? presentation.title })
4245
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4246
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "#5f87af", children: "\u2502 " }),
4247
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "ansi:whiteBright", wrap: "truncate-end", children: presentation.url ?? presentation.title })
3972
4248
  ] }),
3973
- /* @__PURE__ */ jsxs4(Box_default, { children: [
3974
- /* @__PURE__ */ jsx5(Text, { color: "#5f87af", children: "\u2514\u2500 " }),
3975
- /* @__PURE__ */ jsx5(Text, { dimColor: true, children: "Page content added to context" })
4249
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4250
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "#5f87af", children: "\u2514\u2500 " }),
4251
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { dimColor: true, children: "Page content added to context" })
3976
4252
  ] })
3977
4253
  ] });
3978
4254
  const visibleItems = expanded ? items : [];
3979
4255
  const query = presentation.title.replace(/^Search:\s*/iu, "").trim();
3980
- return /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "column", paddingLeft: 2, marginBottom: 1, children: [
3981
- /* @__PURE__ */ jsxs4(Box_default, { children: [
3982
- /* @__PURE__ */ jsx5(Text, { color: "#5f87af", children: "\u250C\u2500 " }),
3983
- /* @__PURE__ */ jsx5(Text, { color: "ansi:cyanBright", bold: true, children: "WEB SEARCH" }),
3984
- /* @__PURE__ */ jsx5(Text, { dimColor: true, children: ` \xB7 ${items.length} ${items.length === 1 ? "RESULT" : "RESULTS"}` })
4256
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 2, marginBottom: 1, children: [
4257
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4258
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "#5f87af", children: "\u250C\u2500 " }),
4259
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "ansi:cyanBright", bold: true, children: "WEB SEARCH" }),
4260
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { dimColor: true, children: ` \xB7 ${items.length} ${items.length === 1 ? "RESULT" : "RESULTS"}` })
3985
4261
  ] }),
3986
- /* @__PURE__ */ jsxs4(Box_default, { children: [
3987
- /* @__PURE__ */ jsx5(Text, { color: "#5f87af", children: "\u2502 " }),
3988
- /* @__PURE__ */ jsx5(Text, { color: "ansi:whiteBright", bold: true, wrap: "truncate-end", children: query })
4262
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4263
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "#5f87af", children: "\u2502 " }),
4264
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "ansi:whiteBright", bold: true, wrap: "truncate-end", children: query })
3989
4265
  ] }),
3990
- /* @__PURE__ */ jsx5(Text, { color: "#5f87af", children: "\u2502" }),
3991
- visibleItems.map((item, index) => /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "column", children: [
3992
- /* @__PURE__ */ jsxs4(Box_default, { children: [
3993
- /* @__PURE__ */ jsx5(Text, { color: "#5f87af", children: "\u2502 " }),
3994
- /* @__PURE__ */ jsx5(Text, { color: "ansi:cyanBright", bold: true, children: String(index + 1).padStart(2, "0") }),
3995
- /* @__PURE__ */ jsxs4(Text, { color: "ansi:whiteBright", wrap: "truncate-end", children: [
4266
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "#5f87af", children: "\u2502" }),
4267
+ visibleItems.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "column", children: [
4268
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4269
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "#5f87af", children: "\u2502 " }),
4270
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "ansi:cyanBright", bold: true, children: String(index + 1).padStart(2, "0") }),
4271
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "ansi:whiteBright", wrap: "truncate-end", children: [
3996
4272
  " ",
3997
4273
  item.title
3998
4274
  ] })
3999
4275
  ] }),
4000
- /* @__PURE__ */ jsxs4(Box_default, { children: [
4001
- /* @__PURE__ */ jsx5(Text, { color: "#5f87af", children: "\u2502 " }),
4002
- /* @__PURE__ */ jsx5(Text, { dimColor: true, wrap: "truncate-end", children: compactWebSource(item.url) })
4276
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4277
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "#5f87af", children: "\u2502 " }),
4278
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { dimColor: true, wrap: "truncate-end", children: compactWebSource(item.url) })
4003
4279
  ] })
4004
4280
  ] }, item.url)),
4005
- /* @__PURE__ */ jsxs4(Box_default, { children: [
4006
- /* @__PURE__ */ jsx5(Text, { color: "#5f87af", children: "\u2514\u2500 " }),
4007
- /* @__PURE__ */ jsx5(Text, { dimColor: true, children: items.length > visibleItems.length ? `Showing ${visibleItems.length} of ${items.length}` : `${items.length} ${items.length === 1 ? "source" : "sources"}` })
4281
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4282
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "#5f87af", children: "\u2514\u2500 " }),
4283
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { dimColor: true, children: items.length > visibleItems.length ? `Showing ${visibleItems.length} of ${items.length}` : `${items.length} ${items.length === 1 ? "source" : "sources"}` })
4008
4284
  ] })
4009
4285
  ] });
4010
4286
  }
@@ -4022,43 +4298,43 @@ function JobPresentationView({
4022
4298
  presentation,
4023
4299
  expanded
4024
4300
  }) {
4025
- if (presentation.action === "list") return /* @__PURE__ */ jsx5(JobListPresentationView, { presentation, expanded });
4301
+ if (presentation.action === "list") return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(JobListPresentationView, { presentation, expanded });
4026
4302
  const state = presentation.state ?? "running";
4027
4303
  const tone = jobStateColor(state);
4028
4304
  const lines = jobOutputLines(presentation.output ?? "");
4029
4305
  const visibleLines = expanded ? lines : [];
4030
4306
  const hiddenLines = lines.length - visibleLines.length;
4031
4307
  const showLog = presentation.action === "read" || presentation.action === "kill" || lines.length > 0;
4032
- return /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "column", paddingLeft: 2, marginBottom: 1, children: [
4033
- /* @__PURE__ */ jsxs4(Box_default, { children: [
4034
- /* @__PURE__ */ jsx5(Text, { color: tone, children: "\u250C\u2500 " }),
4035
- /* @__PURE__ */ jsxs4(Text, { color: tone, bold: true, children: [
4308
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 2, marginBottom: 1, children: [
4309
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4310
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: tone, children: "\u250C\u2500 " }),
4311
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: tone, bold: true, children: [
4036
4312
  "JOB \xB7 ",
4037
4313
  state.toUpperCase()
4038
4314
  ] })
4039
4315
  ] }),
4040
- /* @__PURE__ */ jsxs4(Box_default, { children: [
4041
- /* @__PURE__ */ jsx5(Text, { color: tone, children: "\u2502 " }),
4042
- /* @__PURE__ */ jsx5(Text, { color: "ansi:whiteBright", bold: true, children: presentation.id ?? "unknown job" }),
4043
- presentation.jobKind === void 0 ? null : /* @__PURE__ */ jsx5(Text, { dimColor: true, children: ` \xB7 ${presentation.jobKind}` })
4316
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4317
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: tone, children: "\u2502 " }),
4318
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "ansi:whiteBright", bold: true, children: presentation.id ?? "unknown job" }),
4319
+ presentation.jobKind === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { dimColor: true, children: ` \xB7 ${presentation.jobKind}` })
4044
4320
  ] }),
4045
- presentation.label === void 0 ? null : /* @__PURE__ */ jsxs4(Box_default, { children: [
4046
- /* @__PURE__ */ jsx5(Text, { color: tone, children: "\u2502 " }),
4047
- /* @__PURE__ */ jsx5(Text, { color: "ansi:whiteBright", wrap: "truncate-end", children: presentation.label })
4321
+ presentation.label === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4322
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: tone, children: "\u2502 " }),
4323
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "ansi:whiteBright", wrap: "truncate-end", children: presentation.label })
4048
4324
  ] }),
4049
- presentation.error === void 0 ? null : /* @__PURE__ */ jsxs4(Box_default, { children: [
4050
- /* @__PURE__ */ jsx5(Text, { color: tone, children: "\u2502 " }),
4051
- /* @__PURE__ */ jsx5(Text, { color: "#e06c50", wrap: "truncate-end", children: presentation.error })
4325
+ presentation.error === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4326
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: tone, children: "\u2502 " }),
4327
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "#e06c50", wrap: "truncate-end", children: presentation.error })
4052
4328
  ] }),
4053
- showLog ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
4054
- /* @__PURE__ */ jsxs4(Box_default, { children: [
4055
- /* @__PURE__ */ jsx5(Text, { color: tone, children: "\u251C\u2500 " }),
4056
- /* @__PURE__ */ jsx5(Text, { color: tone, bold: true, children: "LOG" }),
4057
- /* @__PURE__ */ jsx5(Text, { dimColor: true, children: lines.length === 0 ? " \xB7 NO NEW OUTPUT" : ` \xB7 ${lines.length} ${lines.length === 1 ? "LINE" : "LINES"}` })
4329
+ showLog ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
4330
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4331
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: tone, children: "\u251C\u2500 " }),
4332
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: tone, bold: true, children: "LOG" }),
4333
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { dimColor: true, children: lines.length === 0 ? " \xB7 NO NEW OUTPUT" : ` \xB7 ${lines.length} ${lines.length === 1 ? "LINE" : "LINES"}` })
4058
4334
  ] }),
4059
- hiddenLines > 0 ? /* @__PURE__ */ jsxs4(Box_default, { children: [
4060
- /* @__PURE__ */ jsx5(Text, { color: tone, children: "\u2502 " }),
4061
- /* @__PURE__ */ jsxs4(Text, { dimColor: true, children: [
4335
+ hiddenLines > 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4336
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: tone, children: "\u2502 " }),
4337
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { dimColor: true, children: [
4062
4338
  "\u2026 ",
4063
4339
  hiddenLines,
4064
4340
  " earlier ",
@@ -4066,11 +4342,11 @@ function JobPresentationView({
4066
4342
  " hidden"
4067
4343
  ] })
4068
4344
  ] }) : null,
4069
- visibleLines.map((line, index) => /* @__PURE__ */ jsx5(JobLogLine, { line, tone }, `${index}:${line}`))
4345
+ visibleLines.map((line, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(JobLogLine, { line, tone }, `${index}:${line}`))
4070
4346
  ] }) : null,
4071
- /* @__PURE__ */ jsxs4(Box_default, { children: [
4072
- /* @__PURE__ */ jsx5(Text, { color: tone, children: "\u2514\u2500 " }),
4073
- /* @__PURE__ */ jsx5(Text, { dimColor: true, children: jobFooter(presentation) })
4347
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4348
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: tone, children: "\u2514\u2500 " }),
4349
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { dimColor: true, children: jobFooter(presentation) })
4074
4350
  ] })
4075
4351
  ] });
4076
4352
  }
@@ -4080,41 +4356,41 @@ function JobListPresentationView({
4080
4356
  }) {
4081
4357
  const jobs = presentation.jobs ?? [];
4082
4358
  const visibleJobs = expanded ? jobs : [];
4083
- return /* @__PURE__ */ jsxs4(Box_default, { flexDirection: "column", paddingLeft: 2, marginBottom: 1, children: [
4084
- /* @__PURE__ */ jsxs4(Box_default, { children: [
4085
- /* @__PURE__ */ jsx5(Text, { color: "#d7a657", children: "\u250C\u2500 " }),
4086
- /* @__PURE__ */ jsxs4(Text, { color: "#d7a657", bold: true, children: [
4359
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "column", paddingLeft: 2, marginBottom: 1, children: [
4360
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4361
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "#d7a657", children: "\u250C\u2500 " }),
4362
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "#d7a657", bold: true, children: [
4087
4363
  "JOBS \xB7 ",
4088
4364
  jobs.length
4089
4365
  ] })
4090
4366
  ] }),
4091
- jobs.length === 0 ? /* @__PURE__ */ jsxs4(Box_default, { children: [
4092
- /* @__PURE__ */ jsx5(Text, { color: "#d7a657", children: "\u2502 " }),
4093
- /* @__PURE__ */ jsx5(Text, { dimColor: true, children: "No background jobs" })
4094
- ] }) : visibleJobs.map((job) => /* @__PURE__ */ jsxs4(Box_default, { children: [
4095
- /* @__PURE__ */ jsx5(Text, { color: "#d7a657", children: "\u2502 " }),
4096
- /* @__PURE__ */ jsx5(Text, { color: jobStateColor(job.state), bold: true, children: job.state.toUpperCase().padEnd(9) }),
4097
- /* @__PURE__ */ jsxs4(Text, { color: "ansi:whiteBright", children: [
4367
+ jobs.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4368
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "#d7a657", children: "\u2502 " }),
4369
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { dimColor: true, children: "No background jobs" })
4370
+ ] }) : visibleJobs.map((job) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4371
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "#d7a657", children: "\u2502 " }),
4372
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: jobStateColor(job.state), bold: true, children: job.state.toUpperCase().padEnd(9) }),
4373
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "ansi:whiteBright", children: [
4098
4374
  " ",
4099
4375
  job.id
4100
4376
  ] }),
4101
- /* @__PURE__ */ jsxs4(Text, { dimColor: true, wrap: "truncate-end", children: [
4377
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { dimColor: true, wrap: "truncate-end", children: [
4102
4378
  " \xB7 ",
4103
4379
  job.label
4104
4380
  ] })
4105
4381
  ] }, job.id)),
4106
- /* @__PURE__ */ jsxs4(Box_default, { children: [
4107
- /* @__PURE__ */ jsx5(Text, { color: "#d7a657", children: "\u2514\u2500 " }),
4108
- /* @__PURE__ */ jsx5(Text, { dimColor: true, children: jobs.length > visibleJobs.length ? `Showing ${visibleJobs.length} of ${jobs.length}` : `${jobs.length} ${jobs.length === 1 ? "job" : "jobs"}` })
4382
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4383
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "#d7a657", children: "\u2514\u2500 " }),
4384
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { dimColor: true, children: jobs.length > visibleJobs.length ? `Showing ${visibleJobs.length} of ${jobs.length}` : `${jobs.length} ${jobs.length === 1 ? "job" : "jobs"}` })
4109
4385
  ] })
4110
4386
  ] });
4111
4387
  }
4112
4388
  function JobLogLine({ line, tone }) {
4113
4389
  const error = /^(?:\[stderr\]|ERR(?:OR)?(?:!|:|\s)|npm ERR!)/iu.test(line.trimStart());
4114
4390
  const stage = /^={3}.*={3}$/u.test(line.trim());
4115
- return /* @__PURE__ */ jsxs4(Box_default, { children: [
4116
- /* @__PURE__ */ jsx5(Text, { color: tone, children: "\u2502 " }),
4117
- /* @__PURE__ */ jsx5(
4391
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { children: [
4392
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: tone, children: "\u2502 " }),
4393
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4118
4394
  Text,
4119
4395
  {
4120
4396
  ...error ? { color: "#e06c50" } : stage ? { color: "ansi:cyanBright", bold: true } : { dimColor: true },
@@ -4286,11 +4562,11 @@ function PromptLineContent({
4286
4562
  styledCount
4287
4563
  }) {
4288
4564
  const tokenStyle = completedSlashTokenPresentation();
4289
- return /* @__PURE__ */ jsxs4(Text, { children: [
4565
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { children: [
4290
4566
  points.map((point, index) => {
4291
4567
  const styled = index < styledCount;
4292
4568
  const caret = cursorVisible && index === cursor;
4293
- return /* @__PURE__ */ jsx5(
4569
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4294
4570
  Text,
4295
4571
  {
4296
4572
  ...styled ? tokenStyle : {},
@@ -4300,7 +4576,7 @@ function PromptLineContent({
4300
4576
  index
4301
4577
  );
4302
4578
  }),
4303
- cursorVisible && cursor >= points.length ? /* @__PURE__ */ jsx5(Text, { inverse: true, children: " " }) : null
4579
+ cursorVisible && cursor >= points.length ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { inverse: true, children: " " }) : null
4304
4580
  ] });
4305
4581
  }
4306
4582
  function editPrompt(state, edit) {
@@ -4375,6 +4651,13 @@ var FORCE_EXIT_GRACE_MS = 250;
4375
4651
  async function shutdownRuntime(runtime, exit, report, options = {}) {
4376
4652
  const timeoutMs = options.shutdownTimeoutMs ?? SHUTDOWN_TIMEOUT_MS;
4377
4653
  let timedOut = false;
4654
+ if (runtime?.sessionId !== void 0 && options.onSessionEnd !== void 0) {
4655
+ try {
4656
+ options.onSessionEnd(runtime.sessionId);
4657
+ } catch (error) {
4658
+ safeReport(report, safeUiError(error));
4659
+ }
4660
+ }
4378
4661
  try {
4379
4662
  const outcome = await withTimeout(closeAndDisposeRuntime(runtime, report), timeoutMs);
4380
4663
  timedOut = outcome.timedOut;
@@ -4441,6 +4724,8 @@ export {
4441
4724
  isCopyShortcut,
4442
4725
  isOutputToggleShortcut,
4443
4726
  isPlatformShortcut,
4727
+ jumpScroll,
4728
+ jumpToAdjacentTurn,
4444
4729
  navigateHistory,
4445
4730
  navigatePromptHistory,
4446
4731
  outputToggleShortcut,
@@ -4456,6 +4741,8 @@ export {
4456
4741
  reverseSearchHistory,
4457
4742
  runTerminalSubmissionChain,
4458
4743
  runningEscapeAction,
4744
+ scrollDown,
4745
+ scrollUp,
4459
4746
  selectWheelScrollTarget,
4460
4747
  shutdownRuntime,
4461
4748
  slashKeyAction,