create-claude-workspace 1.1.131 → 1.1.132
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/scripts/lib/tui.mjs +107 -93
- package/package.json +1 -1
package/dist/scripts/lib/tui.mjs
CHANGED
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
// ─── Terminal UI for autonomous loop ───
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
// Agent names shown as colored prefix on every log line.
|
|
2
|
+
// Events push lines to a buffer. Render loop (4 fps) draws pending lines
|
|
3
|
+
// + status bar. No cursor tricks — just append lines and \r overwrite status.
|
|
5
4
|
import { appendFileSync } from 'node:fs';
|
|
6
5
|
// ─── ANSI ───
|
|
7
6
|
const a = {
|
|
8
|
-
reset: '\x1b[0m',
|
|
9
|
-
bold: '\x1b[1m',
|
|
10
|
-
dim: '\x1b[2m',
|
|
7
|
+
reset: '\x1b[0m', bold: '\x1b[1m', dim: '\x1b[2m',
|
|
11
8
|
fg: {
|
|
12
9
|
red: '\x1b[31m', green: '\x1b[32m', yellow: '\x1b[33m',
|
|
13
10
|
blue: '\x1b[34m', magenta: '\x1b[35m', cyan: '\x1b[36m', white: '\x1b[37m',
|
|
@@ -17,7 +14,7 @@ const a = {
|
|
|
17
14
|
},
|
|
18
15
|
bg: { gray: '\x1b[48;5;236m' },
|
|
19
16
|
};
|
|
20
|
-
// ───
|
|
17
|
+
// ─── Shared utilities ───
|
|
21
18
|
const AGENT_PALETTE = [a.fg.brightCyan, a.fg.brightMagenta, a.fg.brightGreen, a.fg.brightYellow, a.fg.brightBlue, a.fg.brightRed];
|
|
22
19
|
const agentColors = new Map();
|
|
23
20
|
let nextColor = 0;
|
|
@@ -26,13 +23,10 @@ function agentColor(name) {
|
|
|
26
23
|
agentColors.set(name, AGENT_PALETTE[nextColor++ % AGENT_PALETTE.length]);
|
|
27
24
|
return agentColors.get(name);
|
|
28
25
|
}
|
|
29
|
-
// ─── Tool icons ───
|
|
30
26
|
const ICONS = {
|
|
31
27
|
Bash: '⚡', Read: '📖', Write: '✏️ ', Edit: '🔧', Glob: '🔍', Grep: '🔎',
|
|
32
|
-
Agent: '🤖', TodoRead: '📋', TodoWrite: '📝', WebSearch: '🌐', WebFetch: '🌐',
|
|
33
|
-
AskUserQuestion: '❓',
|
|
28
|
+
Agent: '🤖', TodoRead: '📋', TodoWrite: '📝', WebSearch: '🌐', WebFetch: '🌐', AskUserQuestion: '❓',
|
|
34
29
|
};
|
|
35
|
-
// ─── Helpers ───
|
|
36
30
|
function ts() { return new Date().toLocaleTimeString('en-GB', { hour12: false }); }
|
|
37
31
|
function strip(s) { return s.replace(/\x1b\[[0-9;]*m/g, ''); }
|
|
38
32
|
function trunc(s, n) { const c = s.replace(/\n/g, ' ').trim(); return c.length > n ? c.slice(0, n) + '…' : c; }
|
|
@@ -46,6 +40,10 @@ export class TUI {
|
|
|
46
40
|
onInput = null;
|
|
47
41
|
onHotkey = null;
|
|
48
42
|
paused_ = false;
|
|
43
|
+
// Render state
|
|
44
|
+
pendingLines = [];
|
|
45
|
+
renderTimer = null;
|
|
46
|
+
lastStatusLen = 0;
|
|
49
47
|
// Stats
|
|
50
48
|
loopStart = Date.now();
|
|
51
49
|
iteration_ = 0;
|
|
@@ -58,17 +56,60 @@ export class TUI {
|
|
|
58
56
|
iterStart_ = 0;
|
|
59
57
|
agents = [];
|
|
60
58
|
inputBuf = '';
|
|
61
|
-
ticker = null;
|
|
62
|
-
statusVisible = false; // track if status line is currently on screen
|
|
63
59
|
constructor(logFile, interactive = false) {
|
|
64
60
|
this.logFile = logFile;
|
|
65
61
|
this.interactive = interactive && process.stdin.isTTY === true;
|
|
66
62
|
if (this.interactive) {
|
|
67
63
|
this.setupInput();
|
|
68
|
-
|
|
64
|
+
// 4 fps render loop
|
|
65
|
+
this.renderTimer = setInterval(() => this.render(), 250);
|
|
69
66
|
}
|
|
70
67
|
}
|
|
71
|
-
// ───
|
|
68
|
+
// ─── Render loop ───
|
|
69
|
+
render() {
|
|
70
|
+
const out = process.stdout;
|
|
71
|
+
// Clear current status line
|
|
72
|
+
if (this.lastStatusLen > 0) {
|
|
73
|
+
out.write('\r\x1b[2K');
|
|
74
|
+
}
|
|
75
|
+
// Flush pending log lines
|
|
76
|
+
for (const line of this.pendingLines) {
|
|
77
|
+
out.write(line + '\n');
|
|
78
|
+
}
|
|
79
|
+
this.pendingLines = [];
|
|
80
|
+
// Draw status bar (single line, no \n — stays overwritable)
|
|
81
|
+
const status = this.buildStatus();
|
|
82
|
+
out.write(status);
|
|
83
|
+
this.lastStatusLen = strip(status).length;
|
|
84
|
+
}
|
|
85
|
+
buildStatus() {
|
|
86
|
+
const elapsed = fmtDur(Date.now() - this.loopStart);
|
|
87
|
+
const iterTime = this.iterStart_ ? fmtDur(Date.now() - this.iterStart_) : '—';
|
|
88
|
+
const pct = this.maxIter > 0 ? Math.round((this.iteration_ / this.maxIter) * 100) : 0;
|
|
89
|
+
const tok = fmtTok(this.tokens_.input + this.tokens_.output);
|
|
90
|
+
const parts = [
|
|
91
|
+
`${a.fg.white}${elapsed}`,
|
|
92
|
+
`Iter ${this.iteration_}/${this.maxIter} ${bar(pct, 8)}`,
|
|
93
|
+
`${iterTime}`,
|
|
94
|
+
`${a.fg.cyan}${this.tools}${a.reset} tools`,
|
|
95
|
+
`${a.fg.yellow}${tok}${a.reset} tok`,
|
|
96
|
+
];
|
|
97
|
+
if (this.agents.length > 0) {
|
|
98
|
+
const cur = this.agents[this.agents.length - 1];
|
|
99
|
+
parts.push(`${agentColor(cur)}${cur}${a.reset}`);
|
|
100
|
+
}
|
|
101
|
+
if (this.taskName_)
|
|
102
|
+
parts.push(`${a.fg.cyan}${trunc(this.taskName_, 20)}${a.reset}`);
|
|
103
|
+
if (this.paused_)
|
|
104
|
+
parts.push(`${a.fg.yellow}⏸ PAUSED${a.reset}`);
|
|
105
|
+
const info = parts.join(`${a.fg.gray} │ ${a.reset}`);
|
|
106
|
+
const input = this.inputBuf ? ` ${a.fg.gray}›${a.reset} ${this.inputBuf}` : '';
|
|
107
|
+
const cols = process.stdout.columns || 120;
|
|
108
|
+
const line = ` ${info}${input} `;
|
|
109
|
+
const pad = Math.max(0, cols - strip(line).length);
|
|
110
|
+
return `\r${a.bg.gray}${line}${' '.repeat(pad)}${a.reset}`;
|
|
111
|
+
}
|
|
112
|
+
// ─── Input ───
|
|
72
113
|
setupInput() {
|
|
73
114
|
if (!process.stdin.isTTY)
|
|
74
115
|
return;
|
|
@@ -83,7 +124,6 @@ export class TUI {
|
|
|
83
124
|
if (key === '\x1a') {
|
|
84
125
|
this.paused_ = !this.paused_;
|
|
85
126
|
this.onHotkey?.(this.paused_ ? 'pause' : 'resume');
|
|
86
|
-
this.tickStatus();
|
|
87
127
|
return;
|
|
88
128
|
}
|
|
89
129
|
if (key === '\x13') {
|
|
@@ -94,68 +134,37 @@ export class TUI {
|
|
|
94
134
|
if (this.inputBuf.trim())
|
|
95
135
|
this.onInput?.(this.inputBuf.trim());
|
|
96
136
|
this.inputBuf = '';
|
|
97
|
-
this.tickStatus();
|
|
98
137
|
return;
|
|
99
138
|
}
|
|
100
139
|
if (key === '\x7f' || key === '\b') {
|
|
101
140
|
this.inputBuf = this.inputBuf.slice(0, -1);
|
|
102
|
-
this.tickStatus();
|
|
103
141
|
return;
|
|
104
142
|
}
|
|
105
143
|
if (key.length === 1 && key >= ' ') {
|
|
106
144
|
this.inputBuf += key;
|
|
107
|
-
this.tickStatus();
|
|
108
145
|
}
|
|
109
146
|
});
|
|
110
147
|
}
|
|
111
148
|
destroy() {
|
|
112
|
-
if (this.
|
|
113
|
-
clearInterval(this.
|
|
114
|
-
this.
|
|
149
|
+
if (this.renderTimer) {
|
|
150
|
+
clearInterval(this.renderTimer);
|
|
151
|
+
this.renderTimer = null;
|
|
115
152
|
}
|
|
116
|
-
if (this.interactive
|
|
117
|
-
|
|
118
|
-
this.
|
|
153
|
+
if (this.interactive) {
|
|
154
|
+
// Final flush
|
|
155
|
+
this.render();
|
|
119
156
|
process.stdout.write('\n');
|
|
157
|
+
if (process.stdin.isTTY)
|
|
158
|
+
process.stdin.setRawMode(false);
|
|
120
159
|
}
|
|
121
160
|
}
|
|
122
161
|
setInputHandler(handler) { this.onInput = handler; }
|
|
123
162
|
setHotkeyHandler(handler) { this.onHotkey = handler; }
|
|
124
163
|
isPaused() { return this.paused_; }
|
|
125
|
-
// ───
|
|
126
|
-
|
|
127
|
-
const elapsed = fmtDur(Date.now() - this.loopStart);
|
|
128
|
-
const iterTime = this.iterStart_ ? fmtDur(Date.now() - this.iterStart_) : '—';
|
|
129
|
-
const pct = this.maxIter > 0 ? Math.round((this.iteration_ / this.maxIter) * 100) : 0;
|
|
130
|
-
const tok = fmtTok(this.tokens_.input + this.tokens_.output);
|
|
131
|
-
const agent = this.agents.length > 0 ? ` │ ${agentColor(this.agents[this.agents.length - 1])}${this.agents[this.agents.length - 1]}${a.reset}` : '';
|
|
132
|
-
const task = this.taskName_ ? ` │ ${a.fg.cyan}${trunc(this.taskName_, 25)}${a.reset}` : '';
|
|
133
|
-
const pause = this.paused_ ? ` │ ${a.fg.yellow}⏸ PAUSED${a.reset}` : '';
|
|
134
|
-
const input = this.inputBuf ? ` › ${this.inputBuf}` : '';
|
|
135
|
-
return `${a.bg.gray} ${elapsed} │ Iter ${this.iteration_}/${this.maxIter} ${bar(pct, 8)} │ ${iterTime} │ ${this.tools} tools │ ${tok} tok${agent}${task}${pause}${input} ${a.reset}`;
|
|
136
|
-
}
|
|
137
|
-
tickStatus() {
|
|
138
|
-
if (!this.interactive)
|
|
139
|
-
return;
|
|
140
|
-
// Overwrite current status line in place
|
|
141
|
-
const line = this.buildStatusLine();
|
|
142
|
-
const cols = process.stdout.columns || 120;
|
|
143
|
-
const padded = line + ' '.repeat(Math.max(0, cols - strip(line).length));
|
|
144
|
-
process.stdout.write(`\r\x1b[2K${padded}`);
|
|
145
|
-
this.statusVisible = true;
|
|
146
|
-
}
|
|
147
|
-
clearStatus() {
|
|
148
|
-
if (this.statusVisible) {
|
|
149
|
-
process.stdout.write('\r\x1b[2K');
|
|
150
|
-
this.statusVisible = false;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
// ─── Output ───
|
|
154
|
-
out(formatted, raw) {
|
|
164
|
+
// ─── Output (buffered) ───
|
|
165
|
+
push(formatted, raw) {
|
|
155
166
|
if (this.interactive) {
|
|
156
|
-
this.
|
|
157
|
-
console.log(formatted); // print log line (scrolls naturally)
|
|
158
|
-
this.tickStatus(); // redraw status line after log
|
|
167
|
+
this.pendingLines.push(formatted);
|
|
159
168
|
}
|
|
160
169
|
else {
|
|
161
170
|
console.log(formatted);
|
|
@@ -176,13 +185,13 @@ export class TUI {
|
|
|
176
185
|
catch { /* */ }
|
|
177
186
|
}
|
|
178
187
|
}
|
|
179
|
-
// ─── Agent
|
|
188
|
+
// ─── Agent prefix ───
|
|
180
189
|
agentPrefix() {
|
|
181
190
|
if (this.agents.length === 0)
|
|
182
191
|
return '';
|
|
183
|
-
const
|
|
184
|
-
const col = agentColor(
|
|
185
|
-
const short =
|
|
192
|
+
const cur = this.agents[this.agents.length - 1];
|
|
193
|
+
const col = agentColor(cur);
|
|
194
|
+
const short = cur.length > 14 ? cur.slice(0, 14) : cur;
|
|
186
195
|
return `${col}${short}${a.reset} `;
|
|
187
196
|
}
|
|
188
197
|
indent() {
|
|
@@ -192,21 +201,21 @@ export class TUI {
|
|
|
192
201
|
const pipes = this.agents.slice(0, -1).map(n => `${agentColor(n)}│${a.reset}`).join('');
|
|
193
202
|
return ` ${pipes} ${prefix}`;
|
|
194
203
|
}
|
|
195
|
-
// ─── Public
|
|
204
|
+
// ─── Public API ───
|
|
196
205
|
banner() {
|
|
197
|
-
this.
|
|
198
|
-
this.
|
|
199
|
-
this.
|
|
200
|
-
this.
|
|
206
|
+
this.push('');
|
|
207
|
+
this.push(` ${a.fg.cyan}${a.bold}╔══════════════════════════════════════════════╗${a.reset}`);
|
|
208
|
+
this.push(` ${a.fg.cyan}${a.bold}║ ${a.fg.white}Claude Starter Kit — Autonomous Loop${a.fg.cyan} ║${a.reset}`);
|
|
209
|
+
this.push(` ${a.fg.cyan}${a.bold}╚══════════════════════════════════════════════╝${a.reset}`);
|
|
201
210
|
if (this.interactive) {
|
|
202
|
-
this.
|
|
211
|
+
this.push(` ${a.fg.gray} Ctrl+Z pause │ Ctrl+S stop │ Ctrl+C quit │ Type to send input${a.reset}`);
|
|
203
212
|
}
|
|
204
|
-
this.
|
|
213
|
+
this.push('');
|
|
205
214
|
}
|
|
206
|
-
info(msg) { this.
|
|
207
|
-
warn(msg) { this.
|
|
208
|
-
error(msg) { this.
|
|
209
|
-
success(msg) { this.
|
|
215
|
+
info(msg) { this.push(` ${a.fg.gray}${ts()}${a.reset} ${a.fg.blue}ℹ${a.reset} ${msg}`); }
|
|
216
|
+
warn(msg) { this.push(` ${a.fg.gray}${ts()}${a.reset} ${a.fg.yellow}⚠${a.reset} ${a.fg.yellow}${msg}${a.reset}`); }
|
|
217
|
+
error(msg) { this.push(` ${a.fg.gray}${ts()}${a.reset} ${a.fg.red}✗${a.reset} ${a.fg.red}${msg}${a.reset}`); }
|
|
218
|
+
success(msg) { this.push(` ${a.fg.gray}${ts()}${a.reset} ${a.fg.green}✓${a.reset} ${a.fg.green}${msg}${a.reset}`); }
|
|
210
219
|
setIteration(i, max) {
|
|
211
220
|
this.iteration_ = i;
|
|
212
221
|
this.maxIter = max;
|
|
@@ -216,13 +225,13 @@ export class TUI {
|
|
|
216
225
|
this.agents = [];
|
|
217
226
|
const pct = Math.round((i / max) * 100);
|
|
218
227
|
const elapsed = fmtDur(Date.now() - this.loopStart);
|
|
219
|
-
this.
|
|
220
|
-
this.
|
|
228
|
+
this.push('');
|
|
229
|
+
this.push(` ${a.bold}${a.fg.white}━━━ Iteration ${i}/${max} ${bar(pct, 20)} ${pct}% ${a.fg.gray}│ ${elapsed} elapsed${a.fg.white} ━━━${a.reset}`);
|
|
221
230
|
if (this.taskName_) {
|
|
222
231
|
const tPct = this.tasksTotal_ > 0 ? Math.round((this.tasksDone_ / this.tasksTotal_) * 100) : 0;
|
|
223
|
-
this.
|
|
232
|
+
this.push(` ${a.fg.cyan}📋 ${this.taskName_}${a.reset} ${a.fg.gray}(${this.tasksDone_}/${this.tasksTotal_} tasks ${bar(tPct, 10)} ${tPct}%)${a.reset}`);
|
|
224
233
|
}
|
|
225
|
-
this.
|
|
234
|
+
this.push('');
|
|
226
235
|
}
|
|
227
236
|
setTask(name, done, total) {
|
|
228
237
|
this.taskName_ = name;
|
|
@@ -233,8 +242,8 @@ export class TUI {
|
|
|
233
242
|
const iterElapsed = fmtDur(Date.now() - this.iterStart_);
|
|
234
243
|
const totalElapsed = fmtDur(Date.now() - this.loopStart);
|
|
235
244
|
const tok = fmtTok(this.tokens_.input + this.tokens_.output);
|
|
236
|
-
this.
|
|
237
|
-
this.
|
|
245
|
+
this.push('');
|
|
246
|
+
this.push(` ${a.fg.gray}━━━━ ${iterElapsed} (iter) │ ${totalElapsed} (total) │ ${this.tools} tools │ ${tok} tokens ━━━━${a.reset}`);
|
|
238
247
|
}
|
|
239
248
|
// ─── SDK message handler ───
|
|
240
249
|
handleMessage(message) {
|
|
@@ -263,7 +272,7 @@ export class TUI {
|
|
|
263
272
|
}
|
|
264
273
|
for (const block of content) {
|
|
265
274
|
if (block.type === 'text' && block.text?.trim()) {
|
|
266
|
-
this.
|
|
275
|
+
this.push(`${this.indent()}${a.fg.white}${trunc(block.text, 300)}${a.reset}`, `TEXT: ${trunc(block.text, 300)}`);
|
|
267
276
|
}
|
|
268
277
|
if (block.type === 'tool_use')
|
|
269
278
|
this.onToolUse(block);
|
|
@@ -276,14 +285,13 @@ export class TUI {
|
|
|
276
285
|
const input = block.input || {};
|
|
277
286
|
const pre = this.indent();
|
|
278
287
|
const time = `${a.fg.gray}${ts()}${a.reset}`;
|
|
279
|
-
// Agent delegation via tool
|
|
280
288
|
if (name === 'Agent') {
|
|
281
289
|
const type = input.subagent_type || input.type || 'agent';
|
|
282
290
|
const model = input.model ? ` ${a.fg.gray}(${input.model})${a.reset}` : '';
|
|
283
291
|
const desc = trunc(input.description || input.prompt || '', 50);
|
|
284
292
|
const col = agentColor(type);
|
|
285
293
|
this.agents.push(type);
|
|
286
|
-
this.
|
|
294
|
+
this.push(`${pre}${time} ${icon} ${col}${a.bold}${type}${a.reset}${model} ${a.fg.gray}${desc}${a.reset}`, `AGENT: ${type} ${input.model || ''} — ${desc}`);
|
|
287
295
|
return;
|
|
288
296
|
}
|
|
289
297
|
let detail;
|
|
@@ -306,7 +314,7 @@ export class TUI {
|
|
|
306
314
|
break;
|
|
307
315
|
default: detail = `${a.fg.gray}${trunc(JSON.stringify(input), 60)}${a.reset}`;
|
|
308
316
|
}
|
|
309
|
-
this.
|
|
317
|
+
this.push(`${pre}${time} ${icon} ${a.bold}${name}${a.reset} ${detail}`, `TOOL: ${name} ${JSON.stringify(input).slice(0, 200)}`);
|
|
310
318
|
}
|
|
311
319
|
onToolResult(msg) {
|
|
312
320
|
const content = msg.message?.content;
|
|
@@ -320,30 +328,36 @@ export class TUI {
|
|
|
320
328
|
continue;
|
|
321
329
|
const pre = this.indent();
|
|
322
330
|
if (block.is_error) {
|
|
323
|
-
this.
|
|
331
|
+
this.push(`${pre} ${a.fg.red}✗ ${trunc(output, 100)}${a.reset}`, `ERROR: ${trunc(output, 100)}`);
|
|
324
332
|
}
|
|
325
333
|
else if (output.length < 150) {
|
|
326
|
-
this.
|
|
334
|
+
this.push(`${pre} ${a.fg.green}✓${a.reset} ${a.fg.gray}${trunc(output, 100)}${a.reset}`, `OK: ${trunc(output, 100)}`);
|
|
327
335
|
}
|
|
328
336
|
else {
|
|
329
337
|
const n = output.split('\n').length;
|
|
330
|
-
this.
|
|
338
|
+
this.push(`${pre} ${a.fg.green}✓${a.reset} ${a.fg.gray}${n} lines${a.reset}`, `OK: (${n} lines)`);
|
|
331
339
|
}
|
|
332
340
|
}
|
|
333
341
|
}
|
|
334
342
|
onSystem(msg) {
|
|
335
343
|
if (msg.subtype === 'init') {
|
|
336
|
-
const model = msg.model || '
|
|
337
|
-
const agents = msg.agents?.length ? msg.agents.join(', ') : 'none';
|
|
344
|
+
const model = msg.model || '?';
|
|
338
345
|
const ver = msg.claude_code_version || '';
|
|
339
|
-
|
|
346
|
+
const agentList = msg.agents?.join(', ') || 'none';
|
|
347
|
+
this.push(` ${a.fg.gray}${ts()}${a.reset} ${a.fg.cyan}⚙${a.reset} Claude Code ${ver} │ Model: ${a.bold}${model}${a.reset} │ Agents: ${a.fg.cyan}${agentList}${a.reset}`);
|
|
348
|
+
// Set top-level agent name from permissionMode or first agent
|
|
349
|
+
if (this.agents.length === 0 && msg.agents?.length) {
|
|
350
|
+
const topAgent = msg.agents[0];
|
|
351
|
+
this.agents.push(topAgent);
|
|
352
|
+
this.push(` ${a.fg.gray}${ts()}${a.reset} 🤖 ${agentColor(topAgent)}${a.bold}${topAgent}${a.reset} ${a.fg.gray}(${model})${a.reset}`, `AGENT_START: ${topAgent} (${model})`);
|
|
353
|
+
}
|
|
340
354
|
return;
|
|
341
355
|
}
|
|
342
356
|
if (msg.subtype === 'task_started') {
|
|
343
357
|
const desc = msg.description || '';
|
|
344
358
|
const col = agentColor(desc);
|
|
345
359
|
this.agents.push(desc);
|
|
346
|
-
this.
|
|
360
|
+
this.push(` ${a.fg.gray}${ts()}${a.reset} 🤖 ${col}${a.bold}${desc}${a.reset}`, `AGENT_START: ${desc}`);
|
|
347
361
|
return;
|
|
348
362
|
}
|
|
349
363
|
if (msg.subtype === 'task_notification') {
|
|
@@ -352,15 +366,15 @@ export class TUI {
|
|
|
352
366
|
const col = agentColor(name);
|
|
353
367
|
const icon = status === 'completed' ? `${a.fg.green}✓` : `${a.fg.red}✗`;
|
|
354
368
|
const summary = msg.summary ? ` ${a.fg.gray}${trunc(msg.summary, 60)}${a.reset}` : '';
|
|
355
|
-
this.
|
|
369
|
+
this.push(` ${a.fg.gray}${ts()}${a.reset} ${icon}${a.reset} ${col}${name}${a.reset} ${status}${summary}`, `AGENT_END: ${name} ${status}`);
|
|
356
370
|
return;
|
|
357
371
|
}
|
|
358
372
|
if (msg.subtype === 'task_progress' && msg.description) {
|
|
359
|
-
this.
|
|
373
|
+
this.push(`${this.indent()} ${a.dim}${trunc(msg.description, 70)}${a.reset}`, `PROGRESS: ${msg.description}`);
|
|
360
374
|
return;
|
|
361
375
|
}
|
|
362
376
|
if (msg.subtype === 'api_retry') {
|
|
363
|
-
this.
|
|
377
|
+
this.push(` ${a.fg.gray}${ts()}${a.reset} ${a.fg.yellow}↻${a.reset} ${a.fg.yellow}API retry ${msg.attempt}/${msg.max_retries} (${msg.error || ''})${a.reset}`);
|
|
364
378
|
return;
|
|
365
379
|
}
|
|
366
380
|
}
|