@renxqoo/renx-code 0.0.1

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 (215) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +278 -0
  3. package/dist/App.d.ts +2 -0
  4. package/dist/App.d.ts.map +1 -0
  5. package/dist/App.js +170 -0
  6. package/dist/App.js.map +1 -0
  7. package/dist/agent/prompts/system.d.ts +24 -0
  8. package/dist/agent/prompts/system.d.ts.map +1 -0
  9. package/dist/agent/prompts/system.js +222 -0
  10. package/dist/agent/prompts/system.js.map +1 -0
  11. package/dist/agent/runtime/event-format.d.ts +17 -0
  12. package/dist/agent/runtime/event-format.d.ts.map +1 -0
  13. package/dist/agent/runtime/event-format.js +194 -0
  14. package/dist/agent/runtime/event-format.js.map +1 -0
  15. package/dist/agent/runtime/model-types.d.ts +13 -0
  16. package/dist/agent/runtime/model-types.d.ts.map +1 -0
  17. package/dist/agent/runtime/model-types.js +1 -0
  18. package/dist/agent/runtime/model-types.js.map +1 -0
  19. package/dist/agent/runtime/runtime.d.ts +16 -0
  20. package/dist/agent/runtime/runtime.d.ts.map +1 -0
  21. package/dist/agent/runtime/runtime.js +691 -0
  22. package/dist/agent/runtime/runtime.js.map +1 -0
  23. package/dist/agent/runtime/source-modules.d.ts +176 -0
  24. package/dist/agent/runtime/source-modules.d.ts.map +1 -0
  25. package/dist/agent/runtime/source-modules.js +110 -0
  26. package/dist/agent/runtime/source-modules.js.map +1 -0
  27. package/dist/agent/runtime/tool-call-buffer.d.ts +12 -0
  28. package/dist/agent/runtime/tool-call-buffer.d.ts.map +1 -0
  29. package/dist/agent/runtime/tool-call-buffer.js +48 -0
  30. package/dist/agent/runtime/tool-call-buffer.js.map +1 -0
  31. package/dist/agent/runtime/tool-confirmation.d.ts +3 -0
  32. package/dist/agent/runtime/tool-confirmation.d.ts.map +1 -0
  33. package/dist/agent/runtime/tool-confirmation.js +9 -0
  34. package/dist/agent/runtime/tool-confirmation.js.map +1 -0
  35. package/dist/agent/runtime/types.d.ts +86 -0
  36. package/dist/agent/runtime/types.d.ts.map +1 -0
  37. package/dist/agent/runtime/types.js +1 -0
  38. package/dist/agent/runtime/types.js.map +1 -0
  39. package/dist/cli.d.ts +3 -0
  40. package/dist/cli.d.ts.map +1 -0
  41. package/dist/cli.js +43 -0
  42. package/dist/cli.js.map +1 -0
  43. package/dist/commands/slash-commands.d.ts +11 -0
  44. package/dist/commands/slash-commands.d.ts.map +1 -0
  45. package/dist/commands/slash-commands.js +48 -0
  46. package/dist/commands/slash-commands.js.map +1 -0
  47. package/dist/components/chat/assistant-reply.d.ts +13 -0
  48. package/dist/components/chat/assistant-reply.d.ts.map +1 -0
  49. package/dist/components/chat/assistant-reply.js +78 -0
  50. package/dist/components/chat/assistant-reply.js.map +1 -0
  51. package/dist/components/chat/assistant-segment.d.ts +8 -0
  52. package/dist/components/chat/assistant-segment.d.ts.map +1 -0
  53. package/dist/components/chat/assistant-segment.js +54 -0
  54. package/dist/components/chat/assistant-segment.js.map +1 -0
  55. package/dist/components/chat/assistant-tool-group.d.ts +7 -0
  56. package/dist/components/chat/assistant-tool-group.d.ts.map +1 -0
  57. package/dist/components/chat/assistant-tool-group.js +695 -0
  58. package/dist/components/chat/assistant-tool-group.js.map +1 -0
  59. package/dist/components/chat/code-block.d.ts +16 -0
  60. package/dist/components/chat/code-block.d.ts.map +1 -0
  61. package/dist/components/chat/code-block.js +194 -0
  62. package/dist/components/chat/code-block.js.map +1 -0
  63. package/dist/components/chat/prompt-card.d.ts +9 -0
  64. package/dist/components/chat/prompt-card.d.ts.map +1 -0
  65. package/dist/components/chat/prompt-card.js +18 -0
  66. package/dist/components/chat/prompt-card.js.map +1 -0
  67. package/dist/components/chat/segment-groups.d.ts +24 -0
  68. package/dist/components/chat/segment-groups.d.ts.map +1 -0
  69. package/dist/components/chat/segment-groups.js +69 -0
  70. package/dist/components/chat/segment-groups.js.map +1 -0
  71. package/dist/components/chat/turn-item.d.ts +9 -0
  72. package/dist/components/chat/turn-item.d.ts.map +1 -0
  73. package/dist/components/chat/turn-item.js +11 -0
  74. package/dist/components/chat/turn-item.js.map +1 -0
  75. package/dist/components/conversation-panel.d.ts +8 -0
  76. package/dist/components/conversation-panel.d.ts.map +1 -0
  77. package/dist/components/conversation-panel.js +8 -0
  78. package/dist/components/conversation-panel.js.map +1 -0
  79. package/dist/components/file-mention-menu.d.ts +11 -0
  80. package/dist/components/file-mention-menu.d.ts.map +1 -0
  81. package/dist/components/file-mention-menu.js +15 -0
  82. package/dist/components/file-mention-menu.js.map +1 -0
  83. package/dist/components/file-picker-dialog.d.ts +21 -0
  84. package/dist/components/file-picker-dialog.d.ts.map +1 -0
  85. package/dist/components/file-picker-dialog.js +48 -0
  86. package/dist/components/file-picker-dialog.js.map +1 -0
  87. package/dist/components/footer-hints.d.ts +7 -0
  88. package/dist/components/footer-hints.d.ts.map +1 -0
  89. package/dist/components/footer-hints.js +29 -0
  90. package/dist/components/footer-hints.js.map +1 -0
  91. package/dist/components/model-picker-dialog.d.ts +20 -0
  92. package/dist/components/model-picker-dialog.d.ts.map +1 -0
  93. package/dist/components/model-picker-dialog.js +72 -0
  94. package/dist/components/model-picker-dialog.js.map +1 -0
  95. package/dist/components/prompt.d.ts +18 -0
  96. package/dist/components/prompt.d.ts.map +1 -0
  97. package/dist/components/prompt.js +96 -0
  98. package/dist/components/prompt.js.map +1 -0
  99. package/dist/components/slash-command-menu.d.ts +9 -0
  100. package/dist/components/slash-command-menu.d.ts.map +1 -0
  101. package/dist/components/slash-command-menu.js +20 -0
  102. package/dist/components/slash-command-menu.js.map +1 -0
  103. package/dist/components/tool-confirm-dialog-content.d.ts +15 -0
  104. package/dist/components/tool-confirm-dialog-content.d.ts.map +1 -0
  105. package/dist/components/tool-confirm-dialog-content.js +143 -0
  106. package/dist/components/tool-confirm-dialog-content.js.map +1 -0
  107. package/dist/components/tool-confirm-dialog.d.ts +12 -0
  108. package/dist/components/tool-confirm-dialog.d.ts.map +1 -0
  109. package/dist/components/tool-confirm-dialog.js +21 -0
  110. package/dist/components/tool-confirm-dialog.js.map +1 -0
  111. package/dist/components/tool-display-config.d.ts +11 -0
  112. package/dist/components/tool-display-config.d.ts.map +1 -0
  113. package/dist/components/tool-display-config.js +94 -0
  114. package/dist/components/tool-display-config.js.map +1 -0
  115. package/dist/config/paths.d.ts +7 -0
  116. package/dist/config/paths.d.ts.map +1 -0
  117. package/dist/config/paths.js +24 -0
  118. package/dist/config/paths.js.map +1 -0
  119. package/dist/files/attachment-capabilities.d.ts +19 -0
  120. package/dist/files/attachment-capabilities.d.ts.map +1 -0
  121. package/dist/files/attachment-capabilities.js +26 -0
  122. package/dist/files/attachment-capabilities.js.map +1 -0
  123. package/dist/files/attachment-content.d.ts +5 -0
  124. package/dist/files/attachment-content.d.ts.map +1 -0
  125. package/dist/files/attachment-content.js +117 -0
  126. package/dist/files/attachment-content.js.map +1 -0
  127. package/dist/files/file-mention-query.d.ts +9 -0
  128. package/dist/files/file-mention-query.d.ts.map +1 -0
  129. package/dist/files/file-mention-query.js +23 -0
  130. package/dist/files/file-mention-query.js.map +1 -0
  131. package/dist/files/prompt-display.d.ts +3 -0
  132. package/dist/files/prompt-display.d.ts.map +1 -0
  133. package/dist/files/prompt-display.js +11 -0
  134. package/dist/files/prompt-display.js.map +1 -0
  135. package/dist/files/types.d.ts +6 -0
  136. package/dist/files/types.d.ts.map +1 -0
  137. package/dist/files/types.js +1 -0
  138. package/dist/files/types.js.map +1 -0
  139. package/dist/files/workspace-files.d.ts +3 -0
  140. package/dist/files/workspace-files.d.ts.map +1 -0
  141. package/dist/files/workspace-files.js +50 -0
  142. package/dist/files/workspace-files.js.map +1 -0
  143. package/dist/hooks/agent-event-handlers.d.ts +11 -0
  144. package/dist/hooks/agent-event-handlers.d.ts.map +1 -0
  145. package/dist/hooks/agent-event-handlers.js +137 -0
  146. package/dist/hooks/agent-event-handlers.js.map +1 -0
  147. package/dist/hooks/chat-local-replies.d.ts +9 -0
  148. package/dist/hooks/chat-local-replies.d.ts.map +1 -0
  149. package/dist/hooks/chat-local-replies.js +54 -0
  150. package/dist/hooks/chat-local-replies.js.map +1 -0
  151. package/dist/hooks/turn-updater.d.ts +9 -0
  152. package/dist/hooks/turn-updater.d.ts.map +1 -0
  153. package/dist/hooks/turn-updater.js +103 -0
  154. package/dist/hooks/turn-updater.js.map +1 -0
  155. package/dist/hooks/use-agent-chat.d.ts +29 -0
  156. package/dist/hooks/use-agent-chat.d.ts.map +1 -0
  157. package/dist/hooks/use-agent-chat.js +455 -0
  158. package/dist/hooks/use-agent-chat.js.map +1 -0
  159. package/dist/hooks/use-file-mention-menu.d.ts +22 -0
  160. package/dist/hooks/use-file-mention-menu.d.ts.map +1 -0
  161. package/dist/hooks/use-file-mention-menu.js +137 -0
  162. package/dist/hooks/use-file-mention-menu.js.map +1 -0
  163. package/dist/hooks/use-file-picker.d.ts +21 -0
  164. package/dist/hooks/use-file-picker.d.ts.map +1 -0
  165. package/dist/hooks/use-file-picker.js +145 -0
  166. package/dist/hooks/use-file-picker.js.map +1 -0
  167. package/dist/hooks/use-model-picker.d.ts +23 -0
  168. package/dist/hooks/use-model-picker.d.ts.map +1 -0
  169. package/dist/hooks/use-model-picker.js +151 -0
  170. package/dist/hooks/use-model-picker.js.map +1 -0
  171. package/dist/hooks/use-slash-command-menu.d.ts +19 -0
  172. package/dist/hooks/use-slash-command-menu.d.ts.map +1 -0
  173. package/dist/hooks/use-slash-command-menu.js +101 -0
  174. package/dist/hooks/use-slash-command-menu.js.map +1 -0
  175. package/dist/index.d.ts +2 -0
  176. package/dist/index.d.ts.map +1 -0
  177. package/dist/index.js +39 -0
  178. package/dist/index.js.map +1 -0
  179. package/dist/runtime/clipboard.d.ts +10 -0
  180. package/dist/runtime/clipboard.d.ts.map +1 -0
  181. package/dist/runtime/clipboard.js +64 -0
  182. package/dist/runtime/clipboard.js.map +1 -0
  183. package/dist/runtime/exit.d.ts +7 -0
  184. package/dist/runtime/exit.d.ts.map +1 -0
  185. package/dist/runtime/exit.js +85 -0
  186. package/dist/runtime/exit.js.map +1 -0
  187. package/dist/runtime/terminal-theme.d.ts +25 -0
  188. package/dist/runtime/terminal-theme.d.ts.map +1 -0
  189. package/dist/runtime/terminal-theme.js +148 -0
  190. package/dist/runtime/terminal-theme.js.map +1 -0
  191. package/dist/types/chat.d.ts +29 -0
  192. package/dist/types/chat.d.ts.map +1 -0
  193. package/dist/types/chat.js +1 -0
  194. package/dist/types/chat.js.map +1 -0
  195. package/dist/types/message-content.d.ts +38 -0
  196. package/dist/types/message-content.d.ts.map +1 -0
  197. package/dist/types/message-content.js +1 -0
  198. package/dist/types/message-content.js.map +1 -0
  199. package/dist/ui/open-code-theme.d.ts +58 -0
  200. package/dist/ui/open-code-theme.d.ts.map +1 -0
  201. package/dist/ui/open-code-theme.js +113 -0
  202. package/dist/ui/open-code-theme.js.map +1 -0
  203. package/dist/ui/opencode-markdown.d.ts +7 -0
  204. package/dist/ui/opencode-markdown.d.ts.map +1 -0
  205. package/dist/ui/opencode-markdown.js +169 -0
  206. package/dist/ui/opencode-markdown.js.map +1 -0
  207. package/dist/ui/theme.d.ts +68 -0
  208. package/dist/ui/theme.d.ts.map +1 -0
  209. package/dist/ui/theme.js +80 -0
  210. package/dist/ui/theme.js.map +1 -0
  211. package/dist/utils/time.d.ts +2 -0
  212. package/dist/utils/time.d.ts.map +1 -0
  213. package/dist/utils/time.js +7 -0
  214. package/dist/utils/time.js.map +1 -0
  215. package/package.json +128 -0
@@ -0,0 +1,695 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "@opentui/react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { uiTheme } from '../../ui/theme';
4
+ import { getToolDisplayIcon, getToolDisplayName } from '../tool-display-config';
5
+ import { CodeBlock } from './code-block';
6
+ const COLLAPSIBLE_OUTPUT_LINES = 16;
7
+ const COLLAPSIBLE_OUTPUT_LABELS = new Set(['output', 'error', 'result', 'details']);
8
+ const asObjectLike = (value) => {
9
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
10
+ return null;
11
+ }
12
+ return value;
13
+ };
14
+ const parseToolArgumentsObject = (raw) => {
15
+ if (!raw) {
16
+ return null;
17
+ }
18
+ try {
19
+ return asObjectLike(JSON.parse(raw));
20
+ }
21
+ catch {
22
+ return null;
23
+ }
24
+ };
25
+ const parseToolUseFromData = (value) => {
26
+ const toolCall = asObjectLike(value);
27
+ const toolFunction = asObjectLike(toolCall?.function);
28
+ if (!toolFunction) {
29
+ return null;
30
+ }
31
+ const name = typeof toolFunction.name === 'string' ? toolFunction.name : undefined;
32
+ const callId = typeof toolCall?.id === 'string' ? toolCall.id : undefined;
33
+ if (!name || !callId) {
34
+ return null;
35
+ }
36
+ const rawArguments = typeof toolFunction.arguments === 'string' ? toolFunction.arguments : undefined;
37
+ const args = parseToolArgumentsObject(rawArguments);
38
+ const command = name === 'bash' && typeof args?.command === 'string' ? args.command : undefined;
39
+ return {
40
+ name,
41
+ callId,
42
+ command,
43
+ details: rawArguments,
44
+ args,
45
+ };
46
+ };
47
+ const parseToolUse = (content, data) => {
48
+ const structured = parseToolUseFromData(data);
49
+ if (structured) {
50
+ return structured;
51
+ }
52
+ if (!content) {
53
+ return null;
54
+ }
55
+ const lines = content.split('\n');
56
+ const header = lines[0]?.trim();
57
+ if (!header) {
58
+ return null;
59
+ }
60
+ const match = header.match(/^# Tool:\s+(.+?)\s+\(([^)]+)\)$/);
61
+ if (!match || !match[1] || !match[2]) {
62
+ return null;
63
+ }
64
+ const [_, name, callId] = match;
65
+ const bodyLines = lines.slice(1);
66
+ const commandLine = bodyLines.find(line => line.trim().startsWith('$ '));
67
+ const command = commandLine ? commandLine.trim().slice(2).trim() : undefined;
68
+ const details = bodyLines
69
+ .filter(line => !line.trim().startsWith('$ '))
70
+ .join('\n')
71
+ .trim();
72
+ return {
73
+ name,
74
+ callId,
75
+ command: command || undefined,
76
+ details: details || undefined,
77
+ args: parseJsonObject(details),
78
+ };
79
+ };
80
+ const parseToolResultFromData = (value) => {
81
+ const event = asObjectLike(value);
82
+ const toolCall = asObjectLike(event?.toolCall);
83
+ const toolFunction = asObjectLike(toolCall?.function);
84
+ const result = asObjectLike(event?.result);
85
+ const data = asObjectLike(result?.data);
86
+ const name = typeof toolFunction?.name === 'string' ? toolFunction.name : undefined;
87
+ const callId = typeof toolCall?.id === 'string' ? toolCall.id : undefined;
88
+ if (!name || !callId) {
89
+ return null;
90
+ }
91
+ const successValue = result?.success;
92
+ const status = successValue === true ? 'success' : successValue === false ? 'error' : 'unknown';
93
+ const summary = typeof data?.summary === 'string' ? data.summary : undefined;
94
+ const output = typeof data?.output === 'string' ? data.output : undefined;
95
+ const error = typeof result?.error === 'string' ? result.error : undefined;
96
+ return {
97
+ name,
98
+ callId,
99
+ status,
100
+ details: output || summary || error,
101
+ summary,
102
+ output,
103
+ payload: data?.payload,
104
+ metadata: data?.metadata,
105
+ error,
106
+ };
107
+ };
108
+ const parseToolResult = (content, data) => {
109
+ const structured = parseToolResultFromData(data);
110
+ if (structured) {
111
+ return structured;
112
+ }
113
+ if (!content) {
114
+ return null;
115
+ }
116
+ const lines = content.split('\n');
117
+ const header = lines[0]?.trim();
118
+ if (!header) {
119
+ return null;
120
+ }
121
+ const match = header.match(/^# Result:\s+(.+?)\s+\(([^)]+)\)\s+(success|error)$/);
122
+ if (!match || !match[1] || !match[2] || !match[3]) {
123
+ return null;
124
+ }
125
+ const [_, name, callId, status] = match;
126
+ const details = lines.slice(1).join('\n').trim();
127
+ return {
128
+ name,
129
+ callId,
130
+ status: status === 'success' || status === 'error' ? status : 'unknown',
131
+ details: details || undefined,
132
+ ...(status === 'error' ? { error: details || undefined } : {}),
133
+ };
134
+ };
135
+ const resolveToolIcon = (toolName) => {
136
+ return getToolDisplayIcon(toolName);
137
+ };
138
+ const mergeOutputLines = (group, parsedResult) => {
139
+ const streamText = group.streams
140
+ .map(segment => segment.content)
141
+ .join('')
142
+ .trim();
143
+ const resultText = parsedResult?.output?.trim() || parsedResult?.details?.trim();
144
+ if (streamText && resultText && streamText === resultText) {
145
+ return streamText;
146
+ }
147
+ if (streamText && resultText) {
148
+ return `${streamText}\n${resultText}`;
149
+ }
150
+ return streamText || resultText || parsedResult?.summary?.trim() || '';
151
+ };
152
+ const readObject = (value) => {
153
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
154
+ return null;
155
+ }
156
+ return value;
157
+ };
158
+ const readArray = (value) => {
159
+ return Array.isArray(value) ? value : [];
160
+ };
161
+ const readString = (value) => {
162
+ return typeof value === 'string' ? value : undefined;
163
+ };
164
+ const readNumber = (value) => {
165
+ return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
166
+ };
167
+ const readBoolean = (value) => {
168
+ return typeof value === 'boolean' ? value : undefined;
169
+ };
170
+ const parseJsonObject = (content) => {
171
+ if (!content) {
172
+ return null;
173
+ }
174
+ try {
175
+ return readObject(JSON.parse(content));
176
+ }
177
+ catch {
178
+ return null;
179
+ }
180
+ };
181
+ const parseJsonValue = (content) => {
182
+ if (!content) {
183
+ return undefined;
184
+ }
185
+ try {
186
+ return JSON.parse(content);
187
+ }
188
+ catch {
189
+ return undefined;
190
+ }
191
+ };
192
+ const countEscapeMarkers = (value) => {
193
+ return (value.match(/\\r\\n|\\n|\\t|\\"|\\\\/g) ?? []).length;
194
+ };
195
+ const decodeEscapeSequencesOnce = (value) => {
196
+ return value
197
+ .replace(/\\r\\n/g, '\n')
198
+ .replace(/\\n/g, '\n')
199
+ .replace(/\\t/g, '\t')
200
+ .replace(/\\"/g, '"')
201
+ .replace(/\\\\/g, '\\');
202
+ };
203
+ const normalizeToolDisplayText = (value) => {
204
+ let current = value.replace(/\r\n/g, '\n').trimEnd();
205
+ for (let index = 0; index < 2; index += 1) {
206
+ const next = decodeEscapeSequencesOnce(current);
207
+ if (countEscapeMarkers(next) >= countEscapeMarkers(current)) {
208
+ break;
209
+ }
210
+ current = next;
211
+ }
212
+ const parsed = parseJsonValue(current);
213
+ if (parsed !== undefined && typeof parsed !== 'string') {
214
+ try {
215
+ return JSON.stringify(parsed, null, 2);
216
+ }
217
+ catch {
218
+ return current;
219
+ }
220
+ }
221
+ return current;
222
+ };
223
+ const resolveSectionLanguageHint = (toolName, section) => {
224
+ if (section.tone !== 'code') {
225
+ return undefined;
226
+ }
227
+ if (section.label === 'command') {
228
+ return toolName === 'bash' ? 'bash' : undefined;
229
+ }
230
+ if (section.label === 'arguments') {
231
+ return 'json';
232
+ }
233
+ return undefined;
234
+ };
235
+ const isCollapsibleResultSection = (section) => {
236
+ if (section.tone !== 'code') {
237
+ return false;
238
+ }
239
+ if (!section.label) {
240
+ return false;
241
+ }
242
+ return COLLAPSIBLE_OUTPUT_LABELS.has(section.label.toLowerCase());
243
+ };
244
+ const resolveStructuredResultObject = (result) => {
245
+ return (readObject(result?.payload) ?? readObject(result?.metadata) ?? parseJsonObject(result?.details));
246
+ };
247
+ const formatToolName = (toolName) => {
248
+ return getToolDisplayName(toolName);
249
+ };
250
+ const truncate = (value, maxLength = 88) => {
251
+ const normalized = value.trim().replace(/\s+/g, ' ');
252
+ if (normalized.length <= maxLength) {
253
+ return normalized;
254
+ }
255
+ return `${normalized.slice(0, maxLength - 1)}…`;
256
+ };
257
+ const compactDetail = (value, maxLength = 72) => {
258
+ if (!value) {
259
+ return null;
260
+ }
261
+ const normalized = value.trim().replace(/\s+/g, ' ');
262
+ if (!normalized) {
263
+ return null;
264
+ }
265
+ return truncate(normalized, maxLength);
266
+ };
267
+ const formatStatusLabel = (status) => {
268
+ if (!status) {
269
+ return null;
270
+ }
271
+ return status.replace(/_/g, ' ');
272
+ };
273
+ const formatTaskStatusIcon = (status) => {
274
+ switch (status) {
275
+ case 'completed':
276
+ return '●';
277
+ case 'in_progress':
278
+ case 'running':
279
+ return '◐';
280
+ case 'pending':
281
+ case 'queued':
282
+ return '○';
283
+ case 'cancelled':
284
+ return '⊘';
285
+ case 'failed':
286
+ case 'timed_out':
287
+ return '×';
288
+ case 'paused':
289
+ return '⏸';
290
+ default:
291
+ return '•';
292
+ }
293
+ };
294
+ const formatSummaryMeta = (parts) => {
295
+ const filtered = parts.map(part => part?.trim()).filter((part) => Boolean(part));
296
+ return filtered.length > 0 ? filtered.join(' · ') : null;
297
+ };
298
+ const summarizeTaskRecord = (task, options) => {
299
+ const subject = readString(task.subject) ?? readString(task.activeForm) ?? readString(task.id) ?? 'task';
300
+ const id = readString(task.id);
301
+ const status = readString(task.status);
302
+ const priority = readString(task.priority);
303
+ const progress = readNumber(task.effective_progress) ?? readNumber(task.progress);
304
+ const owner = readString(task.owner);
305
+ const blockers = readArray(task.blockers).length || readArray(task.blocked_by).length;
306
+ const blocks = readArray(task.blocked_tasks).length || readArray(task.blocks).length;
307
+ const lines = [`${formatTaskStatusIcon(status)} ${truncate(subject)}`];
308
+ const meta = formatSummaryMeta([
309
+ id,
310
+ formatStatusLabel(status),
311
+ priority,
312
+ progress !== undefined ? `${Math.round(progress)}%` : null,
313
+ owner ? `owner ${owner}` : null,
314
+ blockers > 0 ? `${blockers} blocker${blockers === 1 ? '' : 's'}` : null,
315
+ blocks > 0 ? `blocks ${blocks}` : null,
316
+ ]);
317
+ if (meta) {
318
+ lines.push(meta);
319
+ }
320
+ const canStart = options?.canStart;
321
+ if (canStart && readBoolean(canStart.canStart) === false) {
322
+ const reason = readString(canStart.reason);
323
+ if (reason) {
324
+ lines.push(`blocked: ${truncate(reason, 96)}`);
325
+ }
326
+ }
327
+ return lines;
328
+ };
329
+ const summarizeAgentRun = (run, extras) => {
330
+ const agentId = readString(run.agentId);
331
+ const status = readString(run.status);
332
+ const subagentType = readString(run.subagentType);
333
+ const description = readString(run.description);
334
+ const linkedTaskId = readString(run.linkedTaskId);
335
+ const progress = readNumber(run.progress);
336
+ const error = readString(run.error);
337
+ const output = readString(run.output);
338
+ const headline = description ?? agentId ?? 'agent run';
339
+ const lines = [`${formatTaskStatusIcon(status)} ${truncate(headline)}`];
340
+ const meta = formatSummaryMeta([
341
+ agentId,
342
+ formatStatusLabel(status),
343
+ subagentType,
344
+ progress !== undefined ? `${Math.round(progress)}%` : null,
345
+ linkedTaskId ? `task ${linkedTaskId}` : null,
346
+ readBoolean(extras?.completed) === false ? 'still running' : null,
347
+ readBoolean(extras?.timeout_hit) === true ? 'timeout hit' : null,
348
+ readNumber(extras?.waited_ms) !== undefined
349
+ ? `${Math.round((readNumber(extras?.waited_ms) ?? 0) / 1000)}s waited`
350
+ : null,
351
+ ]);
352
+ if (meta) {
353
+ lines.push(meta);
354
+ }
355
+ if (error && !output) {
356
+ lines.push(`error: ${truncate(error, 96)}`);
357
+ }
358
+ return {
359
+ lines,
360
+ output: output?.trim() ? output : undefined,
361
+ };
362
+ };
363
+ const buildTaskHeaderDetail = (toolName, args) => {
364
+ if (!args) {
365
+ return null;
366
+ }
367
+ if (toolName === 'task_create') {
368
+ const subject = readString(args.subject);
369
+ return formatSummaryMeta([
370
+ subject ? `create ${truncate(subject, 56)}` : null,
371
+ readString(args.namespace),
372
+ readString(args.priority),
373
+ readArray(args.checkpoints).length > 0
374
+ ? `${readArray(args.checkpoints).length} checkpoints`
375
+ : null,
376
+ ]);
377
+ }
378
+ if (toolName === 'task_get') {
379
+ return formatSummaryMeta([
380
+ `inspect ${readString(args.task_id) ?? 'task'}`,
381
+ readBoolean(args.include_history) ? 'include history' : null,
382
+ ]);
383
+ }
384
+ if (toolName === 'task_list') {
385
+ const statuses = readArray(args.statuses)
386
+ .map(value => readString(value))
387
+ .filter(Boolean)
388
+ .join(', ');
389
+ return formatSummaryMeta([
390
+ `list${readString(args.namespace) ? ` in ${readString(args.namespace)}` : ''}`,
391
+ statuses ? `status ${statuses}` : null,
392
+ readString(args.owner) ? `owner ${readString(args.owner)}` : null,
393
+ readString(args.tag) ? `tag ${readString(args.tag)}` : null,
394
+ ]);
395
+ }
396
+ if (toolName === 'task_update') {
397
+ const changes = [`update ${readString(args.task_id) ?? 'task'}`];
398
+ if (readString(args.status))
399
+ changes.push(`status -> ${readString(args.status)?.replace(/_/g, ' ')}`);
400
+ if (readNumber(args.progress) !== undefined)
401
+ changes.push(`progress ${Math.round(readNumber(args.progress) ?? 0)}%`);
402
+ if (readString(args.owner))
403
+ changes.push(`owner ${readString(args.owner)}`);
404
+ if (readArray(args.add_blocked_by).length > 0)
405
+ changes.push(`+${readArray(args.add_blocked_by).length} blockers`);
406
+ if (readArray(args.remove_blocked_by).length > 0)
407
+ changes.push(`-${readArray(args.remove_blocked_by).length} blockers`);
408
+ return changes.join(' · ');
409
+ }
410
+ if (toolName === 'task_stop') {
411
+ return formatSummaryMeta([
412
+ `stop ${readString(args.task_id) ?? readString(args.agent_id) ?? 'agent run'}`,
413
+ readBoolean(args.cancel_linked_task) !== false ? 'cancel linked tasks' : null,
414
+ ]);
415
+ }
416
+ if (toolName === 'task_output') {
417
+ return formatSummaryMeta([
418
+ `watch ${readString(args.task_id) ?? readString(args.agent_id) ?? 'agent run'}`,
419
+ readBoolean(args.block) === false ? 'non-blocking poll' : 'wait for completion',
420
+ ]);
421
+ }
422
+ if (toolName === 'agent' || toolName === 'task') {
423
+ const prompt = readString(args.prompt);
424
+ const description = readString(args.description);
425
+ return formatSummaryMeta([
426
+ description ? truncate(description, 56) : prompt ? truncate(prompt, 56) : null,
427
+ readString(args.subagent_type),
428
+ readBoolean(args.run_in_background) ? 'background' : 'foreground',
429
+ readString(args.linked_task_id) ? `task ${readString(args.linked_task_id)}` : null,
430
+ ]);
431
+ }
432
+ return null;
433
+ };
434
+ const buildTaskResultSections = (toolName, result) => {
435
+ const resultDetails = result?.details?.trim();
436
+ const summary = result?.summary?.trim();
437
+ if (!resultDetails && !summary && !result?.payload && !result?.metadata) {
438
+ return [];
439
+ }
440
+ if (result?.status === 'error') {
441
+ return [
442
+ {
443
+ label: 'result',
444
+ content: result?.error?.trim() || resultDetails || summary || 'task failed',
445
+ tone: 'body',
446
+ },
447
+ ];
448
+ }
449
+ const payload = resolveStructuredResultObject(result);
450
+ if (!payload) {
451
+ return [
452
+ {
453
+ label: 'result',
454
+ content: resultDetails || summary || '',
455
+ tone: 'body',
456
+ },
457
+ ];
458
+ }
459
+ if (toolName === 'task_list') {
460
+ const namespace = readString(payload.namespace) ?? 'default';
461
+ const tasks = readArray(payload.tasks)
462
+ .map(item => readObject(item))
463
+ .filter((item) => Boolean(item));
464
+ const total = readNumber(payload.total) ?? tasks.length;
465
+ const lines = [`${total} task${total === 1 ? '' : 's'} in ${namespace}`];
466
+ tasks.slice(0, 5).forEach(task => {
467
+ const summary = summarizeTaskRecord(task);
468
+ if (summary[0]) {
469
+ lines.push(summary[0]);
470
+ }
471
+ if (summary[1]) {
472
+ lines.push(` ${summary[1]}`);
473
+ }
474
+ });
475
+ if (tasks.length > 5) {
476
+ lines.push(`+${tasks.length - 5} more`);
477
+ }
478
+ return [{ label: 'result', content: lines.join('\n'), tone: 'body' }];
479
+ }
480
+ if (toolName === 'task_stop') {
481
+ const run = readObject(payload.agent_run);
482
+ const cancelledTaskIds = readArray(payload.cancelled_task_ids)
483
+ .map(item => readString(item))
484
+ .filter(Boolean);
485
+ const sections = [];
486
+ if (run) {
487
+ sections.push({
488
+ label: 'result',
489
+ content: summarizeAgentRun(run).lines.join('\n'),
490
+ tone: 'body',
491
+ });
492
+ }
493
+ if (cancelledTaskIds.length > 0) {
494
+ sections.push({
495
+ label: 'cancelled',
496
+ content: cancelledTaskIds.join(', '),
497
+ tone: 'body',
498
+ });
499
+ }
500
+ return sections;
501
+ }
502
+ if (toolName === 'task_output' || toolName === 'task' || toolName === 'agent') {
503
+ const run = readObject(payload.agent_run);
504
+ if (run) {
505
+ const summary = summarizeAgentRun(run, payload);
506
+ const sections = [
507
+ {
508
+ label: 'result',
509
+ content: summary.lines.join('\n'),
510
+ tone: 'body',
511
+ },
512
+ ];
513
+ if (summary.output) {
514
+ sections.push({
515
+ label: 'output',
516
+ content: summary.output,
517
+ tone: 'body',
518
+ });
519
+ }
520
+ return sections;
521
+ }
522
+ }
523
+ const task = readObject(payload.task);
524
+ if (task) {
525
+ const canStart = readObject(payload.can_start) ?? readObject(task.can_start);
526
+ return [
527
+ {
528
+ label: 'result',
529
+ content: summarizeTaskRecord(task, { canStart }).join('\n'),
530
+ tone: 'body',
531
+ },
532
+ ];
533
+ }
534
+ return [
535
+ {
536
+ label: 'result',
537
+ content: resultDetails || summary || '',
538
+ tone: 'body',
539
+ },
540
+ ];
541
+ };
542
+ const buildSearchHeaderDetail = (toolName, args) => {
543
+ if (!args) {
544
+ return null;
545
+ }
546
+ if (toolName === 'grep') {
547
+ const pattern = readString(args.pattern);
548
+ if (!pattern) {
549
+ return null;
550
+ }
551
+ return formatSummaryMeta([
552
+ JSON.stringify(pattern),
553
+ readString(args.path) ? `in ${readString(args.path)}` : null,
554
+ readString(args.glob) ? `glob ${readString(args.glob)}` : null,
555
+ readNumber(args.max_results) !== undefined
556
+ ? `limit ${Math.round(readNumber(args.max_results) ?? 0)}`
557
+ : null,
558
+ readNumber(args.timeout_ms) !== undefined
559
+ ? `${Math.round((readNumber(args.timeout_ms) ?? 0) / 1000)}s timeout`
560
+ : null,
561
+ ]);
562
+ }
563
+ if (toolName === 'glob') {
564
+ const pattern = readString(args.pattern);
565
+ if (!pattern) {
566
+ return null;
567
+ }
568
+ return formatSummaryMeta([
569
+ pattern,
570
+ readString(args.path) ? `in ${readString(args.path)}` : null,
571
+ readBoolean(args.include_hidden) ? 'include hidden' : null,
572
+ readNumber(args.max_results) !== undefined
573
+ ? `limit ${Math.round(readNumber(args.max_results) ?? 0)}`
574
+ : null,
575
+ ]);
576
+ }
577
+ return null;
578
+ };
579
+ const buildSearchResultSections = (result) => {
580
+ const summary = result?.summary?.trim();
581
+ const output = result?.output?.trim() || result?.details?.trim();
582
+ const metadata = readObject(result?.metadata) ?? readObject(result?.payload);
583
+ if (!summary && !output && !metadata) {
584
+ return [];
585
+ }
586
+ if (metadata) {
587
+ const matchCount = readNumber(metadata.countMatches);
588
+ const fileCount = readNumber(metadata.countFiles);
589
+ const path = readString(metadata.path);
590
+ const flags = formatSummaryMeta([
591
+ matchCount !== undefined ? `${matchCount} matches` : null,
592
+ fileCount !== undefined ? `${fileCount} files` : null,
593
+ path ? `in ${path}` : null,
594
+ readBoolean(metadata.truncated) ? 'truncated' : null,
595
+ readBoolean(metadata.timed_out) ? 'timed out' : null,
596
+ ]);
597
+ if (summary && output && summary !== output && flags) {
598
+ return [
599
+ { label: 'result', content: summary, tone: 'body' },
600
+ { label: 'details', content: `${flags}\n${output}`, tone: 'body' },
601
+ ];
602
+ }
603
+ }
604
+ return [
605
+ {
606
+ label: 'result',
607
+ content: output || summary || '',
608
+ tone: 'body',
609
+ },
610
+ ];
611
+ };
612
+ const buildSpecialToolPresentation = (toolName, parsedUse, parsedResult) => {
613
+ const args = parsedUse?.args ?? parseJsonObject(parsedUse?.details);
614
+ if (toolName === 'agent' || toolName === 'task' || toolName.startsWith('task_')) {
615
+ const sections = buildTaskResultSections(toolName, parsedResult);
616
+ return {
617
+ toolLabel: formatToolName(toolName),
618
+ headerDetail: buildTaskHeaderDetail(toolName, args) ?? undefined,
619
+ sections,
620
+ };
621
+ }
622
+ if (toolName === 'grep' || toolName === 'glob') {
623
+ const sections = buildSearchResultSections(parsedResult);
624
+ return {
625
+ toolLabel: formatToolName(toolName),
626
+ headerDetail: buildSearchHeaderDetail(toolName, args) ?? undefined,
627
+ sections,
628
+ };
629
+ }
630
+ return null;
631
+ };
632
+ export const AssistantToolGroup = ({ group }) => {
633
+ const [expandedSections, setExpandedSections] = useState({});
634
+ const parsedUse = parseToolUse(group.use?.content, group.use?.data);
635
+ const parsedResult = parseToolResult(group.result?.content, group.result?.data);
636
+ const toolName = parsedUse?.name ?? parsedResult?.name ?? 'tool';
637
+ const commandText = parsedUse?.command;
638
+ const invocationDetails = parsedUse?.details;
639
+ const icon = resolveToolIcon(toolName);
640
+ const outputText = mergeOutputLines(group, parsedResult);
641
+ const _hasInvocationDetails = Boolean(invocationDetails);
642
+ const hasOutput = outputText.length > 0;
643
+ const specialPresentation = buildSpecialToolPresentation(toolName, parsedUse, parsedResult);
644
+ const titleDetail = specialPresentation?.headerDetail ??
645
+ compactDetail(commandText, 64) ??
646
+ compactDetail(invocationDetails, 64);
647
+ const defaultSections = [];
648
+ if (commandText && !titleDetail) {
649
+ defaultSections.push({
650
+ label: 'command',
651
+ content: `$ ${commandText}`,
652
+ tone: 'code',
653
+ });
654
+ }
655
+ if (invocationDetails && !titleDetail) {
656
+ defaultSections.push({
657
+ label: 'arguments',
658
+ content: invocationDetails,
659
+ tone: 'code',
660
+ });
661
+ }
662
+ if (hasOutput) {
663
+ defaultSections.push({
664
+ label: parsedResult?.status === 'error' ? 'error' : 'output',
665
+ content: outputText,
666
+ tone: 'code',
667
+ });
668
+ }
669
+ const sections = specialPresentation?.sections ?? defaultSections;
670
+ const hasBody = sections.length > 0;
671
+ const statusText = parsedResult?.status === 'success'
672
+ ? 'completed'
673
+ : parsedResult?.status === 'error'
674
+ ? 'error'
675
+ : group.result
676
+ ? 'finished'
677
+ : 'running';
678
+ return (_jsxs("box", { flexDirection: "column", children: [_jsx("box", { paddingLeft: 3, children: _jsxs("text", { fg: uiTheme.text, attributes: uiTheme.typography.note, wrapMode: "word", children: [_jsx("span", { fg: uiTheme.accent, children: icon }), ' ', specialPresentation?.toolLabel ?? formatToolName(toolName), titleDetail ? _jsxs("span", { fg: uiTheme.muted, children: ["(", titleDetail, ")"] }) : null, _jsxs("span", { fg: uiTheme.subtle, children: [" (", statusText, ")"] })] }) }), hasBody ? (_jsxs("box", { flexDirection: "row", marginTop: 1, children: [_jsx("box", { width: 1, backgroundColor: uiTheme.divider }), _jsx("box", { flexGrow: 1, backgroundColor: uiTheme.panel, paddingLeft: 2, paddingRight: 1, paddingTop: 1, paddingBottom: 1, children: sections.map((section, index) => {
679
+ const content = normalizeToolDisplayText(section.content);
680
+ const isCode = section.tone === 'code';
681
+ const sectionId = `${toolName}:section:${index}`;
682
+ const collapsible = isCollapsibleResultSection(section);
683
+ const expanded = Boolean(expandedSections[sectionId]);
684
+ return (_jsxs("box", { flexDirection: "column", paddingBottom: index < sections.length - 1 ? 1 : 0, children: [section.label ? (isCode ? null : (_jsx("text", { fg: uiTheme.muted, attributes: uiTheme.typography.note, children: section.label }))) : null, isCode ? (_jsx("box", { children: _jsx(CodeBlock, { content: content, label: section.label, languageHint: resolveSectionLanguageHint(toolName, section), collapsible: collapsible, collapsedLines: COLLAPSIBLE_OUTPUT_LINES, expanded: expanded, onToggleExpanded: () => {
685
+ if (!collapsible) {
686
+ return;
687
+ }
688
+ setExpandedSections(previous => ({
689
+ ...previous,
690
+ [sectionId]: !previous[sectionId],
691
+ }));
692
+ } }) })) : (_jsx("box", { marginTop: section.label ? 1 : 0, children: _jsx("text", { fg: uiTheme.text, attributes: uiTheme.typography.body, wrapMode: "word", children: content }) }))] }, sectionId));
693
+ }) })] })) : null] }));
694
+ };
695
+ //# sourceMappingURL=assistant-tool-group.js.map