@yeshwanthyk/coding-agent 0.3.13 → 0.3.14
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.
- package/dist/adapters/tui/app.js +29 -17
- package/dist/adapters/tui/{app.js.map → app.jsx.map} +1 -1
- package/dist/components/Footer.js +60 -24
- package/dist/components/{Footer.js.map → Footer.jsx.map} +1 -1
- package/dist/components/Header.js +312 -96
- package/dist/components/{Header.js.map → Header.jsx.map} +1 -1
- package/dist/components/MessageList.js +393 -146
- package/dist/components/MessageList.jsx.map +1 -0
- package/dist/runtime/context.js +15 -9
- package/dist/runtime/context.jsx.map +1 -0
- package/dist/session-picker.js +123 -69
- package/dist/session-picker.jsx.map +1 -0
- package/dist/tui-open-rendering.js +716 -343
- package/dist/tui-open-rendering.jsx.map +1 -0
- package/dist/ui/app-shell/TuiApp.js +590 -441
- package/dist/ui/app-shell/{TuiApp.js.map → TuiApp.jsx.map} +1 -1
- package/dist/ui/components/modals/ConfirmModal.js +80 -23
- package/dist/ui/components/modals/ConfirmModal.jsx.map +1 -0
- package/dist/ui/components/modals/EditorModal.js +55 -15
- package/dist/ui/components/modals/EditorModal.jsx.map +1 -0
- package/dist/ui/components/modals/InputModal.js +36 -9
- package/dist/ui/components/modals/InputModal.jsx.map +1 -0
- package/dist/ui/components/modals/ModalContainer.js +72 -16
- package/dist/ui/components/modals/ModalContainer.jsx.map +1 -0
- package/dist/ui/components/modals/SelectModal.js +53 -24
- package/dist/ui/components/modals/SelectModal.jsx.map +1 -0
- package/dist/ui/features/composer/Composer.js +145 -26
- package/dist/ui/features/composer/Composer.jsx.map +1 -0
- package/dist/ui/features/main-view/MainView.js +341 -248
- package/dist/ui/features/main-view/{MainView.js.map → MainView.jsx.map} +1 -1
- package/dist/ui/features/message-pane/MessagePane.js +46 -4
- package/dist/ui/features/message-pane/MessagePane.jsx.map +1 -0
- package/package.json +2 -2
- package/dist/components/MessageList.js.map +0 -1
- package/dist/runtime/context.js.map +0 -1
- package/dist/session-picker.js.map +0 -1
- package/dist/tui-open-rendering.js.map +0 -1
- package/dist/ui/components/modals/ConfirmModal.js.map +0 -1
- package/dist/ui/components/modals/EditorModal.js.map +0 -1
- package/dist/ui/components/modals/InputModal.js.map +0 -1
- package/dist/ui/components/modals/ModalContainer.js.map +0 -1
- package/dist/ui/components/modals/SelectModal.js.map +0 -1
- package/dist/ui/features/composer/Composer.js.map +0 -1
- package/dist/ui/features/message-pane/MessagePane.js.map +0 -1
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
21
|
+
running: "·",
|
|
22
|
+
complete: "▸",
|
|
23
|
+
expanded: "▾",
|
|
24
|
+
error: "✕"
|
|
18
25
|
};
|
|
19
26
|
export const shortenPath = (p, maxLen = 40) => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
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
|
-
|
|
80
|
+
return s.split("\n")[0] || "";
|
|
58
81
|
}
|
|
59
82
|
function truncate(s, max) {
|
|
60
|
-
|
|
61
|
-
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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
|
-
|
|
145
|
-
|
|
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
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
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
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
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
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
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
|
-
|
|
217
|
-
|
|
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
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
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
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
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
|
-
|
|
261
|
-
|
|
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
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
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
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
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
|
-
|
|
300
|
-
|
|
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
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
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
|
-
|
|
327
|
-
|
|
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
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
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
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
|
|
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
|
+
}
|