@markusylisiurunen/tau 0.1.37 → 0.1.39

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.
@@ -1,55 +1,70 @@
1
1
  import { Container, Spacer } from "@mariozechner/pi-tui";
2
2
  import { AssistantMessageComponent } from "./assistant_message.js";
3
+ import { isAssistantMessageModel, renderChatMessage, updateAssistantComponent, } from "./chat_message_model.js";
3
4
  export class ChatContainerComponent extends Container {
4
5
  chatContainer;
6
+ theme;
5
7
  thoughtsVisible = false;
6
8
  compactToolUi = false;
7
9
  allMessages = [];
8
10
  idToIndex = new Map();
9
- constructor(thoughtsVisible = false) {
11
+ constructor(theme, thoughtsVisible = false) {
10
12
  super();
13
+ this.theme = theme;
11
14
  this.thoughtsVisible = thoughtsVisible;
12
15
  this.chatContainer = new Container();
13
16
  this.addChild(this.chatContainer);
14
17
  }
15
- addMessage(message) {
16
- const id = this.generateId();
17
- const isAssistant = message instanceof AssistantMessageComponent;
18
- this.allMessages.push({ id, type: "component", component: message, isAssistant });
19
- this.idToIndex.set(id, this.allMessages.length - 1);
20
- // Always add immediately (rebuild() will filter later if needed)
21
- this.addSpacerIfNeeded();
22
- this.chatContainer.addChild(message);
23
- return id;
18
+ addMessage(model, id) {
19
+ const finalId = id ?? this.generateId();
20
+ const record = { id: finalId, model, rendered: false };
21
+ this.allMessages.push(record);
22
+ this.idToIndex.set(finalId, this.allMessages.length - 1);
23
+ const rendered = this.renderMessage(record);
24
+ if (this.shouldShowMessage(rendered)) {
25
+ this.addSpacerIfNeeded();
26
+ this.chatContainer.addChild(rendered.component);
27
+ record.rendered = true;
28
+ }
29
+ return finalId;
24
30
  }
25
- replaceMessage(id, newComponent) {
31
+ replaceMessage(id, model) {
26
32
  const index = this.idToIndex.get(id);
27
33
  if (index === undefined)
28
34
  return;
29
- const isAssistant = newComponent instanceof AssistantMessageComponent;
30
- this.allMessages[index] = { id, type: "component", component: newComponent, isAssistant };
31
- // Rebuild to update the display
35
+ this.allMessages[index] = { id, model, rendered: false };
32
36
  this.rebuild();
33
37
  }
34
- addToolMessage(render, id) {
35
- const finalId = id ?? this.generateId();
36
- this.allMessages.push({ id: finalId, type: "tool", render, isAssistant: false });
37
- this.idToIndex.set(finalId, this.allMessages.length - 1);
38
- const component = render(this.compactToolUi);
39
- this.addSpacerIfNeeded();
40
- this.chatContainer.addChild(component);
41
- return finalId;
42
- }
43
- replaceToolMessage(id, render) {
38
+ updateMessage(id, model) {
44
39
  const index = this.idToIndex.get(id);
45
40
  if (index === undefined)
46
41
  return;
47
- this.allMessages[index] = {
48
- id,
49
- type: "tool",
50
- render,
51
- isAssistant: false,
52
- };
42
+ const record = this.allMessages[index];
43
+ if (!record)
44
+ return;
45
+ record.model = model;
46
+ if (record.component instanceof AssistantMessageComponent && isAssistantMessageModel(model)) {
47
+ const wasVisible = record.component.hasVisibleText;
48
+ updateAssistantComponent(record.component, model, this.thoughtsVisible);
49
+ const shouldShow = this.shouldShowMessage({
50
+ component: record.component,
51
+ isAssistant: true,
52
+ });
53
+ if (record.rendered && shouldShow) {
54
+ if (!wasVisible && record.component.hasVisibleText) {
55
+ this.rebuild();
56
+ }
57
+ return;
58
+ }
59
+ if (!record.rendered && shouldShow) {
60
+ this.rebuild();
61
+ return;
62
+ }
63
+ if (record.rendered && !shouldShow) {
64
+ this.rebuild();
65
+ }
66
+ return;
67
+ }
53
68
  this.rebuild();
54
69
  }
55
70
  setThinkingVisibility(visible) {
@@ -72,21 +87,31 @@ export class ChatContainerComponent extends Container {
72
87
  rebuild() {
73
88
  this.chatContainer.clear();
74
89
  for (const record of this.allMessages) {
75
- const component = record.type === "component" ? record.component : record.render(this.compactToolUi);
76
- const isAssistant = record.isAssistant;
77
- if (this.shouldShowMessage(component, isAssistant)) {
90
+ record.rendered = false;
91
+ const rendered = this.renderMessage(record);
92
+ if (this.shouldShowMessage(rendered)) {
78
93
  this.addSpacerIfNeeded();
79
- this.chatContainer.addChild(component);
94
+ this.chatContainer.addChild(rendered.component);
95
+ record.rendered = true;
80
96
  }
81
97
  }
82
98
  }
83
- shouldShowMessage(component, isAssistant) {
84
- if (!isAssistant)
99
+ renderMessage(record) {
100
+ const rendered = renderChatMessage(record.model, {
101
+ theme: this.theme,
102
+ thoughtsVisible: this.thoughtsVisible,
103
+ compactToolUi: this.compactToolUi,
104
+ });
105
+ record.component = rendered.component;
106
+ return rendered;
107
+ }
108
+ shouldShowMessage(rendered) {
109
+ if (!rendered.isAssistant)
85
110
  return true;
86
111
  if (this.thoughtsVisible)
87
112
  return true;
88
- if (component instanceof AssistantMessageComponent) {
89
- return component.hasVisibleText;
113
+ if (rendered.component instanceof AssistantMessageComponent) {
114
+ return rendered.component.hasVisibleText;
90
115
  }
91
116
  return true;
92
117
  }
@@ -1 +1 @@
1
- {"version":3,"file":"chat_container.js","sourceRoot":"","sources":["../../src/ui/chat_container.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chat_container.js","sourceRoot":"","sources":["../../src/ui/chat_container.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ import { AppIntroComponent } from "./app_intro.js";
2
+ import { AssistantMessageComponent } from "./assistant_message.js";
3
+ import { SessionDividerComponent } from "./session_divider.js";
4
+ import { SessionSummaryComponent } from "./session_summary.js";
5
+ import { SystemMessageComponent } from "./system_message.js";
6
+ import { renderToolOutput } from "./tool_output_layout.js";
7
+ import { UserMessageComponent } from "./user_message.js";
8
+ export function isAssistantMessageModel(model) {
9
+ return model.type === "assistant" || model.type === "assistant_partial";
10
+ }
11
+ export function updateAssistantComponent(component, model, thoughtsVisible) {
12
+ component.setThinkingVisibility(thoughtsVisible);
13
+ if (model.type === "assistant") {
14
+ component.updateFromMessage(model.message);
15
+ }
16
+ else {
17
+ component.updatePartial(model.text, model.thinking);
18
+ }
19
+ }
20
+ export function renderChatMessage(model, options) {
21
+ const { theme, thoughtsVisible, compactToolUi } = options;
22
+ switch (model.type) {
23
+ case "app_intro":
24
+ return {
25
+ component: new AppIntroComponent(theme, model.appName, model.version, model.helpText),
26
+ isAssistant: false,
27
+ };
28
+ case "assistant": {
29
+ const component = new AssistantMessageComponent(theme, model.message, thoughtsVisible);
30
+ return { component, isAssistant: true };
31
+ }
32
+ case "assistant_partial": {
33
+ const component = new AssistantMessageComponent(theme, undefined, thoughtsVisible);
34
+ component.updatePartial(model.text, model.thinking);
35
+ return { component, isAssistant: true };
36
+ }
37
+ case "system":
38
+ return {
39
+ component: new SystemMessageComponent(theme, model.text, model.kind),
40
+ isAssistant: false,
41
+ };
42
+ case "user":
43
+ return {
44
+ component: new UserMessageComponent(theme, model.text, {
45
+ isMemoryMode: model.isMemoryMode,
46
+ }),
47
+ isAssistant: false,
48
+ };
49
+ case "tool":
50
+ return { component: renderToolOutput(model.view, compactToolUi), isAssistant: false };
51
+ case "session_divider":
52
+ return { component: new SessionDividerComponent(theme, model.label), isAssistant: false };
53
+ case "session_summary":
54
+ return { component: new SessionSummaryComponent(theme, model.summary), isAssistant: false };
55
+ }
56
+ }
57
+ //# sourceMappingURL=chat_message_model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat_message_model.js","sourceRoot":"","sources":["../../src/ui/chat_message_model.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { OneLineSegmentsComponent, WrappedSegmentsComponent, } from "./one_line_segments.js";
2
+ export class HeaderLineComponent {
3
+ inner;
4
+ constructor(model) {
5
+ this.inner =
6
+ model.wrapIndex !== undefined
7
+ ? new WrappedSegmentsComponent(model.segments, model.wrapIndex)
8
+ : new OneLineSegmentsComponent(model.segments, model.flexIndices ?? []);
9
+ }
10
+ invalidate() {
11
+ this.inner.invalidate();
12
+ }
13
+ render(width) {
14
+ return this.inner.render(width);
15
+ }
16
+ }
17
+ //# sourceMappingURL=header_line.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"header_line.js","sourceRoot":"","sources":["../../../src/ui/components/header_line.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,wBAAwB,CAAC;AAQhC,MAAM,OAAO,mBAAmB;IACtB,KAAK,CAAY;IAEzB,YAAY,KAAsB;QAChC,IAAI,CAAC,KAAK;YACR,KAAK,CAAC,SAAS,KAAK,SAAS;gBAC3B,CAAC,CAAC,IAAI,wBAAwB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;gBAC/D,CAAC,CAAC,IAAI,wBAAwB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,UAAU;QACR,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;IAC1B,CAAC;IAED,MAAM,CAAC,KAAa;QAClB,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;CACF"}
@@ -90,8 +90,28 @@ export class OneLineSegmentsComponent {
90
90
  }
91
91
  // Last resort: width smaller than fixed parts; hard truncate the fully rendered line.
92
92
  if (excess > 0) {
93
- const raw = texts.join("");
94
- return [truncateFromEndByWidth(raw, minWidth)];
93
+ let remaining = minWidth;
94
+ let usedWidth = 0;
95
+ const styledParts = [];
96
+ for (let i = 0; i < texts.length && remaining > 0; i++) {
97
+ const segmentText = texts[i] ?? "";
98
+ const segmentWidth = visibleWidth(segmentText);
99
+ const style = this.segments[i]?.style ?? ((s) => s);
100
+ if (segmentWidth <= remaining) {
101
+ styledParts.push(style(segmentText));
102
+ remaining -= segmentWidth;
103
+ usedWidth += segmentWidth;
104
+ }
105
+ else {
106
+ const truncated = truncateFromEndByWidth(segmentText, remaining);
107
+ const truncatedWidth = visibleWidth(truncated);
108
+ styledParts.push(style(truncated));
109
+ usedWidth += truncatedWidth;
110
+ remaining = Math.max(0, remaining - truncatedWidth);
111
+ }
112
+ }
113
+ const pad = Math.max(0, minWidth - usedWidth);
114
+ return [`${styledParts.join("")}${" ".repeat(pad)}`];
95
115
  }
96
116
  const rendered = texts
97
117
  .map((t, i) => {
@@ -1 +1 @@
1
- {"version":3,"file":"one_line_segments.js","sourceRoot":"","sources":["../../../src/ui/components/one_line_segments.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"one_line_segments.js","sourceRoot":"","sources":["../../../src/ui/components/one_line_segments.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,8 @@
1
1
  import { bytesToTokens } from "../utils/token.js";
2
2
  import { inlineText } from "./inline.js";
3
- import { ToolOutputComponent } from "./tool_output.js";
4
- import { EDIT_DIFF_MAX_LINES, EDIT_DIFF_MAX_TOKENS, truncateForUi, WRITE_UI_PREVIEW_LINES, } from "./tool_truncation.js";
3
+ import { buildHeaderLine, buildSection, renderToolOutput, } from "./tool_output_layout.js";
4
+ import { applyPreviewPolicy, buildCompactPreviewLines } from "./tool_output_preview.js";
5
+ import { EDIT_DIFF_MAX_LINES, EDIT_DIFF_MAX_TOKENS, WRITE_UI_PREVIEW_LINES, } from "./tool_truncation.js";
5
6
  function buildSimpleDiff(oldText, newText) {
6
7
  const oldLines = oldText.length === 0 ? ["(empty)"] : oldText.split("\n");
7
8
  const newLines = newText.length === 0 ? ["(empty)"] : newText.split("\n");
@@ -41,87 +42,80 @@ function buildSimpleDiff(oldText, newText) {
41
42
  },
42
43
  };
43
44
  }
44
- export function renderWriteSuccess(theme, path, bytes, lines, content, compact) {
45
+ export function buildWriteSuccessView(theme, path, bytes, lines, content) {
45
46
  const { palette, text } = theme;
46
47
  const writeColor = (s) => palette.toolFileRan(s);
47
- const previewTruncation = truncateForUi(content, {
48
+ const { truncation: previewTruncation, previewLines } = applyPreviewPolicy(content, {
48
49
  maxLines: WRITE_UI_PREVIEW_LINES,
49
50
  strategy: "head",
50
51
  });
51
52
  const preview = previewTruncation.content;
52
- const expandedParts = [];
53
- expandedParts.push(writeColor(text.bold(`write ${path}`)));
54
- expandedParts.push("");
55
- expandedParts.push(palette.muted(`${bytes} bytes (${lines} lines)`));
53
+ const expandedSections = [];
54
+ expandedSections.push(palette.muted(`${bytes} bytes (${lines} lines)`));
56
55
  if (preview) {
57
- expandedParts.push("");
58
- expandedParts.push(palette.filePreview(preview));
56
+ expandedSections.push(palette.filePreview(preview));
59
57
  }
60
58
  if (previewTruncation.truncated) {
61
59
  const icon = palette.warn("◆");
62
60
  const msg = palette.dim(`preview: ${previewTruncation.outputLines} of ${previewTruncation.totalLines} lines`);
63
- expandedParts.push("");
64
- expandedParts.push(`${icon} ${msg}`);
61
+ expandedSections.push(`${icon} ${msg}`);
65
62
  }
66
63
  const pathInline = inlineText(path);
67
- const segments = [
68
- { text: " ", style: (s) => s },
69
- { text: "", style: writeColor },
70
- { text: " ", style: (s) => s },
71
- { text: "wrote", style: palette.muted },
72
- { text: " ", style: (s) => s },
73
- { text: pathInline, style: palette.accent },
74
- { text: " ", style: (s) => s },
75
- { text: `(${lines} lines)`, style: palette.muted },
76
- ];
77
- const maxPreviewLines = 4;
78
- const previewLines = preview.trimEnd() ? preview.trimEnd().split("\n") : [];
79
- const shownPreviewLines = previewLines.slice(0, maxPreviewLines);
80
- const shownCount = Math.min(lines, shownPreviewLines.length);
81
- const remaining = Math.max(0, lines - shownCount);
82
- const compactLines = [];
83
- for (const l of shownPreviewLines) {
84
- compactLines.push(palette.muted(` ${l}`));
85
- }
86
- if (remaining > 0) {
87
- compactLines.push(palette.dim(` (${remaining} more lines)`));
88
- }
89
- return new ToolOutputComponent({
90
- compact,
91
- expanded: { borderColor: writeColor, text: expandedParts.join("\n") },
92
- compactView: {
93
- segments,
94
- flexIndices: [5],
95
- extraText: compactLines.length > 0 ? compactLines.join("\n") : undefined,
96
- },
64
+ const header = buildHeaderLine({
65
+ bulletStyle: writeColor,
66
+ label: "wrote",
67
+ labelStyle: palette.muted,
68
+ accent: pathInline,
69
+ accentStyle: palette.accent,
70
+ tailSegments: [
71
+ { text: " ", style: (s) => s },
72
+ { text: `(${lines} lines)`, style: palette.muted },
73
+ ],
74
+ });
75
+ const compactLines = buildCompactPreviewLines(previewLines, {
76
+ totalLines: lines,
77
+ lineStyle: palette.muted,
78
+ moreStyle: palette.dim,
97
79
  });
80
+ return {
81
+ borderColor: writeColor,
82
+ expanded: {
83
+ title: writeColor(text.bold(`write ${path}`)),
84
+ sections: expandedSections,
85
+ },
86
+ compact: {
87
+ header,
88
+ extraText: compactLines,
89
+ },
90
+ };
98
91
  }
99
- export function renderWriteBlocked(theme, path, reason, compact) {
92
+ export function buildWriteBlockedView(theme, path, reason) {
100
93
  const { palette, text } = theme;
101
94
  const errorColor = (s) => palette.error(s);
102
- const expandedParts = [errorColor(text.bold(`write ${path}`))];
103
95
  const msg = reason.trim();
104
- if (msg) {
105
- expandedParts.push("");
106
- expandedParts.push(errorColor(msg));
107
- }
96
+ const section = buildSection(msg ? [errorColor(msg)] : []);
108
97
  const pathInline = inlineText(path);
109
98
  const whyInline = inlineText(reason);
110
- const segments = [
111
- { text: " ", style: (s) => s },
112
- { text: "", style: errorColor },
113
- { text: " ", style: (s) => s },
114
- { text: "write", style: palette.muted },
115
- { text: " ", style: (s) => s },
116
- { text: pathInline, style: palette.accent },
117
- { text: " ", style: (s) => s },
118
- { text: `(blocked: ${whyInline})`, style: palette.muted },
119
- ];
120
- return new ToolOutputComponent({
121
- compact,
122
- expanded: { borderColor: errorColor, text: expandedParts.join("\n") },
123
- compactView: { segments, flexIndices: [5, 7] },
99
+ const header = buildHeaderLine({
100
+ bulletStyle: errorColor,
101
+ label: "write",
102
+ labelStyle: palette.muted,
103
+ accent: pathInline,
104
+ accentStyle: palette.accent,
105
+ tailSegments: [
106
+ { text: " ", style: (s) => s },
107
+ { text: `(blocked: ${whyInline})`, style: palette.muted },
108
+ ],
109
+ flexTailIndices: [1],
124
110
  });
111
+ return {
112
+ borderColor: errorColor,
113
+ expanded: {
114
+ title: errorColor(text.bold(`write ${path}`)),
115
+ sections: section ? [section] : [],
116
+ },
117
+ compact: { header },
118
+ };
125
119
  }
126
120
  function countDiffChanges(diff) {
127
121
  let added = 0;
@@ -141,39 +135,36 @@ function colorDiffLine(palette, line) {
141
135
  return palette.diffAdded(line);
142
136
  return palette.muted(line);
143
137
  }
144
- export function renderEditSuccess(theme, path, oldLength, newLength, oldText, newText, compact) {
138
+ export function buildEditSuccessView(theme, path, oldLength, newLength, oldText, newText) {
145
139
  const { palette, text } = theme;
146
140
  const editColor = (s) => palette.toolFileRan(s);
147
141
  const { diff, truncation: diffTruncation } = buildSimpleDiff(oldText, newText);
148
142
  const sizeDiff = newLength - oldLength;
149
143
  const diffStr = sizeDiff === 0 ? "same size" : sizeDiff > 0 ? `+${sizeDiff} chars` : `${sizeDiff} chars`;
150
- const expandedParts = [];
151
- expandedParts.push(editColor(text.bold(`edit ${path}`)));
152
- expandedParts.push("");
153
- expandedParts.push(palette.muted(`replaced ${oldLength} → ${newLength} chars (${diffStr})`));
154
- expandedParts.push("");
155
- expandedParts.push(diff
144
+ const expandedSections = [];
145
+ expandedSections.push(palette.muted(`replaced ${oldLength} → ${newLength} chars (${diffStr})`));
146
+ expandedSections.push(diff
156
147
  .split("\n")
157
148
  .map((line) => colorDiffLine(palette, line))
158
149
  .join("\n"));
159
150
  if (diffTruncation.truncated) {
160
151
  const icon = palette.warn("◆");
161
152
  const msg = palette.dim(`truncated: ${diffTruncation.outputLines} of ${diffTruncation.totalLines} lines`);
162
- expandedParts.push("");
163
- expandedParts.push(`${icon} ${msg}`);
153
+ expandedSections.push(`${icon} ${msg}`);
164
154
  }
165
155
  const { added, removed } = countDiffChanges(diff);
166
156
  const pathInline = inlineText(path);
167
- const segments = [
168
- { text: " ", style: (s) => s },
169
- { text: "", style: editColor },
170
- { text: " ", style: (s) => s },
171
- { text: "edited", style: palette.muted },
172
- { text: " ", style: (s) => s },
173
- { text: pathInline, style: palette.accent },
174
- { text: " ", style: (s) => s },
175
- { text: `(+${added}, -${removed})`, style: palette.muted },
176
- ];
157
+ const header = buildHeaderLine({
158
+ bulletStyle: editColor,
159
+ label: "edited",
160
+ labelStyle: palette.muted,
161
+ accent: pathInline,
162
+ accentStyle: palette.accent,
163
+ tailSegments: [
164
+ { text: " ", style: (s) => s },
165
+ { text: `(+${added}, -${removed})`, style: palette.muted },
166
+ ],
167
+ });
177
168
  const diffLines = diff ? diff.split("\n") : [];
178
169
  const compactLines = [];
179
170
  for (const l of diffLines) {
@@ -192,41 +183,56 @@ export function renderEditSuccess(theme, path, oldLength, newLength, oldText, ne
192
183
  const msg = palette.dim(`truncated: ${diffTruncation.outputLines} of ${diffTruncation.totalLines} lines`);
193
184
  compactLines.push(` ${icon} ${msg}`);
194
185
  }
195
- return new ToolOutputComponent({
196
- compact,
197
- expanded: { borderColor: editColor, text: expandedParts.join("\n") },
198
- compactView: {
199
- segments,
200
- flexIndices: [5],
186
+ return {
187
+ borderColor: editColor,
188
+ expanded: {
189
+ title: editColor(text.bold(`edit ${path}`)),
190
+ sections: expandedSections,
191
+ },
192
+ compact: {
193
+ header,
201
194
  extraText: compactLines.length > 0 ? compactLines.join("\n") : undefined,
202
195
  },
203
- });
196
+ };
204
197
  }
205
- export function renderEditBlocked(theme, path, reason, compact) {
198
+ export function buildEditBlockedView(theme, path, reason) {
206
199
  const { palette, text } = theme;
207
200
  const errorColor = (s) => palette.error(s);
208
- const expandedParts = [errorColor(text.bold(`edit ${path}`))];
209
201
  const msg = reason.trim();
210
- if (msg) {
211
- expandedParts.push("");
212
- expandedParts.push(errorColor(msg));
213
- }
202
+ const section = buildSection(msg ? [errorColor(msg)] : []);
214
203
  const pathInline = inlineText(path);
215
204
  const whyInline = inlineText(reason);
216
- const segments = [
217
- { text: " ", style: (s) => s },
218
- { text: "", style: errorColor },
219
- { text: " ", style: (s) => s },
220
- { text: "edit", style: palette.muted },
221
- { text: " ", style: (s) => s },
222
- { text: pathInline, style: palette.accent },
223
- { text: " ", style: (s) => s },
224
- { text: `(blocked: ${whyInline})`, style: palette.muted },
225
- ];
226
- return new ToolOutputComponent({
227
- compact,
228
- expanded: { borderColor: errorColor, text: expandedParts.join("\n") },
229
- compactView: { segments, flexIndices: [5, 7] },
205
+ const header = buildHeaderLine({
206
+ bulletStyle: errorColor,
207
+ label: "edit",
208
+ labelStyle: palette.muted,
209
+ accent: pathInline,
210
+ accentStyle: palette.accent,
211
+ tailSegments: [
212
+ { text: " ", style: (s) => s },
213
+ { text: `(blocked: ${whyInline})`, style: palette.muted },
214
+ ],
215
+ flexTailIndices: [1],
230
216
  });
217
+ return {
218
+ borderColor: errorColor,
219
+ expanded: {
220
+ title: errorColor(text.bold(`edit ${path}`)),
221
+ sections: section ? [section] : [],
222
+ },
223
+ compact: { header },
224
+ };
225
+ }
226
+ export function renderWriteSuccess(theme, path, bytes, lines, content, compact) {
227
+ return renderToolOutput(buildWriteSuccessView(theme, path, bytes, lines, content), compact);
228
+ }
229
+ export function renderWriteBlocked(theme, path, reason, compact) {
230
+ return renderToolOutput(buildWriteBlockedView(theme, path, reason), compact);
231
+ }
232
+ export function renderEditSuccess(theme, path, oldLength, newLength, oldText, newText, compact) {
233
+ return renderToolOutput(buildEditSuccessView(theme, path, oldLength, newLength, oldText, newText), compact);
234
+ }
235
+ export function renderEditBlocked(theme, path, reason, compact) {
236
+ return renderToolOutput(buildEditBlockedView(theme, path, reason), compact);
231
237
  }
232
238
  //# sourceMappingURL=file_execution.js.map