@yeshwanthyk/coding-agent 0.3.13 → 0.3.15

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 (44) hide show
  1. package/dist/adapters/tui/app.js +29 -17
  2. package/dist/adapters/tui/{app.js.map → app.jsx.map} +1 -1
  3. package/dist/components/Footer.js +60 -24
  4. package/dist/components/{Footer.js.map → Footer.jsx.map} +1 -1
  5. package/dist/components/Header.js +312 -96
  6. package/dist/components/{Header.js.map → Header.jsx.map} +1 -1
  7. package/dist/components/MessageList.js +393 -146
  8. package/dist/components/MessageList.jsx.map +1 -0
  9. package/dist/runtime/context.js +15 -9
  10. package/dist/runtime/context.jsx.map +1 -0
  11. package/dist/session-picker.js +123 -69
  12. package/dist/session-picker.jsx.map +1 -0
  13. package/dist/tui-open-rendering.js +716 -343
  14. package/dist/tui-open-rendering.jsx.map +1 -0
  15. package/dist/ui/app-shell/TuiApp.js +590 -441
  16. package/dist/ui/app-shell/{TuiApp.js.map → TuiApp.jsx.map} +1 -1
  17. package/dist/ui/components/modals/ConfirmModal.js +80 -23
  18. package/dist/ui/components/modals/ConfirmModal.jsx.map +1 -0
  19. package/dist/ui/components/modals/EditorModal.js +55 -15
  20. package/dist/ui/components/modals/EditorModal.jsx.map +1 -0
  21. package/dist/ui/components/modals/InputModal.js +36 -9
  22. package/dist/ui/components/modals/InputModal.jsx.map +1 -0
  23. package/dist/ui/components/modals/ModalContainer.js +72 -16
  24. package/dist/ui/components/modals/ModalContainer.jsx.map +1 -0
  25. package/dist/ui/components/modals/SelectModal.js +53 -24
  26. package/dist/ui/components/modals/SelectModal.jsx.map +1 -0
  27. package/dist/ui/features/composer/Composer.js +145 -26
  28. package/dist/ui/features/composer/Composer.jsx.map +1 -0
  29. package/dist/ui/features/main-view/MainView.js +341 -248
  30. package/dist/ui/features/main-view/{MainView.js.map → MainView.jsx.map} +1 -1
  31. package/dist/ui/features/message-pane/MessagePane.js +46 -4
  32. package/dist/ui/features/message-pane/MessagePane.jsx.map +1 -0
  33. package/package.json +3 -3
  34. package/dist/components/MessageList.js.map +0 -1
  35. package/dist/runtime/context.js.map +0 -1
  36. package/dist/session-picker.js.map +0 -1
  37. package/dist/tui-open-rendering.js.map +0 -1
  38. package/dist/ui/components/modals/ConfirmModal.js.map +0 -1
  39. package/dist/ui/components/modals/EditorModal.js.map +0 -1
  40. package/dist/ui/components/modals/InputModal.js.map +0 -1
  41. package/dist/ui/components/modals/ModalContainer.js.map +0 -1
  42. package/dist/ui/components/modals/SelectModal.js.map +0 -1
  43. package/dist/ui/features/composer/Composer.js.map +0 -1
  44. package/dist/ui/features/message-pane/MessagePane.js.map +0 -1
@@ -1,4 +1,11 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "@opentui/solid/jsx-runtime";
1
+ import { createComponent as _$createComponent } from "@opentui/solid";
2
+ import { createTextNode as _$createTextNode } from "@opentui/solid";
3
+ import { insertNode as _$insertNode } from "@opentui/solid";
4
+ import { memo as _$memo } from "@opentui/solid";
5
+ import { effect as _$effect } from "@opentui/solid";
6
+ import { insert as _$insert } from "@opentui/solid";
7
+ import { setProp as _$setProp } from "@opentui/solid";
8
+ import { createElement as _$createElement } from "@opentui/solid";
2
9
  /**
3
10
  * OpenTUI-native rendering components for tool output.
4
11
  */
@@ -11,401 +18,767 @@ import { getAgentDelegationArgs, getAgentDelegationUi } from "./tool-ui-contract
11
18
  export { getToolText, getEditDiffText };
12
19
  // Design tokens - minimal symbols
13
20
  const symbols = {
14
- running: "·",
15
- complete: "▸",
16
- expanded: "▾",
17
- error: "✕",
21
+ running: "·",
22
+ complete: "▸",
23
+ expanded: "▾",
24
+ error: "✕"
18
25
  };
19
26
  export const shortenPath = (p, maxLen = 40) => {
20
- const home = process.env.HOME || process.env.USERPROFILE || "";
21
- let shortened = p;
22
- // Replace home with ~
23
- if (home && shortened.startsWith(home)) {
24
- shortened = "~" + shortened.slice(home.length);
25
- }
26
- // If still long, show .../{parent}/{file}
27
- const parts = shortened.split("/");
28
- if (parts.length > 3) {
29
- shortened = "…/" + parts.slice(-2).join("/");
30
- }
31
- // Final truncation if still too long
32
- if (shortened.length > maxLen) {
33
- shortened = "…" + shortened.slice(-(maxLen - 1));
34
- }
35
- return shortened;
27
+ const home = process.env.HOME || process.env.USERPROFILE || "";
28
+ let shortened = p;
29
+ // Replace home with ~
30
+ if (home && shortened.startsWith(home)) {
31
+ shortened = "~" + shortened.slice(home.length);
32
+ }
33
+ // If still long, show .../{parent}/{file}
34
+ const parts = shortened.split("/");
35
+ if (parts.length > 3) {
36
+ shortened = "…/" + parts.slice(-2).join("/");
37
+ }
38
+ // Final truncation if still too long
39
+ if (shortened.length > maxLen) {
40
+ shortened = "…" + shortened.slice(-(maxLen - 1));
41
+ }
42
+ return shortened;
36
43
  };
37
44
  // Simple diff preview with manual line coloring (tree-sitter lacks diff grammar)
38
45
  const diffAddedColor = parseColor("#98c379");
39
46
  const diffRemovedColor = parseColor("#e06c75");
40
47
  const diffHunkColor = parseColor("#61afef");
41
48
  function DiffPreview(props) {
42
- const { theme } = useTheme();
43
- const coloredLines = () => props.text.split("\n").map((line) => {
44
- let fg = theme.text;
45
- if (line.startsWith("+") && !line.startsWith("+++"))
46
- fg = diffAddedColor;
47
- else if (line.startsWith("-") && !line.startsWith("---"))
48
- fg = diffRemovedColor;
49
- else if (line.startsWith("@@"))
50
- fg = diffHunkColor;
51
- return { line, fg };
52
- });
53
- return (_jsx("box", { flexDirection: "column", backgroundColor: theme.backgroundElement, paddingLeft: 1, paddingRight: 1, children: coloredLines().map(({ line, fg }) => (_jsx("text", { fg: fg, children: line }))) }));
49
+ const {
50
+ theme
51
+ } = useTheme();
52
+ const coloredLines = () => props.text.split("\n").map(line => {
53
+ let fg = theme.text;
54
+ if (line.startsWith("+") && !line.startsWith("+++")) fg = diffAddedColor;else if (line.startsWith("-") && !line.startsWith("---")) fg = diffRemovedColor;else if (line.startsWith("@@")) fg = diffHunkColor;
55
+ return {
56
+ line,
57
+ fg
58
+ };
59
+ });
60
+ return (() => {
61
+ var _el$ = _$createElement("box");
62
+ _$setProp(_el$, "flexDirection", "column");
63
+ _$setProp(_el$, "paddingLeft", 1);
64
+ _$setProp(_el$, "paddingRight", 1);
65
+ _$insert(_el$, () => coloredLines().map(({
66
+ line,
67
+ fg
68
+ }) => (() => {
69
+ var _el$2 = _$createElement("text");
70
+ _$setProp(_el$2, "fg", fg);
71
+ _$insert(_el$2, line);
72
+ return _el$2;
73
+ })()));
74
+ _$effect(_$p => _$setProp(_el$, "backgroundColor", theme.backgroundElement, _$p));
75
+ return _el$;
76
+ })();
54
77
  }
55
78
  const delegationOkColor = diffAddedColor;
56
79
  function firstLine(s) {
57
- return s.split("\n")[0] || "";
80
+ return s.split("\n")[0] || "";
58
81
  }
59
82
  function truncate(s, max) {
60
- if (s.length <= max)
61
- return s;
62
- return s.slice(0, Math.max(0, max - 1)) + "…";
83
+ if (s.length <= max) return s;
84
+ return s.slice(0, Math.max(0, max - 1)) + "…";
63
85
  }
64
86
  function delegationSymbol(status) {
65
- switch (status) {
66
- case "running":
67
- return "◌";
68
- case "pending":
69
- return "○";
70
- case "ok":
71
- return "✓";
72
- case "error":
73
- return "✕";
74
- default:
75
- return "·";
76
- }
87
+ switch (status) {
88
+ case "running":
89
+ return "◌";
90
+ case "pending":
91
+ return "○";
92
+ case "ok":
93
+ return "✓";
94
+ case "error":
95
+ return "✕";
96
+ default:
97
+ return "·";
98
+ }
77
99
  }
78
100
  function delegationColor(theme, status) {
79
- if (status === "error")
80
- return theme.error;
81
- if (status === "ok")
82
- return delegationOkColor;
83
- if (status === "running")
84
- return theme.accent;
85
- return theme.textMuted;
101
+ if (status === "error") return theme.error;
102
+ if (status === "ok") return delegationOkColor;
103
+ if (status === "running") return theme.accent;
104
+ return theme.textMuted;
86
105
  }
87
106
  function formatDelegationSuffix(ui) {
88
- const ok = ui.items.filter((i) => i.status === "ok").length;
89
- const err = ui.items.filter((i) => i.status === "error").length;
90
- const total = ui.items.length;
91
- if (err > 0)
92
- return `${ok} ok · ${err} err / ${total}`;
93
- return `${ok} ok / ${total}`;
107
+ const ok = ui.items.filter(i => i.status === "ok").length;
108
+ const err = ui.items.filter(i => i.status === "error").length;
109
+ const total = ui.items.length;
110
+ if (err > 0) return `${ok} ok · ${err} err / ${total}`;
111
+ return `${ok} ok / ${total}`;
94
112
  }
95
113
  function AgentDelegationView(props) {
96
- const { theme } = useTheme();
97
- const maxItems = () => props.expanded ? 50 : 8;
98
- const rows = () => {
99
- if (props.ui) {
100
- return props.ui.items.slice(0, maxItems()).map((item) => ({
101
- id: item.id,
102
- agent: item.agent,
103
- task: item.task,
104
- status: item.status,
105
- preview: item.preview,
106
- active: props.ui?.activeId === item.id,
107
- }));
108
- }
109
- if (props.args?.chain?.length) {
110
- return props.args.chain.slice(0, maxItems()).map((item, idx) => ({
111
- id: String(idx + 1),
112
- agent: item.agent,
113
- task: item.task,
114
- status: "unknown",
115
- preview: undefined,
116
- active: false,
117
- }));
118
- }
119
- if (props.args?.tasks?.length) {
120
- return props.args.tasks.slice(0, maxItems()).map((item, idx) => ({
121
- id: String(idx + 1),
122
- agent: item.agent,
123
- task: item.task,
124
- status: "unknown",
125
- preview: undefined,
126
- active: false,
127
- }));
128
- }
129
- if (props.args?.agent && props.args?.task) {
130
- return [{
131
- id: "1",
132
- agent: props.args.agent,
133
- task: props.args.task,
134
- status: "unknown",
135
- preview: undefined,
136
- active: false,
137
- }];
114
+ const {
115
+ theme
116
+ } = useTheme();
117
+ const maxItems = () => props.expanded ? 50 : 8;
118
+ const rows = () => {
119
+ if (props.ui) {
120
+ return props.ui.items.slice(0, maxItems()).map(item => ({
121
+ id: item.id,
122
+ agent: item.agent,
123
+ task: item.task,
124
+ status: item.status,
125
+ preview: item.preview,
126
+ active: props.ui?.activeId === item.id
127
+ }));
128
+ }
129
+ if (props.args?.chain?.length) {
130
+ return props.args.chain.slice(0, maxItems()).map((item, idx) => ({
131
+ id: String(idx + 1),
132
+ agent: item.agent,
133
+ task: item.task,
134
+ status: "unknown",
135
+ preview: undefined,
136
+ active: false
137
+ }));
138
+ }
139
+ if (props.args?.tasks?.length) {
140
+ return props.args.tasks.slice(0, maxItems()).map((item, idx) => ({
141
+ id: String(idx + 1),
142
+ agent: item.agent,
143
+ task: item.task,
144
+ status: "unknown",
145
+ preview: undefined,
146
+ active: false
147
+ }));
148
+ }
149
+ if (props.args?.agent && props.args?.task) {
150
+ return [{
151
+ id: "1",
152
+ agent: props.args.agent,
153
+ task: props.args.task,
154
+ status: "unknown",
155
+ preview: undefined,
156
+ active: false
157
+ }];
158
+ }
159
+ return [];
160
+ };
161
+ return (() => {
162
+ var _el$3 = _$createElement("box");
163
+ _$setProp(_el$3, "flexDirection", "column");
164
+ _$setProp(_el$3, "paddingLeft", 1);
165
+ _$setProp(_el$3, "paddingRight", 1);
166
+ _$insert(_el$3, () => rows().map(row => (() => {
167
+ var _el$9 = _$createElement("box"),
168
+ _el$0 = _$createElement("box"),
169
+ _el$1 = _$createElement("text"),
170
+ _el$10 = _$createElement("text"),
171
+ _el$11 = _$createElement("text");
172
+ _$insertNode(_el$9, _el$0);
173
+ _$setProp(_el$9, "flexDirection", "column");
174
+ _$setProp(_el$9, "gap", 0);
175
+ _$insertNode(_el$0, _el$1);
176
+ _$insertNode(_el$0, _el$10);
177
+ _$insertNode(_el$0, _el$11);
178
+ _$setProp(_el$0, "flexDirection", "row");
179
+ _$setProp(_el$0, "gap", 1);
180
+ _$setProp(_el$1, "selectable", false);
181
+ _$insert(_el$1, () => delegationSymbol(row.status));
182
+ _$insert(_el$10, () => truncate(row.agent, 24));
183
+ _$insert(_el$11, () => truncate(firstLine(row.task), 80));
184
+ _$insert(_el$9, _$createComponent(Show, {
185
+ get when() {
186
+ return _$memo(() => !!props.expanded)() && row.preview;
187
+ },
188
+ get children() {
189
+ var _el$12 = _$createElement("box"),
190
+ _el$13 = _$createElement("text");
191
+ _$insertNode(_el$12, _el$13);
192
+ _$setProp(_el$12, "paddingLeft", 2);
193
+ _$insert(_el$13, () => truncate(firstLine(String(row.preview)), 120));
194
+ _$effect(_$p => _$setProp(_el$13, "fg", theme.textMuted, _$p));
195
+ return _el$12;
138
196
  }
139
- return [];
140
- };
141
- return (_jsxs("box", { flexDirection: "column", backgroundColor: theme.backgroundElement, paddingLeft: 1, paddingRight: 1, children: [rows().map((row) => (_jsxs("box", { flexDirection: "column", gap: 0, children: [_jsxs("box", { flexDirection: "row", gap: 1, children: [_jsx("text", { selectable: false, fg: delegationColor(theme, row.status), children: delegationSymbol(row.status) }), _jsx("text", { fg: row.active ? theme.accent : theme.text, children: truncate(row.agent, 24) }), _jsx("text", { fg: theme.textMuted, children: truncate(firstLine(row.task), 80) })] }), _jsx(Show, { when: props.expanded && row.preview, children: _jsx("box", { paddingLeft: 2, children: _jsx("text", { fg: theme.textMuted, children: truncate(firstLine(String(row.preview)), 120) }) }) })] }))), _jsx(Show, { when: props.ui && props.ui.items.length > maxItems(), children: _jsxs("text", { fg: theme.textMuted, children: ["\u2026 ", props.ui.items.length - maxItems(), " more \u2026"] }) }), _jsx(Show, { when: !props.ui && ((props.args?.chain?.length ?? 0) > maxItems() || (props.args?.tasks?.length ?? 0) > maxItems()), children: _jsx("text", { fg: theme.textMuted, children: "\u2026 more \u2026" }) })] }));
197
+ }), null);
198
+ _$effect(_p$ => {
199
+ var _v$ = delegationColor(theme, row.status),
200
+ _v$2 = row.active ? theme.accent : theme.text,
201
+ _v$3 = theme.textMuted;
202
+ _v$ !== _p$.e && (_p$.e = _$setProp(_el$1, "fg", _v$, _p$.e));
203
+ _v$2 !== _p$.t && (_p$.t = _$setProp(_el$10, "fg", _v$2, _p$.t));
204
+ _v$3 !== _p$.a && (_p$.a = _$setProp(_el$11, "fg", _v$3, _p$.a));
205
+ return _p$;
206
+ }, {
207
+ e: undefined,
208
+ t: undefined,
209
+ a: undefined
210
+ });
211
+ return _el$9;
212
+ })()), null);
213
+ _$insert(_el$3, _$createComponent(Show, {
214
+ get when() {
215
+ return _$memo(() => !!props.ui)() && props.ui.items.length > maxItems();
216
+ },
217
+ get children() {
218
+ var _el$4 = _$createElement("text"),
219
+ _el$5 = _$createTextNode(`… `),
220
+ _el$6 = _$createTextNode(` more …`);
221
+ _$insertNode(_el$4, _el$5);
222
+ _$insertNode(_el$4, _el$6);
223
+ _$insert(_el$4, () => props.ui.items.length - maxItems(), _el$6);
224
+ _$effect(_$p => _$setProp(_el$4, "fg", theme.textMuted, _$p));
225
+ return _el$4;
226
+ }
227
+ }), null);
228
+ _$insert(_el$3, _$createComponent(Show, {
229
+ get when() {
230
+ return _$memo(() => !!!props.ui)() && ((props.args?.chain?.length ?? 0) > maxItems() || (props.args?.tasks?.length ?? 0) > maxItems());
231
+ },
232
+ get children() {
233
+ var _el$7 = _$createElement("text");
234
+ _$insertNode(_el$7, _$createTextNode(`… more …`));
235
+ _$effect(_$p => _$setProp(_el$7, "fg", theme.textMuted, _$p));
236
+ return _el$7;
237
+ }
238
+ }), null);
239
+ _$effect(_$p => _$setProp(_el$3, "backgroundColor", theme.backgroundElement, _$p));
240
+ return _el$3;
241
+ })();
142
242
  }
143
243
  function truncateHeadTail(text, headCount, tailCount) {
144
- const lines = replaceTabs(text).split("\n");
145
- if (lines.length <= headCount + tailCount) {
146
- return { text: lines.join("\n"), truncated: false, omitted: 0 };
147
- }
148
- const head = lines.slice(0, headCount);
149
- const tail = lines.slice(-tailCount);
244
+ const lines = replaceTabs(text).split("\n");
245
+ if (lines.length <= headCount + tailCount) {
150
246
  return {
151
- text: [...head, "", `… ${lines.length - (headCount + tailCount)} lines omitted …`, "", ...tail].join("\n"),
152
- truncated: true,
153
- omitted: lines.length - (headCount + tailCount),
247
+ text: lines.join("\n"),
248
+ truncated: false,
249
+ omitted: 0
154
250
  };
251
+ }
252
+ const head = lines.slice(0, headCount);
253
+ const tail = lines.slice(-tailCount);
254
+ return {
255
+ text: [...head, "", `… ${lines.length - (headCount + tailCount)} lines omitted …`, "", ...tail].join("\n"),
256
+ truncated: true,
257
+ omitted: lines.length - (headCount + tailCount)
258
+ };
155
259
  }
156
260
  function truncateLines(text, maxLines) {
157
- const lines = replaceTabs(text).split("\n");
158
- if (lines.length <= maxLines)
159
- return { text: lines.join("\n"), truncated: false, omitted: 0 };
160
- return {
161
- text: [...lines.slice(0, maxLines), `… ${lines.length - maxLines} more lines …`].join("\n"),
162
- truncated: true,
163
- omitted: lines.length - maxLines,
164
- };
261
+ const lines = replaceTabs(text).split("\n");
262
+ if (lines.length <= maxLines) return {
263
+ text: lines.join("\n"),
264
+ truncated: false,
265
+ omitted: 0
266
+ };
267
+ return {
268
+ text: [...lines.slice(0, maxLines), `… ${lines.length - maxLines} more lines …`].join("\n"),
269
+ truncated: true,
270
+ omitted: lines.length - maxLines
271
+ };
165
272
  }
166
273
  /** Extract +/- line counts from unified diff */
167
274
  function getDiffStats(diffText) {
168
- let added = 0;
169
- let removed = 0;
170
- for (const line of diffText.split("\n")) {
171
- if (line.startsWith("+") && !line.startsWith("+++"))
172
- added++;
173
- else if (line.startsWith("-") && !line.startsWith("---"))
174
- removed++;
175
- }
176
- return { added, removed };
275
+ let added = 0;
276
+ let removed = 0;
277
+ for (const line of diffText.split("\n")) {
278
+ if (line.startsWith("+") && !line.startsWith("+++")) added++;else if (line.startsWith("-") && !line.startsWith("---")) removed++;
279
+ }
280
+ return {
281
+ added,
282
+ removed
283
+ };
177
284
  }
178
285
  function getDiffStartLine(diffText) {
179
- const match = diffText.match(/^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/m);
180
- if (!match)
181
- return undefined;
182
- const line = Number.parseInt(match[1], 10);
183
- if (!Number.isFinite(line) || line <= 0)
184
- return undefined;
185
- return line;
286
+ const match = diffText.match(/^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/m);
287
+ if (!match) return undefined;
288
+ const line = Number.parseInt(match[1], 10);
289
+ if (!Number.isFinite(line) || line <= 0) return undefined;
290
+ return line;
186
291
  }
187
292
  function toolTitle(name, args) {
188
- switch (name) {
189
- case "bash": {
190
- // Prefer description if available
191
- if (args?.description)
192
- return truncate(String(args.description), 50);
193
- const cmd = String(args?.command || "…");
194
- return truncate(cmd.split("\n")[0] || "…", 40);
195
- }
196
- case "read":
197
- return shortenPath(String(args?.path || args?.file_path || "…"), 35);
198
- case "write":
199
- return shortenPath(String(args?.path || args?.file_path || "…"), 35);
200
- case "edit":
201
- return shortenPath(String(args?.path || args?.file_path || "…"), 35);
202
- // ask_user_question removed - use interview custom tool
203
- default: {
204
- const delegation = getAgentDelegationArgs(args);
205
- if (delegation?.chain?.length)
206
- return `chain ${delegation.chain.length}`;
207
- if (delegation?.tasks?.length)
208
- return `${delegation.tasks.length} tasks`;
209
- if (delegation?.agent)
210
- return truncate(delegation.agent, 30);
211
- return "";
212
- }
213
- }
293
+ switch (name) {
294
+ case "bash":
295
+ {
296
+ // Prefer description if available
297
+ if (args?.description) return truncate(String(args.description), 50);
298
+ const cmd = String(args?.command || "…");
299
+ return truncate(cmd.split("\n")[0] || "…", 40);
300
+ }
301
+ case "read":
302
+ return shortenPath(String(args?.path || args?.file_path || "…"), 35);
303
+ case "write":
304
+ return shortenPath(String(args?.path || args?.file_path || "…"), 35);
305
+ case "edit":
306
+ return shortenPath(String(args?.path || args?.file_path || "…"), 35);
307
+ // ask_user_question removed - use interview custom tool
308
+ default:
309
+ {
310
+ const delegation = getAgentDelegationArgs(args);
311
+ if (delegation?.chain?.length) return `chain ${delegation.chain.length}`;
312
+ if (delegation?.tasks?.length) return `${delegation.tasks.length} tasks`;
313
+ if (delegation?.agent) return truncate(delegation.agent, 30);
314
+ return "";
315
+ }
316
+ }
214
317
  }
215
318
  export function Thinking(props) {
216
- const { theme } = useTheme();
217
- return (_jsxs("text", { selectable: false, fg: theme.textMuted, attributes: TextAttributes.ITALIC, children: ["thinking ", props.summary] }));
319
+ const {
320
+ theme
321
+ } = useTheme();
322
+ return (() => {
323
+ var _el$14 = _$createElement("text"),
324
+ _el$15 = _$createTextNode(`thinking `);
325
+ _$insertNode(_el$14, _el$15);
326
+ _$setProp(_el$14, "selectable", false);
327
+ _$insert(_el$14, () => props.summary, null);
328
+ _$effect(_p$ => {
329
+ var _v$4 = theme.textMuted,
330
+ _v$5 = TextAttributes.ITALIC;
331
+ _v$4 !== _p$.e && (_p$.e = _$setProp(_el$14, "fg", _v$4, _p$.e));
332
+ _v$5 !== _p$.t && (_p$.t = _$setProp(_el$14, "attributes", _v$5, _p$.t));
333
+ return _p$;
334
+ }, {
335
+ e: undefined,
336
+ t: undefined
337
+ });
338
+ return _el$14;
339
+ })();
218
340
  }
219
341
  function defaultHeader(ctx) {
220
- const title = toolTitle(ctx.name, ctx.args);
221
- const delegationUi = getAgentDelegationUi(ctx.result?.details);
222
- const suffix = delegationUi ? formatDelegationSuffix(delegationUi) : undefined;
223
- return _jsx(ToolHeader, { label: ctx.name, detail: title, suffix: suffix, isComplete: ctx.isComplete, isError: ctx.isError, expanded: ctx.expanded });
342
+ const title = toolTitle(ctx.name, ctx.args);
343
+ const delegationUi = getAgentDelegationUi(ctx.result?.details);
344
+ const suffix = delegationUi ? formatDelegationSuffix(delegationUi) : undefined;
345
+ return _$createComponent(ToolHeader, {
346
+ get label() {
347
+ return ctx.name;
348
+ },
349
+ detail: title,
350
+ suffix: suffix,
351
+ get isComplete() {
352
+ return ctx.isComplete;
353
+ },
354
+ get isError() {
355
+ return ctx.isError;
356
+ },
357
+ get expanded() {
358
+ return ctx.expanded;
359
+ }
360
+ });
224
361
  }
225
362
  function ToolHeader(props) {
226
- const { theme } = useTheme();
227
- const symbol = () => {
228
- if (!props.isComplete)
229
- return symbols.running;
230
- if (props.isError)
231
- return symbols.error;
232
- if (props.expanded)
233
- return symbols.expanded;
234
- return symbols.complete;
235
- };
236
- const symbolColor = () => {
237
- if (props.isError)
238
- return theme.error;
239
- return theme.textMuted;
240
- };
241
- // Tool name gets subtle accent, rest muted
242
- return (_jsxs("text", { selectable: false, children: [_jsx("span", { style: { fg: symbolColor() }, children: symbol() }), _jsxs("span", { style: { fg: theme.accent }, children: [" ", props.label] }), _jsx(Show, { when: props.detail, children: _jsxs("span", { style: { fg: theme.textMuted }, children: [" ", props.detail] }) }), _jsx(Show, { when: props.suffix, children: _jsxs("span", { style: { fg: theme.textMuted }, children: [" \u00B7 ", props.suffix] }) })] }));
363
+ const {
364
+ theme
365
+ } = useTheme();
366
+ const symbol = () => {
367
+ if (!props.isComplete) return symbols.running;
368
+ if (props.isError) return symbols.error;
369
+ if (props.expanded) return symbols.expanded;
370
+ return symbols.complete;
371
+ };
372
+ const symbolColor = () => {
373
+ if (props.isError) return theme.error;
374
+ return theme.textMuted;
375
+ };
376
+ // Tool name gets subtle accent, rest muted
377
+ return (() => {
378
+ var _el$16 = _$createElement("text"),
379
+ _el$17 = _$createElement("span"),
380
+ _el$18 = _$createElement("span"),
381
+ _el$19 = _$createTextNode(` `);
382
+ _$insertNode(_el$16, _el$17);
383
+ _$insertNode(_el$16, _el$18);
384
+ _$setProp(_el$16, "selectable", false);
385
+ _$insert(_el$17, symbol);
386
+ _$insertNode(_el$18, _el$19);
387
+ _$insert(_el$18, () => props.label, null);
388
+ _$insert(_el$16, _$createComponent(Show, {
389
+ get when() {
390
+ return props.detail;
391
+ },
392
+ get children() {
393
+ var _el$20 = _$createElement("span"),
394
+ _el$21 = _$createTextNode(` `);
395
+ _$insertNode(_el$20, _el$21);
396
+ _$insert(_el$20, () => props.detail, null);
397
+ _$effect(_$p => _$setProp(_el$20, "style", {
398
+ fg: theme.textMuted
399
+ }, _$p));
400
+ return _el$20;
401
+ }
402
+ }), null);
403
+ _$insert(_el$16, _$createComponent(Show, {
404
+ get when() {
405
+ return props.suffix;
406
+ },
407
+ get children() {
408
+ var _el$22 = _$createElement("span"),
409
+ _el$23 = _$createTextNode(` · `);
410
+ _$insertNode(_el$22, _el$23);
411
+ _$insert(_el$22, () => props.suffix, null);
412
+ _$effect(_$p => _$setProp(_el$22, "style", {
413
+ fg: theme.textMuted
414
+ }, _$p));
415
+ return _el$22;
416
+ }
417
+ }), null);
418
+ _$effect(_p$ => {
419
+ var _v$6 = {
420
+ fg: symbolColor()
421
+ },
422
+ _v$7 = {
423
+ fg: theme.accent
424
+ };
425
+ _v$6 !== _p$.e && (_p$.e = _$setProp(_el$17, "style", _v$6, _p$.e));
426
+ _v$7 !== _p$.t && (_p$.t = _$setProp(_el$18, "style", _v$7, _p$.t));
427
+ return _p$;
428
+ }, {
429
+ e: undefined,
430
+ t: undefined
431
+ });
432
+ return _el$16;
433
+ })();
243
434
  }
244
435
  const registry = {
245
- bash: {
246
- // Inline when collapsed (just command), block when expanded (show output)
247
- mode: (ctx) => (ctx.expanded ? "block" : "inline"),
248
- renderHeader: (ctx) => {
249
- // Prefer description if available, otherwise truncate command
250
- let detail;
251
- if (ctx.args?.description) {
252
- detail = truncate(String(ctx.args.description), 60);
253
- }
254
- else {
255
- const cmd = String(ctx.args?.command || "…").split("\n")[0] || "…";
256
- detail = truncate(cmd, 50);
257
- }
258
- return _jsx(ToolHeader, { label: "bash", detail: detail, isComplete: ctx.isComplete, isError: ctx.isError, expanded: ctx.expanded });
436
+ bash: {
437
+ // Inline when collapsed (just command), block when expanded (show output)
438
+ mode: ctx => ctx.expanded ? "block" : "inline",
439
+ renderHeader: ctx => {
440
+ // Prefer description if available, otherwise truncate command
441
+ let detail;
442
+ if (ctx.args?.description) {
443
+ detail = truncate(String(ctx.args.description), 60);
444
+ } else {
445
+ const cmd = String(ctx.args?.command || "…").split("\n")[0] || "…";
446
+ detail = truncate(cmd, 50);
447
+ }
448
+ return _$createComponent(ToolHeader, {
449
+ label: "bash",
450
+ detail: detail,
451
+ get isComplete() {
452
+ return ctx.isComplete;
259
453
  },
260
- renderBody: (ctx) => {
261
- const { theme } = useTheme();
262
- // Only show body when expanded
263
- if (!ctx.expanded)
264
- return null;
265
- if (!ctx.output)
266
- return _jsx("text", { fg: theme.textMuted, children: "no output" });
267
- return _jsx(CodeBlock, { content: replaceTabs(ctx.output), filetype: "text", showLineNumbers: false, wrapMode: "none" });
454
+ get isError() {
455
+ return ctx.isError;
268
456
  },
457
+ get expanded() {
458
+ return ctx.expanded;
459
+ }
460
+ });
269
461
  },
270
- read: {
271
- mode: (ctx) => (ctx.expanded ? "block" : "inline"),
272
- renderHeader: (ctx) => {
273
- const path = shortenPath(String(ctx.args?.path || ctx.args?.file_path || "…"));
274
- return _jsx(ToolHeader, { label: "read", detail: path, isComplete: ctx.isComplete, isError: ctx.isError, expanded: ctx.expanded });
462
+ renderBody: ctx => {
463
+ const {
464
+ theme
465
+ } = useTheme();
466
+ // Only show body when expanded
467
+ if (!ctx.expanded) return null;
468
+ if (!ctx.output) return (() => {
469
+ var _el$24 = _$createElement("text");
470
+ _$insertNode(_el$24, _$createTextNode(`no output`));
471
+ _$effect(_$p => _$setProp(_el$24, "fg", theme.textMuted, _$p));
472
+ return _el$24;
473
+ })();
474
+ return _$createComponent(CodeBlock, {
475
+ get content() {
476
+ return replaceTabs(ctx.output);
275
477
  },
276
- renderBody: (ctx) => {
277
- const { theme } = useTheme();
278
- const imageBlocks = (ctx.result?.content ?? []).filter((block) => typeof block === "object" &&
279
- block !== null &&
280
- block.type === "image" &&
281
- typeof block.data === "string" &&
282
- typeof block.mimeType === "string");
283
- if (!ctx.output && imageBlocks.length === 0)
284
- return _jsx("text", { fg: theme.textMuted, children: "reading\u2026" });
285
- const rendered = ctx.output ? (ctx.expanded ? replaceTabs(ctx.output) : truncateLines(ctx.output, 20).text) : "";
286
- const filetype = getLanguageFromPath(String(ctx.args?.path || ctx.args?.file_path || ""));
287
- const preview = rendered ? _jsx(CodeBlock, { content: rendered, filetype: filetype, title: "preview" }) : null;
288
- if (imageBlocks.length === 0)
289
- return preview ?? _jsx("text", { fg: theme.textMuted, children: "no preview" });
290
- return (_jsxs("box", { flexDirection: "column", gap: 1, children: [preview, imageBlocks.map((img) => (_jsx(Image, { data: img.data, mimeType: img.mimeType, maxWidth: 60 })))] }));
291
- },
292
- },
293
- write: {
294
- mode: () => "block",
295
- renderHeader: (ctx) => {
296
- const path = shortenPath(String(ctx.args?.path || ctx.args?.file_path || "…"));
297
- return _jsx(ToolHeader, { label: "write", detail: path, isComplete: ctx.isComplete, isError: ctx.isError, expanded: ctx.expanded });
478
+ filetype: "text",
479
+ showLineNumbers: false,
480
+ wrapMode: "none"
481
+ });
482
+ }
483
+ },
484
+ read: {
485
+ mode: ctx => ctx.expanded ? "block" : "inline",
486
+ renderHeader: ctx => {
487
+ const path = shortenPath(String(ctx.args?.path || ctx.args?.file_path || ""));
488
+ return _$createComponent(ToolHeader, {
489
+ label: "read",
490
+ detail: path,
491
+ get isComplete() {
492
+ return ctx.isComplete;
298
493
  },
299
- renderBody: (ctx) => {
300
- const { theme } = useTheme();
301
- const content = String(ctx.args?.content || "");
302
- if (!content && !ctx.isComplete)
303
- return _jsx("text", { fg: theme.textMuted, children: "writing\u2026" });
304
- if (!content)
305
- return _jsx("text", { fg: theme.textMuted, children: "no content" });
306
- const filetype = getLanguageFromPath(String(ctx.args?.path || ctx.args?.file_path || ""));
307
- const rendered = ctx.expanded ? replaceTabs(content) : truncateLines(content, 40).text;
308
- return _jsx(CodeBlock, { content: rendered, filetype: filetype, title: "write" });
494
+ get isError() {
495
+ return ctx.isError;
309
496
  },
497
+ get expanded() {
498
+ return ctx.expanded;
499
+ }
500
+ });
310
501
  },
311
- edit: {
312
- mode: (ctx) => (ctx.expanded ? "block" : "inline"),
313
- renderHeader: (ctx) => {
314
- const { theme } = useTheme();
315
- const path = shortenPath(String(ctx.args?.path || ctx.args?.file_path || ""));
316
- const fullPath = String(ctx.args?.path || ctx.args?.file_path || "");
317
- const diffStats = ctx.editDiff ? getDiffStats(ctx.editDiff) : null;
318
- const startLine = ctx.editDiff ? getDiffStartLine(ctx.editDiff) : undefined;
319
- const suffix = ctx.isComplete && !ctx.isError && diffStats ? `+${diffStats.added}/-${diffStats.removed}` : undefined;
320
- const showEditButton = ctx.isComplete && !ctx.isError && ctx.onEditFile && fullPath;
321
- return (_jsxs("box", { flexDirection: "row", children: [_jsx(ToolHeader, { label: "edit", detail: path, suffix: suffix, isComplete: ctx.isComplete, isError: ctx.isError, expanded: ctx.expanded }), showEditButton && (_jsx("text", { fg: theme.textMuted, onMouseUp: (e) => {
322
- e.stopPropagation?.();
323
- ctx.onEditFile?.(fullPath, startLine);
324
- }, children: " [e]" }))] }));
502
+ renderBody: ctx => {
503
+ const {
504
+ theme
505
+ } = useTheme();
506
+ const imageBlocks = (ctx.result?.content ?? []).filter(block => typeof block === "object" && block !== null && block.type === "image" && typeof block.data === "string" && typeof block.mimeType === "string");
507
+ if (!ctx.output && imageBlocks.length === 0) return (() => {
508
+ var _el$26 = _$createElement("text");
509
+ _$insertNode(_el$26, _$createTextNode(`reading…`));
510
+ _$effect(_$p => _$setProp(_el$26, "fg", theme.textMuted, _$p));
511
+ return _el$26;
512
+ })();
513
+ const rendered = ctx.output ? ctx.expanded ? replaceTabs(ctx.output) : truncateLines(ctx.output, 20).text : "";
514
+ const filetype = getLanguageFromPath(String(ctx.args?.path || ctx.args?.file_path || ""));
515
+ const preview = rendered ? _$createComponent(CodeBlock, {
516
+ content: rendered,
517
+ filetype: filetype,
518
+ title: "preview"
519
+ }) : null;
520
+ if (imageBlocks.length === 0) return preview ?? (() => {
521
+ var _el$28 = _$createElement("text");
522
+ _$insertNode(_el$28, _$createTextNode(`no preview`));
523
+ _$effect(_$p => _$setProp(_el$28, "fg", theme.textMuted, _$p));
524
+ return _el$28;
525
+ })();
526
+ return (() => {
527
+ var _el$30 = _$createElement("box");
528
+ _$setProp(_el$30, "flexDirection", "column");
529
+ _$setProp(_el$30, "gap", 1);
530
+ _$insert(_el$30, preview, null);
531
+ _$insert(_el$30, () => imageBlocks.map(img => _$createComponent(Image, {
532
+ get data() {
533
+ return img.data;
534
+ },
535
+ get mimeType() {
536
+ return img.mimeType;
537
+ },
538
+ maxWidth: 60
539
+ })), null);
540
+ return _el$30;
541
+ })();
542
+ }
543
+ },
544
+ write: {
545
+ mode: () => "block",
546
+ renderHeader: ctx => {
547
+ const path = shortenPath(String(ctx.args?.path || ctx.args?.file_path || "…"));
548
+ return _$createComponent(ToolHeader, {
549
+ label: "write",
550
+ detail: path,
551
+ get isComplete() {
552
+ return ctx.isComplete;
325
553
  },
326
- renderBody: (ctx) => {
327
- const { theme } = useTheme();
328
- // Only show body when expanded
329
- if (!ctx.expanded)
330
- return null;
331
- if (ctx.editDiff) {
332
- const filetype = getLanguageFromPath(String(ctx.args?.path || ctx.args?.file_path || ""));
333
- const diffLines = ctx.editDiff.split("\n").length;
334
- if (diffLines > 150) {
335
- const truncated = truncateHeadTail(ctx.editDiff, 60, 40);
336
- return _jsx(DiffPreview, { text: truncated.text });
337
- }
338
- return _jsx(Diff, { diffText: ctx.editDiff, filetype: filetype, wrapMode: ctx.diffWrapMode });
339
- }
340
- if (!ctx.output && !ctx.isComplete)
341
- return _jsx("text", { fg: theme.textMuted, children: "editing\u2026" });
342
- return _jsx("text", { fg: ctx.isError ? theme.error : theme.text, children: ctx.output ?? "" });
554
+ get isError() {
555
+ return ctx.isError;
343
556
  },
557
+ get expanded() {
558
+ return ctx.expanded;
559
+ }
560
+ });
561
+ },
562
+ renderBody: ctx => {
563
+ const {
564
+ theme
565
+ } = useTheme();
566
+ const content = String(ctx.args?.content || "");
567
+ if (!content && !ctx.isComplete) return (() => {
568
+ var _el$31 = _$createElement("text");
569
+ _$insertNode(_el$31, _$createTextNode(`writing…`));
570
+ _$effect(_$p => _$setProp(_el$31, "fg", theme.textMuted, _$p));
571
+ return _el$31;
572
+ })();
573
+ if (!content) return (() => {
574
+ var _el$33 = _$createElement("text");
575
+ _$insertNode(_el$33, _$createTextNode(`no content`));
576
+ _$effect(_$p => _$setProp(_el$33, "fg", theme.textMuted, _$p));
577
+ return _el$33;
578
+ })();
579
+ const filetype = getLanguageFromPath(String(ctx.args?.path || ctx.args?.file_path || ""));
580
+ const rendered = ctx.expanded ? replaceTabs(content) : truncateLines(content, 40).text;
581
+ return _$createComponent(CodeBlock, {
582
+ content: rendered,
583
+ filetype: filetype,
584
+ title: "write"
585
+ });
586
+ }
587
+ },
588
+ edit: {
589
+ mode: ctx => ctx.expanded ? "block" : "inline",
590
+ renderHeader: ctx => {
591
+ const {
592
+ theme
593
+ } = useTheme();
594
+ const path = shortenPath(String(ctx.args?.path || ctx.args?.file_path || "…"));
595
+ const fullPath = String(ctx.args?.path || ctx.args?.file_path || "");
596
+ const diffStats = ctx.editDiff ? getDiffStats(ctx.editDiff) : null;
597
+ const startLine = ctx.editDiff ? getDiffStartLine(ctx.editDiff) : undefined;
598
+ const suffix = ctx.isComplete && !ctx.isError && diffStats ? `+${diffStats.added}/-${diffStats.removed}` : undefined;
599
+ const showEditButton = ctx.isComplete && !ctx.isError && ctx.onEditFile && fullPath;
600
+ return (() => {
601
+ var _el$35 = _$createElement("box");
602
+ _$setProp(_el$35, "flexDirection", "row");
603
+ _$insert(_el$35, _$createComponent(ToolHeader, {
604
+ label: "edit",
605
+ detail: path,
606
+ suffix: suffix,
607
+ get isComplete() {
608
+ return ctx.isComplete;
609
+ },
610
+ get isError() {
611
+ return ctx.isError;
612
+ },
613
+ get expanded() {
614
+ return ctx.expanded;
615
+ }
616
+ }), null);
617
+ _$insert(_el$35, showEditButton && (() => {
618
+ var _el$36 = _$createElement("text");
619
+ _$insertNode(_el$36, _$createTextNode(` [e]`));
620
+ _$setProp(_el$36, "onMouseUp", e => {
621
+ e.stopPropagation?.();
622
+ ctx.onEditFile?.(fullPath, startLine);
623
+ });
624
+ _$effect(_$p => _$setProp(_el$36, "fg", theme.textMuted, _$p));
625
+ return _el$36;
626
+ })(), null);
627
+ return _el$35;
628
+ })();
344
629
  },
630
+ renderBody: ctx => {
631
+ const {
632
+ theme
633
+ } = useTheme();
634
+ // Only show body when expanded
635
+ if (!ctx.expanded) return null;
636
+ if (ctx.editDiff) {
637
+ const filetype = getLanguageFromPath(String(ctx.args?.path || ctx.args?.file_path || ""));
638
+ const diffLines = ctx.editDiff.split("\n").length;
639
+ if (diffLines > 150) {
640
+ const truncated = truncateHeadTail(ctx.editDiff, 60, 40);
641
+ return _$createComponent(DiffPreview, {
642
+ get text() {
643
+ return truncated.text;
644
+ }
645
+ });
646
+ }
647
+ return _$createComponent(Diff, {
648
+ get diffText() {
649
+ return ctx.editDiff;
650
+ },
651
+ filetype: filetype,
652
+ get wrapMode() {
653
+ return ctx.diffWrapMode;
654
+ }
655
+ });
656
+ }
657
+ if (!ctx.output && !ctx.isComplete) return (() => {
658
+ var _el$38 = _$createElement("text");
659
+ _$insertNode(_el$38, _$createTextNode(`editing…`));
660
+ _$effect(_$p => _$setProp(_el$38, "fg", theme.textMuted, _$p));
661
+ return _el$38;
662
+ })();
663
+ return (() => {
664
+ var _el$40 = _$createElement("text");
665
+ _$insert(_el$40, () => ctx.output ?? "");
666
+ _$effect(_$p => _$setProp(_el$40, "fg", ctx.isError ? theme.error : theme.text, _$p));
667
+ return _el$40;
668
+ })();
669
+ }
670
+ }
345
671
  };
346
672
  export function ToolBlock(props) {
347
- const { theme } = useTheme();
348
- // Use a getter for expanded to maintain reactivity
349
- const ctx = {
350
- name: props.name,
351
- args: props.args,
352
- output: props.output,
353
- editDiff: props.editDiff,
354
- result: props.result ?? null,
355
- isError: props.isError,
356
- isComplete: props.isComplete,
357
- get expanded() { return props.expanded ?? false; },
358
- get diffWrapMode() { return props.diffWrapMode ?? "word"; },
359
- onEditFile: props.onEditFile,
360
- };
361
- const renderer = registry[props.name] ?? {
362
- mode: () => "block",
363
- renderBody: (innerCtx) => {
364
- const delegationUi = getAgentDelegationUi(innerCtx.result?.details);
365
- const delegationArgs = getAgentDelegationArgs(innerCtx.args);
366
- if (delegationUi || delegationArgs) {
367
- return _jsx(AgentDelegationView, { args: delegationArgs, ui: delegationUi, expanded: innerCtx.expanded });
673
+ const {
674
+ theme
675
+ } = useTheme();
676
+ // Use a getter for expanded to maintain reactivity
677
+ const ctx = {
678
+ name: props.name,
679
+ args: props.args,
680
+ output: props.output,
681
+ editDiff: props.editDiff,
682
+ result: props.result ?? null,
683
+ isError: props.isError,
684
+ isComplete: props.isComplete,
685
+ get expanded() {
686
+ return props.expanded ?? false;
687
+ },
688
+ get diffWrapMode() {
689
+ return props.diffWrapMode ?? "word";
690
+ },
691
+ onEditFile: props.onEditFile
692
+ };
693
+ const renderer = registry[props.name] ?? {
694
+ mode: () => "block",
695
+ renderBody: innerCtx => {
696
+ const delegationUi = getAgentDelegationUi(innerCtx.result?.details);
697
+ const delegationArgs = getAgentDelegationArgs(innerCtx.args);
698
+ if (delegationUi || delegationArgs) {
699
+ return _$createComponent(AgentDelegationView, {
700
+ args: delegationArgs,
701
+ ui: delegationUi,
702
+ get expanded() {
703
+ return innerCtx.expanded;
704
+ }
705
+ });
706
+ }
707
+ const out = innerCtx.output ? innerCtx.output : JSON.stringify(innerCtx.args ?? {}, null, 2);
708
+ const rendered = innerCtx.expanded ? replaceTabs(out) : truncateLines(out, 20).text;
709
+ return _$createComponent(CodeBlock, {
710
+ content: rendered,
711
+ filetype: "text",
712
+ title: "output",
713
+ showLineNumbers: false
714
+ });
715
+ }
716
+ };
717
+ // Custom tool rendering: prefer tool-provided renderers, fallback to registry
718
+ const tryCustomRenderCall = () => {
719
+ if (!props.renderCall) return null;
720
+ try {
721
+ return props.renderCall(props.args, theme);
722
+ } catch {
723
+ return null; // Fallback to default on error
724
+ }
725
+ };
726
+ const tryCustomRenderResult = () => {
727
+ if (!props.renderResult || !props.result) return null;
728
+ try {
729
+ return props.renderResult(props.result, {
730
+ expanded: props.expanded ?? false,
731
+ isPartial: !props.isComplete
732
+ }, theme);
733
+ } catch {
734
+ return null; // Fallback to default on error
735
+ }
736
+ };
737
+ // Use functions to ensure reactivity
738
+ const mode = () => renderer.mode(ctx);
739
+ const header = () => tryCustomRenderCall() ?? renderer.renderHeader?.(ctx) ?? defaultHeader(ctx);
740
+ const body = () => tryCustomRenderResult() ?? renderer.renderBody?.(ctx);
741
+ return _$createComponent(Show, {
742
+ get when() {
743
+ return mode() === "inline";
744
+ },
745
+ get fallback() {
746
+ return (// Block layout - entire block is clickable to toggle
747
+ (() => {
748
+ var _el$42 = _$createElement("box");
749
+ _$setProp(_el$42, "flexDirection", "column");
750
+ _$setProp(_el$42, "gap", 0);
751
+ _$setProp(_el$42, "onMouseUp", e => {
752
+ if (e.isSelecting) return;
753
+ props.onToggleExpanded?.();
754
+ });
755
+ _$insert(_el$42, header, null);
756
+ _$insert(_el$42, _$createComponent(Show, {
757
+ get when() {
758
+ return body();
759
+ },
760
+ get children() {
761
+ var _el$43 = _$createElement("box");
762
+ _$setProp(_el$43, "paddingLeft", 2);
763
+ _$setProp(_el$43, "paddingTop", 1);
764
+ _$insert(_el$43, body);
765
+ return _el$43;
368
766
  }
369
- const out = innerCtx.output ? innerCtx.output : JSON.stringify(innerCtx.args ?? {}, null, 2);
370
- const rendered = innerCtx.expanded ? replaceTabs(out) : truncateLines(out, 20).text;
371
- return _jsx(CodeBlock, { content: rendered, filetype: "text", title: "output", showLineNumbers: false });
372
- },
373
- };
374
- // Custom tool rendering: prefer tool-provided renderers, fallback to registry
375
- const tryCustomRenderCall = () => {
376
- if (!props.renderCall)
377
- return null;
378
- try {
379
- return props.renderCall(props.args, theme);
380
- }
381
- catch {
382
- return null; // Fallback to default on error
383
- }
384
- };
385
- const tryCustomRenderResult = () => {
386
- if (!props.renderResult || !props.result)
387
- return null;
388
- try {
389
- return props.renderResult(props.result, { expanded: props.expanded ?? false, isPartial: !props.isComplete }, theme);
390
- }
391
- catch {
392
- return null; // Fallback to default on error
393
- }
394
- };
395
- // Use functions to ensure reactivity
396
- const mode = () => renderer.mode(ctx);
397
- const header = () => tryCustomRenderCall() ?? renderer.renderHeader?.(ctx) ?? defaultHeader(ctx);
398
- const body = () => tryCustomRenderResult() ?? renderer.renderBody?.(ctx);
399
- return (_jsx(Show, { when: mode() === "inline", fallback:
400
- // Block layout - entire block is clickable to toggle
401
- _jsxs("box", { flexDirection: "column", gap: 0, onMouseUp: (e) => {
402
- if (e.isSelecting)
403
- return;
404
- props.onToggleExpanded?.();
405
- }, children: [header(), _jsx(Show, { when: body(), children: _jsx("box", { paddingLeft: 2, paddingTop: 1, children: body() }) })] }), children: _jsx("box", { flexDirection: "row", gap: 0, onMouseUp: (e) => {
406
- if (e.isSelecting)
407
- return;
408
- props.onToggleExpanded?.();
409
- }, children: header() }) }));
410
- }
411
- //# sourceMappingURL=tui-open-rendering.js.map
767
+ }), null);
768
+ return _el$42;
769
+ })()
770
+ );
771
+ },
772
+ get children() {
773
+ var _el$41 = _$createElement("box");
774
+ _$setProp(_el$41, "flexDirection", "row");
775
+ _$setProp(_el$41, "gap", 0);
776
+ _$setProp(_el$41, "onMouseUp", e => {
777
+ if (e.isSelecting) return;
778
+ props.onToggleExpanded?.();
779
+ });
780
+ _$insert(_el$41, header);
781
+ return _el$41;
782
+ }
783
+ });
784
+ }