@prestyj/cli 4.2.56 → 4.2.75

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 (195) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.js +4 -4
  3. package/dist/cli.js.map +1 -1
  4. package/dist/config.d.ts +1 -0
  5. package/dist/config.d.ts.map +1 -1
  6. package/dist/config.js +6 -5
  7. package/dist/config.js.map +1 -1
  8. package/dist/core/agent-session.d.ts.map +1 -1
  9. package/dist/core/agent-session.js +11 -0
  10. package/dist/core/agent-session.js.map +1 -1
  11. package/dist/core/compaction/compactor.d.ts +3 -1
  12. package/dist/core/compaction/compactor.d.ts.map +1 -1
  13. package/dist/core/compaction/compactor.js +28 -5
  14. package/dist/core/compaction/compactor.js.map +1 -1
  15. package/dist/core/compaction/compactor.test.js +86 -10
  16. package/dist/core/compaction/compactor.test.js.map +1 -1
  17. package/dist/core/compaction/token-estimator.test.js +1 -1
  18. package/dist/core/compaction/token-estimator.test.js.map +1 -1
  19. package/dist/core/model-registry.js +8 -8
  20. package/dist/core/model-registry.js.map +1 -1
  21. package/dist/core/settings-manager.d.ts +1 -0
  22. package/dist/core/settings-manager.d.ts.map +1 -1
  23. package/dist/core/settings-manager.js +2 -0
  24. package/dist/core/settings-manager.js.map +1 -1
  25. package/dist/core/slash-commands.d.ts.map +1 -1
  26. package/dist/core/slash-commands.js +18 -4
  27. package/dist/core/slash-commands.js.map +1 -1
  28. package/dist/core/telegram.d.ts.map +1 -1
  29. package/dist/core/telegram.js +3 -0
  30. package/dist/core/telegram.js.map +1 -1
  31. package/dist/interactive.d.ts.map +1 -1
  32. package/dist/interactive.js +1 -0
  33. package/dist/interactive.js.map +1 -1
  34. package/dist/system-prompt.d.ts.map +1 -1
  35. package/dist/system-prompt.js +21 -3
  36. package/dist/system-prompt.js.map +1 -1
  37. package/dist/tools/bash.d.ts.map +1 -1
  38. package/dist/tools/bash.js +4 -7
  39. package/dist/tools/bash.js.map +1 -1
  40. package/dist/tools/edit.d.ts.map +1 -1
  41. package/dist/tools/edit.js +4 -1
  42. package/dist/tools/edit.js.map +1 -1
  43. package/dist/tools/overflow.d.ts +6 -0
  44. package/dist/tools/overflow.d.ts.map +1 -0
  45. package/dist/tools/overflow.js +13 -0
  46. package/dist/tools/overflow.js.map +1 -0
  47. package/dist/tools/read.d.ts.map +1 -1
  48. package/dist/tools/read.js +6 -2
  49. package/dist/tools/read.js.map +1 -1
  50. package/dist/tools/truncate-utils.test.js +11 -11
  51. package/dist/tools/truncate-utils.test.js.map +1 -1
  52. package/dist/tools/truncate.d.ts +6 -4
  53. package/dist/tools/truncate.d.ts.map +1 -1
  54. package/dist/tools/truncate.js +12 -10
  55. package/dist/tools/truncate.js.map +1 -1
  56. package/dist/ui/App.d.ts +1 -0
  57. package/dist/ui/App.d.ts.map +1 -1
  58. package/dist/ui/App.js +261 -62
  59. package/dist/ui/App.js.map +1 -1
  60. package/dist/ui/buddy/Buddy.d.ts +15 -0
  61. package/dist/ui/buddy/Buddy.d.ts.map +1 -0
  62. package/dist/ui/buddy/Buddy.js +118 -0
  63. package/dist/ui/buddy/Buddy.js.map +1 -0
  64. package/dist/ui/buddy/gacha.d.ts +8 -0
  65. package/dist/ui/buddy/gacha.d.ts.map +1 -0
  66. package/dist/ui/buddy/gacha.js +94 -0
  67. package/dist/ui/buddy/gacha.js.map +1 -0
  68. package/dist/ui/buddy/species.d.ts +52 -0
  69. package/dist/ui/buddy/species.d.ts.map +1 -0
  70. package/dist/ui/buddy/species.js +257 -0
  71. package/dist/ui/buddy/species.js.map +1 -0
  72. package/dist/ui/components/ActivityIndicator.d.ts +10 -2
  73. package/dist/ui/components/ActivityIndicator.d.ts.map +1 -1
  74. package/dist/ui/components/ActivityIndicator.js +79 -22
  75. package/dist/ui/components/ActivityIndicator.js.map +1 -1
  76. package/dist/ui/components/AnimationContext.d.ts +14 -2
  77. package/dist/ui/components/AnimationContext.d.ts.map +1 -1
  78. package/dist/ui/components/AnimationContext.js +54 -8
  79. package/dist/ui/components/AnimationContext.js.map +1 -1
  80. package/dist/ui/components/AssistantMessage.d.ts +2 -1
  81. package/dist/ui/components/AssistantMessage.d.ts.map +1 -1
  82. package/dist/ui/components/AssistantMessage.js +5 -4
  83. package/dist/ui/components/AssistantMessage.js.map +1 -1
  84. package/dist/ui/components/BackgroundTasksBar.js +2 -2
  85. package/dist/ui/components/BackgroundTasksBar.js.map +1 -1
  86. package/dist/ui/components/CompactionNotice.d.ts.map +1 -1
  87. package/dist/ui/components/CompactionNotice.js +2 -1
  88. package/dist/ui/components/CompactionNotice.js.map +1 -1
  89. package/dist/ui/components/Footer.d.ts +3 -1
  90. package/dist/ui/components/Footer.d.ts.map +1 -1
  91. package/dist/ui/components/Footer.js +23 -48
  92. package/dist/ui/components/Footer.js.map +1 -1
  93. package/dist/ui/components/InputArea.d.ts.map +1 -1
  94. package/dist/ui/components/InputArea.js +2 -1
  95. package/dist/ui/components/InputArea.js.map +1 -1
  96. package/dist/ui/components/Markdown.d.ts +11 -6
  97. package/dist/ui/components/Markdown.d.ts.map +1 -1
  98. package/dist/ui/components/Markdown.js +170 -18
  99. package/dist/ui/components/Markdown.js.map +1 -1
  100. package/dist/ui/components/MessageResponse.d.ts +25 -0
  101. package/dist/ui/components/MessageResponse.d.ts.map +1 -0
  102. package/dist/ui/components/MessageResponse.js +42 -0
  103. package/dist/ui/components/MessageResponse.js.map +1 -0
  104. package/dist/ui/components/NoSelect.d.ts +20 -0
  105. package/dist/ui/components/NoSelect.d.ts.map +1 -0
  106. package/dist/ui/components/NoSelect.js +14 -0
  107. package/dist/ui/components/NoSelect.js.map +1 -0
  108. package/dist/ui/components/PlanProgress.d.ts +7 -0
  109. package/dist/ui/components/PlanProgress.d.ts.map +1 -0
  110. package/dist/ui/components/PlanProgress.js +30 -0
  111. package/dist/ui/components/PlanProgress.js.map +1 -0
  112. package/dist/ui/components/Ratchet.d.ts +20 -0
  113. package/dist/ui/components/Ratchet.d.ts.map +1 -0
  114. package/dist/ui/components/Ratchet.js +30 -0
  115. package/dist/ui/components/Ratchet.js.map +1 -0
  116. package/dist/ui/components/ServerToolExecution.d.ts.map +1 -1
  117. package/dist/ui/components/ServerToolExecution.js +5 -6
  118. package/dist/ui/components/ServerToolExecution.js.map +1 -1
  119. package/dist/ui/components/Spinner.d.ts +8 -2
  120. package/dist/ui/components/Spinner.d.ts.map +1 -1
  121. package/dist/ui/components/Spinner.js +52 -5
  122. package/dist/ui/components/Spinner.js.map +1 -1
  123. package/dist/ui/components/StreamingArea.d.ts +2 -1
  124. package/dist/ui/components/StreamingArea.d.ts.map +1 -1
  125. package/dist/ui/components/StreamingArea.js +9 -44
  126. package/dist/ui/components/StreamingArea.js.map +1 -1
  127. package/dist/ui/components/SubAgentPanel.d.ts.map +1 -1
  128. package/dist/ui/components/SubAgentPanel.js +6 -4
  129. package/dist/ui/components/SubAgentPanel.js.map +1 -1
  130. package/dist/ui/components/ThinkingBlock.d.ts +2 -1
  131. package/dist/ui/components/ThinkingBlock.d.ts.map +1 -1
  132. package/dist/ui/components/ThinkingBlock.js +2 -2
  133. package/dist/ui/components/ThinkingBlock.js.map +1 -1
  134. package/dist/ui/components/ThinkingIndicator.d.ts.map +1 -1
  135. package/dist/ui/components/ThinkingIndicator.js +2 -1
  136. package/dist/ui/components/ThinkingIndicator.js.map +1 -1
  137. package/dist/ui/components/ToolExecution.d.ts +1 -0
  138. package/dist/ui/components/ToolExecution.d.ts.map +1 -1
  139. package/dist/ui/components/ToolExecution.js +44 -15
  140. package/dist/ui/components/ToolExecution.js.map +1 -1
  141. package/dist/ui/components/ToolGroupExecution.d.ts.map +1 -1
  142. package/dist/ui/components/ToolGroupExecution.js +21 -17
  143. package/dist/ui/components/ToolGroupExecution.js.map +1 -1
  144. package/dist/ui/components/ToolUseLoader.d.ts +19 -0
  145. package/dist/ui/components/ToolUseLoader.d.ts.map +1 -0
  146. package/dist/ui/components/ToolUseLoader.js +42 -0
  147. package/dist/ui/components/ToolUseLoader.js.map +1 -0
  148. package/dist/ui/components/index.d.ts +1 -1
  149. package/dist/ui/components/index.d.ts.map +1 -1
  150. package/dist/ui/components/index.js +1 -1
  151. package/dist/ui/components/index.js.map +1 -1
  152. package/dist/ui/constants/figures.d.ts +30 -0
  153. package/dist/ui/constants/figures.d.ts.map +1 -0
  154. package/dist/ui/constants/figures.js +41 -0
  155. package/dist/ui/constants/figures.js.map +1 -0
  156. package/dist/ui/hooks/useAgentLoop.d.ts +16 -1
  157. package/dist/ui/hooks/useAgentLoop.d.ts.map +1 -1
  158. package/dist/ui/hooks/useAgentLoop.js +49 -141
  159. package/dist/ui/hooks/useAgentLoop.js.map +1 -1
  160. package/dist/ui/hooks/useBlink.d.ts +11 -0
  161. package/dist/ui/hooks/useBlink.d.ts.map +1 -0
  162. package/dist/ui/hooks/useBlink.js +19 -0
  163. package/dist/ui/hooks/useBlink.js.map +1 -0
  164. package/dist/ui/hooks/useMinDisplayTime.d.ts +11 -0
  165. package/dist/ui/hooks/useMinDisplayTime.d.ts.map +1 -0
  166. package/dist/ui/hooks/useMinDisplayTime.js +34 -0
  167. package/dist/ui/hooks/useMinDisplayTime.js.map +1 -0
  168. package/dist/ui/hooks/useTerminalProgress.d.ts +2 -0
  169. package/dist/ui/hooks/useTerminalProgress.d.ts.map +1 -0
  170. package/dist/ui/hooks/useTerminalProgress.js +98 -0
  171. package/dist/ui/hooks/useTerminalProgress.js.map +1 -0
  172. package/dist/ui/hooks/useTerminalTitle.d.ts.map +1 -1
  173. package/dist/ui/hooks/useTerminalTitle.js +2 -1
  174. package/dist/ui/hooks/useTerminalTitle.js.map +1 -1
  175. package/dist/ui/spinner-frames.d.ts +1 -0
  176. package/dist/ui/spinner-frames.d.ts.map +1 -1
  177. package/dist/ui/spinner-frames.js +15 -5
  178. package/dist/ui/spinner-frames.js.map +1 -1
  179. package/dist/ui/theme/dark.json +2 -1
  180. package/dist/ui/theme/light.json +2 -1
  181. package/dist/ui/theme/theme.d.ts +1 -0
  182. package/dist/ui/theme/theme.d.ts.map +1 -1
  183. package/dist/ui/utils/markdown-cache.d.ts +12 -0
  184. package/dist/ui/utils/markdown-cache.d.ts.map +1 -0
  185. package/dist/ui/utils/markdown-cache.js +43 -0
  186. package/dist/ui/utils/markdown-cache.js.map +1 -0
  187. package/dist/ui/utils/word-diff.d.ts +11 -0
  188. package/dist/ui/utils/word-diff.d.ts.map +1 -0
  189. package/dist/ui/utils/word-diff.js +23 -0
  190. package/dist/ui/utils/word-diff.js.map +1 -0
  191. package/dist/utils/plan-steps.d.ts +41 -0
  192. package/dist/utils/plan-steps.d.ts.map +1 -0
  193. package/dist/utils/plan-steps.js +91 -0
  194. package/dist/utils/plan-steps.js.map +1 -0
  195. package/package.json +3 -3
@@ -1,4 +1,10 @@
1
- export declare function Spinner({ label }: {
1
+ interface SpinnerProps {
2
2
  label?: string;
3
- }): import("react/jsx-runtime").JSX.Element;
3
+ /** When true, the spinner transitions to the error/red color. */
4
+ isStalled?: boolean;
5
+ /** How long (in ms) the spinner has been stalled. Controls transition speed. */
6
+ stallDurationMs?: number;
7
+ }
8
+ export declare function Spinner({ label, isStalled, stallDurationMs }: SpinnerProps): import("react/jsx-runtime").JSX.Element;
9
+ export {};
4
10
  //# sourceMappingURL=Spinner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Spinner.d.ts","sourceRoot":"","sources":["../../../src/ui/components/Spinner.tsx"],"names":[],"mappings":"AAMA,wBAAgB,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,2CAUpD"}
1
+ {"version":3,"file":"Spinner.d.ts","sourceRoot":"","sources":["../../../src/ui/components/Spinner.tsx"],"names":[],"mappings":"AAyCA,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gFAAgF;IAChF,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,eAAmB,EAAE,EAAE,YAAY,2CA0C9E"}
@@ -1,13 +1,60 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import React from "react";
2
+ import React, { useRef } from "react";
3
3
  import { Text } from "ink";
4
4
  import { useTheme } from "../theme/theme.js";
5
- import { SPINNER_FRAMES, SPINNER_INTERVAL } from "../spinner-frames.js";
6
- import { useAnimationTick, deriveFrame } from "./AnimationContext.js";
7
- export function Spinner({ label }) {
5
+ import { SPINNER_FRAMES, SPINNER_INTERVAL, REDUCED_MOTION_DOT } from "../spinner-frames.js";
6
+ import { useAnimationTick, useAnimationActive, deriveFrame, useReducedMotion, TICK_INTERVAL, } from "./AnimationContext.js";
7
+ // Claude Code's error red for stall interpolation
8
+ const ERROR_RED = { r: 171, g: 43, b: 63 };
9
+ /**
10
+ * Parse a hex color string to RGB components.
11
+ */
12
+ function parseHex(hex) {
13
+ const h = hex.replace("#", "");
14
+ return {
15
+ r: parseInt(h.slice(0, 2), 16),
16
+ g: parseInt(h.slice(2, 4), 16),
17
+ b: parseInt(h.slice(4, 6), 16),
18
+ };
19
+ }
20
+ /**
21
+ * Interpolate between two RGB colors by ratio t (0–1).
22
+ */
23
+ function interpolateColor(a, b, t) {
24
+ const r = Math.round(a.r + (b.r - a.r) * t);
25
+ const g = Math.round(a.g + (b.g - a.g) * t);
26
+ const bl = Math.round(a.b + (b.b - a.b) * t);
27
+ return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${bl.toString(16).padStart(2, "0")}`;
28
+ }
29
+ export function Spinner({ label, isStalled, stallDurationMs = 0 }) {
8
30
  const theme = useTheme();
31
+ const reducedMotion = useReducedMotion();
32
+ useAnimationActive();
9
33
  const tick = useAnimationTick();
34
+ // Smoothed stall intensity via exponential lerp (matches CC: 0.1 step)
35
+ const intensityRef = useRef(0);
36
+ if (reducedMotion) {
37
+ // Static filled circle with slow dim/undim cycle (2s)
38
+ const dimCycle = Math.floor((tick * TICK_INTERVAL) / 1000) % 2;
39
+ return (_jsxs(Text, { color: theme.text, dimColor: dimCycle === 1, children: [REDUCED_MOTION_DOT, " ", label && _jsx(Text, { dimColor: true, children: label })] }));
40
+ }
10
41
  const frame = deriveFrame(tick, SPINNER_INTERVAL, SPINNER_FRAMES.length);
11
- return (_jsxs(Text, { color: theme.spinnerColor, wrap: "wrap", children: [SPINNER_FRAMES[frame], " ", label && _jsx(Text, { dimColor: true, children: label })] }));
42
+ // Stall color interpolation:
43
+ // - Stall starts after 3000ms of no tokens
44
+ // - Intensity ramps from 0 to 1 over the next 2000ms
45
+ // - Smoothed with 0.1 lerp steps
46
+ let color = theme.spinnerColor;
47
+ if (isStalled && stallDurationMs > 3000) {
48
+ const rawIntensity = Math.min((stallDurationMs - 3000) / 2000, 1);
49
+ const diff = rawIntensity - intensityRef.current;
50
+ intensityRef.current += diff * 0.1;
51
+ const baseRGB = parseHex(theme.spinnerColor);
52
+ color = interpolateColor(baseRGB, ERROR_RED, intensityRef.current);
53
+ }
54
+ else {
55
+ // Decay back toward 0 when not stalled
56
+ intensityRef.current *= 0.9;
57
+ }
58
+ return (_jsxs(Text, { color: color, wrap: "wrap", children: [SPINNER_FRAMES[frame], " ", label && _jsx(Text, { dimColor: true, children: label })] }));
12
59
  }
13
60
  //# sourceMappingURL=Spinner.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Spinner.js","sourceRoot":"","sources":["../../../src/ui/components/Spinner.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC3B,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEtE,MAAM,UAAU,OAAO,CAAC,EAAE,KAAK,EAAsB;IACnD,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAC;IAChC,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,EAAE,gBAAgB,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IAEzE,OAAO,CACL,MAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,YAAY,EAAE,IAAI,EAAC,MAAM,aACzC,cAAc,CAAC,KAAK,CAAC,OAAG,KAAK,IAAI,KAAC,IAAI,IAAC,QAAQ,kBAAE,KAAK,GAAQ,IAC1D,CACR,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"Spinner.js","sourceRoot":"","sources":["../../../src/ui/components/Spinner.tsx"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import React from "react";
1
2
  interface StreamingAreaProps {
2
3
  isRunning: boolean;
3
4
  streamingText: string;
@@ -6,6 +7,6 @@ interface StreamingAreaProps {
6
7
  thinkingMs?: number;
7
8
  planMode?: boolean;
8
9
  }
9
- export declare function StreamingArea({ isRunning, streamingText, streamingThinking, showThinking, thinkingMs, planMode, }: StreamingAreaProps): import("react/jsx-runtime").JSX.Element | null;
10
+ export declare const StreamingArea: React.NamedExoticComponent<StreamingAreaProps>;
10
11
  export {};
11
12
  //# sourceMappingURL=StreamingArea.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"StreamingArea.d.ts","sourceRoot":"","sources":["../../../src/ui/components/StreamingArea.tsx"],"names":[],"mappings":"AAUA,UAAU,kBAAkB;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,YAAmB,EACnB,UAAU,EACV,QAAQ,GACT,EAAE,kBAAkB,kDA0EpB"}
1
+ {"version":3,"file":"StreamingArea.d.ts","sourceRoot":"","sources":["../../../src/ui/components/StreamingArea.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAwB,MAAM,OAAO,CAAC;AAY7C,UAAU,kBAAkB;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,aAAa,gDA6CxB,CAAC"}
@@ -1,54 +1,19 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import React, { useState, useEffect, useRef } from "react";
2
+ import React, { memo, useMemo } from "react";
3
3
  import { Text, Box } from "ink";
4
4
  import { useTheme } from "../theme/theme.js";
5
- import { Markdown } from "./Markdown.js";
5
+ import { StreamingMarkdown } from "./Markdown.js";
6
6
  import { ThinkingBlock } from "./ThinkingBlock.js";
7
7
  import { useTerminalSize } from "../hooks/useTerminalSize.js";
8
- // "⏺ " prefix = 2 chars
8
+ import { stripDoneMarkers } from "../../utils/plan-steps.js";
9
+ import { BLACK_CIRCLE, PLAN_SYMBOL } from "../constants/figures.js";
10
+ // BLACK_CIRCLE + " " = 2 chars
9
11
  const PREFIX_WIDTH = 2;
10
- export function StreamingArea({ isRunning, streamingText, streamingThinking, showThinking = true, thinkingMs, planMode, }) {
12
+ export const StreamingArea = memo(function StreamingArea({ isRunning, streamingText, streamingThinking, showThinking = true, thinkingMs, planMode, }) {
11
13
  const theme = useTheme();
12
14
  const { columns } = useTerminalSize();
13
15
  const contentWidth = Math.max(10, columns - PREFIX_WIDTH);
14
- // Blinking cursor only blink when text is NOT actively changing.
15
- // While text streams, the reveal animation already provides visual feedback,
16
- // so we show a static cursor and avoid the extra re-renders from blinking.
17
- const [cursorVisible, setCursorVisible] = useState(true);
18
- const prevTextRef = useRef(streamingText);
19
- const staleTimerRef = useRef(null);
20
- // Track whether text is actively changing. The stale flag is promoted to
21
- // React state so it can gate the blink interval — when text is actively
22
- // streaming we skip the blink entirely (no interval running = no extra
23
- // re-renders).
24
- const [textStale, setTextStale] = useState(false);
25
- useEffect(() => {
26
- if (streamingText !== prevTextRef.current) {
27
- prevTextRef.current = streamingText;
28
- // Only trigger a re-render if we're transitioning from stale → active
29
- if (textStale)
30
- setTextStale(false);
31
- if (staleTimerRef.current)
32
- clearTimeout(staleTimerRef.current);
33
- staleTimerRef.current = setTimeout(() => {
34
- setTextStale(true);
35
- }, 600);
36
- }
37
- return () => {
38
- if (staleTimerRef.current)
39
- clearTimeout(staleTimerRef.current);
40
- };
41
- }, [streamingText]); // textStale intentionally omitted — we only read it to gate the setState
42
- useEffect(() => {
43
- if (!isRunning || !textStale) {
44
- setCursorVisible(true);
45
- return;
46
- }
47
- const timer = setInterval(() => {
48
- setCursorVisible((v) => !v);
49
- }, 800);
50
- return () => clearInterval(timer);
51
- }, [isRunning, textStale]);
16
+ const displayText = useMemo(() => (streamingText ? stripDoneMarkers(streamingText) : ""), [streamingText]);
52
17
  // Return null when there is nothing to display. Previously this kept an
53
18
  // empty <Box marginTop={1}> alive while isRunning was true, adding phantom
54
19
  // height to Ink's live area. When isRunning later flipped to false in a
@@ -58,6 +23,6 @@ export function StreamingArea({ isRunning, streamingText, streamingThinking, sho
58
23
  return null;
59
24
  if (!isRunning && !streamingText)
60
25
  return null;
61
- return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [showThinking && streamingThinking && (_jsx(ThinkingBlock, { text: streamingThinking, streaming: true, durationMs: thinkingMs })), streamingText && (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: PREFIX_WIDTH, flexShrink: 0, children: _jsx(Text, { color: planMode ? theme.planPrimary : theme.primary, children: planMode ? " " : " " }) }), _jsx(Box, { flexDirection: "column", flexGrow: 1, width: contentWidth, children: _jsx(Markdown, { children: streamingText.trimStart() + (isRunning && cursorVisible ? "\u258D" : "") }) })] }))] }));
62
- }
26
+ return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [showThinking && streamingThinking && (_jsx(ThinkingBlock, { text: streamingThinking, streaming: true, durationMs: thinkingMs })), displayText && (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: PREFIX_WIDTH, flexShrink: 0, children: _jsx(Text, { color: planMode ? theme.planPrimary : theme.primary, children: planMode ? PLAN_SYMBOL + " " : BLACK_CIRCLE + " " }) }), _jsx(Box, { flexDirection: "column", flexGrow: 1, width: contentWidth, children: _jsx(StreamingMarkdown, { width: contentWidth, children: displayText.trimStart() }) })] }))] }));
27
+ });
63
28
  //# sourceMappingURL=StreamingArea.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"StreamingArea.js","sourceRoot":"","sources":["../../../src/ui/components/StreamingArea.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"StreamingArea.js","sourceRoot":"","sources":["../../../src/ui/components/StreamingArea.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEpE,+BAA+B;AAC/B,MAAM,YAAY,GAAG,CAAC,CAAC;AAWvB,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,aAAa,CAAC,EACvD,SAAS,EACT,aAAa,EACb,iBAAiB,EACjB,YAAY,GAAG,IAAI,EACnB,UAAU,EACV,QAAQ,GACW;IACnB,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,MAAM,EAAE,OAAO,EAAE,GAAG,eAAe,EAAE,CAAC;IACtC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,GAAG,YAAY,CAAC,CAAC;IAC1D,MAAM,WAAW,GAAG,OAAO,CACzB,GAAG,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAC5D,CAAC,aAAa,CAAC,CAChB,CAAC;IAEF,yEAAyE;IACzE,2EAA2E;IAC3E,yEAAyE;IACzE,oEAAoE;IACpE,yEAAyE;IACzE,IAAI,CAAC,aAAa,IAAI,CAAC,iBAAiB;QAAE,OAAO,IAAI,CAAC;IACtD,IAAI,CAAC,SAAS,IAAI,CAAC,aAAa;QAAE,OAAO,IAAI,CAAC;IAE9C,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,SAAS,EAAE,CAAC,aACrC,YAAY,IAAI,iBAAiB,IAAI,CACpC,KAAC,aAAa,IAAC,IAAI,EAAE,iBAAiB,EAAE,SAAS,QAAC,UAAU,EAAE,UAAU,GAAI,CAC7E,EAEA,WAAW,IAAI,CACd,MAAC,GAAG,IAAC,aAAa,EAAC,KAAK,aACtB,KAAC,GAAG,IAAC,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC,YACrC,KAAC,IAAI,IAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,YACtD,QAAQ,CAAC,CAAC,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC,CAAC,YAAY,GAAG,GAAG,GAC7C,GACH,EACN,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,YAAY,YAE1D,KAAC,iBAAiB,IAAC,KAAK,EAAE,YAAY,YAAG,WAAW,CAAC,SAAS,EAAE,GAAqB,GACjF,IACF,CACP,IACG,CACP,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"SubAgentPanel.d.ts","sourceRoot":"","sources":["../../../src/ui/components/SubAgentPanel.tsx"],"names":[],"mappings":"AAOA,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IACjD,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,kBAAkB;IAC1B,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AA4HD,wBAAgB,aAAa,CAAC,EAAE,MAAM,EAAE,OAAe,EAAE,EAAE,kBAAkB,kDAwC5E"}
1
+ {"version":3,"file":"SubAgentPanel.d.ts","sourceRoot":"","sources":["../../../src/ui/components/SubAgentPanel.tsx"],"names":[],"mappings":"AAQA,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IACjD,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,kBAAkB;IAC1B,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AA6HD,wBAAgB,aAAa,CAAC,EAAE,MAAM,EAAE,OAAe,EAAE,EAAE,kBAAkB,kDAuC5E"}
@@ -3,8 +3,9 @@ import React from "react";
3
3
  import { Text, Box } from "ink";
4
4
  import { useTheme } from "../theme/theme.js";
5
5
  import { SPINNER_FRAMES, SPINNER_INTERVAL } from "../spinner-frames.js";
6
- import { useAnimationTick, deriveFrame } from "./AnimationContext.js";
6
+ import { useAnimationTick, useAnimationActive, deriveFrame } from "./AnimationContext.js";
7
7
  import { useTerminalSize } from "../hooks/useTerminalSize.js";
8
+ import { ToolUseLoader } from "./ToolUseLoader.js";
8
9
  function formatTokens(n) {
9
10
  if (n >= 1_000_000)
10
11
  return `${(n / 1_000_000).toFixed(1)}M`;
@@ -28,6 +29,7 @@ const AgentRow = React.memo(function AgentRow({ agent, isLast, aborted, columns,
28
29
  const theme = useTheme();
29
30
  const isRunning = agent.status === "running" && !aborted;
30
31
  // Derive spinner frame from global animation tick
32
+ useAnimationActive();
31
33
  const tick = useAnimationTick();
32
34
  const frame = deriveFrame(tick, SPINNER_INTERVAL, SPINNER_FRAMES.length);
33
35
  const branch = isLast ? "└─" : "├─";
@@ -62,13 +64,12 @@ const AgentRow = React.memo(function AgentRow({ agent, isLast, aborted, columns,
62
64
  return false;
63
65
  });
64
66
  export function SubAgentPanel({ agents, aborted = false }) {
65
- const theme = useTheme();
66
67
  const { columns } = useTerminalSize();
67
68
  if (agents.length === 0)
68
69
  return null;
69
70
  const runningCount = agents.filter((a) => a.status === "running").length;
70
71
  const allDone = runningCount === 0;
71
- // "⏺ " prefix = 2 chars — content area gets the rest
72
+ // ToolUseLoader minWidth={2} = 2 chars
72
73
  const HEADER_PREFIX = 2;
73
74
  const contentColumns = Math.max(10, columns - HEADER_PREFIX);
74
75
  const headerText = aborted
@@ -76,6 +77,7 @@ export function SubAgentPanel({ agents, aborted = false }) {
76
77
  : allDone
77
78
  ? `${agents.length} agent${agents.length !== 1 ? "s" : ""} completed`
78
79
  : `${agents.length} agent${agents.length !== 1 ? "s" : ""} launched`;
79
- return (_jsxs(Box, { marginTop: 1, flexDirection: "row", children: [_jsx(Box, { width: HEADER_PREFIX, flexShrink: 0, children: _jsx(Text, { color: theme.primary, children: "" }) }), _jsxs(Box, { flexDirection: "column", flexGrow: 1, width: contentColumns, children: [_jsx(Text, { bold: true, wrap: "wrap", children: headerText }), agents.map((agent, i) => (_jsx(AgentRow, { agent: agent, isLast: i === agents.length - 1, aborted: aborted, columns: contentColumns }, agent.toolCallId)))] })] }));
80
+ const dotStatus = aborted ? "error" : allDone ? "done" : "running";
81
+ return (_jsxs(Box, { marginTop: 1, flexDirection: "row", children: [_jsx(ToolUseLoader, { status: dotStatus }), _jsxs(Box, { flexDirection: "column", flexGrow: 1, width: contentColumns, children: [_jsx(Text, { bold: true, wrap: "wrap", children: headerText }), agents.map((agent, i) => (_jsx(AgentRow, { agent: agent, isLast: i === agents.length - 1, aborted: aborted, columns: contentColumns }, agent.toolCallId)))] })] }));
80
82
  }
81
83
  //# sourceMappingURL=SubAgentPanel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SubAgentPanel.js","sourceRoot":"","sources":["../../../src/ui/components/SubAgentPanel.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SubAgentPanel.js","sourceRoot":"","sources":["../../../src/ui/components/SubAgentPanel.tsx"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import React from "react";
1
2
  interface ThinkingBlockProps {
2
3
  text: string;
3
4
  durationMs?: number;
@@ -6,6 +7,6 @@ interface ThinkingBlockProps {
6
7
  /** Start collapsed (default true for completed, ignored when streaming) */
7
8
  defaultCollapsed?: boolean;
8
9
  }
9
- export declare function ThinkingBlock({ text, durationMs, streaming, defaultCollapsed, }: ThinkingBlockProps): import("react/jsx-runtime").JSX.Element | null;
10
+ export declare const ThinkingBlock: React.NamedExoticComponent<ThinkingBlockProps>;
10
11
  export {};
11
12
  //# sourceMappingURL=ThinkingBlock.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ThinkingBlock.d.ts","sourceRoot":"","sources":["../../../src/ui/components/ThinkingBlock.tsx"],"names":[],"mappings":"AAIA,UAAU,kBAAkB;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAaD,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,UAAU,EACV,SAAiB,EACjB,gBAAuB,GACxB,EAAE,kBAAkB,kDA6DpB"}
1
+ {"version":3,"file":"ThinkingBlock.d.ts","sourceRoot":"","sources":["../../../src/ui/components/ThinkingBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAInD,UAAU,kBAAkB;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,2EAA2E;IAC3E,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAaD,eAAO,MAAM,aAAa,gDAkExB,CAAC"}
@@ -12,7 +12,7 @@ function formatThinkingDuration(ms) {
12
12
  }
13
13
  const ACCENT_COLOR = "#818cf8";
14
14
  const BORDER_COLOR = "#4b5563";
15
- export function ThinkingBlock({ text, durationMs, streaming = false, defaultCollapsed = true, }) {
15
+ export const ThinkingBlock = React.memo(function ThinkingBlock({ text, durationMs, streaming = false, defaultCollapsed = true, }) {
16
16
  const theme = useTheme();
17
17
  const [collapsed, setCollapsed] = useState(!streaming && defaultCollapsed);
18
18
  // When streaming finishes (streaming goes from true to false), auto-collapse
@@ -39,5 +39,5 @@ export function ThinkingBlock({ text, durationMs, streaming = false, defaultColl
39
39
  const showContent = !streaming && !collapsed;
40
40
  const chevron = showContent ? " ▼" : " ▶";
41
41
  return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: ACCENT_COLOR, children: "💭 " }), _jsx(Text, { color: theme.textMuted, italic: true, children: headerText }), !streaming && _jsx(Text, { color: theme.textDim, children: chevron })] }), showContent && (_jsx(Box, { marginLeft: 1, borderStyle: "single", borderLeft: true, borderRight: false, borderTop: false, borderBottom: false, borderLeftColor: streaming ? ACCENT_COLOR : BORDER_COLOR, paddingLeft: 1, children: _jsx(Text, { color: theme.textDim, wrap: "wrap", children: text }) }))] }));
42
- }
42
+ });
43
43
  //# sourceMappingURL=ThinkingBlock.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ThinkingBlock.js","sourceRoot":"","sources":["../../../src/ui/components/ThinkingBlock.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ThinkingBlock.js","sourceRoot":"","sources":["../../../src/ui/components/ThinkingBlock.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAW7C,SAAS,sBAAsB,CAAC,EAAU;IACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IACvC,IAAI,QAAQ,GAAG,EAAE;QAAE,OAAO,GAAG,QAAQ,GAAG,CAAC;IACzC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,EAAE,CAAC,CAAC;IACtC,MAAM,GAAG,GAAG,QAAQ,GAAG,EAAE,CAAC;IAC1B,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC;AACjD,CAAC;AAED,MAAM,YAAY,GAAG,SAAS,CAAC;AAC/B,MAAM,YAAY,GAAG,SAAS,CAAC;AAE/B,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,aAAa,CAAC,EAC7D,IAAI,EACJ,UAAU,EACV,SAAS,GAAG,KAAK,EACjB,gBAAgB,GAAG,IAAI,GACJ;IACnB,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,CAAC,SAAS,IAAI,gBAAgB,CAAC,CAAC;IAE3E,6EAA6E;IAC7E,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC5D,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,YAAY,IAAI,CAAC,SAAS,EAAE,CAAC;YAC/B,YAAY,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;QACD,eAAe,CAAC,SAAS,CAAC,CAAC;IAC7B,CAAC,EAAE,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC;IAE9B,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAEvB,MAAM,aAAa,GACjB,UAAU,IAAI,IAAI,IAAI,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACnF,MAAM,UAAU,GAAG,SAAS;QAC1B,CAAC,CAAC,aAAa;YACb,CAAC,CAAC,gBAAgB,aAAa,GAAG;YAClC,CAAC,CAAC,aAAa;QACjB,CAAC,CAAC,aAAa;YACb,CAAC,CAAC,eAAe,aAAa,EAAE;YAChC,CAAC,CAAC,SAAS,CAAC;IAEhB,wEAAwE;IACxE,4EAA4E;IAC5E,wEAAwE;IACxE,MAAM,WAAW,GAAG,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC;IAC7C,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAE1C,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,YAAY,EAAE,CAAC,aAEzC,MAAC,GAAG,eACF,KAAC,IAAI,IAAC,KAAK,EAAE,YAAY,YAAG,KAAK,GAAQ,EACzC,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,kBACjC,UAAU,GACN,EACN,CAAC,SAAS,IAAI,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,OAAO,YAAG,OAAO,GAAQ,IACvD,EAGL,WAAW,IAAI,CACd,KAAC,GAAG,IACF,UAAU,EAAE,CAAC,EACb,WAAW,EAAC,QAAQ,EACpB,UAAU,QACV,WAAW,EAAE,KAAK,EAClB,SAAS,EAAE,KAAK,EAChB,YAAY,EAAE,KAAK,EACnB,eAAe,EAAE,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,EACxD,WAAW,EAAE,CAAC,YAEd,KAAC,IAAI,IAAC,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAC,MAAM,YACpC,IAAI,GACA,GACH,CACP,IACG,CACP,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ThinkingIndicator.d.ts","sourceRoot":"","sources":["../../../src/ui/components/ThinkingIndicator.tsx"],"names":[],"mappings":"AAgJA,UAAU,sBAAsB;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,iBAAiB,CAAC,EAAE,WAAgB,EAAE,EAAE,sBAAsB,2CA8B7E"}
1
+ {"version":3,"file":"ThinkingIndicator.d.ts","sourceRoot":"","sources":["../../../src/ui/components/ThinkingIndicator.tsx"],"names":[],"mappings":"AAgJA,UAAU,sBAAsB;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,iBAAiB,CAAC,EAAE,WAAgB,EAAE,EAAE,sBAAsB,2CA+B7E"}
@@ -3,7 +3,7 @@ import React, { useMemo } from "react";
3
3
  import { Text, Box } from "ink";
4
4
  import { useTheme } from "../theme/theme.js";
5
5
  import { SPINNER_FRAMES, SPINNER_INTERVAL } from "../spinner-frames.js";
6
- import { useAnimationTick, deriveFrame } from "./AnimationContext.js";
6
+ import { useAnimationTick, useAnimationActive, deriveFrame } from "./AnimationContext.js";
7
7
  // ── Color pulse cycle ─────────────────────────────────────
8
8
  const PULSE_COLORS = [
9
9
  "#60a5fa", // blue
@@ -126,6 +126,7 @@ function shuffleArray(arr) {
126
126
  }
127
127
  export function ThinkingIndicator({ userMessage = "" }) {
128
128
  const theme = useTheme();
129
+ useAnimationActive();
129
130
  const tick = useAnimationTick();
130
131
  // Derive all animation frames from the single global tick
131
132
  const spinnerFrame = deriveFrame(tick, SPINNER_INTERVAL, SPINNER_FRAMES.length);
@@ -1 +1 @@
1
- {"version":3,"file":"ThinkingIndicator.js","sourceRoot":"","sources":["../../../src/ui/components/ThinkingIndicator.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ThinkingIndicator.js","sourceRoot":"","sources":["../../../src/ui/components/ThinkingIndicator.tsx"],"names":[],"mappings":"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"}
@@ -9,6 +9,7 @@ interface ToolDoneProps {
9
9
  args: Record<string, unknown>;
10
10
  result: string;
11
11
  isError: boolean;
12
+ details?: unknown;
12
13
  }
13
14
  type ToolExecutionProps = ToolRunningProps | ToolDoneProps;
14
15
  export declare function ToolExecution(props: ToolExecutionProps): import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"ToolExecution.d.ts","sourceRoot":"","sources":["../../../src/ui/components/ToolExecution.tsx"],"names":[],"mappings":"AAoBA,UAAU,gBAAgB;IACxB,MAAM,EAAE,SAAS,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,UAAU,aAAa;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,KAAK,kBAAkB,GAAG,gBAAgB,GAAG,aAAa,CAAC;AAK3D,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,2CAgItD"}
1
+ {"version":3,"file":"ToolExecution.d.ts","sourceRoot":"","sources":["../../../src/ui/components/ToolExecution.tsx"],"names":[],"mappings":"AAwBA,UAAU,gBAAgB;IACxB,MAAM,EAAE,SAAS,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,UAAU,aAAa;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,KAAK,kBAAkB,GAAG,gBAAgB,GAAG,aAAa,CAAC;AAK3D,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,2CA8HtD"}
@@ -3,13 +3,17 @@ import React, { memo } from "react";
3
3
  import { Text, Box } from "ink";
4
4
  import { useTheme } from "../theme/theme.js";
5
5
  import { Spinner } from "./Spinner.js";
6
+ import { ToolUseLoader } from "./ToolUseLoader.js";
7
+ import { MessageResponse } from "./MessageResponse.js";
6
8
  import { highlightCode, langFromPath } from "../utils/highlight.js";
7
9
  import { useTerminalSize } from "../hooks/useTerminalSize.js";
10
+ import { computeWordDiff } from "../utils/word-diff.js";
11
+ import { DASHED_H } from "../constants/figures.js";
8
12
  const MAX_OUTPUT_LINES = 4; // max lines shown per tool result
9
- // "⏺ " prefix = 2 chars
13
+ // ToolUseLoader minWidth={2} = 2 chars
10
14
  const HEADER_PREFIX = 2;
11
- // Body is indented paddingLeft={2} + "⎿ " or " " = 3 chars
12
- const BODY_PREFIX = 5;
15
+ // MessageResponse gutter: " ⎿ " = 6 chars
16
+ const BODY_PREFIX = 6;
13
17
  /** Truncate a line so it fits within ~1 terminal row. */
14
18
  function truncateLine(line, cols, reservedChars = 6) {
15
19
  const max = cols - reservedChars;
@@ -21,36 +25,40 @@ export function ToolExecution(props) {
21
25
  const theme = useTheme();
22
26
  const { columns } = useTerminalSize();
23
27
  if (props.status === "running") {
24
- // Compact tools get a summary label while running
28
+ // Compact tools get a blinking dot + summary label
25
29
  if (COMPACT_TOOLS.has(props.name)) {
26
30
  const summary = getCompactRunningLabel(props.name, props.args);
27
- return (_jsx(Box, { marginTop: 1, children: _jsx(Spinner, { label: `${summary} (ctrl+o to expand)` }) }));
31
+ return (_jsxs(Box, { marginTop: 1, flexDirection: "row", children: [_jsx(ToolUseLoader, { status: "running" }), _jsx(Text, { color: theme.toolName, bold: true, children: summary }), _jsx(Text, { color: theme.textDim, children: " (ctrl+o to expand)" })] }));
28
32
  }
33
+ // Non-compact tools keep the sparkle spinner with a blinking dot prefix
29
34
  const { label, detail } = getToolHeaderParts(props.name, props.args);
30
- return (_jsx(Box, { marginTop: 1, children: _jsx(Spinner, { label: detail ? `${label}(${detail})` : label }) }));
35
+ return (_jsxs(Box, { marginTop: 1, flexDirection: "row", children: [_jsx(ToolUseLoader, { status: "running" }), _jsx(Spinner, { label: detail ? `${label}(${detail})` : label })] }));
31
36
  }
32
- const { name, args, result, isError } = props;
37
+ const { name, args, result, isError, details } = props;
33
38
  const headerContentWidth = Math.max(10, columns - HEADER_PREFIX);
34
39
  const bodyContentWidth = Math.max(10, columns - BODY_PREFIX);
35
40
  // Compact tools — one-line summary, no output content
36
41
  if (COMPACT_TOOLS.has(name) && !isError) {
37
42
  const summary = getCompactDoneLabel(name, args, result);
38
- return (_jsxs(Box, { marginTop: 1, flexDirection: "row", children: [_jsx(Box, { width: HEADER_PREFIX, flexShrink: 0, children: _jsx(Text, { color: theme.primary, children: "" }) }), _jsx(Box, { flexGrow: 1, width: headerContentWidth, children: _jsx(Text, { bold: true, color: theme.toolName, wrap: "wrap", children: summary }) })] }));
43
+ return (_jsxs(Box, { marginTop: 1, flexDirection: "row", children: [_jsx(ToolUseLoader, { status: "done" }), _jsx(Box, { flexGrow: 1, width: headerContentWidth, children: _jsx(Text, { bold: true, color: theme.toolName, wrap: "wrap", children: summary }) })] }));
39
44
  }
40
- const isDiff = name === "edit" && !isError && result.includes("---");
45
+ // Extract diff from details (structured result) or fall back to result string
46
+ const editDetails = details;
47
+ const diffText = editDetails?.diff ?? (result.includes("---") ? result : undefined);
48
+ const isDiff = name === "edit" && !isError && !!diffText;
41
49
  const { label, detail } = getToolHeaderParts(name, args);
42
50
  const body = isDiff
43
- ? buildDiffBody(result, args, columns)
51
+ ? buildDiffBody(diffText, args, columns)
44
52
  : buildResultBody(name, result, isError, columns);
45
53
  const headerColor = isError ? theme.toolError : theme.toolName;
46
54
  // Compact display — no body to show, but show inline summary
47
55
  if (!body) {
48
56
  const inline = getInlineSummary(name, result, isError);
49
- return (_jsxs(Box, { marginTop: 1, flexDirection: "row", children: [_jsx(Box, { width: HEADER_PREFIX, flexShrink: 0, children: _jsx(Text, { color: theme.primary, children: "" }) }), _jsx(Box, { flexGrow: 1, width: headerContentWidth, children: _jsxs(Text, { wrap: "wrap", children: [_jsx(Text, { bold: true, color: headerColor, children: label }), detail && (_jsxs(Text, { color: theme.text, children: ["(", detail, ")"] })), inline && _jsxs(Text, { color: theme.textDim, children: [" ", inline] })] }) })] }));
57
+ return (_jsxs(Box, { marginTop: 1, flexDirection: "row", children: [_jsx(ToolUseLoader, { status: isError ? "error" : "done" }), _jsx(Box, { flexGrow: 1, width: headerContentWidth, children: _jsxs(Text, { wrap: "wrap", children: [_jsx(Text, { bold: true, color: headerColor, children: label }), detail && (_jsxs(Text, { color: theme.text, children: ["(", detail, ")"] })), inline && _jsxs(Text, { color: theme.textDim, children: [" ", inline] })] }) })] }));
50
58
  }
51
59
  const { lines, totalLines } = body;
52
60
  const hiddenCount = totalLines - lines.length;
53
- return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: HEADER_PREFIX, flexShrink: 0, children: _jsx(Text, { color: theme.primary, children: "" }) }), _jsx(Box, { flexGrow: 1, width: headerContentWidth, children: _jsxs(Text, { wrap: "wrap", children: [_jsx(Text, { bold: true, color: headerColor, children: label }), detail && (_jsxs(Text, { color: theme.text, children: ["(", detail, ")"] }))] }) })] }), _jsxs(Box, { flexDirection: "column", paddingLeft: 2, children: [lines.map((line, i) => (_jsxs(Box, { flexDirection: "row", children: [_jsx(Box, { width: 3, flexShrink: 0, children: _jsx(Text, { color: theme.textDim, children: i === 0 ? "⎿ " : " " }) }), _jsx(Box, { flexGrow: 1, width: bodyContentWidth, children: line })] }, i))), hiddenCount > 0 && (_jsx(Box, { children: _jsxs(Text, { color: theme.textDim, wrap: "wrap", children: [" … +", hiddenCount, " lines (ctrl+o to expand)"] }) }))] })] }));
61
+ return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Box, { flexDirection: "row", children: [_jsx(ToolUseLoader, { status: isError ? "error" : "done" }), _jsx(Box, { flexGrow: 1, width: headerContentWidth, children: _jsxs(Text, { wrap: "wrap", children: [_jsx(Text, { bold: true, color: headerColor, children: label }), detail && (_jsxs(Text, { color: theme.text, children: ["(", detail, ")"] }))] }) })] }), _jsx(MessageResponse, { children: _jsxs(Box, { flexDirection: "column", children: [lines.map((line, i) => (_jsx(Box, { flexGrow: 1, width: bodyContentWidth, children: line }, i))), hiddenCount > 0 && (_jsxs(Text, { color: theme.textDim, wrap: "wrap", children: ["… +", hiddenCount, " lines (ctrl+o to expand)"] }))] }) })] }));
54
62
  }
55
63
  // ── Compact tool labels ─────────────────────────────────────
56
64
  function getCompactRunningLabel(name, _args) {
@@ -283,6 +291,17 @@ function buildDiffBody(result, args, _columns) {
283
291
  const startIdx = Math.max(0, firstChangeIdx - 2);
284
292
  const endIdx = Math.min(numbered.length, lastChangeIdx + 3);
285
293
  const focused = numbered.slice(startIdx, endIdx);
294
+ // Compute word-level diffs for adjacent remove/add pairs
295
+ for (let i = 0; i < focused.length - 1; i++) {
296
+ if (focused[i].type === "remove" && focused[i + 1].type === "add") {
297
+ const segments = computeWordDiff(focused[i].content, focused[i + 1].content);
298
+ focused[i] = { ...focused[i], wordSegments: segments.filter((s) => s.type !== "added") };
299
+ focused[i + 1] = {
300
+ ...focused[i + 1],
301
+ wordSegments: segments.filter((s) => s.type !== "removed"),
302
+ };
303
+ }
304
+ }
286
305
  // Highlight context lines using file extension
287
306
  const filePath = String(args?.file_path ?? "");
288
307
  const lang = langFromPath(filePath);
@@ -291,10 +310,12 @@ function buildDiffBody(result, args, _columns) {
291
310
  const padWidth = String(maxLineNo).length;
292
311
  const displayLines = highlighted.slice(0, MAX_OUTPUT_LINES);
293
312
  const rendered = displayLines.map((line, i) => (_jsx(DiffLine, { line: line, padWidth: padWidth }, i)));
313
+ // Wrap diff lines in a dashed border frame (top/bottom only)
314
+ const diffFrame = (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "#4b5563", children: DASHED_H.repeat(40) }), rendered, _jsx(Text, { color: "#4b5563", children: DASHED_H.repeat(40) })] }, "diff-frame"));
294
315
  return {
295
316
  lines: [
296
317
  _jsx(Text, { color: "#9ca3af", children: summaryText }, "summary"),
297
- ...rendered,
318
+ diffFrame,
298
319
  ],
299
320
  totalLines: focused.length + 1,
300
321
  };
@@ -412,10 +433,18 @@ function buildResultBody(name, result, isError, columns) {
412
433
  const DiffLine = memo(function DiffLine({ line, padWidth, }) {
413
434
  const lineNo = String(line.lineNo).padStart(padWidth, " ");
414
435
  if (line.type === "add") {
415
- return (_jsxs(Text, { backgroundColor: "#16a34a", color: "#ffffff", children: [lineNo, " ", line.content] }));
436
+ const bgColor = "#16a34a";
437
+ const wordHighlight = "#bbf7d0"; // brighter green for changed words
438
+ return (_jsxs(Text, { backgroundColor: bgColor, color: "#ffffff", children: [lineNo, " ", line.wordSegments
439
+ ? line.wordSegments.map((seg, i) => seg.type === "added" ? (_jsx(Text, { color: wordHighlight, bold: true, children: seg.text }, i)) : (_jsx(Text, { children: seg.text }, i)))
440
+ : line.content] }));
416
441
  }
417
442
  if (line.type === "remove") {
418
- return (_jsxs(Text, { backgroundColor: "#dc2626", color: "#ffffff", children: [lineNo, " ", line.content] }));
443
+ const bgColor = "#dc2626";
444
+ const wordHighlight = "#fecaca"; // brighter red for changed words
445
+ return (_jsxs(Text, { backgroundColor: bgColor, color: "#ffffff", children: [lineNo, " ", line.wordSegments
446
+ ? line.wordSegments.map((seg, i) => seg.type === "removed" ? (_jsx(Text, { color: wordHighlight, bold: true, children: seg.text }, i)) : (_jsx(Text, { children: seg.text }, i)))
447
+ : line.content] }));
419
448
  }
420
449
  return (_jsxs(Text, { children: [_jsxs(Text, { color: "#6b7280", children: [lineNo, " "] }), line.content] }));
421
450
  });