lsd-pi 1.3.2 → 1.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/dist/cli.js +2 -1
  2. package/dist/lsd-settings-manager.d.ts +2 -0
  3. package/dist/lsd-settings-manager.js +5 -0
  4. package/dist/resource-loader.js +33 -3
  5. package/dist/resources/extensions/browser-tools/tools/codegen.js +5 -5
  6. package/dist/resources/extensions/browser-tools/tools/navigation.js +107 -178
  7. package/dist/resources/extensions/browser-tools/tools/network-mock.js +112 -167
  8. package/dist/resources/extensions/browser-tools/tools/pages.js +182 -234
  9. package/dist/resources/extensions/browser-tools/tools/refs.js +202 -461
  10. package/dist/resources/extensions/browser-tools/tools/session.js +176 -323
  11. package/dist/resources/extensions/browser-tools/tools/state-persistence.js +91 -154
  12. package/dist/resources/extensions/browser-tools/utils.js +1 -1
  13. package/dist/resources/extensions/cache-timer/index.js +3 -2
  14. package/dist/resources/extensions/slash-commands/extension-manifest.json +2 -2
  15. package/dist/resources/extensions/slash-commands/fast.js +73 -0
  16. package/dist/resources/extensions/slash-commands/index.js +2 -0
  17. package/dist/resources/extensions/slash-commands/plan.js +37 -12
  18. package/dist/resources/extensions/subagent/background-job-manager.js +13 -0
  19. package/dist/resources/extensions/subagent/in-process-runner.js +387 -0
  20. package/dist/resources/extensions/subagent/index.js +278 -626
  21. package/dist/resources/extensions/subagent/legacy-runner.js +503 -0
  22. package/dist/resources/extensions/voice/index.js +96 -36
  23. package/dist/resources/extensions/voice/push-to-talk.js +26 -0
  24. package/dist/welcome-screen.js +2 -2
  25. package/package.json +1 -1
  26. package/packages/pi-agent-core/dist/agent.d.ts +19 -0
  27. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  28. package/packages/pi-agent-core/dist/agent.js +16 -0
  29. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  30. package/packages/pi-agent-core/src/agent.ts +32 -2
  31. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts +34 -1
  32. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  33. package/packages/pi-ai/dist/providers/openai-codex-responses.js +32 -4
  34. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  35. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +127 -16
  36. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -1
  37. package/packages/pi-ai/dist/providers/openai-responses.d.ts +8 -1
  38. package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
  39. package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.d.ts +2 -0
  40. package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.d.ts.map +1 -0
  41. package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.js +67 -0
  42. package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.js.map +1 -0
  43. package/packages/pi-ai/dist/providers/openai-responses.js +21 -3
  44. package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
  45. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  46. package/packages/pi-ai/dist/providers/simple-options.js +2 -0
  47. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  48. package/packages/pi-ai/dist/types.d.ts +5 -0
  49. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  50. package/packages/pi-ai/dist/types.js.map +1 -1
  51. package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +143 -20
  52. package/packages/pi-ai/src/providers/openai-codex-responses.ts +47 -4
  53. package/packages/pi-ai/src/providers/openai-responses.fast-mode.test.ts +73 -0
  54. package/packages/pi-ai/src/providers/openai-responses.ts +26 -3
  55. package/packages/pi-ai/src/providers/simple-options.ts +2 -0
  56. package/packages/pi-ai/src/types.ts +5 -0
  57. package/packages/pi-coding-agent/dist/core/keybindings.d.ts +1 -1
  58. package/packages/pi-coding-agent/dist/core/keybindings.d.ts.map +1 -1
  59. package/packages/pi-coding-agent/dist/core/keybindings.js +2 -0
  60. package/packages/pi-coding-agent/dist/core/keybindings.js.map +1 -1
  61. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  62. package/packages/pi-coding-agent/dist/core/sdk.js +4 -2
  63. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  64. package/packages/pi-coding-agent/dist/core/settings-manager.collapse-tool-calls.test.d.ts +2 -0
  65. package/packages/pi-coding-agent/dist/core/settings-manager.collapse-tool-calls.test.d.ts.map +1 -0
  66. package/packages/pi-coding-agent/dist/core/settings-manager.collapse-tool-calls.test.js +35 -0
  67. package/packages/pi-coding-agent/dist/core/settings-manager.collapse-tool-calls.test.js.map +1 -0
  68. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +12 -0
  69. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  70. package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.d.ts +2 -0
  71. package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.d.ts.map +1 -0
  72. package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.js +35 -0
  73. package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.js.map +1 -0
  74. package/packages/pi-coding-agent/dist/core/settings-manager.js +24 -0
  75. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  76. package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
  77. package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
  78. package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
  79. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  80. package/packages/pi-coding-agent/dist/core/system-prompt.js +6 -1
  81. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  82. package/packages/pi-coding-agent/dist/core/tool-priority.d.ts +4 -0
  83. package/packages/pi-coding-agent/dist/core/tool-priority.d.ts.map +1 -0
  84. package/packages/pi-coding-agent/dist/core/tool-priority.js +18 -0
  85. package/packages/pi-coding-agent/dist/core/tool-priority.js.map +1 -0
  86. package/packages/pi-coding-agent/dist/core/tool-priority.test.d.ts +2 -0
  87. package/packages/pi-coding-agent/dist/core/tool-priority.test.d.ts.map +1 -0
  88. package/packages/pi-coding-agent/dist/core/tool-priority.test.js +27 -0
  89. package/packages/pi-coding-agent/dist/core/tool-priority.test.js.map +1 -0
  90. package/packages/pi-coding-agent/dist/core/tools/edit-diff.d.ts +5 -0
  91. package/packages/pi-coding-agent/dist/core/tools/edit-diff.d.ts.map +1 -1
  92. package/packages/pi-coding-agent/dist/core/tools/edit-diff.js +21 -0
  93. package/packages/pi-coding-agent/dist/core/tools/edit-diff.js.map +1 -1
  94. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +16 -1
  95. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
  96. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.d.ts +2 -0
  97. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.d.ts.map +1 -0
  98. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.js +34 -0
  99. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.js.map +1 -0
  100. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.d.ts +45 -0
  101. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.d.ts.map +1 -0
  102. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.js +314 -0
  103. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.js.map +1 -0
  104. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.d.ts +2 -0
  105. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.d.ts.map +1 -0
  106. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.js +122 -0
  107. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.js.map +1 -0
  108. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts +7 -5
  109. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts.map +1 -1
  110. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js +86 -28
  111. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js.map +1 -1
  112. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts +4 -0
  113. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  114. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +23 -10
  115. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  116. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +8 -0
  117. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  118. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +52 -6
  119. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  120. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +19 -0
  121. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  122. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +127 -14
  123. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  124. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.d.ts +14 -0
  125. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.d.ts.map +1 -0
  126. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.js +93 -0
  127. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.js.map +1 -0
  128. package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.d.ts +2 -0
  129. package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.d.ts.map +1 -0
  130. package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.js +328 -0
  131. package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.js.map +1 -0
  132. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  133. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +123 -0
  134. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  135. package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.js +1 -1
  136. package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.js.map +1 -1
  137. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  138. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +7 -0
  139. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  140. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +4 -0
  141. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  142. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  143. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +9 -1
  144. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  145. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +103 -23
  146. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  147. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
  148. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +41 -0
  149. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
  150. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +4 -4
  151. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  152. package/packages/pi-coding-agent/package.json +1 -1
  153. package/packages/pi-coding-agent/src/core/keybindings.ts +4 -1
  154. package/packages/pi-coding-agent/src/core/sdk.ts +4 -2
  155. package/packages/pi-coding-agent/src/core/settings-manager.collapse-tool-calls.test.ts +46 -0
  156. package/packages/pi-coding-agent/src/core/settings-manager.fast-mode.test.ts +46 -0
  157. package/packages/pi-coding-agent/src/core/settings-manager.ts +36 -0
  158. package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
  159. package/packages/pi-coding-agent/src/core/system-prompt.ts +6 -1
  160. package/packages/pi-coding-agent/src/core/tool-priority.test.ts +30 -0
  161. package/packages/pi-coding-agent/src/core/tool-priority.ts +17 -0
  162. package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +20 -0
  163. package/packages/pi-coding-agent/src/core/tools/edit-diff.ts +26 -0
  164. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-summary-line.test.ts +41 -0
  165. package/packages/pi-coding-agent/src/modes/interactive/components/btw-overlay.test.ts +172 -0
  166. package/packages/pi-coding-agent/src/modes/interactive/components/btw-overlay.ts +402 -0
  167. package/packages/pi-coding-agent/src/modes/interactive/components/diff.ts +105 -28
  168. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +21 -6
  169. package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +63 -6
  170. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1262 -1138
  171. package/packages/pi-coding-agent/src/modes/interactive/components/tool-summary-line.ts +120 -0
  172. package/packages/pi-coding-agent/src/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.ts +396 -0
  173. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +530 -398
  174. package/packages/pi-coding-agent/src/modes/interactive/controllers/extension-ui-controller.ts +1 -1
  175. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +7 -0
  176. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +4 -0
  177. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +109 -23
  178. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +60 -1
  179. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +4 -4
  180. package/packages/pi-tui/dist/components/editor.js +3 -3
  181. package/packages/pi-tui/dist/components/editor.js.map +1 -1
  182. package/packages/pi-tui/src/components/editor.ts +3 -3
  183. package/pkg/dist/modes/interactive/theme/themes.js +4 -4
  184. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  185. package/pkg/package.json +1 -1
  186. package/src/resources/extensions/browser-tools/tools/codegen.ts +5 -5
  187. package/src/resources/extensions/browser-tools/tools/navigation.ts +118 -196
  188. package/src/resources/extensions/browser-tools/tools/network-mock.ts +114 -205
  189. package/src/resources/extensions/browser-tools/tools/pages.ts +183 -237
  190. package/src/resources/extensions/browser-tools/tools/refs.ts +193 -507
  191. package/src/resources/extensions/browser-tools/tools/session.ts +182 -321
  192. package/src/resources/extensions/browser-tools/tools/state-persistence.ts +94 -172
  193. package/src/resources/extensions/browser-tools/utils.ts +1 -1
  194. package/src/resources/extensions/cache-timer/index.ts +3 -2
  195. package/src/resources/extensions/slash-commands/extension-manifest.json +2 -2
  196. package/src/resources/extensions/slash-commands/fast.ts +89 -0
  197. package/src/resources/extensions/slash-commands/index.ts +2 -0
  198. package/src/resources/extensions/slash-commands/plan.ts +42 -12
  199. package/src/resources/extensions/subagent/background-job-manager.ts +28 -0
  200. package/src/resources/extensions/subagent/in-process-runner.ts +534 -0
  201. package/src/resources/extensions/subagent/index.ts +489 -799
  202. package/src/resources/extensions/subagent/legacy-runner.ts +607 -0
  203. package/src/resources/extensions/voice/index.ts +308 -238
  204. package/src/resources/extensions/voice/push-to-talk.ts +42 -0
  205. package/src/resources/extensions/voice/tests/push-to-talk.test.ts +109 -0
@@ -1,7 +1,8 @@
1
1
  import { Box, Container, getCapabilities, Image, imageFallback, Spacer, Text, truncateToWidth, } from "@gsd/pi-tui";
2
2
  import stripAnsi from "strip-ansi";
3
- import { computeEditDiff } from "../../../core/tools/edit-diff.js";
3
+ import { computeEditDiff, computeWriteDiff, } from "../../../core/tools/edit-diff.js";
4
4
  import { allTools } from "../../../core/tools/index.js";
5
+ import { shouldCollapse } from "../../../core/tool-priority.js";
5
6
  import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize } from "../../../core/tools/truncate.js";
6
7
  import { convertToPng } from "../../../utils/image-convert.js";
7
8
  import { sanitizeBinaryOutput } from "../../../utils/shell.js";
@@ -9,7 +10,7 @@ import { renderTerminalText } from "../../../utils/terminal-serializer.js";
9
10
  import { getLanguageFromPath, highlightCode, theme } from "../theme/theme.js";
10
11
  import { editorLink } from "../utils/editor-link.js";
11
12
  import { shortenPath } from "../utils/shorten-path.js";
12
- import { renderDiff } from "./diff.js";
13
+ import { renderDiff, renderDiffLines } from "./diff.js";
13
14
  import { truncateToVisualLines } from "./visual-truncate.js";
14
15
  // Preview line limit for bash when not expanded
15
16
  const BASH_PREVIEW_LINES = 5;
@@ -80,6 +81,8 @@ export class ToolExecutionComponent extends Container {
80
81
  this.convertedImages = new Map();
81
82
  // When true, this component intentionally renders no lines
82
83
  this.hideComponent = false;
84
+ this.manuallyHidden = false;
85
+ this.startTime = Date.now();
83
86
  // Tool status spinner state
84
87
  this.spinnerTimer = null;
85
88
  this.spinnerFrame = 0;
@@ -114,6 +117,40 @@ export class ToolExecutionComponent extends Container {
114
117
  const hasCustomRenderers = this.toolDefinition?.renderCall || this.toolDefinition?.renderResult;
115
118
  return isBuiltInName && !hasCustomRenderers;
116
119
  }
120
+ setPrimaryContent(useBox) {
121
+ const hasBox = this.children.includes(this.contentBox);
122
+ const hasText = this.children.includes(this.contentText);
123
+ if (useBox) {
124
+ if (hasText)
125
+ this.removeChild(this.contentText);
126
+ if (!hasBox)
127
+ this.addChild(this.contentBox);
128
+ }
129
+ else {
130
+ if (hasBox)
131
+ this.removeChild(this.contentBox);
132
+ if (!hasText)
133
+ this.addChild(this.contentText);
134
+ }
135
+ }
136
+ getDiffTextToRender() {
137
+ if (this.toolName === "write") {
138
+ if (!this.isPartial && this.writeDiffPreview && !("error" in this.writeDiffPreview) && this.writeDiffPreview.diff) {
139
+ return this.writeDiffPreview.diff;
140
+ }
141
+ return undefined;
142
+ }
143
+ if (this.toolName !== "edit" || this.result?.isError) {
144
+ return undefined;
145
+ }
146
+ if (this.result?.details?.diff) {
147
+ return this.result.details.diff;
148
+ }
149
+ if (this.editDiffPreview && !("error" in this.editDiffPreview) && this.editDiffPreview.diff) {
150
+ return this.editDiffPreview.diff;
151
+ }
152
+ return undefined;
153
+ }
117
154
  updateArgs(args) {
118
155
  this.args = args;
119
156
  if (this.toolName === "write" && this.isPartial) {
@@ -209,9 +246,33 @@ export class ToolExecutionComponent extends Container {
209
246
  if (rawPath !== null && fileContent !== null) {
210
247
  this.rebuildWriteHighlightCacheFull(rawPath, fileContent);
211
248
  }
249
+ this.maybeComputeWriteDiff();
212
250
  }
213
251
  this.maybeComputeEditDiff();
214
252
  }
253
+ /**
254
+ * Compute write diff preview when we have complete args.
255
+ * This runs async and updates display when done.
256
+ */
257
+ maybeComputeWriteDiff() {
258
+ if (this.toolName !== "write")
259
+ return;
260
+ const path = this.args?.path ?? this.args?.file_path;
261
+ const content = this.args?.content;
262
+ if (!path || content === undefined)
263
+ return;
264
+ const argsKey = JSON.stringify({ path, content });
265
+ if (this.writeDiffArgsKey === argsKey)
266
+ return;
267
+ this.writeDiffArgsKey = argsKey;
268
+ computeWriteDiff(path, content, this.cwd).then((result) => {
269
+ if (this.writeDiffArgsKey === argsKey) {
270
+ this.writeDiffPreview = result;
271
+ this.updateDisplay();
272
+ this.ui.requestRender();
273
+ }
274
+ });
275
+ }
215
276
  /**
216
277
  * Compute edit diff preview when we have complete args.
217
278
  * This runs async and updates display when done.
@@ -291,6 +352,19 @@ export class ToolExecutionComponent extends Container {
291
352
  this.expanded = expanded;
292
353
  this.updateDisplay();
293
354
  }
355
+ setHidden(hidden) {
356
+ this.manuallyHidden = hidden;
357
+ this.updateDisplay();
358
+ }
359
+ isHidden() {
360
+ return this.hideComponent;
361
+ }
362
+ getElapsed() {
363
+ return Date.now() - this.startTime;
364
+ }
365
+ shouldHideWhenCollapsed(collapseToolCalls = true) {
366
+ return collapseToolCalls && !this.isPartial && shouldCollapse(this.toolName, this.result?.isError ?? false);
367
+ }
294
368
  setRenderMode(mode) {
295
369
  if (this.renderMode !== mode) {
296
370
  this.renderMode = mode;
@@ -354,16 +428,23 @@ export class ToolExecutionComponent extends Container {
354
428
  }
355
429
  }
356
430
  const useBuiltInRenderer = this.shouldUseBuiltInRenderer();
431
+ const diffTextToRender = this.getDiffTextToRender();
357
432
  let customRendererHasContent = false;
358
- this.hideComponent = false;
359
433
  // Use built-in rendering for built-in tools (or overrides without custom renderers)
360
434
  if (useBuiltInRenderer) {
435
+ const useDiffBox = !!diffTextToRender && !this.shouldHideCollapsedPreview();
436
+ this.setPrimaryContent(this.toolName === "bash" || useDiffBox);
361
437
  if (this.toolName === "bash") {
362
438
  // Bash uses Box with visual line truncation - no background
363
439
  this.contentBox.setBgFn((text) => text);
364
440
  this.contentBox.clear();
365
441
  this.renderBashContent(statusIndicator);
366
442
  }
443
+ else if (useDiffBox && diffTextToRender) {
444
+ this.contentBox.setBgFn((text) => text);
445
+ this.contentBox.clear();
446
+ this.renderBuiltInDiffContent(statusIndicator, diffTextToRender);
447
+ }
367
448
  else {
368
449
  // Other built-in tools: use Text directly with caching - no background
369
450
  this.contentText.setCustomBgFn((text) => text);
@@ -489,9 +570,22 @@ export class ToolExecutionComponent extends Container {
489
570
  }
490
571
  }
491
572
  }
492
- if (!useBuiltInRenderer && this.toolDefinition) {
493
- this.hideComponent = !customRendererHasContent && this.imageComponents.length === 0;
494
- }
573
+ const computedHidden = !useBuiltInRenderer && this.toolDefinition ? !customRendererHasContent && this.imageComponents.length === 0 : false;
574
+ this.hideComponent = this.manuallyHidden || computedHidden;
575
+ }
576
+ /**
577
+ * Render built-in edit/write diff blocks with width-aware full-line backgrounds.
578
+ */
579
+ renderBuiltInDiffContent(statusIndicator, diffText) {
580
+ const header = this.formatToolExecution(statusIndicator).split("\n\n", 1)[0] ?? "";
581
+ this.contentBox.addChild(new Text(header, 0, 0));
582
+ this.contentBox.addChild({
583
+ render: (width) => {
584
+ const contentWidth = Math.max(1, width - 2);
585
+ return ["", ...renderDiffLines(diffText, contentWidth).map((line) => ` ${line} `)];
586
+ },
587
+ invalidate: () => { },
588
+ });
495
589
  }
496
590
  /**
497
591
  * Render bash content using visual line truncation (like bash-execution.ts)
@@ -712,14 +806,40 @@ export class ToolExecutionComponent extends Container {
712
806
  const rawPath = str(this.args?.file_path ?? this.args?.path);
713
807
  const fileContent = str(this.args?.content);
714
808
  const path = rawPath !== null ? shortenPath(rawPath) : null;
809
+ const firstChangedLine = this.writeDiffPreview && "firstChangedLine" in this.writeDiffPreview
810
+ ? this.writeDiffPreview.firstChangedLine
811
+ : undefined;
715
812
  let writePathDisplay = path === null ? invalidArg : path ? theme.fg("accent", path) : theme.fg("toolOutput", "...");
716
813
  if (rawPath && path) {
717
- writePathDisplay = editorLink(rawPath, writePathDisplay, { cwd: this.cwd, scheme: this.editorScheme });
814
+ writePathDisplay = editorLink(rawPath, writePathDisplay, {
815
+ cwd: this.cwd,
816
+ line: firstChangedLine ?? undefined,
817
+ scheme: this.editorScheme,
818
+ });
819
+ }
820
+ if (firstChangedLine) {
821
+ writePathDisplay += theme.fg("warning", `:${firstChangedLine}`);
718
822
  }
719
823
  text = `${statusIndicator} ${theme.fg("toolTitle", theme.bold("write"))} ${writePathDisplay}`;
720
824
  if (fileContent === null) {
721
825
  text += `\n\n${theme.fg("error", "[invalid content arg - expected string]")}`;
722
826
  }
827
+ else if (this.result?.isError) {
828
+ const errorText = this.getTextOutput();
829
+ if (errorText) {
830
+ text += `\n\n${theme.fg("error", errorText)}`;
831
+ }
832
+ }
833
+ else if (!this.isPartial && this.writeDiffPreview) {
834
+ if ("error" in this.writeDiffPreview) {
835
+ text += `\n\n${theme.fg("error", this.writeDiffPreview.error)}`;
836
+ }
837
+ else if (this.writeDiffPreview.diff) {
838
+ text += hideCollapsedPreview
839
+ ? this.collapsedHintWithPrefix()
840
+ : `\n\n${renderDiff(this.writeDiffPreview.diff, { filePath: rawPath ?? undefined })}`;
841
+ }
842
+ }
723
843
  else if (fileContent) {
724
844
  const lang = rawPath ? getLanguageFromPath(rawPath) : undefined;
725
845
  let lines;
@@ -761,13 +881,6 @@ export class ToolExecutionComponent extends Container {
761
881
  }
762
882
  }
763
883
  }
764
- // Show error if tool execution failed
765
- if (this.result?.isError) {
766
- const errorText = this.getTextOutput();
767
- if (errorText) {
768
- text += `\n\n${theme.fg("error", errorText)}`;
769
- }
770
- }
771
884
  }
772
885
  else if (this.toolName === "edit") {
773
886
  const rawPath = str(this.args?.file_path ?? this.args?.path);