@crewx/dreaming 0.1.0-rc.172 → 0.1.0-rc.173

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.
@@ -1,571 +1 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.READ_ONLY_BASH_PREFIXES = exports.READ_ONLY_TOOLS = void 0;
37
- exports.normalizeToolName = normalizeToolName;
38
- exports.extractToolCallsFromLogs = extractToolCallsFromLogs;
39
- exports.analyzeTask = analyzeTask;
40
- exports.isReadOnlyToolCall = isReadOnlyToolCall;
41
- exports.checkFileStaleness = checkFileStaleness;
42
- exports.extractActivityLogEntries = extractActivityLogEntries;
43
- exports.buildActivityLog = buildActivityLog;
44
- exports.summarizeAnalysis = summarizeAnalysis;
45
- const fs = __importStar(require("fs"));
46
- const sdk_1 = require("@crewx/sdk");
47
- const VERIFY_COMMANDS = [
48
- 'tsc', 'npm test', 'npm run test', 'npm run lint', 'eslint',
49
- 'prettier', 'jest', 'vitest', 'biome', 'npx tsc',
50
- ];
51
- const BASH_ERROR_PATTERNS = [
52
- /error/i, /failed/i, /exit code [^0]/, /cannot find/i,
53
- /does not exist/i, /FAILED/, /✗/, /ERR!/,
54
- ];
55
- const ERROR_CATEGORIES = [
56
- [/Type .+ is not assignable to type/i, 'Type mismatch'],
57
- [/Cannot find module/i, 'Module path error'],
58
- [/Property .+ does not exist/i, 'Missing property'],
59
- [/Expected \d+ arguments/i, 'Argument count mismatch'],
60
- [/Cannot find name/i, 'Undeclared variable/function'],
61
- [/has no exported member/i, 'Missing export'],
62
- [/FAIL|AssertionError|expect\(/i, 'Test failure'],
63
- [/SyntaxError|Unexpected token/i, 'Syntax error'],
64
- ];
65
- const FILE_PLACEHOLDERS = new Set(['Read File', 'Edit File', 'Write File', 'Terminal', '{}', '']);
66
- function normalizeToolName(name) {
67
- if (!name)
68
- return '';
69
- const lower = name.toLowerCase();
70
- if (lower === 'bash' || lower === 'terminal')
71
- return 'Bash';
72
- if (lower === 'read' || lower === 'view')
73
- return 'Read';
74
- if (lower === 'edit' || lower === 'apply_patch')
75
- return 'Edit';
76
- if (lower === 'write')
77
- return 'Write';
78
- if (lower === 'grep' || lower === 'rg')
79
- return 'Grep';
80
- if (lower === 'glob' || lower === 'find')
81
- return 'Find';
82
- return name;
83
- }
84
- function shortenPath(p) {
85
- const segments = p.replace(/\\/g, '/').split('/').filter(Boolean);
86
- const keep = segments.length <= 3 ? segments : segments.slice(-3);
87
- return keep.join('/');
88
- }
89
- function extractFilePath(toolName, input) {
90
- const normalized = normalizeToolName(toolName);
91
- if (normalized !== 'Read' && normalized !== 'Edit' && normalized !== 'Write')
92
- return null;
93
- if (!input)
94
- return null;
95
- if (FILE_PLACEHOLDERS.has(input))
96
- return null;
97
- if (input.includes('*** Update File:') || input.includes('*** Add File:')) {
98
- const paths = [];
99
- for (const m of input.matchAll(/\*\*\*\s+(?:Update|Add)\s+File:\s*(.+)/g)) {
100
- const fp = m[1].trim();
101
- if (fp)
102
- paths.push(shortenPath(fp));
103
- }
104
- return paths.length ? paths : null;
105
- }
106
- let cleaned = input;
107
- if (/^(Read|Edit|Write|View)\s+/.test(cleaned)) {
108
- cleaned = cleaned.replace(/^(Read|Edit|Write|View)\s+/, '');
109
- }
110
- if (/[*?{}]/.test(cleaned))
111
- return null;
112
- if (cleaned.length > 300)
113
- return null;
114
- if (!/\.\w+$/.test(cleaned) && !cleaned.includes('/'))
115
- return null;
116
- if (cleaned.startsWith('/') || /^[A-Za-z]:[\\/]/.test(cleaned)) {
117
- return shortenPath(cleaned);
118
- }
119
- return cleaned;
120
- }
121
- function detectProvider(stdoutLines) {
122
- const types = new Set();
123
- for (const line of stdoutLines) {
124
- try {
125
- const p = JSON.parse(line);
126
- if (p.type)
127
- types.add(p.type);
128
- }
129
- catch { }
130
- }
131
- if (types.has('turn.started') || types.has('turn.failed') || types.has('thread.started'))
132
- return 'codex';
133
- if (types.has('assistant.message_delta') || types.has('tool.execution_complete'))
134
- return 'copilot';
135
- if (types.has('step_start') && types.has('step_finish'))
136
- return 'opencode';
137
- if (types.has('system') && types.has('result'))
138
- return 'claude';
139
- if (types.has('init') && types.has('message'))
140
- return 'gemini';
141
- if (types.has('result') && types.has('assistant'))
142
- return 'claude';
143
- return null;
144
- }
145
- function resolveProvider(metaProvider, stdoutLines) {
146
- const key = metaProvider?.split('/').pop();
147
- if (key && key in sdk_1.BUILTIN_ADAPTERS)
148
- return key;
149
- return detectProvider(stdoutLines);
150
- }
151
- function extractToolCallsFromLogs(logs, metaProvider) {
152
- if (!Array.isArray(logs))
153
- return [];
154
- const logEntries = logs;
155
- const stdoutLines = logEntries
156
- .filter((e) => e.level === 'stdout' && e.message)
157
- .map((e) => e.message);
158
- const provider = resolveProvider(metaProvider, stdoutLines);
159
- const allEntries = [];
160
- for (const entry of logEntries) {
161
- if (entry.level === 'info' && entry.message) {
162
- allEntries.push(...(0, sdk_1.defaultParseEvent)(entry.message, entry.timestamp));
163
- }
164
- else if (entry.level === 'stdout' && entry.message) {
165
- allEntries.push(...(0, sdk_1.parseStdoutEvent)('', entry.message, provider ?? undefined));
166
- }
167
- }
168
- if (!allEntries.length)
169
- return [];
170
- const toolUseMap = new Map();
171
- const toolUseOrder = [];
172
- for (const e of allEntries) {
173
- if (e.type === 'tool_use') {
174
- const tc = {
175
- toolUseId: e.toolUseId ?? null,
176
- name: normalizeToolName(e.toolName),
177
- input: e.toolInput ?? null,
178
- isError: null,
179
- resultPreview: null,
180
- };
181
- const id = tc.toolUseId;
182
- if (id) {
183
- if (toolUseMap.has(id)) {
184
- toolUseMap.get(id).input = tc.input;
185
- continue;
186
- }
187
- toolUseMap.set(id, tc);
188
- }
189
- toolUseOrder.push(tc);
190
- }
191
- else if (e.type === 'tool_result') {
192
- const resultE = e;
193
- if (resultE.toolUseId && toolUseMap.has(resultE.toolUseId)) {
194
- const tc = toolUseMap.get(resultE.toolUseId);
195
- tc.isError = resultE.isError === true;
196
- tc.resultPreview = resultE.resultPreview ?? null;
197
- }
198
- else {
199
- for (let i = toolUseOrder.length - 1; i >= 0; i--) {
200
- const tc2 = toolUseOrder[i];
201
- if (tc2.resultPreview === null) {
202
- tc2.isError = resultE.isError === true;
203
- tc2.resultPreview = resultE.resultPreview ?? null;
204
- break;
205
- }
206
- }
207
- }
208
- }
209
- }
210
- return toolUseOrder;
211
- }
212
- function normalizeSkillName(spanName) {
213
- const bracket = spanName.match(/^\[skill:([^\]]+)\]/);
214
- if (bracket) {
215
- const raw = bracket[1];
216
- if (raw === 'memory-v2')
217
- return 'crewx/memory';
218
- return raw;
219
- }
220
- if (spanName.startsWith('skill:'))
221
- return spanName.slice(6);
222
- return spanName;
223
- }
224
- function extractSkillSubCmd(skillName, input) {
225
- if (!input)
226
- return null;
227
- const tokens = input.trim().split(/\s+/);
228
- const stripMap = {
229
- 'crewx/memory': 'memory', 'crewx/doc': 'doc', 'crewx/skill': 'skill',
230
- 'crewx/workflow': 'workflow', 'tsserver': 'tsserver',
231
- };
232
- if (skillName === 'crewx/search')
233
- return null;
234
- let i = 0;
235
- const prefix = stripMap[skillName];
236
- if (prefix && tokens[0] === prefix)
237
- i++;
238
- const sub = tokens[i];
239
- if (!sub || sub.startsWith('-') || sub.startsWith('/'))
240
- return null;
241
- return sub;
242
- }
243
- function aggregateSpans(spans) {
244
- const bySkill = {};
245
- for (const s of spans) {
246
- if (s.input && s.input.includes('summarize-dirty'))
247
- continue;
248
- const skill = normalizeSkillName(s.name);
249
- if (!bySkill[skill])
250
- bySkill[skill] = { count: 0, subCmds: {} };
251
- bySkill[skill].count++;
252
- const sub = extractSkillSubCmd(skill, s.input ?? null);
253
- if (sub)
254
- bySkill[skill].subCmds[sub] = (bySkill[skill].subCmds[sub] ?? 0) + 1;
255
- }
256
- return bySkill;
257
- }
258
- function classifyBashCmd(cmd) {
259
- if (!cmd)
260
- return null;
261
- for (const v of VERIFY_COMMANDS) {
262
- if (cmd.includes(v))
263
- return v;
264
- }
265
- return null;
266
- }
267
- function isBashFailed(tc) {
268
- if (tc.isError === true)
269
- return true;
270
- if (!tc.resultPreview)
271
- return false;
272
- return BASH_ERROR_PATTERNS.some((p) => p.test(tc.resultPreview));
273
- }
274
- function categorizeError(msg) {
275
- if (!msg)
276
- return null;
277
- for (const [pattern, cat] of ERROR_CATEGORIES) {
278
- if (pattern.test(msg))
279
- return cat;
280
- }
281
- return null;
282
- }
283
- function buildTimeline(toolCalls) {
284
- const fileEditCounts = {};
285
- return toolCalls.map((tc) => {
286
- const name = normalizeToolName(tc.name);
287
- const entry = {
288
- name,
289
- input: tc.input,
290
- isError: tc.isError,
291
- resultPreview: tc.resultPreview,
292
- filePath: null,
293
- bashCmd: null,
294
- bashResult: null,
295
- bashErrorMsg: null,
296
- errorCategory: null,
297
- isVerify: false,
298
- editCount: null,
299
- };
300
- if (name === 'Read' || name === 'Edit' || name === 'Write') {
301
- entry.filePath = extractFilePath(tc.name, tc.input);
302
- }
303
- if ((name === 'Edit' || name === 'Write') && entry.filePath) {
304
- const paths = Array.isArray(entry.filePath) ? entry.filePath : [entry.filePath];
305
- for (const p of paths)
306
- fileEditCounts[p] = (fileEditCounts[p] ?? 0) + 1;
307
- entry.editCount = fileEditCounts[paths[0]] ?? null;
308
- }
309
- if (name === 'Bash') {
310
- entry.bashCmd = tc.input ? tc.input.split('\n')[0].slice(0, 150) : '';
311
- entry.isVerify = !!classifyBashCmd(entry.bashCmd);
312
- const failed = isBashFailed(tc);
313
- entry.bashResult = failed ? 'fail' : 'pass';
314
- if (failed && tc.resultPreview) {
315
- entry.bashErrorMsg = tc.resultPreview.trim().split('\n')[0].slice(0, 100);
316
- entry.errorCategory = categorizeError(tc.resultPreview);
317
- }
318
- }
319
- return entry;
320
- });
321
- }
322
- function detectPatterns(timeline) {
323
- const struggles = [];
324
- const efficients = [];
325
- for (let i = 0; i < timeline.length; i++) {
326
- const e = timeline[i];
327
- if (e.name !== 'Bash' || !e.isVerify || e.bashResult !== 'pass')
328
- continue;
329
- const verifyType = classifyBashCmd(e.bashCmd);
330
- const failIndices = [];
331
- let j = i - 1;
332
- while (j >= 0) {
333
- const prev = timeline[j];
334
- if (prev.name === 'Bash' && prev.isVerify) {
335
- if (classifyBashCmd(prev.bashCmd) === verifyType && prev.bashResult === 'fail') {
336
- failIndices.unshift(j);
337
- }
338
- else if (prev.bashResult === 'pass') {
339
- break;
340
- }
341
- }
342
- j--;
343
- }
344
- if (failIndices.length >= 1) {
345
- const startI = failIndices[0];
346
- const editFiles = {};
347
- const errors = [];
348
- for (let k = startI; k <= i; k++) {
349
- const t = timeline[k];
350
- if ((t.name === 'Edit' || t.name === 'Write') && t.filePath) {
351
- const paths = Array.isArray(t.filePath) ? t.filePath : [t.filePath];
352
- for (const p of paths)
353
- editFiles[p] = (editFiles[p] ?? 0) + 1;
354
- }
355
- if (t.name === 'Bash' && t.bashResult === 'fail' && t.bashErrorMsg) {
356
- errors.push(t.bashErrorMsg);
357
- }
358
- }
359
- const errorCategories = errors.map(categorizeError).filter((c) => c !== null);
360
- struggles.push({
361
- startIdx: startI,
362
- endIdx: i,
363
- failCount: failIndices.length,
364
- editFiles,
365
- errors: [...new Set(errors)].slice(0, 3),
366
- errorCategories: [...new Set(errorCategories)],
367
- verifyCmd: verifyType,
368
- });
369
- }
370
- else {
371
- let editCount = 0, readCount = 0, k = i - 1;
372
- while (k >= 0) {
373
- const prev = timeline[k];
374
- if (prev.name === 'Edit' || prev.name === 'Write')
375
- editCount++;
376
- else if (prev.name === 'Read' || prev.name === 'Grep' || prev.name === 'Find')
377
- readCount++;
378
- else
379
- break;
380
- k--;
381
- }
382
- if (editCount > 0) {
383
- efficients.push({ startIdx: k + 1, endIdx: i, readCount, editCount });
384
- }
385
- }
386
- }
387
- return { struggles, efficients };
388
- }
389
- function analyzeTask(row, spans, logs = []) {
390
- let metaProvider = null;
391
- if (row.metadata) {
392
- try {
393
- metaProvider = JSON.parse(row.metadata).provider ?? null;
394
- }
395
- catch { }
396
- }
397
- const toolCalls = extractToolCallsFromLogs(logs, metaProvider ?? undefined);
398
- const duration = row.duration_ms != null ? Math.round(row.duration_ms / 1000) : null;
399
- const timeline = buildTimeline(toolCalls);
400
- const patterns = detectPatterns(timeline);
401
- const readFiles = new Set();
402
- const editFiles = new Set();
403
- let bashCount = 0, verifyRuns = 0;
404
- for (const e of timeline) {
405
- const paths = e.filePath
406
- ? (Array.isArray(e.filePath) ? e.filePath : [e.filePath])
407
- : [];
408
- if (e.name === 'Read')
409
- paths.forEach((p) => readFiles.add(p));
410
- else if (e.name === 'Edit' || e.name === 'Write')
411
- paths.forEach((p) => editFiles.add(p));
412
- else if (e.name === 'Bash') {
413
- bashCount++;
414
- if (e.isVerify)
415
- verifyRuns++;
416
- }
417
- }
418
- const skills = aggregateSpans(spans);
419
- const hasEdits = editFiles.size > 0;
420
- const hasDoc = !!(skills['crewx/doc'] && skills['crewx/doc'].count > 0);
421
- const hasMemory = !!(skills['crewx/memory'] && skills['crewx/memory'].count > 0);
422
- const hasTsserver = !!(skills['tsserver'] && skills['tsserver'].count > 0);
423
- const hasSearch = !!(skills['crewx/search'] && skills['crewx/search'].count > 0);
424
- const promptSummary = row.prompt ? row.prompt.split('\n')[0].slice(0, 120) : null;
425
- const resultSummary = row.result
426
- ? (0, sdk_1.sanitizeLegacyUiCardText)(row.result).split('\n')[0].slice(0, 120)
427
- : null;
428
- return {
429
- taskId: row.id,
430
- agentId: row.agent_id,
431
- metaProvider,
432
- status: row.status,
433
- promptSummary,
434
- resultSummary,
435
- duration,
436
- startedAt: row.started_at ?? null,
437
- completedAt: row.completed_at ?? null,
438
- durationMs: row.duration_ms ?? null,
439
- toolCount: toolCalls.length,
440
- timeline,
441
- patterns,
442
- behavior: {
443
- readFiles: [...readFiles],
444
- editFiles: [...editFiles],
445
- bashCount,
446
- },
447
- metrics: {
448
- struggles: patterns.struggles.length,
449
- total_retries: patterns.struggles.reduce((s, r) => s + r.failCount, 0),
450
- efficients: patterns.efficients.length,
451
- verify_runs: verifyRuns,
452
- },
453
- skills,
454
- skillInsights: { hasEdits, hasDoc, hasMemory, hasTsserver, hasSearch },
455
- hasStruggles: patterns.struggles.length > 0,
456
- };
457
- }
458
- exports.READ_ONLY_TOOLS = new Set([
459
- 'Read', 'Grep', 'Find', 'Glob',
460
- ]);
461
- exports.READ_ONLY_BASH_PREFIXES = [
462
- 'git status', 'git log', 'git branch', 'git diff --stat', 'git show',
463
- 'git remote', 'git rev-parse', 'git ls-files',
464
- 'pwd', 'ls ', 'ls\n', 'echo ',
465
- 'cat ', 'head ', 'tail ',
466
- 'npx skill tsserver find', 'npx skill tsserver refs', 'npx skill tsserver type',
467
- 'crewx memory index', 'crewx memory find', 'crewx memory get',
468
- 'crewx doc toc', 'crewx doc section', 'crewx doc status',
469
- 'crewx search',
470
- 'crewx agent ls', 'crewx agent list',
471
- 'crewx wbs status',
472
- ];
473
- const MUTATING_BASH_PATTERNS = [
474
- /\bgit\s+(commit|push|pull|merge|rebase|reset|checkout|switch|add|rm)\b/,
475
- /\bnpm\s+(install|ci|publish|run\s+(test|lint|build))\b/,
476
- /\bnpx\s+tsc\b/,
477
- /\bpnpm\s+(install|run)\b/,
478
- /\bvitest\b/, /\bjest\b/,
479
- ];
480
- function isReadOnlyToolCall(name, input) {
481
- const normalized = normalizeToolName(name);
482
- if (exports.READ_ONLY_TOOLS.has(normalized))
483
- return true;
484
- if (normalized !== 'Bash')
485
- return false;
486
- if (!input)
487
- return false;
488
- const firstLine = input.split('\n')[0].trimStart();
489
- if (MUTATING_BASH_PATTERNS.some((re) => re.test(firstLine)))
490
- return false;
491
- return exports.READ_ONLY_BASH_PREFIXES.some((prefix) => firstLine.startsWith(prefix));
492
- }
493
- function checkFileStaleness(filePath, taskCompletedAt) {
494
- try {
495
- const stat = fs.statSync(filePath);
496
- if (taskCompletedAt) {
497
- const taskTime = Date.parse(taskCompletedAt);
498
- if (!Number.isNaN(taskTime) && stat.mtimeMs > taskTime)
499
- return 'stale';
500
- }
501
- return 'ok';
502
- }
503
- catch {
504
- return 'unknown';
505
- }
506
- }
507
- function toActivityLogEntry(e, taskCompletedAt) {
508
- if (!isReadOnlyToolCall(e.name, e.input))
509
- return null;
510
- if (e.isError)
511
- return null;
512
- let filePath = null;
513
- let status = 'ok';
514
- if (e.name === 'Read' && e.filePath) {
515
- const fp = Array.isArray(e.filePath) ? e.filePath[0] ?? null : e.filePath;
516
- filePath = fp;
517
- if (fp)
518
- status = checkFileStaleness(fp, taskCompletedAt);
519
- }
520
- const cmd = e.name === 'Bash' ? (e.bashCmd ?? e.input?.slice(0, 150) ?? null) : (e.input?.slice(0, 150) ?? null);
521
- return { tool: e.name, cmd, result: e.resultPreview ?? null, filePath, status };
522
- }
523
- function extractActivityLogEntries(analyses) {
524
- const entries = [];
525
- for (const a of analyses) {
526
- for (const e of a.timeline) {
527
- const entry = toActivityLogEntry(e, a.completedAt);
528
- if (entry)
529
- entries.push(entry);
530
- }
531
- }
532
- return entries;
533
- }
534
- function buildActivityLog(analyses, threadId, agentId, lookback, tokenBudget) {
535
- const allEntries = extractActivityLogEntries(analyses);
536
- const included = [];
537
- let budgetUsed = 0;
538
- let truncated = false;
539
- for (const e of allEntries) {
540
- const size = (e.result?.length ?? 0) + (e.cmd?.length ?? 0) + 80;
541
- if (budgetUsed + size > tokenBudget && included.length > 0) {
542
- truncated = true;
543
- break;
544
- }
545
- included.push(e);
546
- budgetUsed += size;
547
- }
548
- return { threadId, agentId, lookback, totalEntries: allEntries.length, entries: included, truncated, budgetUsed };
549
- }
550
- function summarizeAnalysis(a) {
551
- const toolCounts = {};
552
- for (const e of a.timeline) {
553
- const name = e.name || '?';
554
- toolCounts[name] = (toolCounts[name] ?? 0) + 1;
555
- }
556
- return {
557
- taskId: a.taskId,
558
- agentId: a.agentId,
559
- status: a.status,
560
- duration: a.duration,
561
- startedAt: a.startedAt,
562
- completedAt: a.completedAt,
563
- toolCount: a.toolCount,
564
- toolCounts,
565
- editFiles: a.behavior.editFiles,
566
- readFiles: a.behavior.readFiles,
567
- hasStruggles: a.hasStruggles,
568
- promptSummary: a.promptSummary,
569
- };
570
- }
571
- //# sourceMappingURL=analyzer.js.map
1
+ "use strict";var T=exports&&exports.__createBinding||(Object.create?(function(t,e,s,r){if(r===void 0)r=s;var n=Object.getOwnPropertyDescriptor(e,s);if(!n||("get"in n?!e.__esModule:n.writable||n.configurable)){n={enumerable:true,get:function(){return e[s]}}}Object.defineProperty(t,r,n)}):(function(t,e,s,r){if(r===void 0)r=s;t[r]=e[s]}));var k=exports&&exports.__setModuleDefault||(Object.create?(function(t,e){Object.defineProperty(t,"default",{enumerable:true,value:e})}):function(t,e){t["default"]=e});var L=exports&&exports.__importStar||(function(){var t=function(e){t=Object.getOwnPropertyNames||function(s){var r=[];for(var n in s)if(Object.prototype.hasOwnProperty.call(s,n))r[r.length]=n;return r};return t(e)};return function(e){if(e&&e.__esModule)return e;var s={};if(e!=null){for(var r=t(e),n=0;n<r.length;n++)if(r[n]!=="default")T(s,e,r[n])}k(s,e);return s}})();Object.defineProperty(exports,"__esModule",{value:true});exports.READ_ONLY_BASH_PREFIXES=exports.READ_ONLY_TOOLS=void 0;exports.normalizeToolName=p;exports.extractToolCallsFromLogs=P;exports.analyzeTask=J;exports.isReadOnlyToolCall=S;exports.checkFileStaleness=x;exports.extractActivityLogEntries=R;exports.buildActivityLog=$;exports.summarizeAnalysis=Q;const M=L(require("fs"));const b=require("@crewx/sdk");const B=["tsc","npm test","npm run test","npm run lint","eslint","prettier","jest","vitest","biome","npx tsc"];const N=[/error/i,/failed/i,/exit code [^0]/,/cannot find/i,/does not exist/i,/FAILED/,/✗/,/ERR!/];const U=[[/Type .+ is not assignable to type/i,"Type mismatch"],[/Cannot find module/i,"Module path error"],[/Property .+ does not exist/i,"Missing property"],[/Expected \d+ arguments/i,"Argument count mismatch"],[/Cannot find name/i,"Undeclared variable/function"],[/has no exported member/i,"Missing export"],[/FAIL|AssertionError|expect\(/i,"Test failure"],[/SyntaxError|Unexpected token/i,"Syntax error"]];const z=new Set(["Read File","Edit File","Write File","Terminal","{}",""]);function p(t){if(!t)return"";const e=t.toLowerCase();if(e==="bash"||e==="terminal")return"Bash";if(e==="read"||e==="view")return"Read";if(e==="edit"||e==="apply_patch")return"Edit";if(e==="write")return"Write";if(e==="grep"||e==="rg")return"Grep";if(e==="glob"||e==="find")return"Find";return t}function w(t){const e=t.replace(/\\/g,"/").split("/").filter(Boolean);const s=e.length<=3?e:e.slice(-3);return s.join("/")}function D(t,e){const s=p(t);if(s!=="Read"&&s!=="Edit"&&s!=="Write")return null;if(!e)return null;if(z.has(e))return null;if(e.includes("*** Update File:")||e.includes("*** Add File:")){const n=[];for(const o of e.matchAll(/\*\*\*\s+(?:Update|Add)\s+File:\s*(.+)/g)){const l=o[1].trim();if(l)n.push(w(l))}return n.length?n:null}let r=e;if(/^(Read|Edit|Write|View)\s+/.test(r)){r=r.replace(/^(Read|Edit|Write|View)\s+/,"")}if(/[*?{}]/.test(r))return null;if(r.length>300)return null;if(!/\.\w+$/.test(r)&&!r.includes("/"))return null;if(r.startsWith("/")||/^[A-Za-z]:[\\/]/.test(r)){return w(r)}return r}function W(t){const e=new Set;for(const s of t){try{const r=JSON.parse(s);if(r.type)e.add(r.type)}catch{}}if(e.has("turn.started")||e.has("turn.failed")||e.has("thread.started"))return"codex";if(e.has("assistant.message_delta")||e.has("tool.execution_complete"))return"copilot";if(e.has("step_start")&&e.has("step_finish"))return"opencode";if(e.has("system")&&e.has("result"))return"claude";if(e.has("init")&&e.has("message"))return"gemini";if(e.has("result")&&e.has("assistant"))return"claude";return null}function j(t,e){const s=t?.split("/").pop();if(s&&s in b.BUILTIN_ADAPTERS)return s;return W(e)}function P(t,e){if(!Array.isArray(t))return[];const s=t;const r=s.filter(i=>i.level==="stdout"&&i.message).map(i=>i.message);const n=j(e,r);const o=[];for(const i of s){if(i.level==="info"&&i.message){o.push(...(0,b.defaultParseEvent)(i.message,i.timestamp))}else if(i.level==="stdout"&&i.message){o.push(...(0,b.parseStdoutEvent)("",i.message,n??void 0))}}if(!o.length)return[];const l=new Map;const c=[];for(const i of o){if(i.type==="tool_use"){const a={toolUseId:i.toolUseId??null,name:p(i.toolName),input:i.toolInput??null,isError:null,resultPreview:null};const u=a.toolUseId;if(u){if(l.has(u)){l.get(u).input=a.input;continue}l.set(u,a)}c.push(a)}else if(i.type==="tool_result"){const a=i;if(a.toolUseId&&l.has(a.toolUseId)){const u=l.get(a.toolUseId);u.isError=a.isError===true;u.resultPreview=a.resultPreview??null}else{for(let u=c.length-1;u>=0;u--){const d=c[u];if(d.resultPreview===null){d.isError=a.isError===true;d.resultPreview=a.resultPreview??null;break}}}}}return c}function V(t){const e=t.match(/^\[skill:([^\]]+)\]/);if(e){const s=e[1];if(s==="memory-v2")return"crewx/memory";return s}if(t.startsWith("skill:"))return t.slice(6);return t}function Y(t,e){if(!e)return null;const s=e.trim().split(/\s+/);const r={"crewx/memory":"memory","crewx/doc":"doc","crewx/skill":"skill","crewx/workflow":"workflow","tsserver":"tsserver"};if(t==="crewx/search")return null;let n=0;const o=r[t];if(o&&s[0]===o)n++;const l=s[n];if(!l||l.startsWith("-")||l.startsWith("/"))return null;return l}function G(t){const e={};for(const s of t){if(s.input&&s.input.includes("summarize-dirty"))continue;const r=V(s.name);if(!e[r])e[r]={count:0,subCmds:{}};e[r].count++;const n=Y(r,s.input??null);if(n)e[r].subCmds[n]=(e[r].subCmds[n]??0)+1}return e}function _(t){if(!t)return null;for(const e of B){if(t.includes(e))return e}return null}function H(t){if(t.isError===true)return true;if(!t.resultPreview)return false;return N.some(e=>e.test(t.resultPreview))}function A(t){if(!t)return null;for(const[e,s]of U){if(e.test(t))return s}return null}function X(t){const e={};return t.map(s=>{const r=p(s.name);const n={name:r,input:s.input,isError:s.isError,resultPreview:s.resultPreview,filePath:null,bashCmd:null,bashResult:null,bashErrorMsg:null,errorCategory:null,isVerify:false,editCount:null};if(r==="Read"||r==="Edit"||r==="Write"){n.filePath=D(s.name,s.input)}if((r==="Edit"||r==="Write")&&n.filePath){const o=Array.isArray(n.filePath)?n.filePath:[n.filePath];for(const l of o)e[l]=(e[l]??0)+1;n.editCount=e[o[0]]??null}if(r==="Bash"){n.bashCmd=s.input?s.input.split("\n")[0].slice(0,150):"";n.isVerify=!!_(n.bashCmd);const o=H(s);n.bashResult=o?"fail":"pass";if(o&&s.resultPreview){n.bashErrorMsg=s.resultPreview.trim().split("\n")[0].slice(0,100);n.errorCategory=A(s.resultPreview)}}return n})}function q(t){const e=[];const s=[];for(let r=0;r<t.length;r++){const n=t[r];if(n.name!=="Bash"||!n.isVerify||n.bashResult!=="pass")continue;const o=_(n.bashCmd);const l=[];let c=r-1;while(c>=0){const i=t[c];if(i.name==="Bash"&&i.isVerify){if(_(i.bashCmd)===o&&i.bashResult==="fail"){l.unshift(c)}else if(i.bashResult==="pass"){break}}c--}if(l.length>=1){const i=l[0];const a={};const u=[];for(let f=i;f<=r;f++){const h=t[f];if((h.name==="Edit"||h.name==="Write")&&h.filePath){const v=Array.isArray(h.filePath)?h.filePath:[h.filePath];for(const g of v)a[g]=(a[g]??0)+1}if(h.name==="Bash"&&h.bashResult==="fail"&&h.bashErrorMsg){u.push(h.bashErrorMsg)}}const d=u.map(A).filter(f=>f!==null);e.push({startIdx:i,endIdx:r,failCount:l.length,editFiles:a,errors:[...new Set(u)].slice(0,3),errorCategories:[...new Set(d)],verifyCmd:o})}else{let i=0,a=0,u=r-1;while(u>=0){const d=t[u];if(d.name==="Edit"||d.name==="Write")i++;else if(d.name==="Read"||d.name==="Grep"||d.name==="Find")a++;else break;u--}if(i>0){s.push({startIdx:u+1,endIdx:r,readCount:a,editCount:i})}}}return{struggles:e,efficients:s}}function J(t,e,s=[]){let r=null;if(t.metadata){try{r=JSON.parse(t.metadata).provider??null}catch{}}const n=P(s,r??void 0);const o=t.duration_ms!=null?Math.round(t.duration_ms/1e3):null;const l=X(n);const c=q(l);const i=new Set;const a=new Set;let u=0,d=0;for(const m of l){const y=m.filePath?Array.isArray(m.filePath)?m.filePath:[m.filePath]:[];if(m.name==="Read")y.forEach(E=>i.add(E));else if(m.name==="Edit"||m.name==="Write")y.forEach(E=>a.add(E));else if(m.name==="Bash"){u++;if(m.isVerify)d++}}const f=G(e);const h=a.size>0;const v=!!(f["crewx/doc"]&&f["crewx/doc"].count>0);const g=!!(f["crewx/memory"]&&f["crewx/memory"].count>0);const C=!!(f["tsserver"]&&f["tsserver"].count>0);const O=!!(f["crewx/search"]&&f["crewx/search"].count>0);const F=t.prompt?t.prompt.split("\n")[0].slice(0,120):null;const I=t.result?(0,b.sanitizeLegacyUiCardText)(t.result).split("\n")[0].slice(0,120):null;return{taskId:t.id,agentId:t.agent_id,metaProvider:r,status:t.status,promptSummary:F,resultSummary:I,duration:o,startedAt:t.started_at??null,completedAt:t.completed_at??null,durationMs:t.duration_ms??null,toolCount:n.length,timeline:l,patterns:c,behavior:{readFiles:[...i],editFiles:[...a],bashCount:u},metrics:{struggles:c.struggles.length,total_retries:c.struggles.reduce((m,y)=>m+y.failCount,0),efficients:c.efficients.length,verify_runs:d},skills:f,skillInsights:{hasEdits:h,hasDoc:v,hasMemory:g,hasTsserver:C,hasSearch:O},hasStruggles:c.struggles.length>0}}exports.READ_ONLY_TOOLS=new Set(["Read","Grep","Find","Glob"]);exports.READ_ONLY_BASH_PREFIXES=["git status","git log","git branch","git diff --stat","git show","git remote","git rev-parse","git ls-files","pwd","ls ","ls\n","echo ","cat ","head ","tail ","npx skill tsserver find","npx skill tsserver refs","npx skill tsserver type","crewx memory index","crewx memory find","crewx memory get","crewx doc toc","crewx doc section","crewx doc status","crewx search","crewx agent ls","crewx agent list","crewx wbs status"];const K=[/\bgit\s+(commit|push|pull|merge|rebase|reset|checkout|switch|add|rm)\b/,/\bnpm\s+(install|ci|publish|run\s+(test|lint|build))\b/,/\bnpx\s+tsc\b/,/\bpnpm\s+(install|run)\b/,/\bvitest\b/,/\bjest\b/];function S(t,e){const s=p(t);if(exports.READ_ONLY_TOOLS.has(s))return true;if(s!=="Bash")return false;if(!e)return false;const r=e.split("\n")[0].trimStart();if(K.some(n=>n.test(r)))return false;return exports.READ_ONLY_BASH_PREFIXES.some(n=>r.startsWith(n))}function x(t,e){try{const s=M.statSync(t);if(e){const r=Date.parse(e);if(!Number.isNaN(r)&&s.mtimeMs>r)return"stale"}return"ok"}catch{return"unknown"}}function Z(t,e){if(!S(t.name,t.input))return null;if(t.isError)return null;let s=null;let r="ok";if(t.name==="Read"&&t.filePath){const o=Array.isArray(t.filePath)?t.filePath[0]??null:t.filePath;s=o;if(o)r=x(o,e)}const n=t.name==="Bash"?t.bashCmd??t.input?.slice(0,150)??null:t.input?.slice(0,150)??null;return{tool:t.name,cmd:n,result:t.resultPreview??null,filePath:s,status:r}}function R(t){const e=[];for(const s of t){for(const r of s.timeline){const n=Z(r,s.completedAt);if(n)e.push(n)}}return e}function $(t,e,s,r,n){const o=R(t);const l=[];let c=0;let i=false;for(const a of o){const u=(a.result?.length??0)+(a.cmd?.length??0)+80;if(c+u>n&&l.length>0){i=true;break}l.push(a);c+=u}return{threadId:e,agentId:s,lookback:r,totalEntries:o.length,entries:l,truncated:i,budgetUsed:c}}function Q(t){const e={};for(const s of t.timeline){const r=s.name||"?";e[r]=(e[r]??0)+1}return{taskId:t.taskId,agentId:t.agentId,status:t.status,duration:t.duration,startedAt:t.startedAt,completedAt:t.completedAt,toolCount:t.toolCount,toolCounts:e,editFiles:t.behavior.editFiles,readFiles:t.behavior.readFiles,hasStruggles:t.hasStruggles,promptSummary:t.promptSummary}}
@@ -11,4 +11,4 @@ export interface CalAction {
11
11
  cmd: string;
12
12
  }
13
13
  export declare function buildCalFooter(actions: CalAction[]): string;
14
- //# sourceMappingURL=renderer.d.ts.map
14
+