claude-code-watch 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.
- package/LICENSE +22 -0
- package/README.md +110 -0
- package/README.zh-CN.md +30 -0
- package/bin/claude-watch.js +187 -0
- package/package.json +38 -0
- package/public/index.html +1206 -0
- package/src/parser/parser.js +528 -0
- package/src/server/server.js +375 -0
- package/src/watcher/watcher.js +1130 -0
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// ============================================================================
|
|
4
|
+
// Constants
|
|
5
|
+
// ============================================================================
|
|
6
|
+
|
|
7
|
+
const StreamItemType = {
|
|
8
|
+
THINKING: 'thinking',
|
|
9
|
+
TOOL_INPUT: 'tool_input',
|
|
10
|
+
TOOL_OUTPUT: 'tool_output',
|
|
11
|
+
TEXT: 'text',
|
|
12
|
+
TURN_MARKER: 'turn_marker',
|
|
13
|
+
COMPACT_MARKER: 'compact_marker',
|
|
14
|
+
HOOK_OUTPUT: 'hook_output',
|
|
15
|
+
DIAGNOSTICS: 'diagnostics',
|
|
16
|
+
PR_LINK: 'pr_link',
|
|
17
|
+
DEBUG: 'debug',
|
|
18
|
+
SESSION_TITLE: 'session_title',
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const AgentIDDisplayLength = 7;
|
|
22
|
+
const debugPreviewLen = 240;
|
|
23
|
+
|
|
24
|
+
let debugAll = false;
|
|
25
|
+
|
|
26
|
+
// ============================================================================
|
|
27
|
+
// Exports
|
|
28
|
+
// ============================================================================
|
|
29
|
+
|
|
30
|
+
function setDebugAll(val) {
|
|
31
|
+
debugAll = val;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function agentDisplayName(agentID) {
|
|
35
|
+
if (!agentID) return 'Main';
|
|
36
|
+
return `Agent-${agentID.slice(0, Math.min(AgentIDDisplayLength, agentID.length))}`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ============================================================================
|
|
40
|
+
// ParseLine
|
|
41
|
+
// ============================================================================
|
|
42
|
+
|
|
43
|
+
function parseLine(line) {
|
|
44
|
+
if (!line || !line.trim()) return [];
|
|
45
|
+
|
|
46
|
+
let raw;
|
|
47
|
+
try {
|
|
48
|
+
raw = JSON.parse(line);
|
|
49
|
+
} catch {
|
|
50
|
+
return []; // gracefully skip malformed lines
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const timestamp = raw.timestamp ? new Date(raw.timestamp) : new Date();
|
|
54
|
+
|
|
55
|
+
const items = [];
|
|
56
|
+
|
|
57
|
+
switch (raw.type) {
|
|
58
|
+
case 'assistant':
|
|
59
|
+
items.push(...parseAssistantMessage(raw, timestamp));
|
|
60
|
+
break;
|
|
61
|
+
case 'user':
|
|
62
|
+
items.push(...parseUserMessage(raw, timestamp));
|
|
63
|
+
break;
|
|
64
|
+
case 'system':
|
|
65
|
+
items.push(...parseSystemMessage(raw, timestamp));
|
|
66
|
+
if (debugAll && items.length === 0) {
|
|
67
|
+
items.push(debugItem(raw, line, timestamp));
|
|
68
|
+
}
|
|
69
|
+
break;
|
|
70
|
+
case 'agent-name':
|
|
71
|
+
items.push(...parseSessionTitle(raw, timestamp, raw.agentName));
|
|
72
|
+
break;
|
|
73
|
+
case 'custom-title':
|
|
74
|
+
items.push(...parseSessionTitle(raw, timestamp, raw.customTitle));
|
|
75
|
+
break;
|
|
76
|
+
case 'attachment':
|
|
77
|
+
items.push(...parseAttachment(raw, timestamp));
|
|
78
|
+
if (debugAll && items.length === 0) {
|
|
79
|
+
items.push(debugItem(raw, line, timestamp));
|
|
80
|
+
}
|
|
81
|
+
break;
|
|
82
|
+
case 'pr-link':
|
|
83
|
+
items.push(...parsePRLink(raw, timestamp));
|
|
84
|
+
break;
|
|
85
|
+
default:
|
|
86
|
+
if (debugAll) {
|
|
87
|
+
items.push(debugItem(raw, line, timestamp));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return items;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ============================================================================
|
|
95
|
+
// Debug item
|
|
96
|
+
// ============================================================================
|
|
97
|
+
|
|
98
|
+
function debugItem(raw, line, timestamp) {
|
|
99
|
+
let label = raw.type;
|
|
100
|
+
if (raw.type === 'system' && raw.subtype) {
|
|
101
|
+
label = `system:${raw.subtype}`;
|
|
102
|
+
} else if (raw.type === 'attachment' && raw.attachment && raw.attachment.type) {
|
|
103
|
+
label = `attachment.${raw.attachment.type}`;
|
|
104
|
+
}
|
|
105
|
+
let preview = line;
|
|
106
|
+
if (preview.length > debugPreviewLen) {
|
|
107
|
+
preview = preview.slice(0, debugPreviewLen) + '\u2026';
|
|
108
|
+
}
|
|
109
|
+
const name = agentDisplayName(raw.agentId);
|
|
110
|
+
return {
|
|
111
|
+
type: StreamItemType.DEBUG,
|
|
112
|
+
sessionID: raw.sessionId,
|
|
113
|
+
agentID: raw.agentId || '',
|
|
114
|
+
agentName: name,
|
|
115
|
+
timestamp,
|
|
116
|
+
toolName: label,
|
|
117
|
+
content: preview,
|
|
118
|
+
toolID: '',
|
|
119
|
+
durationMs: 0,
|
|
120
|
+
inputTokens: 0,
|
|
121
|
+
outputTokens: 0,
|
|
122
|
+
cacheCreationTokens: 0,
|
|
123
|
+
cacheReadTokens: 0,
|
|
124
|
+
model: '',
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// ============================================================================
|
|
129
|
+
// Session Title
|
|
130
|
+
// ============================================================================
|
|
131
|
+
|
|
132
|
+
function parseSessionTitle(raw, timestamp, title) {
|
|
133
|
+
if (!title) return [];
|
|
134
|
+
return [{
|
|
135
|
+
type: StreamItemType.SESSION_TITLE,
|
|
136
|
+
sessionID: raw.sessionId,
|
|
137
|
+
agentID: '',
|
|
138
|
+
agentName: '',
|
|
139
|
+
timestamp,
|
|
140
|
+
content: title,
|
|
141
|
+
toolName: '',
|
|
142
|
+
toolID: '',
|
|
143
|
+
durationMs: 0,
|
|
144
|
+
inputTokens: 0,
|
|
145
|
+
outputTokens: 0,
|
|
146
|
+
cacheCreationTokens: 0,
|
|
147
|
+
cacheReadTokens: 0,
|
|
148
|
+
model: '',
|
|
149
|
+
}];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ============================================================================
|
|
153
|
+
// System Messages
|
|
154
|
+
// ============================================================================
|
|
155
|
+
|
|
156
|
+
function parseSystemMessage(raw, timestamp) {
|
|
157
|
+
const name = agentDisplayName(raw.agentId);
|
|
158
|
+
switch (raw.subtype) {
|
|
159
|
+
case 'turn_duration':
|
|
160
|
+
return [{
|
|
161
|
+
type: StreamItemType.TURN_MARKER,
|
|
162
|
+
sessionID: raw.sessionId,
|
|
163
|
+
agentID: raw.agentId || '',
|
|
164
|
+
agentName: name,
|
|
165
|
+
timestamp,
|
|
166
|
+
content: '',
|
|
167
|
+
toolName: '',
|
|
168
|
+
toolID: '',
|
|
169
|
+
durationMs: raw.durationMs || 0,
|
|
170
|
+
inputTokens: 0,
|
|
171
|
+
outputTokens: 0,
|
|
172
|
+
cacheCreationTokens: 0,
|
|
173
|
+
cacheReadTokens: 0,
|
|
174
|
+
model: '',
|
|
175
|
+
}];
|
|
176
|
+
case 'compact_boundary':
|
|
177
|
+
return [{
|
|
178
|
+
type: StreamItemType.COMPACT_MARKER,
|
|
179
|
+
sessionID: raw.sessionId,
|
|
180
|
+
agentID: raw.agentId || '',
|
|
181
|
+
agentName: name,
|
|
182
|
+
timestamp,
|
|
183
|
+
content: formatCompactSummary(raw.compactMetadata),
|
|
184
|
+
toolName: '',
|
|
185
|
+
toolID: '',
|
|
186
|
+
durationMs: 0,
|
|
187
|
+
inputTokens: 0,
|
|
188
|
+
outputTokens: 0,
|
|
189
|
+
cacheCreationTokens: 0,
|
|
190
|
+
cacheReadTokens: 0,
|
|
191
|
+
model: '',
|
|
192
|
+
}];
|
|
193
|
+
default:
|
|
194
|
+
return [];
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function formatCompactSummary(metadata) {
|
|
199
|
+
if (!metadata) return '';
|
|
200
|
+
const parts = [];
|
|
201
|
+
if (metadata.trigger) parts.push(metadata.trigger);
|
|
202
|
+
if (metadata.preTokens > 0) parts.push(`${formatTokenCount(metadata.preTokens)} pre-tokens`);
|
|
203
|
+
return parts.join(', ');
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function formatTokenCount(n) {
|
|
207
|
+
if (n >= 1000000) return `${(n / 1000000).toFixed(1)}M`;
|
|
208
|
+
if (n >= 1000) return `${Math.floor(n / 1000)}k`;
|
|
209
|
+
return String(n);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function contextWindowFor(model) {
|
|
213
|
+
if (!model) return 200000;
|
|
214
|
+
if (model.startsWith('claude-opus-4-7') || model.startsWith('claude-sonnet-4-6')) return 1000000;
|
|
215
|
+
if (model.startsWith('claude-haiku-4-5') || model.startsWith('claude-opus-4-6') ||
|
|
216
|
+
model.startsWith('claude-sonnet-4-5') || model.startsWith('claude-haiku-4')) return 200000;
|
|
217
|
+
return 200000;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// ============================================================================
|
|
221
|
+
// Attachment Messages
|
|
222
|
+
// ============================================================================
|
|
223
|
+
|
|
224
|
+
function parseAttachment(raw, timestamp) {
|
|
225
|
+
if (!raw.attachment) return [];
|
|
226
|
+
const name = agentDisplayName(raw.agentId);
|
|
227
|
+
switch (raw.attachment.type) {
|
|
228
|
+
case 'hook_success': {
|
|
229
|
+
const body = raw.attachment.stdout || '';
|
|
230
|
+
return [{
|
|
231
|
+
type: StreamItemType.HOOK_OUTPUT,
|
|
232
|
+
sessionID: raw.sessionId,
|
|
233
|
+
agentID: raw.agentId || '',
|
|
234
|
+
agentName: name,
|
|
235
|
+
timestamp,
|
|
236
|
+
toolName: raw.attachment.hookName || '',
|
|
237
|
+
content: body,
|
|
238
|
+
toolID: '',
|
|
239
|
+
durationMs: raw.attachment.durationMs || 0,
|
|
240
|
+
inputTokens: 0, outputTokens: 0, cacheCreationTokens: 0, cacheReadTokens: 0, model: '',
|
|
241
|
+
}];
|
|
242
|
+
}
|
|
243
|
+
case 'diagnostics':
|
|
244
|
+
return diagnosticsItems(raw, timestamp, name);
|
|
245
|
+
default:
|
|
246
|
+
return [];
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function diagnosticsItems(raw, timestamp, agentName) {
|
|
251
|
+
if (!raw.attachment || !raw.attachment.files) return [];
|
|
252
|
+
const items = [];
|
|
253
|
+
for (const f of raw.attachment.files) {
|
|
254
|
+
if (!f.diagnostics || f.diagnostics.length === 0) continue;
|
|
255
|
+
items.push({
|
|
256
|
+
type: StreamItemType.DIAGNOSTICS,
|
|
257
|
+
sessionID: raw.sessionId,
|
|
258
|
+
agentID: raw.agentId || '',
|
|
259
|
+
agentName,
|
|
260
|
+
timestamp,
|
|
261
|
+
toolName: diagnosticsHeader(f),
|
|
262
|
+
content: diagnosticsBody(f.diagnostics),
|
|
263
|
+
toolID: '',
|
|
264
|
+
durationMs: 0,
|
|
265
|
+
inputTokens: 0, outputTokens: 0, cacheCreationTokens: 0, cacheReadTokens: 0, model: '',
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
return items;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function diagnosticsHeader(f) {
|
|
272
|
+
const counts = {};
|
|
273
|
+
for (const d of f.diagnostics) {
|
|
274
|
+
const sev = (d.severity || '').toLowerCase();
|
|
275
|
+
counts[sev] = (counts[sev] || 0) + 1;
|
|
276
|
+
}
|
|
277
|
+
const parts = [];
|
|
278
|
+
for (const sev of ['error', 'warning', 'info', 'hint']) {
|
|
279
|
+
if (counts[sev]) {
|
|
280
|
+
const label = counts[sev] === 1 ? sev : `${sev}s`;
|
|
281
|
+
parts.push(`${counts[sev]} ${label}`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
let name = f.uri;
|
|
285
|
+
const idx = name.lastIndexOf('/');
|
|
286
|
+
if (idx >= 0) name = name.slice(idx + 1);
|
|
287
|
+
if (parts.length === 0) return name;
|
|
288
|
+
return `${name} (${parts.join(', ')})`;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function diagnosticsBody(diagnostics) {
|
|
292
|
+
return diagnostics.map(d => {
|
|
293
|
+
const sev = d.severity || '?';
|
|
294
|
+
let line = `[${sev}] ${d.message}`;
|
|
295
|
+
if (d.source) line += ` (${d.source})`;
|
|
296
|
+
return line;
|
|
297
|
+
}).join('\n');
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// ============================================================================
|
|
301
|
+
// PR Link
|
|
302
|
+
// ============================================================================
|
|
303
|
+
|
|
304
|
+
function parsePRLink(raw, timestamp) {
|
|
305
|
+
if (!raw.prNumber && !raw.prUrl) return [];
|
|
306
|
+
let content;
|
|
307
|
+
if (raw.prRepository && raw.prUrl) {
|
|
308
|
+
content = `PR #${raw.prNumber} ${raw.prRepository} \u2192 ${raw.prUrl}`;
|
|
309
|
+
} else if (raw.prUrl) {
|
|
310
|
+
content = `PR #${raw.prNumber} \u2192 ${raw.prUrl}`;
|
|
311
|
+
} else {
|
|
312
|
+
content = `PR #${raw.prNumber}`;
|
|
313
|
+
}
|
|
314
|
+
return [{
|
|
315
|
+
type: StreamItemType.PR_LINK,
|
|
316
|
+
sessionID: raw.sessionId,
|
|
317
|
+
agentID: '',
|
|
318
|
+
agentName: '',
|
|
319
|
+
timestamp,
|
|
320
|
+
content,
|
|
321
|
+
toolName: '',
|
|
322
|
+
toolID: '',
|
|
323
|
+
durationMs: 0,
|
|
324
|
+
inputTokens: 0, outputTokens: 0, cacheCreationTokens: 0, cacheReadTokens: 0, model: '',
|
|
325
|
+
}];
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// ============================================================================
|
|
329
|
+
// Assistant Messages
|
|
330
|
+
// ============================================================================
|
|
331
|
+
|
|
332
|
+
function parseAssistantMessage(raw, timestamp) {
|
|
333
|
+
const msg = raw.message;
|
|
334
|
+
if (!msg || !Array.isArray(msg.content)) return [];
|
|
335
|
+
|
|
336
|
+
const items = [];
|
|
337
|
+
const name = agentDisplayName(raw.agentId);
|
|
338
|
+
|
|
339
|
+
for (const block of msg.content) {
|
|
340
|
+
switch (block.type) {
|
|
341
|
+
case 'thinking':
|
|
342
|
+
if (block.thinking) {
|
|
343
|
+
items.push({
|
|
344
|
+
type: StreamItemType.THINKING,
|
|
345
|
+
agentID: raw.agentId || '',
|
|
346
|
+
agentName: name,
|
|
347
|
+
timestamp,
|
|
348
|
+
content: block.thinking,
|
|
349
|
+
toolName: '',
|
|
350
|
+
toolID: '',
|
|
351
|
+
durationMs: 0,
|
|
352
|
+
inputTokens: 0, outputTokens: 0, cacheCreationTokens: 0, cacheReadTokens: 0, model: '',
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
break;
|
|
356
|
+
case 'text':
|
|
357
|
+
if (block.text) {
|
|
358
|
+
items.push({
|
|
359
|
+
type: StreamItemType.TEXT,
|
|
360
|
+
agentID: raw.agentId || '',
|
|
361
|
+
agentName: name,
|
|
362
|
+
timestamp,
|
|
363
|
+
content: block.text,
|
|
364
|
+
toolName: '',
|
|
365
|
+
toolID: '',
|
|
366
|
+
durationMs: 0,
|
|
367
|
+
inputTokens: 0, outputTokens: 0, cacheCreationTokens: 0, cacheReadTokens: 0, model: '',
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
break;
|
|
371
|
+
case 'tool_use':
|
|
372
|
+
items.push({
|
|
373
|
+
type: StreamItemType.TOOL_INPUT,
|
|
374
|
+
agentID: raw.agentId || '',
|
|
375
|
+
agentName: name,
|
|
376
|
+
timestamp,
|
|
377
|
+
content: formatToolInput(block.name, block.input),
|
|
378
|
+
toolName: prettyToolName(block.name),
|
|
379
|
+
toolID: block.id || '',
|
|
380
|
+
durationMs: 0,
|
|
381
|
+
inputTokens: 0, outputTokens: 0, cacheCreationTokens: 0, cacheReadTokens: 0, model: '',
|
|
382
|
+
});
|
|
383
|
+
break;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// Attach token usage + model to first item only
|
|
388
|
+
if (items.length > 0 && msg.usage) {
|
|
389
|
+
items[0].inputTokens = msg.usage.input_tokens || 0;
|
|
390
|
+
items[0].outputTokens = msg.usage.output_tokens || 0;
|
|
391
|
+
items[0].cacheCreationTokens = msg.usage.cache_creation_input_tokens || 0;
|
|
392
|
+
items[0].cacheReadTokens = msg.usage.cache_read_input_tokens || 0;
|
|
393
|
+
}
|
|
394
|
+
if (items.length > 0 && msg.model && msg.model !== '<synthetic>') {
|
|
395
|
+
items[0].model = msg.model;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
return items;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// ============================================================================
|
|
402
|
+
// User Messages
|
|
403
|
+
// ============================================================================
|
|
404
|
+
|
|
405
|
+
function parseUserMessage(raw, timestamp) {
|
|
406
|
+
const msg = raw.message;
|
|
407
|
+
if (!msg || !Array.isArray(msg.content)) return [];
|
|
408
|
+
|
|
409
|
+
// Parse toolUseResult for duration
|
|
410
|
+
let durationMs = 0;
|
|
411
|
+
if (raw.toolUseResult && typeof raw.toolUseResult.durationMs === 'number') {
|
|
412
|
+
durationMs = raw.toolUseResult.durationMs;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
const items = [];
|
|
416
|
+
const name = agentDisplayName(raw.agentId);
|
|
417
|
+
|
|
418
|
+
for (const result of msg.content) {
|
|
419
|
+
if (result.type === 'tool_result') {
|
|
420
|
+
items.push({
|
|
421
|
+
type: StreamItemType.TOOL_OUTPUT,
|
|
422
|
+
agentID: raw.agentId || '',
|
|
423
|
+
agentName: name,
|
|
424
|
+
timestamp,
|
|
425
|
+
content: extractToolResultContent(result.content),
|
|
426
|
+
toolName: '',
|
|
427
|
+
toolID: result.tool_use_id || '',
|
|
428
|
+
durationMs,
|
|
429
|
+
inputTokens: 0, outputTokens: 0, cacheCreationTokens: 0, cacheReadTokens: 0, model: '',
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
return items;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
function extractToolResultContent(content) {
|
|
438
|
+
if (!content) return '';
|
|
439
|
+
if (typeof content === 'string') return content;
|
|
440
|
+
if (Array.isArray(content)) {
|
|
441
|
+
const parts = content
|
|
442
|
+
.filter(b => b.text)
|
|
443
|
+
.map(b => b.text);
|
|
444
|
+
return parts.join('\n');
|
|
445
|
+
}
|
|
446
|
+
// Fallback: stringify
|
|
447
|
+
try {
|
|
448
|
+
return JSON.stringify(content);
|
|
449
|
+
} catch {
|
|
450
|
+
return String(content);
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// ============================================================================
|
|
455
|
+
// Tool Input Formatting
|
|
456
|
+
// ============================================================================
|
|
457
|
+
|
|
458
|
+
function formatToolInput(toolName, input) {
|
|
459
|
+
if (!input) return '';
|
|
460
|
+
const inp = input;
|
|
461
|
+
|
|
462
|
+
switch (toolName) {
|
|
463
|
+
case 'Bash':
|
|
464
|
+
if (inp.description) return `${inp.command}\n # ${inp.description}`;
|
|
465
|
+
return inp.command || '';
|
|
466
|
+
case 'Read':
|
|
467
|
+
return inp.file_path || '';
|
|
468
|
+
case 'Write':
|
|
469
|
+
return `${inp.file_path || ''} (${(inp.content || '').length} bytes)`;
|
|
470
|
+
case 'Edit':
|
|
471
|
+
return inp.file_path || '';
|
|
472
|
+
case 'Glob':
|
|
473
|
+
if (inp.path) return `${inp.pattern} in ${inp.path}`;
|
|
474
|
+
return inp.pattern || '';
|
|
475
|
+
case 'Grep':
|
|
476
|
+
if (inp.path) return `/${inp.pattern}/ in ${inp.path}`;
|
|
477
|
+
return `/${inp.pattern}/`;
|
|
478
|
+
case 'WebFetch':
|
|
479
|
+
return inp.prompt || '';
|
|
480
|
+
case 'WebSearch':
|
|
481
|
+
return inp.query || '';
|
|
482
|
+
case 'Task':
|
|
483
|
+
case 'Agent':
|
|
484
|
+
if (inp.description) return inp.description;
|
|
485
|
+
return inp.prompt || '';
|
|
486
|
+
case 'Skill':
|
|
487
|
+
if (inp.args) return `${inp.skill} \u2014 ${inp.args}`;
|
|
488
|
+
return inp.skill || '';
|
|
489
|
+
case 'ToolSearch':
|
|
490
|
+
return inp.query || '';
|
|
491
|
+
case 'ScheduleWakeup':
|
|
492
|
+
if (inp.reason) return inp.reason;
|
|
493
|
+
if (inp.delaySeconds > 0) return `delay ${inp.delaySeconds}s`;
|
|
494
|
+
return JSON.stringify(input);
|
|
495
|
+
case 'TaskCreate':
|
|
496
|
+
return inp.subject || '';
|
|
497
|
+
case 'TaskUpdate':
|
|
498
|
+
if (inp.taskId) return `task ${inp.taskId}`;
|
|
499
|
+
return JSON.stringify(input);
|
|
500
|
+
case 'TaskStop':
|
|
501
|
+
return inp.task_id || '';
|
|
502
|
+
case 'EnterPlanMode':
|
|
503
|
+
return '(enter plan mode)';
|
|
504
|
+
case 'ExitPlanMode':
|
|
505
|
+
return '(exit plan mode)';
|
|
506
|
+
case 'CronCreate':
|
|
507
|
+
if (inp.cron && inp.prompt) return `${inp.cron}: ${inp.prompt}`;
|
|
508
|
+
return JSON.stringify(input);
|
|
509
|
+
default:
|
|
510
|
+
return JSON.stringify(input);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
function prettyToolName(name) {
|
|
515
|
+
if (!name.startsWith('mcp__')) return name;
|
|
516
|
+
const idx = name.lastIndexOf('__');
|
|
517
|
+
if (idx <= 'mcp__'.length - 2 || idx === name.length - 2) return name;
|
|
518
|
+
return 'mcp:' + name.slice(idx + 2);
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
module.exports = {
|
|
522
|
+
StreamItemType,
|
|
523
|
+
parseLine,
|
|
524
|
+
setDebugAll,
|
|
525
|
+
contextWindowFor,
|
|
526
|
+
formatTokenCount,
|
|
527
|
+
AgentIDDisplayLength,
|
|
528
|
+
};
|