agent-inspect 4.0.0 → 4.1.0

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,3207 +1,17 @@
1
1
  #!/usr/bin/env node
2
- import { realpathSync, createReadStream, constants as constants$1 } from 'fs';
3
- import path14 from 'path';
2
+ import { resolveTraceDir, TraceDirectory, parseDuration, extractMetadata, filterTraces, truncateName, getTraceFilePath, buildRunSummary, formatDuration, formatTimestamp, isAgentInspectTrace, loadTraceMetadataList, loadSessionRunRecords, filterMetasBySessionScope, aggregateSessionCheckResults, buildRunTimeline, renderTimeline, buildTraceStats, renderTraceStats, parseDurationFilter, searchTraces, buildRunWhatSummary, renderRunWhat, buildLocalExplanation, persistedInspectEventsToTraceEvents, renderStepLine, renderErrorLine, getIndent, Redactor, validateEvent, isPersistedInspectEvent, buildSessionIndex, nanoid, resolveRedactionProfile, applyProfileMetadataCaps, extractCorrelationMetadata, truncateStringForProfile, parseTraceJsonl } from './chunk-MT5G7JFO.mjs';
3
+ import { realpathSync, constants as constants$1 } from 'fs';
4
+ import path10 from 'path';
4
5
  import { fileURLToPath, pathToFileURL } from 'url';
5
6
  import { Command, Option } from 'commander';
6
- import { AsyncLocalStorage } from 'async_hooks';
7
- import crypto, { webcrypto, createHash } from 'crypto';
8
- import { unlink, stat, mkdir, writeFile, appendFile, rm, readdir, readFile, access, open, constants } from 'fs/promises';
9
- import os from 'os';
10
- import process3, { stdin, stdout } from 'process';
11
- import tty from 'tty';
12
- import { createInterface } from 'readline';
7
+ import { unlink, stat, mkdir, writeFile, appendFile, rm, access, readFile, open, readdir, constants } from 'fs/promises';
8
+ import process2, { stdin, stdout } from 'process';
9
+ import crypto, { createHash } from 'crypto';
13
10
  import { createServer } from 'http';
14
11
  import { createRequire } from 'module';
15
12
 
16
13
  // package.json
17
- var version = "4.0.0";
18
-
19
- // packages/core/src/correlation-metadata.ts
20
- var TRACE_CORRELATION_KEYS = [
21
- "correlationId",
22
- "requestId",
23
- "decisionId",
24
- "groupId"
25
- ];
26
- function isNonEmptyString(value) {
27
- return typeof value === "string" && value.length > 0;
28
- }
29
- function extractCorrelationMetadata(record) {
30
- if (!record) {
31
- return void 0;
32
- }
33
- const out = {};
34
- let found = false;
35
- for (const key of TRACE_CORRELATION_KEYS) {
36
- const value = record[key];
37
- if (isNonEmptyString(value)) {
38
- out[key] = value;
39
- found = true;
40
- }
41
- }
42
- return found ? out : void 0;
43
- }
44
- var DEFAULT_REDACT_KEYS = [
45
- "authorization",
46
- "cookie",
47
- "token",
48
- "apiKey",
49
- "password",
50
- "secret",
51
- "email"
52
- ];
53
- function isRecord(v) {
54
- return typeof v === "object" && v !== null && !Array.isArray(v);
55
- }
56
- function toKey(s) {
57
- return s.toLowerCase();
58
- }
59
- function stableHash(value) {
60
- const h = crypto.createHash("sha256").update(value, "utf8").digest("hex");
61
- return h.slice(0, 8);
62
- }
63
- function compileRules(rules, extraKeys) {
64
- const out = /* @__PURE__ */ new Map();
65
- const set = (r) => {
66
- const k = toKey(r.key);
67
- out.set(k, { ...r, key: k });
68
- };
69
- for (const k of DEFAULT_REDACT_KEYS) {
70
- set({ key: k, strategy: "full" });
71
- }
72
- for (const k of extraKeys ?? []) {
73
- if (typeof k === "string" && k.length > 0) {
74
- set({ key: k, strategy: "full" });
75
- }
76
- }
77
- for (const r of rules ?? []) {
78
- if (typeof r === "string") {
79
- set({ key: r, strategy: "full" });
80
- continue;
81
- }
82
- const key = r.key;
83
- if (r.strategy === "full") set({ key, strategy: "full" });
84
- if (r.strategy === "hash") set({ key, strategy: "hash" });
85
- if (r.strategy === "prefix") {
86
- set({ key, strategy: "prefix", keep: typeof r.keep === "number" ? r.keep : 8 });
87
- }
88
- }
89
- return [...out.values()];
90
- }
91
- var Redactor = class {
92
- #rules;
93
- constructor(options) {
94
- this.#rules = compileRules(options?.rules, options?.extraKeys);
95
- }
96
- redactValue(key, value) {
97
- const k = toKey(key);
98
- const rule = this.#rules.find((r) => r.key === k);
99
- if (!rule) {
100
- return this.#redactNested(value);
101
- }
102
- if (rule.strategy === "full") return "[REDACTED]";
103
- const asString = typeof value === "string" ? value : typeof value === "number" || typeof value === "boolean" || typeof value === "bigint" ? String(value) : void 0;
104
- if (rule.strategy === "prefix") {
105
- if (asString === void 0) return "[REDACTED]";
106
- const keep = Math.max(0, Math.floor(rule.keep));
107
- return asString.length <= keep ? `${asString}\u2026` : `${asString.slice(0, keep)}\u2026`;
108
- }
109
- if (rule.strategy === "hash") {
110
- if (asString === void 0) return "[HASH:unknown]";
111
- return `[HASH:${stableHash(asString)}]`;
112
- }
113
- return this.#redactNested(value);
114
- }
115
- redactRecord(record) {
116
- const out = {};
117
- for (const [k, v] of Object.entries(record)) {
118
- out[k] = this.redactValue(k, v);
119
- }
120
- return out;
121
- }
122
- #redactNested(value) {
123
- if (Array.isArray(value)) {
124
- return value.map((v) => this.#redactNested(v));
125
- }
126
- if (isRecord(value)) {
127
- const out = {};
128
- for (const [k, v] of Object.entries(value)) {
129
- out[k] = this.redactValue(k, v);
130
- }
131
- return out;
132
- }
133
- return value;
134
- }
135
- };
136
-
137
- // packages/core/src/redaction-profiles.ts
138
- var SHARE_PROFILE_EXTRA_KEYS = [
139
- "userEmail",
140
- "customerEmail",
141
- "phone",
142
- "phoneNumber",
143
- "address",
144
- "ip",
145
- "ipAddress",
146
- "sessionId",
147
- "requestId",
148
- "correlationId",
149
- "decisionId",
150
- "groupId",
151
- "customerId",
152
- "userId",
153
- "accountId",
154
- "tenantId",
155
- "orgId",
156
- "organizationId",
157
- "traceId",
158
- "spanId",
159
- "parentSpanId"
160
- ];
161
- var STRICT_PROFILE_EXTRA_KEYS = [
162
- "prompt",
163
- "completion",
164
- "input",
165
- "output",
166
- "inputPreview",
167
- "outputPreview",
168
- "message",
169
- "messages",
170
- "transcript",
171
- "context",
172
- "document",
173
- "documents",
174
- "chunk",
175
- "chunks",
176
- "retrieval",
177
- "query"
178
- ];
179
- function resolveRedactionProfile(profile = "local") {
180
- switch (profile) {
181
- case "local":
182
- return { profile: "local", extraKeys: [] };
183
- case "share":
184
- return {
185
- profile: "share",
186
- extraKeys: SHARE_PROFILE_EXTRA_KEYS,
187
- maxMetadataValueLengthCap: 500,
188
- maxPreviewLengthCap: 200
189
- };
190
- case "strict":
191
- return {
192
- profile: "strict",
193
- extraKeys: [...SHARE_PROFILE_EXTRA_KEYS, ...STRICT_PROFILE_EXTRA_KEYS],
194
- maxMetadataValueLengthCap: 200,
195
- maxPreviewLengthCap: 80
196
- };
197
- default:
198
- return { profile: "local", extraKeys: [] };
199
- }
200
- }
201
- function isPreviewKey(key) {
202
- return key.toLowerCase().includes("preview");
203
- }
204
- function applyProfileMetadataCaps(maxMetadataValueLength, maxPreviewLength, resolved) {
205
- let meta = maxMetadataValueLength;
206
- let preview = maxPreviewLength;
207
- if (resolved.maxMetadataValueLengthCap !== void 0) {
208
- meta = Math.min(meta, resolved.maxMetadataValueLengthCap);
209
- }
210
- if (resolved.maxPreviewLengthCap !== void 0) {
211
- preview = Math.min(preview, resolved.maxPreviewLengthCap);
212
- }
213
- return { maxMetadataValueLength: meta, maxPreviewLength: preview };
214
- }
215
- function truncateStringForProfile(value, key, maxMetadataValueLength, maxPreviewLength) {
216
- const max = isPreviewKey(key) ? maxPreviewLength : maxMetadataValueLength;
217
- if (max <= 0) return "\u2026";
218
- if (value.length <= max) return value;
219
- return `${value.slice(0, max)}\u2026`;
220
- }
221
-
222
- // packages/core/src/types.ts
223
- var STEP_TYPES = [
224
- "run",
225
- "llm",
226
- "tool",
227
- "decision",
228
- "logic",
229
- "state",
230
- "custom"
231
- ];
232
- function isRecord2(value) {
233
- return typeof value === "object" && value !== null && !Array.isArray(value);
234
- }
235
- function isStepType(value) {
236
- return typeof value === "string" && STEP_TYPES.includes(value);
237
- }
238
- function isTraceEvent(value) {
239
- if (!isRecord2(value)) return false;
240
- if (value.schemaVersion !== "0.1") return false;
241
- if (typeof value.timestamp !== "number") return false;
242
- if (typeof value.event !== "string") return false;
243
- switch (value.event) {
244
- case "run_started": {
245
- return typeof value.runId === "string" && typeof value.name === "string" && typeof value.startTime === "number";
246
- }
247
- case "run_completed": {
248
- return typeof value.runId === "string" && (value.status === "success" || value.status === "error") && typeof value.endTime === "number" && typeof value.durationMs === "number";
249
- }
250
- case "step_started": {
251
- return typeof value.runId === "string" && typeof value.stepId === "string" && typeof value.name === "string" && isStepType(value.type) && typeof value.startTime === "number";
252
- }
253
- case "step_completed": {
254
- return typeof value.runId === "string" && typeof value.stepId === "string" && (value.status === "success" || value.status === "error") && typeof value.endTime === "number" && typeof value.durationMs === "number";
255
- }
256
- default:
257
- return false;
258
- }
259
- }
260
-
261
- // packages/core/src/types/persisted-inspect-event.ts
262
- var INSPECT_KINDS = [
263
- "RUN",
264
- "AGENT",
265
- "LLM",
266
- "TOOL",
267
- "CHAIN",
268
- "RETRIEVER",
269
- "DECISION",
270
- "RESULT",
271
- "ERROR",
272
- "LOGIC",
273
- "LOG"
274
- ];
275
- var ATTRIBUTION_CONFIDENCES = [
276
- "explicit",
277
- "correlated",
278
- "heuristic",
279
- "unknown"
280
- ];
281
- var PERSISTED_EVENT_SOURCE_TYPES = [
282
- "manual",
283
- "json-log",
284
- "log4js",
285
- "adapter",
286
- "ai-sdk",
287
- "otel"
288
- ];
289
- var PERSISTED_EVENT_STATUSES = [
290
- "running",
291
- "ok",
292
- "error",
293
- "unknown"
294
- ];
295
- function isRecord3(value) {
296
- return typeof value === "object" && value !== null && !Array.isArray(value);
297
- }
298
- function isString(value) {
299
- return typeof value === "string";
300
- }
301
- function isNonEmptyString2(value) {
302
- return typeof value === "string" && value.length > 0;
303
- }
304
- function isOptionalString(value) {
305
- return value === void 0 || isString(value);
306
- }
307
- function isNonNegativeNumber(value) {
308
- return typeof value === "number" && Number.isFinite(value) && value >= 0;
309
- }
310
- function isOptionalNonNegativeNumber(value) {
311
- return value === void 0 || isNonNegativeNumber(value);
312
- }
313
- function isInspectKind(value) {
314
- return typeof value === "string" && INSPECT_KINDS.includes(value);
315
- }
316
- function isAttributionConfidence(value) {
317
- return typeof value === "string" && ATTRIBUTION_CONFIDENCES.includes(value);
318
- }
319
- function isPersistedEventSourceType(value) {
320
- return typeof value === "string" && PERSISTED_EVENT_SOURCE_TYPES.includes(value);
321
- }
322
- function isPersistedEventStatus(value) {
323
- return typeof value === "string" && PERSISTED_EVENT_STATUSES.includes(value);
324
- }
325
- function isPersistedEventSource(value) {
326
- if (!isRecord3(value)) return false;
327
- if (!isPersistedEventSourceType(value.type)) return false;
328
- if (!isOptionalString(value.name)) return false;
329
- if (!isOptionalString(value.version)) return false;
330
- return true;
331
- }
332
- function isPersistedInspectError(value) {
333
- if (!isRecord3(value)) return false;
334
- if (!isNonEmptyString2(value.message)) return false;
335
- if (!isOptionalString(value.name)) return false;
336
- if (!isOptionalString(value.code)) return false;
337
- return true;
338
- }
339
- function isPersistedTokenUsage(value) {
340
- if (!isRecord3(value)) return false;
341
- if (!isOptionalNonNegativeNumber(value.input)) return false;
342
- if (!isOptionalNonNegativeNumber(value.output)) return false;
343
- if (!isOptionalNonNegativeNumber(value.total)) return false;
344
- if (!isOptionalNonNegativeNumber(value.cached)) return false;
345
- return true;
346
- }
347
- function isPersistedTraceContext(value) {
348
- if (!isRecord3(value)) return false;
349
- if (!isOptionalString(value.traceId)) return false;
350
- if (!isOptionalString(value.spanId)) return false;
351
- if (!isOptionalString(value.parentSpanId)) return false;
352
- return true;
353
- }
354
- function isPersistedInspectEvent(value) {
355
- if (!isRecord3(value)) return false;
356
- if (value.schemaVersion !== "0.2" && value.schemaVersion !== "1.0") {
357
- return false;
358
- }
359
- if (!isNonEmptyString2(value.eventId)) return false;
360
- if (!isNonEmptyString2(value.runId)) return false;
361
- if (!isInspectKind(value.kind)) return false;
362
- if (!isNonEmptyString2(value.name)) return false;
363
- if (!isNonEmptyString2(value.timestamp)) return false;
364
- if (!isAttributionConfidence(value.confidence)) return false;
365
- if (!isPersistedEventSource(value.source)) return false;
366
- if (value.parentId !== void 0 && !isNonEmptyString2(value.parentId)) {
367
- return false;
368
- }
369
- if (value.status !== void 0 && !isPersistedEventStatus(value.status)) {
370
- return false;
371
- }
372
- if (!isOptionalString(value.startedAt)) return false;
373
- if (!isOptionalString(value.endedAt)) return false;
374
- if (value.durationMs !== void 0 && !isNonNegativeNumber(value.durationMs)) {
375
- return false;
376
- }
377
- if (value.attributes !== void 0 && !isRecord3(value.attributes)) {
378
- return false;
379
- }
380
- if (value.error !== void 0 && !isPersistedInspectError(value.error)) {
381
- return false;
382
- }
383
- if (value.tokenUsage !== void 0 && !isPersistedTokenUsage(value.tokenUsage)) {
384
- return false;
385
- }
386
- if (value.trace !== void 0 && !isPersistedTraceContext(value.trace)) {
387
- return false;
388
- }
389
- return true;
390
- }
391
-
392
- // packages/core/src/persisted/to-trace-event.ts
393
- function parseIsoToMs(iso) {
394
- const parsed = Date.parse(iso);
395
- return Number.isFinite(parsed) ? parsed : 0;
396
- }
397
- function mapInspectKindToStepType(kind) {
398
- switch (kind) {
399
- case "LLM":
400
- return "llm";
401
- case "TOOL":
402
- return "tool";
403
- case "DECISION":
404
- return "decision";
405
- case "RUN":
406
- return "run";
407
- default:
408
- return "logic";
409
- }
410
- }
411
- function mapPersistedStatusToStepStatus(status) {
412
- switch (status) {
413
- case "ok":
414
- return "success";
415
- case "error":
416
- return "error";
417
- case "running":
418
- return "running";
419
- default:
420
- return void 0;
421
- }
422
- }
423
- function mapPersistedStatusToRunStatus(status) {
424
- switch (status) {
425
- case "ok":
426
- return "success";
427
- case "error":
428
- return "error";
429
- case "running":
430
- return "running";
431
- default:
432
- return void 0;
433
- }
434
- }
435
- function mapPersistedError(error, attributes) {
436
- if (!error?.message) return void 0;
437
- const out = { message: error.message };
438
- const stack = typeof attributes?.errorStack === "string" && attributes.errorStack.length > 0 ? attributes.errorStack : void 0;
439
- if (stack) {
440
- out.stack = stack;
441
- }
442
- return out;
443
- }
444
- function mapTokenUsageToMetadata(tokenUsage, attributes) {
445
- const metadata = {};
446
- if (attributes?.metadata && typeof attributes.metadata === "object") {
447
- Object.assign(metadata, attributes.metadata);
448
- }
449
- if (tokenUsage) {
450
- metadata.tokens = {
451
- ...tokenUsage.input !== void 0 ? { input: tokenUsage.input } : {},
452
- ...tokenUsage.output !== void 0 ? { output: tokenUsage.output } : {},
453
- ...tokenUsage.total !== void 0 ? { total: tokenUsage.total } : {},
454
- ...tokenUsage.cached !== void 0 ? { cached: tokenUsage.cached } : {}
455
- };
456
- }
457
- return Object.keys(metadata).length > 0 ? metadata : void 0;
458
- }
459
- function pickRunMetadata(attributes) {
460
- if (!attributes) return void 0;
461
- const metadata = attributes.metadata && typeof attributes.metadata === "object" ? { ...attributes.metadata } : {};
462
- for (const key of [
463
- "correlationId",
464
- "requestId",
465
- "decisionId",
466
- "groupId"
467
- ]) {
468
- const value = attributes[key];
469
- if (typeof value === "string" && value.trim() !== "") {
470
- metadata[key] = value;
471
- }
472
- }
473
- return Object.keys(metadata).length > 0 ? metadata : void 0;
474
- }
475
- function resolveStepId(event) {
476
- const attrs = event.attributes;
477
- if (attrs && typeof attrs.stepId === "string" && attrs.stepId.trim() !== "") {
478
- return attrs.stepId;
479
- }
480
- return event.eventId;
481
- }
482
- function resolveStepType(event) {
483
- const attrs = event.attributes;
484
- if (attrs && typeof attrs.stepType === "string") {
485
- const t = attrs.stepType;
486
- if (t === "run" || t === "llm" || t === "tool" || t === "decision" || t === "logic" || t === "state" || t === "custom") {
487
- return t;
488
- }
489
- }
490
- return mapInspectKindToStepType(event.kind);
491
- }
492
- function resolveTimes(event) {
493
- const timestamp = parseIsoToMs(event.timestamp);
494
- const startTime = event.startedAt !== void 0 ? parseIsoToMs(event.startedAt) : timestamp;
495
- let endTime = event.endedAt !== void 0 ? parseIsoToMs(event.endedAt) : timestamp;
496
- if (event.durationMs !== void 0 && Number.isFinite(event.durationMs) && event.durationMs >= 0 && event.endedAt === void 0) {
497
- endTime = startTime + event.durationMs;
498
- }
499
- return { timestamp, startTime, endTime };
500
- }
501
- function fromLegacyRunStarted(event) {
502
- const { timestamp, startTime } = resolveTimes(event);
503
- const out = {
504
- schemaVersion: "0.1",
505
- event: "run_started",
506
- timestamp,
507
- runId: event.runId,
508
- name: event.name,
509
- startTime
510
- };
511
- const metadata = pickRunMetadata(event.attributes);
512
- if (metadata) out.metadata = metadata;
513
- return out;
514
- }
515
- function fromLegacyRunCompleted(event) {
516
- const { timestamp, endTime } = resolveTimes(event);
517
- const status = mapPersistedStatusToRunStatus(event.status) ?? "success";
518
- const out = {
519
- schemaVersion: "0.1",
520
- event: "run_completed",
521
- timestamp,
522
- runId: event.runId,
523
- status: status === "running" ? "success" : status,
524
- endTime,
525
- durationMs: event.durationMs ?? Math.max(0, endTime - timestamp)
526
- };
527
- const error = mapPersistedError(event.error, event.attributes);
528
- if (error) out.error = error;
529
- return out;
530
- }
531
- function fromLegacyStepStarted(event) {
532
- const { timestamp, startTime } = resolveTimes(event);
533
- const out = {
534
- schemaVersion: "0.1",
535
- event: "step_started",
536
- timestamp,
537
- runId: event.runId,
538
- stepId: resolveStepId(event),
539
- name: event.name,
540
- type: resolveStepType(event),
541
- startTime
542
- };
543
- if (event.parentId !== void 0) out.parentId = event.parentId;
544
- const metadata = mapTokenUsageToMetadata(event.tokenUsage, event.attributes);
545
- if (metadata) out.metadata = metadata;
546
- return out;
547
- }
548
- function fromLegacyStepCompleted(event) {
549
- const { timestamp, endTime } = resolveTimes(event);
550
- const status = mapPersistedStatusToStepStatus(event.status) ?? "success";
551
- const out = {
552
- schemaVersion: "0.1",
553
- event: "step_completed",
554
- timestamp,
555
- runId: event.runId,
556
- stepId: resolveStepId(event),
557
- status: status === "running" ? "success" : status,
558
- endTime,
559
- durationMs: event.durationMs ?? Math.max(0, endTime - timestamp)
560
- };
561
- const error = mapPersistedError(event.error, event.attributes);
562
- if (error) out.error = error;
563
- return out;
564
- }
565
- function fromNativeRun(event) {
566
- const { timestamp, startTime, endTime } = resolveTimes(event);
567
- const runStatus = mapPersistedStatusToRunStatus(event.status);
568
- const out = [];
569
- if (runStatus === "running" || event.startedAt !== void 0) {
570
- const started = {
571
- schemaVersion: "0.1",
572
- event: "run_started",
573
- timestamp,
574
- runId: event.runId,
575
- name: event.name,
576
- startTime
577
- };
578
- const metadata = pickRunMetadata(event.attributes);
579
- if (metadata) started.metadata = metadata;
580
- out.push(started);
581
- }
582
- if (runStatus === "success" || runStatus === "error" || event.endedAt !== void 0) {
583
- const completed = {
584
- schemaVersion: "0.1",
585
- event: "run_completed",
586
- timestamp,
587
- runId: event.runId,
588
- status: runStatus === "error" ? "error" : "success",
589
- endTime,
590
- durationMs: event.durationMs ?? Math.max(0, endTime - startTime)
591
- };
592
- const error = mapPersistedError(event.error, event.attributes);
593
- if (error) completed.error = error;
594
- out.push(completed);
595
- }
596
- if (out.length === 0) {
597
- out.push(fromLegacyRunStarted(event));
598
- }
599
- return out;
600
- }
601
- function fromNativeStep(event) {
602
- const { timestamp, startTime, endTime } = resolveTimes(event);
603
- const stepStatus = mapPersistedStatusToStepStatus(event.status);
604
- const stepId = resolveStepId(event);
605
- const out = [];
606
- const shouldEmitStarted = stepStatus === "running" || event.startedAt !== void 0 || stepStatus === "success" || stepStatus === "error";
607
- if (shouldEmitStarted) {
608
- const started = {
609
- schemaVersion: "0.1",
610
- event: "step_started",
611
- timestamp,
612
- runId: event.runId,
613
- stepId,
614
- name: event.name,
615
- type: resolveStepType(event),
616
- startTime
617
- };
618
- if (event.parentId !== void 0) started.parentId = event.parentId;
619
- const metadata = mapTokenUsageToMetadata(event.tokenUsage, event.attributes);
620
- if (metadata) started.metadata = metadata;
621
- out.push(started);
622
- }
623
- if (stepStatus === "success" || stepStatus === "error" || event.endedAt !== void 0 || event.durationMs !== void 0) {
624
- const completed = {
625
- schemaVersion: "0.1",
626
- event: "step_completed",
627
- timestamp,
628
- runId: event.runId,
629
- stepId,
630
- status: stepStatus === "error" ? "error" : "success",
631
- endTime,
632
- durationMs: event.durationMs ?? Math.max(0, endTime - startTime)
633
- };
634
- const error = mapPersistedError(event.error, event.attributes);
635
- if (error) completed.error = error;
636
- out.push(completed);
637
- }
638
- if (out.length === 0) {
639
- out.push(fromLegacyStepStarted(event));
640
- }
641
- return out;
642
- }
643
- function persistedInspectEventToTraceEvents(event) {
644
- if (!isPersistedInspectEvent(event)) {
645
- throw new Error("Invalid PersistedInspectEvent: failed isPersistedInspectEvent");
646
- }
647
- const legacyEvent = event.attributes?.legacyEvent;
648
- if (legacyEvent === "run_started") return [fromLegacyRunStarted(event)];
649
- if (legacyEvent === "run_completed") return [fromLegacyRunCompleted(event)];
650
- if (legacyEvent === "step_started") return [fromLegacyStepStarted(event)];
651
- if (legacyEvent === "step_completed") return [fromLegacyStepCompleted(event)];
652
- if (event.kind === "RUN") {
653
- return fromNativeRun(event);
654
- }
655
- return fromNativeStep(event);
656
- }
657
- function persistedInspectEventsToTraceEvents(events, options) {
658
- const out = [];
659
- events.forEach((event, index) => {
660
- const rows = persistedInspectEventToTraceEvents(event);
661
- if (rows.length === 0 && options?.eventIndex !== void 0) ;
662
- out.push(...rows);
663
- });
664
- return out;
665
- }
666
-
667
- // node_modules/.pnpm/nanoid@5.1.11/node_modules/nanoid/url-alphabet/index.js
668
- var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
669
-
670
- // node_modules/.pnpm/nanoid@5.1.11/node_modules/nanoid/index.js
671
- var POOL_SIZE_MULTIPLIER = 128;
672
- var pool;
673
- var poolOffset;
674
- function fillPool(bytes) {
675
- if (bytes < 0 || bytes > 1024) throw new RangeError("Wrong ID size");
676
- if (!pool || pool.length < bytes) {
677
- pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
678
- webcrypto.getRandomValues(pool);
679
- poolOffset = 0;
680
- } else if (poolOffset + bytes > pool.length) {
681
- webcrypto.getRandomValues(pool);
682
- poolOffset = 0;
683
- }
684
- poolOffset += bytes;
685
- }
686
- function nanoid(size = 21) {
687
- fillPool(size |= 0);
688
- let id = "";
689
- for (let i = poolOffset - size; i < poolOffset; i++) {
690
- id += urlAlphabet[pool[i] & 63];
691
- }
692
- return id;
693
- }
694
-
695
- // packages/core/src/utils/duration.ts
696
- function parseDuration(duration) {
697
- const raw = typeof duration === "string" ? duration.trim() : "";
698
- const match = raw.match(/^(\d+)(ms|[smhd])$/);
699
- if (!match) {
700
- throw new Error(
701
- `Invalid duration format: ${duration}. Use a positive integer followed by ms, s, m, h, or d (e.g. 500ms, 30s, 5m, 2h, 7d).`
702
- );
703
- }
704
- const amount = Number.parseInt(match[1], 10);
705
- const unit = match[2];
706
- if (!Number.isFinite(amount) || amount <= 0) {
707
- throw new Error(
708
- `Invalid duration amount: ${duration}. Amount must be a positive integer.`
709
- );
710
- }
711
- switch (unit) {
712
- case "ms":
713
- return amount;
714
- case "s":
715
- return amount * 1e3;
716
- case "m":
717
- return amount * 60 * 1e3;
718
- case "h":
719
- return amount * 60 * 60 * 1e3;
720
- case "d":
721
- return amount * 24 * 60 * 60 * 1e3;
722
- default: {
723
- throw new Error(`Unknown duration unit: ${unit}`);
724
- }
725
- }
726
- }
727
- function formatDuration(ms) {
728
- if (!Number.isFinite(ms)) {
729
- return "0ms";
730
- }
731
- if (ms < 0) {
732
- throw new Error(`formatDuration: ms must be non-negative (got ${ms})`);
733
- }
734
- if (ms < 1e3) {
735
- return `${Math.floor(ms)}ms`;
736
- }
737
- if (ms < 6e4) {
738
- return `${(ms / 1e3).toFixed(2)}s`;
739
- }
740
- if (ms < 36e5) {
741
- return `${(ms / 6e4).toFixed(1)}m`;
742
- }
743
- return `${(ms / 36e5).toFixed(1)}h`;
744
- }
745
-
746
- // packages/core/src/utils.ts
747
- var DEFAULT_TRACE_DIR_NAME = ".agent-inspect";
748
- var RUNS_DIR_NAME = "runs";
749
- var FALLBACK_TRACE_DIR = path14.join(
750
- os.tmpdir(),
751
- "agent-inspect",
752
- RUNS_DIR_NAME
753
- );
754
- var MAX_NAME_LENGTH = 100;
755
- function formatDuration2(ms) {
756
- return formatDuration(ms);
757
- }
758
- function formatTimestamp(timestamp) {
759
- if (!Number.isFinite(timestamp)) {
760
- return "Invalid date";
761
- }
762
- const d = new Date(timestamp);
763
- if (Number.isNaN(d.getTime())) {
764
- return "Invalid date";
765
- }
766
- const y = d.getFullYear();
767
- const mo = String(d.getMonth() + 1).padStart(2, "0");
768
- const day = String(d.getDate()).padStart(2, "0");
769
- const h = String(d.getHours()).padStart(2, "0");
770
- const min = String(d.getMinutes()).padStart(2, "0");
771
- const s = String(d.getSeconds()).padStart(2, "0");
772
- return `${y}-${mo}-${day} ${h}:${min}:${s}`;
773
- }
774
- function getDefaultTraceDir() {
775
- const envDir = process.env.AGENT_INSPECT_TRACE_DIR;
776
- if (typeof envDir === "string" && envDir.trim() !== "") {
777
- return envDir.trim();
778
- }
779
- try {
780
- const home = os.homedir();
781
- if (typeof home !== "string" || home.trim() === "") {
782
- return FALLBACK_TRACE_DIR;
783
- }
784
- return path14.join(home, DEFAULT_TRACE_DIR_NAME, RUNS_DIR_NAME);
785
- } catch {
786
- return FALLBACK_TRACE_DIR;
787
- }
788
- }
789
- function getTraceFilePath(runId, traceDir) {
790
- const baseDir = traceDir ?? getDefaultTraceDir();
791
- let safeId = typeof runId === "string" && runId.trim() !== "" ? runId.trim() : "run_unknown";
792
- safeId = path14.basename(safeId);
793
- if (safeId === "" || safeId === "." || safeId === "..") {
794
- safeId = "run_unknown";
795
- }
796
- return path14.join(baseDir, `${safeId}.jsonl`);
797
- }
798
- function formatError(error) {
799
- if (error instanceof Error) {
800
- const out = { message: error.message };
801
- if (typeof error.stack === "string" && error.stack.length > 0) {
802
- out.stack = error.stack;
803
- }
804
- return out;
805
- }
806
- if (typeof error === "string") {
807
- return { message: error };
808
- }
809
- if (error === null) {
810
- return { message: "Unknown error: null" };
811
- }
812
- if (error === void 0) {
813
- return { message: "Unknown error: undefined" };
814
- }
815
- if (typeof error === "number" || typeof error === "boolean" || typeof error === "bigint") {
816
- return { message: String(error) };
817
- }
818
- if (typeof error === "object") {
819
- try {
820
- return { message: JSON.stringify(error) };
821
- } catch {
822
- return { message: "Unknown error" };
823
- }
824
- }
825
- return { message: "Unknown error" };
826
- }
827
- function truncateName(name, maxLength = MAX_NAME_LENGTH) {
828
- if (typeof name !== "string" || name.trim() === "") {
829
- return "unnamed";
830
- }
831
- const trimmed = name.trim();
832
- if (trimmed.length <= maxLength) {
833
- return trimmed;
834
- }
835
- const ellipsis = "...";
836
- const head = Math.max(0, maxLength - ellipsis.length);
837
- return `${trimmed.slice(0, head)}${ellipsis}`;
838
- }
839
- function warn(message, error) {
840
- const base = `[AgentInspect] ${message}`;
841
- if (error === void 0) {
842
- console.warn(base);
843
- return;
844
- }
845
- console.warn(`${base}: ${formatError(error).message}`);
846
- }
847
-
848
- // packages/core/src/read-trace.ts
849
- function isRecord4(value) {
850
- return typeof value === "object" && value !== null && !Array.isArray(value);
851
- }
852
- function detectLineFormat(parsed) {
853
- if (!isRecord4(parsed)) return "unknown";
854
- if (parsed.schemaVersion === "0.1") return "0.1";
855
- if (parsed.schemaVersion === "0.2") return "0.2";
856
- if (parsed.schemaVersion === "1.0") return "1.0";
857
- return "unknown";
858
- }
859
- function parseTraceJsonl(raw, options = {}) {
860
- const validate = options.validate ?? isTraceEvent;
861
- const emitWarning = (message) => {
862
- if (options.warnings !== false) warn(message);
863
- };
864
- const persisted = [];
865
- const traceEvents = [];
866
- const rows = [];
867
- let sourceEventCount = 0;
868
- let saw01 = false;
869
- let saw02 = false;
870
- let saw10 = false;
871
- let lineNumber = 0;
872
- for (const line of raw.split(/\r?\n/)) {
873
- lineNumber += 1;
874
- const trimmed = line.trim();
875
- if (trimmed === "") continue;
876
- let parsed;
877
- try {
878
- parsed = JSON.parse(trimmed);
879
- } catch {
880
- emitWarning("Skipped invalid JSON line in trace file");
881
- continue;
882
- }
883
- const format2 = detectLineFormat(parsed);
884
- if (format2 === "0.1") {
885
- saw01 = true;
886
- if (validate(parsed)) {
887
- sourceEventCount += 1;
888
- traceEvents.push(parsed);
889
- rows.push({ format: "0.1", event: parsed, sourceLine: lineNumber });
890
- } else {
891
- emitWarning("Skipped invalid trace event line in trace file");
892
- }
893
- continue;
894
- }
895
- if (format2 === "0.2" || format2 === "1.0") {
896
- if (format2 === "0.2") saw02 = true;
897
- else saw10 = true;
898
- if (isPersistedInspectEvent(parsed)) {
899
- sourceEventCount += 1;
900
- persisted.push(parsed);
901
- rows.push({ format: format2, event: parsed, sourceLine: lineNumber });
902
- traceEvents.push(...persistedInspectEventToTraceEvents(parsed));
903
- } else {
904
- emitWarning("Skipped invalid persisted inspect event line in trace file");
905
- }
906
- continue;
907
- }
908
- emitWarning("Skipped trace line with unknown schemaVersion");
909
- }
910
- const seenFormats = [saw01, saw02, saw10].filter(Boolean).length;
911
- if (seenFormats > 1) {
912
- emitWarning(
913
- "Trace file mixes AgentInspect schemaVersion rows; normalizing all rows"
914
- );
915
- }
916
- let format = "empty";
917
- if (seenFormats > 1) format = "mixed";
918
- else if (saw01) format = "0.1";
919
- else if (saw02) format = "0.2";
920
- else if (saw10) format = "1.0";
921
- return { format, sourceEventCount, events: traceEvents, persisted, rows };
922
- }
923
-
924
- // packages/core/src/storage.ts
925
- function isRecord5(value) {
926
- return typeof value === "object" && value !== null && !Array.isArray(value);
927
- }
928
- function nonEmptyString(value) {
929
- return typeof value === "string" && value.trim() !== "";
930
- }
931
- function finiteNumber(value) {
932
- return typeof value === "number" && Number.isFinite(value);
933
- }
934
- function optionalErrorInfo(value) {
935
- if (value === void 0) return true;
936
- if (!isRecord5(value)) return false;
937
- if (typeof value.message !== "string") return false;
938
- if ("stack" in value && value.stack !== void 0) {
939
- if (typeof value.stack !== "string") return false;
940
- }
941
- return true;
942
- }
943
- function validateEvent(event) {
944
- if (!isRecord5(event)) return false;
945
- if (event.schemaVersion !== "0.1") return false;
946
- if (!finiteNumber(event.timestamp)) return false;
947
- if (typeof event.event !== "string") return false;
948
- switch (event.event) {
949
- case "run_started": {
950
- if (!nonEmptyString(event.runId) || !nonEmptyString(event.name) || !finiteNumber(event.startTime)) {
951
- return false;
952
- }
953
- if (event.metadata !== void 0 && !isRecord5(event.metadata)) {
954
- return false;
955
- }
956
- return true;
957
- }
958
- case "run_completed": {
959
- return nonEmptyString(event.runId) && (event.status === "success" || event.status === "error") && finiteNumber(event.endTime) && finiteNumber(event.durationMs) && optionalErrorInfo(event.error);
960
- }
961
- case "step_started": {
962
- if (!nonEmptyString(event.runId) || !nonEmptyString(event.stepId) || !nonEmptyString(event.name) || !isStepType(event.type) || !finiteNumber(event.startTime)) {
963
- return false;
964
- }
965
- if (event.parentId !== void 0 && typeof event.parentId !== "string") {
966
- return false;
967
- }
968
- if (event.metadata !== void 0 && !isRecord5(event.metadata)) {
969
- return false;
970
- }
971
- return true;
972
- }
973
- case "step_completed": {
974
- return nonEmptyString(event.runId) && nonEmptyString(event.stepId) && (event.status === "success" || event.status === "error") && finiteNumber(event.endTime) && finiteNumber(event.durationMs) && optionalErrorInfo(event.error);
975
- }
976
- default:
977
- return false;
978
- }
979
- }
980
- async function readTraceEventsFromFile(filePath) {
981
- try {
982
- const raw = await readFile(filePath, "utf-8");
983
- return parseTraceJsonl(raw, { validate: validateEvent }).events;
984
- } catch (e) {
985
- if (e && typeof e === "object" && "code" in e && e.code === "ENOENT") {
986
- return [];
987
- }
988
- warn("Failed to read trace events from file", e);
989
- return [];
990
- }
991
- }
992
-
993
- // packages/core/src/context.ts
994
- new AsyncLocalStorage();
995
-
996
- // node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/vendor/ansi-styles/index.js
997
- var ANSI_BACKGROUND_OFFSET = 10;
998
- var wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
999
- var wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`;
1000
- var wrapAnsi16m = (offset = 0) => (red, green, blue) => `\x1B[${38 + offset};2;${red};${green};${blue}m`;
1001
- var styles = {
1002
- modifier: {
1003
- reset: [0, 0],
1004
- // 21 isn't widely supported and 22 does the same thing
1005
- bold: [1, 22],
1006
- dim: [2, 22],
1007
- italic: [3, 23],
1008
- underline: [4, 24],
1009
- overline: [53, 55],
1010
- inverse: [7, 27],
1011
- hidden: [8, 28],
1012
- strikethrough: [9, 29]
1013
- },
1014
- color: {
1015
- black: [30, 39],
1016
- red: [31, 39],
1017
- green: [32, 39],
1018
- yellow: [33, 39],
1019
- blue: [34, 39],
1020
- magenta: [35, 39],
1021
- cyan: [36, 39],
1022
- white: [37, 39],
1023
- // Bright color
1024
- blackBright: [90, 39],
1025
- gray: [90, 39],
1026
- // Alias of `blackBright`
1027
- grey: [90, 39],
1028
- // Alias of `blackBright`
1029
- redBright: [91, 39],
1030
- greenBright: [92, 39],
1031
- yellowBright: [93, 39],
1032
- blueBright: [94, 39],
1033
- magentaBright: [95, 39],
1034
- cyanBright: [96, 39],
1035
- whiteBright: [97, 39]
1036
- },
1037
- bgColor: {
1038
- bgBlack: [40, 49],
1039
- bgRed: [41, 49],
1040
- bgGreen: [42, 49],
1041
- bgYellow: [43, 49],
1042
- bgBlue: [44, 49],
1043
- bgMagenta: [45, 49],
1044
- bgCyan: [46, 49],
1045
- bgWhite: [47, 49],
1046
- // Bright color
1047
- bgBlackBright: [100, 49],
1048
- bgGray: [100, 49],
1049
- // Alias of `bgBlackBright`
1050
- bgGrey: [100, 49],
1051
- // Alias of `bgBlackBright`
1052
- bgRedBright: [101, 49],
1053
- bgGreenBright: [102, 49],
1054
- bgYellowBright: [103, 49],
1055
- bgBlueBright: [104, 49],
1056
- bgMagentaBright: [105, 49],
1057
- bgCyanBright: [106, 49],
1058
- bgWhiteBright: [107, 49]
1059
- }
1060
- };
1061
- Object.keys(styles.modifier);
1062
- var foregroundColorNames = Object.keys(styles.color);
1063
- var backgroundColorNames = Object.keys(styles.bgColor);
1064
- [...foregroundColorNames, ...backgroundColorNames];
1065
- function assembleStyles() {
1066
- const codes = /* @__PURE__ */ new Map();
1067
- for (const [groupName, group] of Object.entries(styles)) {
1068
- for (const [styleName, style] of Object.entries(group)) {
1069
- styles[styleName] = {
1070
- open: `\x1B[${style[0]}m`,
1071
- close: `\x1B[${style[1]}m`
1072
- };
1073
- group[styleName] = styles[styleName];
1074
- codes.set(style[0], style[1]);
1075
- }
1076
- Object.defineProperty(styles, groupName, {
1077
- value: group,
1078
- enumerable: false
1079
- });
1080
- }
1081
- Object.defineProperty(styles, "codes", {
1082
- value: codes,
1083
- enumerable: false
1084
- });
1085
- styles.color.close = "\x1B[39m";
1086
- styles.bgColor.close = "\x1B[49m";
1087
- styles.color.ansi = wrapAnsi16();
1088
- styles.color.ansi256 = wrapAnsi256();
1089
- styles.color.ansi16m = wrapAnsi16m();
1090
- styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
1091
- styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
1092
- styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
1093
- Object.defineProperties(styles, {
1094
- rgbToAnsi256: {
1095
- value(red, green, blue) {
1096
- if (red === green && green === blue) {
1097
- if (red < 8) {
1098
- return 16;
1099
- }
1100
- if (red > 248) {
1101
- return 231;
1102
- }
1103
- return Math.round((red - 8) / 247 * 24) + 232;
1104
- }
1105
- return 16 + 36 * Math.round(red / 255 * 5) + 6 * Math.round(green / 255 * 5) + Math.round(blue / 255 * 5);
1106
- },
1107
- enumerable: false
1108
- },
1109
- hexToRgb: {
1110
- value(hex) {
1111
- const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
1112
- if (!matches) {
1113
- return [0, 0, 0];
1114
- }
1115
- let [colorString] = matches;
1116
- if (colorString.length === 3) {
1117
- colorString = [...colorString].map((character) => character + character).join("");
1118
- }
1119
- const integer = Number.parseInt(colorString, 16);
1120
- return [
1121
- /* eslint-disable no-bitwise */
1122
- integer >> 16 & 255,
1123
- integer >> 8 & 255,
1124
- integer & 255
1125
- /* eslint-enable no-bitwise */
1126
- ];
1127
- },
1128
- enumerable: false
1129
- },
1130
- hexToAnsi256: {
1131
- value: (hex) => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
1132
- enumerable: false
1133
- },
1134
- ansi256ToAnsi: {
1135
- value(code) {
1136
- if (code < 8) {
1137
- return 30 + code;
1138
- }
1139
- if (code < 16) {
1140
- return 90 + (code - 8);
1141
- }
1142
- let red;
1143
- let green;
1144
- let blue;
1145
- if (code >= 232) {
1146
- red = ((code - 232) * 10 + 8) / 255;
1147
- green = red;
1148
- blue = red;
1149
- } else {
1150
- code -= 16;
1151
- const remainder = code % 36;
1152
- red = Math.floor(code / 36) / 5;
1153
- green = Math.floor(remainder / 6) / 5;
1154
- blue = remainder % 6 / 5;
1155
- }
1156
- const value = Math.max(red, green, blue) * 2;
1157
- if (value === 0) {
1158
- return 30;
1159
- }
1160
- let result = 30 + (Math.round(blue) << 2 | Math.round(green) << 1 | Math.round(red));
1161
- if (value === 2) {
1162
- result += 60;
1163
- }
1164
- return result;
1165
- },
1166
- enumerable: false
1167
- },
1168
- rgbToAnsi: {
1169
- value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
1170
- enumerable: false
1171
- },
1172
- hexToAnsi: {
1173
- value: (hex) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
1174
- enumerable: false
1175
- }
1176
- });
1177
- return styles;
1178
- }
1179
- var ansiStyles = assembleStyles();
1180
- var ansi_styles_default = ansiStyles;
1181
- function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process3.argv) {
1182
- const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
1183
- const position = argv.indexOf(prefix + flag);
1184
- const terminatorPosition = argv.indexOf("--");
1185
- return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
1186
- }
1187
- var { env } = process3;
1188
- var flagForceColor;
1189
- if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
1190
- flagForceColor = 0;
1191
- } else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
1192
- flagForceColor = 1;
1193
- }
1194
- function envForceColor() {
1195
- if ("FORCE_COLOR" in env) {
1196
- if (env.FORCE_COLOR === "true") {
1197
- return 1;
1198
- }
1199
- if (env.FORCE_COLOR === "false") {
1200
- return 0;
1201
- }
1202
- return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
1203
- }
1204
- }
1205
- function translateLevel(level) {
1206
- if (level === 0) {
1207
- return false;
1208
- }
1209
- return {
1210
- level,
1211
- hasBasic: true,
1212
- has256: level >= 2,
1213
- has16m: level >= 3
1214
- };
1215
- }
1216
- function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
1217
- const noFlagForceColor = envForceColor();
1218
- if (noFlagForceColor !== void 0) {
1219
- flagForceColor = noFlagForceColor;
1220
- }
1221
- const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
1222
- if (forceColor === 0) {
1223
- return 0;
1224
- }
1225
- if (sniffFlags) {
1226
- if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
1227
- return 3;
1228
- }
1229
- if (hasFlag("color=256")) {
1230
- return 2;
1231
- }
1232
- }
1233
- if ("TF_BUILD" in env && "AGENT_NAME" in env) {
1234
- return 1;
1235
- }
1236
- if (haveStream && !streamIsTTY && forceColor === void 0) {
1237
- return 0;
1238
- }
1239
- const min = forceColor || 0;
1240
- if (env.TERM === "dumb") {
1241
- return min;
1242
- }
1243
- if (process3.platform === "win32") {
1244
- const osRelease = os.release().split(".");
1245
- if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
1246
- return Number(osRelease[2]) >= 14931 ? 3 : 2;
1247
- }
1248
- return 1;
1249
- }
1250
- if ("CI" in env) {
1251
- if (["GITHUB_ACTIONS", "GITEA_ACTIONS", "CIRCLECI"].some((key) => key in env)) {
1252
- return 3;
1253
- }
1254
- if (["TRAVIS", "APPVEYOR", "GITLAB_CI", "BUILDKITE", "DRONE"].some((sign) => sign in env) || env.CI_NAME === "codeship") {
1255
- return 1;
1256
- }
1257
- return min;
1258
- }
1259
- if ("TEAMCITY_VERSION" in env) {
1260
- return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
1261
- }
1262
- if (env.COLORTERM === "truecolor") {
1263
- return 3;
1264
- }
1265
- if (env.TERM === "xterm-kitty") {
1266
- return 3;
1267
- }
1268
- if (env.TERM === "xterm-ghostty") {
1269
- return 3;
1270
- }
1271
- if (env.TERM === "wezterm") {
1272
- return 3;
1273
- }
1274
- if ("TERM_PROGRAM" in env) {
1275
- const version2 = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
1276
- switch (env.TERM_PROGRAM) {
1277
- case "iTerm.app": {
1278
- return version2 >= 3 ? 3 : 2;
1279
- }
1280
- case "Apple_Terminal": {
1281
- return 2;
1282
- }
1283
- }
1284
- }
1285
- if (/-256(color)?$/i.test(env.TERM)) {
1286
- return 2;
1287
- }
1288
- if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
1289
- return 1;
1290
- }
1291
- if ("COLORTERM" in env) {
1292
- return 1;
1293
- }
1294
- return min;
1295
- }
1296
- function createSupportsColor(stream, options = {}) {
1297
- const level = _supportsColor(stream, {
1298
- streamIsTTY: stream && stream.isTTY,
1299
- ...options
1300
- });
1301
- return translateLevel(level);
1302
- }
1303
- var supportsColor = {
1304
- stdout: createSupportsColor({ isTTY: tty.isatty(1) }),
1305
- stderr: createSupportsColor({ isTTY: tty.isatty(2) })
1306
- };
1307
- var supports_color_default = supportsColor;
1308
-
1309
- // node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/utilities.js
1310
- function stringReplaceAll(string, substring, replacer) {
1311
- let index = string.indexOf(substring);
1312
- if (index === -1) {
1313
- return string;
1314
- }
1315
- const substringLength = substring.length;
1316
- let endIndex = 0;
1317
- let returnValue = "";
1318
- do {
1319
- returnValue += string.slice(endIndex, index) + substring + replacer;
1320
- endIndex = index + substringLength;
1321
- index = string.indexOf(substring, endIndex);
1322
- } while (index !== -1);
1323
- returnValue += string.slice(endIndex);
1324
- return returnValue;
1325
- }
1326
- function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
1327
- let endIndex = 0;
1328
- let returnValue = "";
1329
- do {
1330
- const gotCR = string[index - 1] === "\r";
1331
- returnValue += string.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
1332
- endIndex = index + 1;
1333
- index = string.indexOf("\n", endIndex);
1334
- } while (index !== -1);
1335
- returnValue += string.slice(endIndex);
1336
- return returnValue;
1337
- }
1338
-
1339
- // node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/index.js
1340
- var { stdout: stdoutColor, stderr: stderrColor } = supports_color_default;
1341
- var GENERATOR = /* @__PURE__ */ Symbol("GENERATOR");
1342
- var STYLER = /* @__PURE__ */ Symbol("STYLER");
1343
- var IS_EMPTY = /* @__PURE__ */ Symbol("IS_EMPTY");
1344
- var levelMapping = [
1345
- "ansi",
1346
- "ansi",
1347
- "ansi256",
1348
- "ansi16m"
1349
- ];
1350
- var styles2 = /* @__PURE__ */ Object.create(null);
1351
- var applyOptions = (object, options = {}) => {
1352
- if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
1353
- throw new Error("The `level` option should be an integer from 0 to 3");
1354
- }
1355
- const colorLevel = stdoutColor ? stdoutColor.level : 0;
1356
- object.level = options.level === void 0 ? colorLevel : options.level;
1357
- };
1358
- var chalkFactory = (options) => {
1359
- const chalk2 = (...strings) => strings.join(" ");
1360
- applyOptions(chalk2, options);
1361
- Object.setPrototypeOf(chalk2, createChalk.prototype);
1362
- return chalk2;
1363
- };
1364
- function createChalk(options) {
1365
- return chalkFactory(options);
1366
- }
1367
- Object.setPrototypeOf(createChalk.prototype, Function.prototype);
1368
- for (const [styleName, style] of Object.entries(ansi_styles_default)) {
1369
- styles2[styleName] = {
1370
- get() {
1371
- const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);
1372
- Object.defineProperty(this, styleName, { value: builder });
1373
- return builder;
1374
- }
1375
- };
1376
- }
1377
- styles2.visible = {
1378
- get() {
1379
- const builder = createBuilder(this, this[STYLER], true);
1380
- Object.defineProperty(this, "visible", { value: builder });
1381
- return builder;
1382
- }
1383
- };
1384
- var getModelAnsi = (model, level, type, ...arguments_) => {
1385
- if (model === "rgb") {
1386
- if (level === "ansi16m") {
1387
- return ansi_styles_default[type].ansi16m(...arguments_);
1388
- }
1389
- if (level === "ansi256") {
1390
- return ansi_styles_default[type].ansi256(ansi_styles_default.rgbToAnsi256(...arguments_));
1391
- }
1392
- return ansi_styles_default[type].ansi(ansi_styles_default.rgbToAnsi(...arguments_));
1393
- }
1394
- if (model === "hex") {
1395
- return getModelAnsi("rgb", level, type, ...ansi_styles_default.hexToRgb(...arguments_));
1396
- }
1397
- return ansi_styles_default[type][model](...arguments_);
1398
- };
1399
- var usedModels = ["rgb", "hex", "ansi256"];
1400
- for (const model of usedModels) {
1401
- styles2[model] = {
1402
- get() {
1403
- const { level } = this;
1404
- return function(...arguments_) {
1405
- const styler = createStyler(getModelAnsi(model, levelMapping[level], "color", ...arguments_), ansi_styles_default.color.close, this[STYLER]);
1406
- return createBuilder(this, styler, this[IS_EMPTY]);
1407
- };
1408
- }
1409
- };
1410
- const bgModel = "bg" + model[0].toUpperCase() + model.slice(1);
1411
- styles2[bgModel] = {
1412
- get() {
1413
- const { level } = this;
1414
- return function(...arguments_) {
1415
- const styler = createStyler(getModelAnsi(model, levelMapping[level], "bgColor", ...arguments_), ansi_styles_default.bgColor.close, this[STYLER]);
1416
- return createBuilder(this, styler, this[IS_EMPTY]);
1417
- };
1418
- }
1419
- };
1420
- }
1421
- var proto = Object.defineProperties(() => {
1422
- }, {
1423
- ...styles2,
1424
- level: {
1425
- enumerable: true,
1426
- get() {
1427
- return this[GENERATOR].level;
1428
- },
1429
- set(level) {
1430
- this[GENERATOR].level = level;
1431
- }
1432
- }
1433
- });
1434
- var createStyler = (open3, close, parent) => {
1435
- let openAll;
1436
- let closeAll;
1437
- if (parent === void 0) {
1438
- openAll = open3;
1439
- closeAll = close;
1440
- } else {
1441
- openAll = parent.openAll + open3;
1442
- closeAll = close + parent.closeAll;
1443
- }
1444
- return {
1445
- open: open3,
1446
- close,
1447
- openAll,
1448
- closeAll,
1449
- parent
1450
- };
1451
- };
1452
- var createBuilder = (self, _styler, _isEmpty) => {
1453
- const builder = (...arguments_) => applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
1454
- Object.setPrototypeOf(builder, proto);
1455
- builder[GENERATOR] = self;
1456
- builder[STYLER] = _styler;
1457
- builder[IS_EMPTY] = _isEmpty;
1458
- return builder;
1459
- };
1460
- var applyStyle = (self, string) => {
1461
- if (self.level <= 0 || !string) {
1462
- return self[IS_EMPTY] ? "" : string;
1463
- }
1464
- let styler = self[STYLER];
1465
- if (styler === void 0) {
1466
- return string;
1467
- }
1468
- const { openAll, closeAll } = styler;
1469
- if (string.includes("\x1B")) {
1470
- while (styler !== void 0) {
1471
- string = stringReplaceAll(string, styler.close, styler.open);
1472
- styler = styler.parent;
1473
- }
1474
- }
1475
- const lfIndex = string.indexOf("\n");
1476
- if (lfIndex !== -1) {
1477
- string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
1478
- }
1479
- return openAll + string + closeAll;
1480
- };
1481
- Object.defineProperties(createChalk.prototype, styles2);
1482
- var chalk = createChalk();
1483
- createChalk({ level: stderrColor ? stderrColor.level : 0 });
1484
- var source_default = chalk;
1485
-
1486
- // packages/core/src/terminal.ts
1487
- var TERMINAL_INDENT = " ";
1488
- var MAX_TERMINAL_NAME_LENGTH = 80;
1489
- var MAX_TERMINAL_DEPTH = 10;
1490
- function normalizeDepth(depth) {
1491
- if (!Number.isFinite(depth) || depth < 0) {
1492
- return 0;
1493
- }
1494
- return Math.min(Math.floor(depth), MAX_TERMINAL_DEPTH);
1495
- }
1496
- function getIndent(depth) {
1497
- return TERMINAL_INDENT.repeat(normalizeDepth(depth));
1498
- }
1499
- function formatTerminalName(name) {
1500
- if (typeof name !== "string" || name.trim() === "") {
1501
- return "unnamed";
1502
- }
1503
- return truncateName(name, MAX_TERMINAL_NAME_LENGTH);
1504
- }
1505
- function getStatusIcon(status) {
1506
- if (status === "success") return source_default.green("\u2714");
1507
- if (status === "error") return source_default.red("\u2716");
1508
- return source_default.yellow("\u23F3");
1509
- }
1510
- function renderStepLine(name, durationMs2, status, depth) {
1511
- try {
1512
- const nm = formatTerminalName(name);
1513
- const ind = getIndent(depth ?? 0);
1514
- if (status === "running" && durationMs2 === void 0) {
1515
- return `${ind}${source_default.yellow("\u23F3")} ${nm}`;
1516
- }
1517
- const hasDur = durationMs2 !== void 0 && Number.isFinite(durationMs2);
1518
- const dur = hasDur ? formatDuration2(durationMs2) : void 0;
1519
- if (status === "running") {
1520
- return dur !== void 0 ? `${ind}${source_default.yellow("\u23F3")} ${nm} (${dur})` : `${ind}${source_default.yellow("\u23F3")} ${nm}`;
1521
- }
1522
- if (!hasDur || dur === void 0) {
1523
- return `${ind}${source_default.yellow("\u23F3")} ${nm}`;
1524
- }
1525
- if (status === "success") {
1526
- return `${ind}${getStatusIcon("success")} ${nm} (${dur})`;
1527
- }
1528
- return `${ind}${getStatusIcon("error")} ${nm} (${dur})`;
1529
- } catch {
1530
- return "";
1531
- }
1532
- }
1533
- function renderErrorLine(error, depth) {
1534
- try {
1535
- const msg = typeof error.message === "string" ? error.message : "";
1536
- const ind = getIndent((depth ?? 0) + 1);
1537
- return `${ind}Error: ${msg}`;
1538
- } catch {
1539
- return "";
1540
- }
1541
- }
1542
- function resolveTraceDir(options = {}) {
1543
- if (typeof options.dir === "string" && options.dir.trim() !== "") {
1544
- return options.dir.trim();
1545
- }
1546
- const envDir = process.env.AGENT_INSPECT_TRACE_DIR;
1547
- if (typeof envDir === "string" && envDir.trim() !== "") {
1548
- return envDir.trim();
1549
- }
1550
- return getDefaultTraceDir();
1551
- }
1552
- var TraceDirectory = class {
1553
- #dir;
1554
- constructor(options = {}) {
1555
- this.#dir = resolveTraceDir(options);
1556
- }
1557
- getPath(filename) {
1558
- return filename ? path14.join(this.#dir, filename) : this.#dir;
1559
- }
1560
- async list() {
1561
- try {
1562
- const files = await readdir(this.#dir);
1563
- return files.filter((f) => f.endsWith(".jsonl"));
1564
- } catch (e) {
1565
- if (e && typeof e === "object" && "code" in e && e.code === "ENOENT") {
1566
- return [];
1567
- }
1568
- throw e;
1569
- }
1570
- }
1571
- async getFileStats(filename) {
1572
- return await stat(this.getPath(filename));
1573
- }
1574
- };
1575
- function isFiniteNumber(v) {
1576
- return typeof v === "number" && Number.isFinite(v);
1577
- }
1578
- function parseIsoToMs2(value) {
1579
- if (value === void 0) return void 0;
1580
- const parsed = Date.parse(value);
1581
- return Number.isFinite(parsed) ? parsed : void 0;
1582
- }
1583
- async function extractMetadata(filePath, _quickScan) {
1584
- const stats = await stat(filePath);
1585
- let runIdFromFile = path14.basename(filePath);
1586
- if (runIdFromFile.endsWith(".jsonl")) {
1587
- runIdFromFile = runIdFromFile.slice(0, -".jsonl".length);
1588
- }
1589
- const raw = await readFile(filePath, "utf-8");
1590
- const parsedTrace = parseTraceJsonl(raw, { warnings: false });
1591
- let runId;
1592
- let name;
1593
- let startedAt;
1594
- let endedAt;
1595
- let explicitDurationMs;
1596
- let hasRunStarted = false;
1597
- let hasRunCompleted = false;
1598
- let runCompletedStatus;
1599
- let anyStepError = false;
1600
- const anyKnownEvent = parsedTrace.sourceEventCount > 0;
1601
- let persistedStatus;
1602
- const persistedRun = parsedTrace.persisted.find(
1603
- (event) => event.kind === "RUN"
1604
- );
1605
- if (persistedRun) {
1606
- runId = persistedRun.runId;
1607
- if (persistedRun.name.trim() !== "") {
1608
- name = persistedRun.name;
1609
- }
1610
- startedAt = parseIsoToMs2(persistedRun.startedAt) ?? parseIsoToMs2(persistedRun.timestamp);
1611
- endedAt = parseIsoToMs2(persistedRun.endedAt);
1612
- if (isFiniteNumber(persistedRun.durationMs)) {
1613
- explicitDurationMs = persistedRun.durationMs;
1614
- if (endedAt === void 0 && startedAt !== void 0) {
1615
- endedAt = startedAt + persistedRun.durationMs;
1616
- }
1617
- }
1618
- if (persistedRun.status === "ok") persistedStatus = "success";
1619
- else if (persistedRun.status === "error") persistedStatus = "error";
1620
- else if (persistedRun.status === "running") persistedStatus = "running";
1621
- else if (persistedRun.status === "unknown") persistedStatus = "unknown";
1622
- } else {
1623
- runId = parsedTrace.persisted[0]?.runId;
1624
- }
1625
- for (const e of parsedTrace.events) {
1626
- if (runId === void 0 && typeof e.runId === "string") {
1627
- runId = e.runId;
1628
- }
1629
- if (e.event === "run_started") {
1630
- hasRunStarted = true;
1631
- const rs = e;
1632
- if (typeof rs.name === "string" && rs.name.trim() !== "") {
1633
- name = rs.name;
1634
- }
1635
- if (isFiniteNumber(rs.startTime)) {
1636
- startedAt = rs.startTime;
1637
- } else if (isFiniteNumber(rs.timestamp)) {
1638
- startedAt = rs.timestamp;
1639
- }
1640
- }
1641
- if (e.event === "run_completed") {
1642
- hasRunCompleted = true;
1643
- const rc = e;
1644
- runCompletedStatus = rc.status;
1645
- if (isFiniteNumber(rc.endTime)) endedAt = rc.endTime;
1646
- else if (isFiniteNumber(rc.timestamp)) endedAt = rc.timestamp;
1647
- if (isFiniteNumber(rc.durationMs)) explicitDurationMs = rc.durationMs;
1648
- }
1649
- if (e.event === "step_completed") {
1650
- const sc = e;
1651
- if (sc.status === "error") {
1652
- anyStepError = true;
1653
- }
1654
- }
1655
- }
1656
- const resolvedRunId = runId ?? runIdFromFile;
1657
- let status = "unknown";
1658
- if (hasRunCompleted && (runCompletedStatus === "success" || runCompletedStatus === "error")) {
1659
- status = runCompletedStatus;
1660
- } else if (anyStepError) {
1661
- status = "error";
1662
- } else if (persistedStatus !== void 0) {
1663
- status = persistedStatus;
1664
- } else if (hasRunStarted && !hasRunCompleted) {
1665
- status = "running";
1666
- } else if (anyKnownEvent) {
1667
- status = "unknown";
1668
- } else {
1669
- status = "unknown";
1670
- }
1671
- const durationMs2 = explicitDurationMs ?? (startedAt !== void 0 && endedAt !== void 0 && Number.isFinite(startedAt) && Number.isFinite(endedAt) && endedAt >= startedAt ? endedAt - startedAt : void 0);
1672
- return {
1673
- runId: resolvedRunId,
1674
- name,
1675
- status,
1676
- startedAt,
1677
- endedAt,
1678
- durationMs: durationMs2,
1679
- eventCount: parsedTrace.sourceEventCount,
1680
- filePath,
1681
- fileSize: stats.size,
1682
- createdAt: stats.birthtime
1683
- };
1684
- }
1685
- function isNonNegativeFiniteNumber(value) {
1686
- return typeof value === "number" && Number.isFinite(value) && value >= 0;
1687
- }
1688
- function buildRunSummary(events) {
1689
- const started = events.find(
1690
- (e) => e.event === "run_started"
1691
- );
1692
- const completed = events.filter(
1693
- (e) => e.event === "run_completed"
1694
- );
1695
- const lastCompleted = completed[completed.length - 1];
1696
- const runId = started?.runId ?? events.find((e) => typeof e.runId === "string")?.runId ?? "unknown-run";
1697
- const name = typeof started?.name === "string" && started.name.trim() !== "" ? started.name : void 0;
1698
- const status = lastCompleted ? lastCompleted.status : started ? "running" : "unknown";
1699
- const durationMs2 = lastCompleted && isFiniteNumber(lastCompleted.durationMs) ? lastCompleted.durationMs : void 0;
1700
- started && isFiniteNumber(started.startTime) ? started.startTime : void 0;
1701
- const steps = /* @__PURE__ */ new Map();
1702
- for (const e of events) {
1703
- if (e.event === "step_started") {
1704
- const s = e;
1705
- steps.set(s.stepId, {
1706
- type: s.type,
1707
- name: s.name,
1708
- status: "running",
1709
- parentId: s.parentId,
1710
- tokensInput: isNonNegativeFiniteNumber(s.metadata?.tokens?.input) ? s.metadata.tokens.input : void 0,
1711
- tokensOutput: isNonNegativeFiniteNumber(s.metadata?.tokens?.output) ? s.metadata.tokens.output : void 0,
1712
- tokensTotal: isNonNegativeFiniteNumber(s.metadata?.tokens?.total) ? s.metadata.tokens.total : void 0,
1713
- tokensCached: isNonNegativeFiniteNumber(s.metadata?.tokens?.cached) ? s.metadata.tokens.cached : void 0
1714
- });
1715
- }
1716
- }
1717
- for (const e of events) {
1718
- if (e.event === "step_completed") {
1719
- const c = e;
1720
- const existing = steps.get(c.stepId);
1721
- if (!existing) continue;
1722
- existing.status = c.status;
1723
- existing.durationMs = c.durationMs;
1724
- }
1725
- }
1726
- let totalSteps = 0;
1727
- let llmSteps = 0;
1728
- let toolSteps = 0;
1729
- let logicSteps = 0;
1730
- let errorSteps = 0;
1731
- let maxDepth = 0;
1732
- let longestStep;
1733
- let totalTokensInput = 0;
1734
- let totalTokensOutput = 0;
1735
- let totalTokensTotal = 0;
1736
- let totalTokensCached = 0;
1737
- let tokenBearingSteps = 0;
1738
- let stepsWithKnownTotal = 0;
1739
- let hasCachedTokens = false;
1740
- const depthCache = /* @__PURE__ */ new Map();
1741
- const computeDepth = (stepId) => {
1742
- const cached = depthCache.get(stepId);
1743
- if (cached !== void 0) return cached;
1744
- const node = steps.get(stepId);
1745
- if (!node) return 0;
1746
- const parent = node.parentId;
1747
- if (typeof parent !== "string" || parent.trim() === "" || !steps.has(parent)) {
1748
- depthCache.set(stepId, 0);
1749
- return 0;
1750
- }
1751
- const d = Math.min(1e3, computeDepth(parent) + 1);
1752
- depthCache.set(stepId, d);
1753
- return d;
1754
- };
1755
- for (const [id, s] of steps.entries()) {
1756
- totalSteps += 1;
1757
- if (s.type === "llm") llmSteps += 1;
1758
- else if (s.type === "tool") toolSteps += 1;
1759
- else logicSteps += 1;
1760
- if (s.status === "error") errorSteps += 1;
1761
- const depth = computeDepth(id);
1762
- if (depth > maxDepth) maxDepth = depth;
1763
- if (typeof s.durationMs === "number" && Number.isFinite(s.durationMs)) {
1764
- if (!longestStep || s.durationMs > longestStep.durationMs) {
1765
- longestStep = { name: s.name, durationMs: s.durationMs, type: s.type };
1766
- }
1767
- }
1768
- if (s.tokensInput !== void 0 || s.tokensOutput !== void 0 || s.tokensTotal !== void 0 || s.tokensCached !== void 0) {
1769
- tokenBearingSteps += 1;
1770
- if (s.tokensInput !== void 0) totalTokensInput += s.tokensInput;
1771
- if (s.tokensOutput !== void 0) totalTokensOutput += s.tokensOutput;
1772
- if (s.tokensTotal !== void 0) {
1773
- totalTokensTotal += s.tokensTotal;
1774
- stepsWithKnownTotal += 1;
1775
- } else if (s.tokensInput !== void 0 && s.tokensOutput !== void 0) {
1776
- totalTokensTotal += s.tokensInput + s.tokensOutput;
1777
- stepsWithKnownTotal += 1;
1778
- }
1779
- if (s.tokensCached !== void 0) {
1780
- totalTokensCached += s.tokensCached;
1781
- hasCachedTokens = true;
1782
- }
1783
- }
1784
- }
1785
- const summary = {
1786
- runId,
1787
- name,
1788
- status,
1789
- durationMs: durationMs2,
1790
- totalSteps,
1791
- llmSteps,
1792
- toolSteps,
1793
- logicSteps,
1794
- errorSteps,
1795
- maxDepth,
1796
- ...longestStep ? { longestStep } : {},
1797
- ...tokenBearingSteps > 0 ? {
1798
- totalTokens: {
1799
- input: totalTokensInput,
1800
- output: totalTokensOutput,
1801
- ...stepsWithKnownTotal === tokenBearingSteps ? { total: totalTokensTotal } : {},
1802
- ...hasCachedTokens ? { cached: totalTokensCached } : {}
1803
- }
1804
- } : {}
1805
- };
1806
- return summary;
1807
- }
1808
-
1809
- // packages/core/src/trace-filter.ts
1810
- function toLower(s) {
1811
- return typeof s === "string" ? s.toLowerCase() : "";
1812
- }
1813
- function filterTraces(traces, options) {
1814
- const input3 = [...traces];
1815
- let out = input3.filter((t) => {
1816
- if (options.status && t.status !== options.status) return false;
1817
- if (options.name) {
1818
- const q = options.name.toLowerCase();
1819
- const hay = `${toLower(t.name)} ${toLower(t.runId)}`;
1820
- if (!hay.includes(q)) return false;
1821
- }
1822
- if (options.since) {
1823
- const windowMs = parseDuration(options.since);
1824
- const cutoff = Date.now() - windowMs;
1825
- const started = typeof t.startedAt === "number" ? t.startedAt : void 0;
1826
- const basis = started ?? t.createdAt.getTime();
1827
- if (!Number.isFinite(basis) || basis < cutoff) return false;
1828
- }
1829
- return true;
1830
- });
1831
- out.sort((a, b) => {
1832
- const aTime = (typeof a.startedAt === "number" ? a.startedAt : void 0) ?? a.createdAt.getTime();
1833
- const bTime = (typeof b.startedAt === "number" ? b.startedAt : void 0) ?? b.createdAt.getTime();
1834
- return bTime - aTime;
1835
- });
1836
- if (typeof options.limit === "number" && Number.isFinite(options.limit)) {
1837
- const n = Math.max(0, Math.floor(options.limit));
1838
- out = out.slice(0, n);
1839
- }
1840
- return out;
1841
- }
1842
-
1843
- // packages/core/src/timeline.ts
1844
- function finite(n) {
1845
- return typeof n === "number" && Number.isFinite(n);
1846
- }
1847
- function pickStreamingMeta(metadata) {
1848
- if (!metadata || typeof metadata !== "object") return void 0;
1849
- const chunkCount = metadata.chunkCount;
1850
- const streamDurationMs = metadata.streamDurationMs;
1851
- const streamedCharCount = metadata.streamedCharCount;
1852
- if (!finite(chunkCount) && !finite(streamDurationMs) && !finite(streamedCharCount)) {
1853
- return void 0;
1854
- }
1855
- return {
1856
- ...finite(chunkCount) ? { chunkCount } : {},
1857
- ...finite(streamDurationMs) ? { streamDurationMs } : {},
1858
- ...finite(streamedCharCount) ? { streamedCharCount } : {}
1859
- };
1860
- }
1861
- function pickCorrelation(metadata) {
1862
- if (!metadata || typeof metadata !== "object") return void 0;
1863
- const out = {};
1864
- for (const key of [
1865
- "correlationId",
1866
- "requestId",
1867
- "decisionId",
1868
- "groupId"
1869
- ]) {
1870
- const v = metadata[key];
1871
- if (typeof v === "string" && v.trim() !== "") {
1872
- out[key] = v;
1873
- }
1874
- }
1875
- return Object.keys(out).length > 0 ? out : void 0;
1876
- }
1877
- function buildRunTimeline(events, options = {}) {
1878
- const started = events.find(
1879
- (e) => e.event === "run_started"
1880
- );
1881
- const completed = events.filter(
1882
- (e) => e.event === "run_completed"
1883
- );
1884
- const lastCompleted = completed[completed.length - 1];
1885
- const runId = started?.runId ?? events.find((e) => typeof e.runId === "string")?.runId ?? "unknown-run";
1886
- const runStart = started && finite(started.startTime) ? started.startTime : started && finite(started.timestamp) ? started.timestamp : void 0;
1887
- const status = lastCompleted ? lastCompleted.status : started ? "running" : "unknown";
1888
- const steps = /* @__PURE__ */ new Map();
1889
- for (const e of events) {
1890
- if (e.event === "step_started") {
1891
- const s = e;
1892
- steps.set(s.stepId, {
1893
- name: s.name,
1894
- type: s.type,
1895
- parentId: s.parentId,
1896
- startedAt: finite(s.startTime) ? s.startTime : s.timestamp,
1897
- status: "running",
1898
- metadata: s.metadata
1899
- });
1900
- }
1901
- }
1902
- for (const e of events) {
1903
- if (e.event !== "step_completed") continue;
1904
- const c = e;
1905
- const node = steps.get(c.stepId);
1906
- if (!node) continue;
1907
- node.status = c.status;
1908
- if (finite(c.durationMs)) node.durationMs = c.durationMs;
1909
- }
1910
- const depthCache = /* @__PURE__ */ new Map();
1911
- const computeDepth = (stepId) => {
1912
- const cached = depthCache.get(stepId);
1913
- if (cached !== void 0) return cached;
1914
- const node = steps.get(stepId);
1915
- if (!node) return 0;
1916
- const parent = node.parentId;
1917
- if (typeof parent !== "string" || parent.trim() === "" || !steps.has(parent)) {
1918
- depthCache.set(stepId, 0);
1919
- return 0;
1920
- }
1921
- const d = Math.min(1e3, computeDepth(parent) + 1);
1922
- depthCache.set(stepId, d);
1923
- return d;
1924
- };
1925
- const entries = [];
1926
- for (const [stepId, s] of steps.entries()) {
1927
- const offsetMs = runStart !== void 0 && finite(s.startedAt) ? Math.max(0, s.startedAt - runStart) : 0;
1928
- entries.push({
1929
- stepId,
1930
- name: s.name,
1931
- type: s.type,
1932
- status: s.status,
1933
- depth: computeDepth(stepId),
1934
- startedAt: s.startedAt,
1935
- offsetMs,
1936
- durationMs: s.durationMs,
1937
- isError: s.status === "error",
1938
- streaming: pickStreamingMeta(s.metadata)
1939
- });
1940
- }
1941
- entries.sort((a, b) => a.startedAt - b.startedAt);
1942
- const slowTopN = options.slowTopN ?? 3;
1943
- if (options.focus === "slow" && entries.length > 0) {
1944
- const ranked = [...entries].filter((e) => finite(e.durationMs)).sort((a, b) => (b.durationMs ?? 0) - (a.durationMs ?? 0));
1945
- const slowIds = new Set(
1946
- ranked.slice(0, slowTopN).map((e) => e.stepId)
1947
- );
1948
- for (const e of entries) {
1949
- if (slowIds.has(e.stepId)) e.slow = true;
1950
- }
1951
- }
1952
- return {
1953
- runId,
1954
- name: typeof started?.name === "string" && started.name.trim() !== "" ? started.name : void 0,
1955
- status,
1956
- startedAt: runStart,
1957
- endedAt: lastCompleted && finite(lastCompleted.endTime) ? lastCompleted.endTime : void 0,
1958
- durationMs: lastCompleted && finite(lastCompleted.durationMs) ? lastCompleted.durationMs : void 0,
1959
- correlation: pickCorrelation(
1960
- started?.metadata
1961
- ),
1962
- entries
1963
- };
1964
- }
1965
- function renderTimeline(timeline, options = {}) {
1966
- const lines = [];
1967
- lines.push(`Timeline: ${timeline.name ?? timeline.runId}`);
1968
- lines.push(`Run ID: ${timeline.runId}`);
1969
- lines.push(`Status: ${timeline.status}`);
1970
- if (timeline.startedAt !== void 0) {
1971
- lines.push(`Started: ${formatTimestamp(timeline.startedAt)}`);
1972
- }
1973
- if (timeline.durationMs !== void 0) {
1974
- lines.push(`Duration: ${formatDuration2(timeline.durationMs)}`);
1975
- }
1976
- if (timeline.correlation) {
1977
- const parts = Object.entries(timeline.correlation).filter(([, v]) => typeof v === "string").map(([k, v]) => `${k}=${v}`);
1978
- if (parts.length > 0) {
1979
- lines.push(`Correlation: ${parts.join(", ")}`);
1980
- }
1981
- }
1982
- lines.push("");
1983
- lines.push("Steps (chronological):");
1984
- const show = timeline.entries.filter((e) => {
1985
- if (options.focus === "slow") return e.slow === true;
1986
- return true;
1987
- });
1988
- if (show.length === 0) {
1989
- lines.push(
1990
- options.focus === "slow" ? "(no steps with duration for slow focus)" : "(no steps)"
1991
- );
1992
- return lines.join("\n");
1993
- }
1994
- for (const e of show) {
1995
- const prefix = e.slow ? "[slow] " : "";
1996
- const typeTag = e.type === "llm" ? "llm" : e.type === "tool" ? "tool" : e.type;
1997
- const dur = e.durationMs !== void 0 ? formatDuration2(e.durationMs) : "-";
1998
- const err = e.isError ? " error" : "";
1999
- const off = formatDuration2(e.offsetMs);
2000
- let line = `${prefix}+${off} ${typeTag}:${e.name} (${dur})${err}`;
2001
- if (e.streaming?.chunkCount !== void 0) {
2002
- line += ` chunks=${e.streaming.chunkCount}`;
2003
- }
2004
- if (e.streaming?.streamDurationMs !== void 0) {
2005
- line += ` stream=${formatDuration2(e.streaming.streamDurationMs)}`;
2006
- }
2007
- lines.push(line);
2008
- }
2009
- return lines.join("\n");
2010
- }
2011
-
2012
- // packages/core/src/what.ts
2013
- function pickCorrelation2(metadata) {
2014
- if (!metadata) return void 0;
2015
- const out = {};
2016
- for (const key of [
2017
- "correlationId",
2018
- "requestId",
2019
- "decisionId",
2020
- "groupId"
2021
- ]) {
2022
- const value = metadata[key];
2023
- if (typeof value === "string" && value.trim() !== "") {
2024
- out[key] = value;
2025
- }
2026
- }
2027
- return Object.keys(out).length > 0 ? out : void 0;
2028
- }
2029
- function stepMixLine(summary) {
2030
- const parts = [];
2031
- if (summary.llmSteps > 0) parts.push(`${summary.llmSteps} LLM`);
2032
- if (summary.toolSteps > 0) parts.push(`${summary.toolSteps} tool`);
2033
- if (summary.logicSteps > 0) parts.push(`${summary.logicSteps} logic`);
2034
- return parts.length > 0 ? parts.join(", ") : "none";
2035
- }
2036
- function outcomeLine(summary) {
2037
- if (summary.status === "success") {
2038
- return summary.errorSteps > 0 ? "Completed with step errors recorded." : "Completed successfully.";
2039
- }
2040
- if (summary.status === "error") {
2041
- if (summary.failedStepNames.length > 0) {
2042
- const names = summary.failedStepNames.slice(0, 3).join(", ");
2043
- const suffix = summary.failedStepNames.length > 3 ? ` (+${summary.failedStepNames.length - 3} more)` : "";
2044
- return `Failed at step(s): ${names}${suffix}.`;
2045
- }
2046
- if (summary.runErrorMessage) {
2047
- return `Run failed: ${summary.runErrorMessage}`;
2048
- }
2049
- return "Run failed.";
2050
- }
2051
- if (summary.status === "running") {
2052
- return "Run is still in progress (no run_completed).";
2053
- }
2054
- return "Outcome unknown \u2014 inspect events may be incomplete.";
2055
- }
2056
- function buildRunWhatSummary(events) {
2057
- const base = buildRunSummary(events);
2058
- const started = events.find(
2059
- (e) => e.event === "run_started"
2060
- );
2061
- const completed = events.filter(
2062
- (e) => e.event === "run_completed"
2063
- );
2064
- const lastCompleted = completed[completed.length - 1];
2065
- const failedStepNames = [];
2066
- const stepNames = /* @__PURE__ */ new Map();
2067
- for (const e of events) {
2068
- if (e.event === "step_started") {
2069
- const s = e;
2070
- stepNames.set(s.stepId, s.name);
2071
- }
2072
- }
2073
- for (const e of events) {
2074
- if (e.event === "step_completed") {
2075
- const sc = e;
2076
- if (sc.status === "error") {
2077
- failedStepNames.push(stepNames.get(sc.stepId) ?? sc.stepId);
2078
- }
2079
- }
2080
- }
2081
- return {
2082
- runId: base.runId,
2083
- name: base.name,
2084
- status: base.status,
2085
- durationMs: base.durationMs,
2086
- totalSteps: base.totalSteps,
2087
- llmSteps: base.llmSteps,
2088
- toolSteps: base.toolSteps,
2089
- logicSteps: base.logicSteps,
2090
- errorSteps: base.errorSteps,
2091
- maxDepth: base.maxDepth,
2092
- longestStep: base.longestStep,
2093
- totalTokens: base.totalTokens,
2094
- correlation: pickCorrelation2(started?.metadata),
2095
- failedStepNames,
2096
- runErrorMessage: lastCompleted?.error?.message
2097
- };
2098
- }
2099
- function renderRunWhat(summary, options = {}) {
2100
- const showCorrelation = options.correlation !== false;
2101
- const lines = [];
2102
- const label = summary.name ?? summary.runId;
2103
- lines.push(`What: ${label}`);
2104
- const duration = summary.durationMs !== void 0 ? formatDuration2(summary.durationMs) : "\u2014";
2105
- lines.push(
2106
- `Status: ${summary.status} \xB7 Duration: ${duration} \xB7 Steps: ${summary.totalSteps} (${stepMixLine(summary)})`
2107
- );
2108
- if (summary.totalTokens) {
2109
- const tokenParts = [
2110
- `${summary.totalTokens.input} in`,
2111
- `${summary.totalTokens.output} out`
2112
- ];
2113
- if (summary.totalTokens.total !== void 0) {
2114
- tokenParts.push(`${summary.totalTokens.total} total`);
2115
- }
2116
- if (summary.totalTokens.cached !== void 0) {
2117
- tokenParts.push(`${summary.totalTokens.cached} cached`);
2118
- }
2119
- lines.push(`Tokens: ${tokenParts.join(" / ")}`);
2120
- }
2121
- if (showCorrelation && summary.correlation) {
2122
- const parts = [];
2123
- if (summary.correlation.correlationId) {
2124
- parts.push(`correlationId=${summary.correlation.correlationId}`);
2125
- }
2126
- if (summary.correlation.requestId) {
2127
- parts.push(`requestId=${summary.correlation.requestId}`);
2128
- }
2129
- if (summary.correlation.decisionId) {
2130
- parts.push(`decisionId=${summary.correlation.decisionId}`);
2131
- }
2132
- if (summary.correlation.groupId) {
2133
- parts.push(`groupId=${summary.correlation.groupId}`);
2134
- }
2135
- if (parts.length > 0) {
2136
- lines.push(`Correlation: ${parts.join(", ")}`);
2137
- }
2138
- }
2139
- lines.push(`Outcome: ${outcomeLine(summary)}`);
2140
- if (summary.longestStep && summary.totalSteps > 0) {
2141
- lines.push(
2142
- `Slowest: ${summary.longestStep.name} (${formatDuration2(summary.longestStep.durationMs)}, ${summary.longestStep.type})`
2143
- );
2144
- }
2145
- if (summary.maxDepth > 0) {
2146
- lines.push(`Max depth: ${summary.maxDepth}`);
2147
- }
2148
- return lines.join("\n");
2149
- }
2150
-
2151
- // packages/core/src/explain.ts
2152
- function flatten(nodes, out = []) {
2153
- for (const node of nodes) {
2154
- out.push({ node, index: out.length + 1 });
2155
- flatten(node.children, out);
2156
- }
2157
- return out;
2158
- }
2159
- function redactValue(redactor, key, value) {
2160
- return redactor.redactValue(key, value);
2161
- }
2162
- function fact(id, label, value, redactor) {
2163
- return {
2164
- id,
2165
- label,
2166
- value: redactValue(redactor, id.split(".").at(-1) ?? id, value),
2167
- source: "trace",
2168
- confidence: "observed"
2169
- };
2170
- }
2171
- function topKinds(run) {
2172
- return Object.entries(run.metadata.kinds).filter(([, count]) => count > 0).sort((a, b) => {
2173
- if (b[1] !== a[1]) return b[1] - a[1];
2174
- return a[0].localeCompare(b[0]);
2175
- }).slice(0, 5).map(([kind, count]) => `${kind}:${count}`);
2176
- }
2177
- function countErrorNodes(nodes) {
2178
- return nodes.filter((entry) => entry.node.event.status === "error").length;
2179
- }
2180
- function slowestNode(nodes) {
2181
- return nodes.filter((entry) => entry.node.event.durationMs !== void 0).sort((a, b) => {
2182
- const delta = (b.node.event.durationMs ?? 0) - (a.node.event.durationMs ?? 0);
2183
- return delta !== 0 ? delta : a.index - b.index;
2184
- })[0];
2185
- }
2186
- function attributeFacts(nodes, redactor) {
2187
- const facts = [];
2188
- for (const entry of nodes) {
2189
- const attrs = entry.node.event.attributes;
2190
- if (attrs === void 0) continue;
2191
- for (const key of Object.keys(attrs).sort()) {
2192
- facts.push({
2193
- id: `node.${entry.index}.attributes.${key}`,
2194
- label: `${entry.node.event.name} attribute ${key}`,
2195
- value: redactValue(redactor, key, attrs[key]),
2196
- source: "trace",
2197
- confidence: "observed"
2198
- });
2199
- if (facts.length >= 8) return facts;
2200
- }
2201
- }
2202
- return facts;
2203
- }
2204
- function buildFacts(run, redactor) {
2205
- const nodes = flatten(run.children);
2206
- const facts = [
2207
- fact("run.id", "Run id", run.runId, redactor),
2208
- fact("run.name", "Run name", run.name ?? run.runId, redactor),
2209
- fact("run.status", "Run status", run.status ?? "unknown", redactor),
2210
- fact("run.totalEvents", "Total events", run.metadata.totalEvents, redactor),
2211
- fact("run.stepCount", "Top-level step count", run.children.length, redactor),
2212
- fact("run.nodeCount", "Total node count", nodes.length, redactor),
2213
- fact("run.errorNodeCount", "Error node count", countErrorNodes(nodes), redactor),
2214
- fact("run.kinds", "Observed kind mix", topKinds(run), redactor)
2215
- ];
2216
- if (run.durationMs !== void 0) {
2217
- facts.push(fact("run.durationMs", "Run duration milliseconds", run.durationMs, redactor));
2218
- }
2219
- const slowest = slowestNode(nodes);
2220
- if (slowest !== void 0) {
2221
- facts.push(
2222
- fact("run.slowestNode", "Slowest observed node", {
2223
- name: slowest.node.event.name,
2224
- kind: slowest.node.event.kind,
2225
- durationMs: slowest.node.event.durationMs
2226
- }, redactor)
2227
- );
2228
- }
2229
- facts.push(...attributeFacts(nodes, redactor));
2230
- return facts;
2231
- }
2232
- function buildInferences(run, facts) {
2233
- const inferences = [];
2234
- const errorFact = facts.find((item) => item.id === "run.errorNodeCount");
2235
- const kindFact = facts.find((item) => item.id === "run.kinds");
2236
- const durationFact = facts.find((item) => item.id === "run.durationMs");
2237
- const errorNodeCount = typeof errorFact?.value === "number" ? errorFact.value : 0;
2238
- if (run.status === "error" || errorNodeCount > 0) {
2239
- inferences.push({
2240
- id: "outcome.error",
2241
- label: "Outcome",
2242
- text: "The run recorded an error status or at least one error node.",
2243
- evidence: ["run.status", "run.errorNodeCount"],
2244
- confidence: "deterministic"
2245
- });
2246
- } else if (run.status === "ok") {
2247
- inferences.push({
2248
- id: "outcome.success",
2249
- label: "Outcome",
2250
- text: "The run completed without observed error nodes.",
2251
- evidence: ["run.status", "run.errorNodeCount"],
2252
- confidence: "deterministic"
2253
- });
2254
- }
2255
- if (kindFact !== void 0) {
2256
- inferences.push({
2257
- id: "shape.kind-mix",
2258
- label: "Trace shape",
2259
- text: "The explanation is based on the observed event kind mix, not generated content.",
2260
- evidence: [kindFact.id],
2261
- confidence: "deterministic"
2262
- });
2263
- }
2264
- if (durationFact !== void 0) {
2265
- inferences.push({
2266
- id: "timing.duration",
2267
- label: "Timing",
2268
- text: "Timing claims are limited to persisted duration fields in the trace.",
2269
- evidence: [durationFact.id],
2270
- confidence: "deterministic"
2271
- });
2272
- }
2273
- return inferences;
2274
- }
2275
- function buildLocalExplanation(run, options = {}) {
2276
- const redactionProfile = options.redactionProfile ?? "local";
2277
- const resolved = resolveRedactionProfile(redactionProfile);
2278
- const redactor = new Redactor({ extraKeys: resolved.extraKeys });
2279
- const mode = options.mode ?? "local";
2280
- const facts = buildFacts(run, redactor);
2281
- return {
2282
- mode,
2283
- runId: String(redactValue(redactor, "runId", run.runId)),
2284
- ...run.name !== void 0 ? { name: String(redactValue(redactor, "name", run.name)) } : {},
2285
- ...run.status !== void 0 ? { status: run.status } : {},
2286
- redactionProfile,
2287
- facts,
2288
- inferences: mode === "dry-run" ? [] : buildInferences(run, facts),
2289
- notes: [
2290
- "Generated locally without provider or network calls.",
2291
- "Facts are observed from normalized trace data; inferences are deterministic labels."
2292
- ]
2293
- };
2294
- }
2295
-
2296
- // packages/core/src/stats.ts
2297
- function percentile(sorted, p) {
2298
- if (sorted.length === 0) return void 0;
2299
- const idx = Math.min(
2300
- sorted.length - 1,
2301
- Math.max(0, Math.ceil(p / 100 * sorted.length) - 1)
2302
- );
2303
- return sorted[idx];
2304
- }
2305
- async function readRunStartedMetadata(filePath) {
2306
- try {
2307
- const events = await readTraceEventsFromFile(filePath);
2308
- for (const event of events) {
2309
- if (event.event !== "run_started") continue;
2310
- const rs = event;
2311
- if (rs.metadata && typeof rs.metadata === "object") {
2312
- return rs.metadata;
2313
- }
2314
- return void 0;
2315
- }
2316
- } catch {
2317
- }
2318
- return void 0;
2319
- }
2320
- function metaMatchesCorrelation(metadata, correlationId, groupId) {
2321
- if (correlationId) {
2322
- const v = metadata?.correlationId;
2323
- if (typeof v !== "string" || v !== correlationId) return false;
2324
- }
2325
- if (groupId) {
2326
- const v = metadata?.groupId;
2327
- if (typeof v !== "string" || v !== groupId) return false;
2328
- }
2329
- return true;
2330
- }
2331
- async function buildTraceStats(metas, options) {
2332
- let filtered = filterTraces(metas, { since: options.since });
2333
- if (options.correlationId || options.groupId) {
2334
- const next = [];
2335
- for (const m of filtered) {
2336
- const md = await readRunStartedMetadata(m.filePath);
2337
- if (metaMatchesCorrelation(md, options.correlationId, options.groupId)) {
2338
- next.push(m);
2339
- }
2340
- }
2341
- filtered = next;
2342
- }
2343
- let successCount = 0;
2344
- let errorCount = 0;
2345
- let runningCount = 0;
2346
- let unknownCount = 0;
2347
- const durations = [];
2348
- let totalSteps = 0;
2349
- let totalLlmSteps = 0;
2350
- let totalToolSteps = 0;
2351
- let totalErrorSteps = 0;
2352
- const slowestRuns = [];
2353
- const slowestSteps = [];
2354
- for (const m of filtered) {
2355
- if (m.status === "success") successCount += 1;
2356
- else if (m.status === "error") errorCount += 1;
2357
- else if (m.status === "running") runningCount += 1;
2358
- else unknownCount += 1;
2359
- if (typeof m.durationMs === "number" && Number.isFinite(m.durationMs) && m.durationMs >= 0) {
2360
- durations.push(m.durationMs);
2361
- slowestRuns.push({
2362
- runId: m.runId,
2363
- name: m.name,
2364
- durationMs: m.durationMs,
2365
- status: m.status
2366
- });
2367
- }
2368
- try {
2369
- const events = await readTraceEventsFromFile(m.filePath);
2370
- if (events.length === 0) continue;
2371
- const summary = buildRunSummary(events);
2372
- totalSteps += summary.totalSteps;
2373
- totalLlmSteps += summary.llmSteps;
2374
- totalToolSteps += summary.toolSteps;
2375
- totalErrorSteps += summary.errorSteps;
2376
- const steps = collectCompletedSteps(events, m.runId);
2377
- for (const s of steps) {
2378
- slowestSteps.push(s);
2379
- }
2380
- } catch {
2381
- }
2382
- }
2383
- slowestRuns.sort((a, b) => (b.durationMs ?? 0) - (a.durationMs ?? 0));
2384
- slowestSteps.sort((a, b) => b.durationMs - a.durationMs);
2385
- const runLimit = options.slowRunLimit ?? 5;
2386
- const stepLimit = options.slowStepLimit ?? 5;
2387
- const sortedDur = [...durations].sort((a, b) => a - b);
2388
- const totalRuns = filtered.length;
2389
- const errorRate = totalRuns > 0 ? errorCount / totalRuns : 0;
2390
- const sumDur = durations.reduce((a, b) => a + b, 0);
2391
- return {
2392
- traceDir: options.traceDir,
2393
- ...options.since ? { since: options.since } : {},
2394
- ...options.correlationId ? { correlationId: options.correlationId } : {},
2395
- ...options.groupId ? { groupId: options.groupId } : {},
2396
- totalRuns,
2397
- successCount,
2398
- errorCount,
2399
- runningCount,
2400
- unknownCount,
2401
- errorRate,
2402
- duration: {
2403
- ...sortedDur.length > 0 ? {
2404
- minMs: sortedDur[0],
2405
- maxMs: sortedDur[sortedDur.length - 1],
2406
- avgMs: sumDur / sortedDur.length,
2407
- p50Ms: percentile(sortedDur, 50),
2408
- p95Ms: percentile(sortedDur, 95)
2409
- } : {}
2410
- },
2411
- totalSteps,
2412
- avgStepsPerRun: totalRuns > 0 ? totalSteps / totalRuns : 0,
2413
- totalLlmSteps,
2414
- totalToolSteps,
2415
- totalErrorSteps,
2416
- slowestRuns: slowestRuns.slice(0, runLimit),
2417
- slowestSteps: slowestSteps.slice(0, stepLimit)
2418
- };
2419
- }
2420
- function collectCompletedSteps(events, runId) {
2421
- const started = /* @__PURE__ */ new Map();
2422
- const out = [];
2423
- for (const e of events) {
2424
- if (e.event === "step_started") {
2425
- const s = e;
2426
- started.set(s.stepId, { name: s.name, type: s.type });
2427
- }
2428
- if (e.event === "step_completed") {
2429
- const c = e;
2430
- if (c.status !== "success" && c.status !== "error") continue;
2431
- if (typeof c.durationMs !== "number" || !Number.isFinite(c.durationMs)) {
2432
- continue;
2433
- }
2434
- const meta = started.get(c.stepId);
2435
- out.push({
2436
- runId,
2437
- stepName: meta?.name ?? c.stepId,
2438
- stepType: meta?.type ?? "logic",
2439
- durationMs: c.durationMs
2440
- });
2441
- }
2442
- }
2443
- return out;
2444
- }
2445
- function renderTraceStats(stats) {
2446
- const lines = [];
2447
- lines.push("Trace stats (local)");
2448
- lines.push(`Directory: ${stats.traceDir}`);
2449
- if (stats.since) lines.push(`Since: ${stats.since}`);
2450
- if (stats.correlationId) lines.push(`Correlation ID: ${stats.correlationId}`);
2451
- if (stats.groupId) lines.push(`Group ID: ${stats.groupId}`);
2452
- lines.push("");
2453
- lines.push(`Runs: ${stats.totalRuns}`);
2454
- lines.push(
2455
- ` success: ${stats.successCount} error: ${stats.errorCount} running: ${stats.runningCount} unknown: ${stats.unknownCount}`
2456
- );
2457
- lines.push(`Error rate: ${(stats.errorRate * 100).toFixed(1)}%`);
2458
- if (stats.duration.avgMs !== void 0) {
2459
- lines.push(
2460
- `Duration: min ${formatDuration2(stats.duration.minMs ?? 0)} | avg ${formatDuration2(stats.duration.avgMs)} | p50 ${formatDuration2(stats.duration.p50Ms ?? 0)} | p95 ${formatDuration2(stats.duration.p95Ms ?? 0)} | max ${formatDuration2(stats.duration.maxMs ?? 0)}`
2461
- );
2462
- }
2463
- lines.push("");
2464
- lines.push(`Steps: ${stats.totalSteps} (avg ${stats.avgStepsPerRun.toFixed(1)} per run)`);
2465
- lines.push(
2466
- ` LLM: ${stats.totalLlmSteps} tool: ${stats.totalToolSteps} errors: ${stats.totalErrorSteps}`
2467
- );
2468
- if (stats.slowestRuns.length > 0) {
2469
- lines.push("");
2470
- lines.push("Slowest runs:");
2471
- for (const r of stats.slowestRuns) {
2472
- lines.push(
2473
- ` ${r.runId} | ${r.name ?? "-"} | ${formatDuration2(r.durationMs ?? 0)} | ${r.status}`
2474
- );
2475
- }
2476
- }
2477
- if (stats.slowestSteps.length > 0) {
2478
- lines.push("");
2479
- lines.push("Slowest steps:");
2480
- for (const s of stats.slowestSteps) {
2481
- lines.push(
2482
- ` ${s.runId} | ${s.stepType}:${s.stepName} | ${formatDuration2(s.durationMs)}`
2483
- );
2484
- }
2485
- }
2486
- return lines.join("\n");
2487
- }
2488
-
2489
- // packages/core/src/search.ts
2490
- function parseDurationFilter(expr) {
2491
- const raw = expr.trim();
2492
- const m = raw.match(/^(>=|<=|>|<)\s*(.+)$/);
2493
- if (!m) {
2494
- throw new Error(
2495
- `Invalid --duration "${expr}". Use forms like >5s, >=500ms, <2m.`
2496
- );
2497
- }
2498
- const op = m[1];
2499
- const ms = parseDuration(m[2].trim());
2500
- return { op, ms };
2501
- }
2502
- function durationMatches(valueMs, filter) {
2503
- if (valueMs === void 0 || !Number.isFinite(valueMs)) return false;
2504
- switch (filter.op) {
2505
- case ">":
2506
- return valueMs > filter.ms;
2507
- case ">=":
2508
- return valueMs >= filter.ms;
2509
- case "<":
2510
- return valueMs < filter.ms;
2511
- case "<=":
2512
- return valueMs <= filter.ms;
2513
- default:
2514
- return false;
2515
- }
2516
- }
2517
- function normalizeStepTypeFilter(kind, type) {
2518
- const v = (kind ?? type)?.trim().toLowerCase();
2519
- return v && v !== "" ? v : void 0;
2520
- }
2521
- function nameMatches(hay, needle) {
2522
- return hay.toLowerCase().includes(needle.toLowerCase());
2523
- }
2524
- async function searchTraces(metas, options) {
2525
- let filtered = filterTraces(metas, { since: options.since });
2526
- const stepTypeFilter = normalizeStepTypeFilter(options.kind, options.type);
2527
- const nameQuery = options.name?.trim();
2528
- const toolQuery = options.tool?.trim();
2529
- let durationFilter;
2530
- if (options.duration) {
2531
- durationFilter = parseDurationFilter(options.duration);
2532
- }
2533
- const limit = options.limit ?? 50;
2534
- const sessionId = options.session?.trim();
2535
- const hasContentFilter = Boolean(
2536
- options.status || stepTypeFilter || nameQuery || toolQuery || durationFilter
2537
- );
2538
- const results = [];
2539
- const sessionLabel = sessionId && sessionId !== "" ? sessionId : void 0;
2540
- if (!hasContentFilter) {
2541
- for (const m of filtered) {
2542
- results.push({
2543
- runId: m.runId,
2544
- runName: m.name,
2545
- runStatus: m.status,
2546
- timestamp: m.startedAt,
2547
- durationMs: m.durationMs,
2548
- matchReason: sessionLabel ? `trace in session ${sessionLabel}` : "trace in directory",
2549
- matchedFields: sessionLabel ? ["run", "session"] : ["run"],
2550
- filePath: m.filePath,
2551
- ...sessionLabel ? { sessionId: sessionLabel } : {}
2552
- });
2553
- }
2554
- return results.slice(0, limit);
2555
- }
2556
- for (const m of filtered) {
2557
- if (options.status && m.status !== options.status) continue;
2558
- let events = [];
2559
- try {
2560
- events = await readTraceEventsFromFile(m.filePath);
2561
- } catch {
2562
- continue;
2563
- }
2564
- if (events.length === 0) continue;
2565
- const runMatches = matchRunLevel(m, {
2566
- stepTypeFilter,
2567
- nameQuery,
2568
- toolQuery,
2569
- durationFilter,
2570
- statusFilter: options.status
2571
- });
2572
- results.push(...runMatches);
2573
- const stepMatches = matchStepLevel(m, events, {
2574
- stepTypeFilter,
2575
- nameQuery,
2576
- toolQuery,
2577
- durationFilter,
2578
- statusFilter: options.status
2579
- });
2580
- results.push(...stepMatches);
2581
- }
2582
- results.sort((a, b) => {
2583
- const ta = a.timestamp ?? 0;
2584
- const tb = b.timestamp ?? 0;
2585
- if (ta !== tb) return ta - tb;
2586
- const runCmp = a.runId.localeCompare(b.runId);
2587
- if (runCmp !== 0) return runCmp;
2588
- return (a.stepName ?? "").localeCompare(b.stepName ?? "");
2589
- });
2590
- return results.slice(0, limit);
2591
- }
2592
- function matchRunLevel(m, opts) {
2593
- if (opts.stepTypeFilter || opts.toolQuery) return [];
2594
- const out = [];
2595
- const fields = [];
2596
- if (opts.statusFilter && m.status === opts.statusFilter) {
2597
- fields.push("run.status");
2598
- }
2599
- if (opts.nameQuery && nameMatches(m.name ?? m.runId, opts.nameQuery)) {
2600
- fields.push("run.name");
2601
- }
2602
- if (opts.durationFilter && durationMatches(m.durationMs, opts.durationFilter)) {
2603
- fields.push("run.durationMs");
2604
- }
2605
- if (fields.length === 0) return out;
2606
- out.push({
2607
- runId: m.runId,
2608
- runName: m.name,
2609
- runStatus: m.status,
2610
- timestamp: m.startedAt,
2611
- durationMs: m.durationMs,
2612
- matchReason: `run match: ${fields.join(", ")}`,
2613
- matchedFields: fields,
2614
- filePath: m.filePath
2615
- });
2616
- return out;
2617
- }
2618
- function matchStepLevel(m, events, opts) {
2619
- const out = [];
2620
- const started = /* @__PURE__ */ new Map();
2621
- for (const e of events) {
2622
- if (e.event === "step_started") {
2623
- started.set(e.stepId, e);
2624
- }
2625
- }
2626
- for (const e of events) {
2627
- if (e.event !== "step_completed") continue;
2628
- const c = e;
2629
- const s = started.get(c.stepId);
2630
- if (!s) continue;
2631
- const fields = [];
2632
- const stepType = s.type;
2633
- if (opts.stepTypeFilter && stepType !== opts.stepTypeFilter) {
2634
- continue;
2635
- }
2636
- const hasStepFilters = opts.stepTypeFilter || opts.nameQuery || opts.toolQuery || opts.durationFilter || opts.statusFilter === "error" || opts.statusFilter === "success";
2637
- if (!hasStepFilters) continue;
2638
- if (opts.statusFilter === "error" && c.status === "error") {
2639
- fields.push("step.status");
2640
- } else if (opts.statusFilter === "success" && c.status === "success") {
2641
- fields.push("step.status");
2642
- } else if (opts.statusFilter === "error" || opts.statusFilter === "success") {
2643
- continue;
2644
- }
2645
- if (opts.nameQuery) {
2646
- if (!nameMatches(s.name, opts.nameQuery)) continue;
2647
- fields.push("step.name");
2648
- }
2649
- if (opts.toolQuery) {
2650
- const toolName2 = typeof s.metadata?.toolName === "string" ? s.metadata.toolName : s.name;
2651
- if (!nameMatches(toolName2, opts.toolQuery)) continue;
2652
- fields.push("step.tool");
2653
- }
2654
- if (opts.durationFilter) {
2655
- if (!durationMatches(c.durationMs, opts.durationFilter)) continue;
2656
- fields.push("step.durationMs");
2657
- }
2658
- if (opts.stepTypeFilter) {
2659
- fields.push("step.type");
2660
- }
2661
- if (fields.length === 0) continue;
2662
- out.push({
2663
- runId: m.runId,
2664
- runName: m.name,
2665
- runStatus: m.status,
2666
- stepId: c.stepId,
2667
- stepName: s.name,
2668
- stepType,
2669
- timestamp: s.startTime ?? s.timestamp,
2670
- durationMs: c.durationMs,
2671
- matchReason: `step match: ${fields.join(", ")}`,
2672
- matchedFields: fields,
2673
- filePath: m.filePath
2674
- });
2675
- }
2676
- return out;
2677
- }
2678
- async function loadTraceMetadataList(_traceDir, fileNames, getPath) {
2679
- const metas = [];
2680
- for (const fileName of fileNames) {
2681
- try {
2682
- const filePath = getPath(fileName);
2683
- const meta = await extractMetadata(filePath);
2684
- metas.push(meta);
2685
- } catch {
2686
- }
2687
- }
2688
- return metas;
2689
- }
2690
-
2691
- // packages/core/src/sessions/metadata.ts
2692
- function isNonEmptyString3(value) {
2693
- return typeof value === "string" && value.trim() !== "";
2694
- }
2695
- function finitePositiveInt(value) {
2696
- if (typeof value !== "number" || !Number.isFinite(value) || value < 1) {
2697
- return void 0;
2698
- }
2699
- return Math.trunc(value);
2700
- }
2701
- function extractSessionWorkflowMetadata(record) {
2702
- if (!record) return void 0;
2703
- const out = {};
2704
- let found = false;
2705
- const assignString = (key, value) => {
2706
- if (isNonEmptyString3(value)) {
2707
- out[key] = value.trim();
2708
- found = true;
2709
- }
2710
- };
2711
- assignString("sessionId", record.sessionId);
2712
- assignString("conversationId", record.conversationId);
2713
- assignString("groupId", record.groupId);
2714
- assignString("parentGroupId", record.parentGroupId);
2715
- assignString("retryOf", record.retryOf);
2716
- assignString("retryReason", record.retryReason);
2717
- assignString("handoffFrom", record.handoffFrom);
2718
- assignString("handoffTo", record.handoffTo);
2719
- assignString("subAgentId", record.subAgentId);
2720
- assignString("subAgentName", record.subAgentName);
2721
- assignString("jobId", record.jobId);
2722
- assignString("queueName", record.queueName);
2723
- assignString("workflowName", record.workflowName);
2724
- assignString("workflowStep", record.workflowStep);
2725
- assignString("toolCallId", record.toolCallId);
2726
- assignString("mcpToolCallId", record.mcpToolCallId);
2727
- assignString("linkedStepId", record.linkedStepId);
2728
- assignString("correlationId", record.correlationId);
2729
- assignString("requestId", record.requestId);
2730
- assignString("decisionId", record.decisionId);
2731
- const attempt = finitePositiveInt(record.attempt);
2732
- if (attempt !== void 0) {
2733
- out.attempt = attempt;
2734
- found = true;
2735
- }
2736
- return found ? out : void 0;
2737
- }
2738
- function sessionKeyForRun(meta, options) {
2739
- if (meta?.sessionId) return meta.sessionId;
2740
- if (options?.correlateByGroupId && meta?.groupId) {
2741
- return `group:${meta.groupId}`;
2742
- }
2743
- return void 0;
2744
- }
2745
-
2746
- // packages/core/src/sessions/load.ts
2747
- async function enrichSessionRunRecord(meta) {
2748
- let metadata;
2749
- try {
2750
- const events = await readTraceEventsFromFile(meta.filePath);
2751
- for (const event of events) {
2752
- if (event.event !== "run_started") continue;
2753
- if (event.metadata && typeof event.metadata === "object") {
2754
- metadata = event.metadata;
2755
- }
2756
- break;
2757
- }
2758
- } catch {
2759
- }
2760
- return {
2761
- runId: meta.runId,
2762
- name: meta.name,
2763
- status: meta.status,
2764
- startedAt: meta.startedAt,
2765
- endedAt: meta.endedAt,
2766
- durationMs: meta.durationMs,
2767
- filePath: meta.filePath,
2768
- metadata
2769
- };
2770
- }
2771
- async function loadSessionRunRecords(metas) {
2772
- const out = [];
2773
- for (const meta of metas) {
2774
- out.push(await enrichSessionRunRecord(meta));
2775
- }
2776
- return out;
2777
- }
2778
-
2779
- // packages/core/src/sessions/scope.ts
2780
- function filterMetasBySessionScope(metas, records, options) {
2781
- const sessionId = options.sessionId?.trim();
2782
- const groupId = options.groupId?.trim();
2783
- const warnings = [];
2784
- if (sessionId) {
2785
- const index = buildSessionIndex(records, {
2786
- correlateByGroupId: options.correlateByGroupId === true
2787
- });
2788
- warnings.push(...index.warnings);
2789
- const session = index.sessions.find((item) => item.sessionId === sessionId);
2790
- if (!session) {
2791
- return {
2792
- metas: [],
2793
- scopeLabel: sessionId,
2794
- scopeKind: "session",
2795
- runIds: [],
2796
- warnings,
2797
- notFound: true
2798
- };
2799
- }
2800
- const runIdSet = new Set(session.runIds);
2801
- const filtered = metas.filter((meta) => runIdSet.has(meta.runId));
2802
- return {
2803
- metas: filtered,
2804
- scopeLabel: sessionId,
2805
- scopeKind: "session",
2806
- runIds: session.runIds,
2807
- warnings,
2808
- notFound: false
2809
- };
2810
- }
2811
- if (groupId) {
2812
- const runIds = records.filter((run) => extractSessionWorkflowMetadata(run.metadata)?.groupId === groupId).map((run) => run.runId).sort();
2813
- if (runIds.length === 0) {
2814
- return {
2815
- metas: [],
2816
- scopeLabel: groupId,
2817
- scopeKind: "group",
2818
- runIds: [],
2819
- warnings,
2820
- notFound: true
2821
- };
2822
- }
2823
- const runIdSet = new Set(runIds);
2824
- return {
2825
- metas: metas.filter((meta) => runIdSet.has(meta.runId)),
2826
- scopeLabel: groupId,
2827
- scopeKind: "group",
2828
- runIds,
2829
- warnings,
2830
- notFound: false
2831
- };
2832
- }
2833
- return {
2834
- metas: [...metas],
2835
- scopeLabel: "",
2836
- scopeKind: "session",
2837
- runIds: [],
2838
- warnings,
2839
- notFound: false
2840
- };
2841
- }
2842
-
2843
- // packages/core/src/sessions/checks.ts
2844
- function emptySummary() {
2845
- return { passed: 0, failed: 0, warnings: 0, errors: 0 };
2846
- }
2847
- function mergeSummary(target, source) {
2848
- return {
2849
- passed: target.passed + source.passed,
2850
- failed: target.failed + source.failed,
2851
- warnings: target.warnings + source.warnings,
2852
- errors: target.errors + source.errors
2853
- };
2854
- }
2855
- function sessionDiagnostic(code, message) {
2856
- return { code, message, severity: "error" };
2857
- }
2858
- function aggregateSessionCheckResults(perRun, scope) {
2859
- if (scope.notFound) {
2860
- return {
2861
- ok: false,
2862
- status: "error",
2863
- format: perRun[0]?.format ?? "agent-inspect-jsonl",
2864
- scopeKind: scope.scopeKind,
2865
- scopeLabel: scope.scopeLabel,
2866
- runIds: [],
2867
- runResults: [],
2868
- summary: { ...emptySummary(), errors: 1 },
2869
- findings: [],
2870
- diagnostics: [
2871
- sessionDiagnostic(
2872
- "AI_CHECK_INVALID_ARGUMENTS",
2873
- `${scope.scopeKind} not found: ${scope.scopeLabel}`
2874
- )
2875
- ],
2876
- ...scope.sessionWarnings?.length ? { sessionWarnings: [...scope.sessionWarnings] } : {}
2877
- };
2878
- }
2879
- if (scope.empty || perRun.length === 0) {
2880
- return {
2881
- ok: false,
2882
- status: "error",
2883
- format: perRun[0]?.format ?? "agent-inspect-jsonl",
2884
- scopeKind: scope.scopeKind,
2885
- scopeLabel: scope.scopeLabel,
2886
- runIds: scope.runIds,
2887
- runResults: [],
2888
- summary: { ...emptySummary(), errors: 1 },
2889
- findings: [],
2890
- diagnostics: [
2891
- sessionDiagnostic(
2892
- "AI_CHECK_TRACE_UNREADABLE",
2893
- `No readable traces in ${scope.scopeKind}: ${scope.scopeLabel}`
2894
- )
2895
- ],
2896
- ...scope.sessionWarnings?.length ? { sessionWarnings: [...scope.sessionWarnings] } : {}
2897
- };
2898
- }
2899
- let summary = emptySummary();
2900
- const findings = [];
2901
- const diagnostics = [];
2902
- const runResults = [];
2903
- for (const result of perRun) {
2904
- summary = mergeSummary(summary, result.summary);
2905
- findings.push(...result.findings);
2906
- diagnostics.push(...result.diagnostics);
2907
- if (result.runId) {
2908
- runResults.push({ runId: result.runId, status: result.status });
2909
- }
2910
- }
2911
- runResults.sort((a, b) => a.runId.localeCompare(b.runId));
2912
- findings.sort((a, b) => {
2913
- const runCmp = (a.evidence[0]?.runId ?? "").localeCompare(
2914
- b.evidence[0]?.runId ?? ""
2915
- );
2916
- if (runCmp !== 0) return runCmp;
2917
- return a.ruleId.localeCompare(b.ruleId);
2918
- });
2919
- const hasErrors = diagnostics.some((item) => item.severity === "error");
2920
- const status = hasErrors ? "error" : summary.failed > 0 ? "fail" : "pass";
2921
- return {
2922
- ok: status === "pass",
2923
- status,
2924
- format: perRun[0]?.format ?? "agent-inspect-jsonl",
2925
- scopeKind: scope.scopeKind,
2926
- scopeLabel: scope.scopeLabel,
2927
- runIds: scope.runIds,
2928
- runResults,
2929
- summary,
2930
- findings,
2931
- diagnostics,
2932
- ...scope.sessionWarnings?.length ? { sessionWarnings: [...scope.sessionWarnings] } : {}
2933
- };
2934
- }
2935
-
2936
- // packages/core/src/sessions/index.ts
2937
- function compareRuns(a, b) {
2938
- const aStart = a.startedAt ?? 0;
2939
- const bStart = b.startedAt ?? 0;
2940
- if (aStart !== bStart) return aStart - bStart;
2941
- return a.runId.localeCompare(b.runId);
2942
- }
2943
- function buildGroups(runIds, metaByRunId) {
2944
- const byGroup = /* @__PURE__ */ new Map();
2945
- for (const runId of runIds) {
2946
- const groupId = metaByRunId.get(runId)?.groupId;
2947
- if (!groupId) continue;
2948
- const existing = byGroup.get(groupId);
2949
- if (existing) {
2950
- existing.runIds.push(runId);
2951
- } else {
2952
- byGroup.set(groupId, {
2953
- groupId,
2954
- parentGroupId: metaByRunId.get(runId)?.parentGroupId,
2955
- runIds: [runId]
2956
- });
2957
- }
2958
- }
2959
- return [...byGroup.values()].map((group) => ({
2960
- ...group,
2961
- runIds: [...group.runIds].sort((a, b) => a.localeCompare(b))
2962
- }));
2963
- }
2964
- function buildHandoffs(runIds, metaByRunId, warnings, sessionId) {
2965
- const edges = [];
2966
- const seen = /* @__PURE__ */ new Set();
2967
- const pushEdge = (edge) => {
2968
- const key = `${edge.from}->${edge.to}:${edge.confidence}`;
2969
- if (seen.has(key)) return;
2970
- seen.add(key);
2971
- edges.push(edge);
2972
- };
2973
- for (const runId of runIds) {
2974
- const meta = metaByRunId.get(runId);
2975
- if (!meta) continue;
2976
- if (meta.handoffFrom && meta.handoffTo) {
2977
- pushEdge({
2978
- from: meta.handoffFrom,
2979
- to: meta.handoffTo,
2980
- source: "manual",
2981
- confidence: "explicit"
2982
- });
2983
- continue;
2984
- }
2985
- if (meta.handoffFrom) {
2986
- pushEdge({
2987
- from: meta.handoffFrom,
2988
- to: runId,
2989
- source: "manual",
2990
- confidence: "explicit"
2991
- });
2992
- }
2993
- if (meta.handoffTo) {
2994
- pushEdge({
2995
- from: runId,
2996
- to: meta.handoffTo,
2997
- source: "manual",
2998
- confidence: "explicit"
2999
- });
3000
- }
3001
- if (meta.subAgentId && meta.parentGroupId && !meta.handoffFrom && !meta.handoffTo) {
3002
- pushEdge({
3003
- from: meta.parentGroupId,
3004
- to: meta.subAgentId,
3005
- source: "inferred",
3006
- confidence: "correlated"
3007
- });
3008
- warnings.push({
3009
- code: "ambiguous-handoff-endpoints",
3010
- message: "Handoff inferred from parentGroupId and subAgentId without explicit handoffFrom/handoffTo.",
3011
- runId,
3012
- sessionId
3013
- });
3014
- }
3015
- }
3016
- return edges.sort((a, b) => {
3017
- const from = a.from.localeCompare(b.from);
3018
- if (from !== 0) return from;
3019
- return a.to.localeCompare(b.to);
3020
- });
3021
- }
3022
- function buildRetries(runIds, metaByRunId, warnings, sessionId) {
3023
- const retries = [];
3024
- for (const runId of runIds) {
3025
- const meta = metaByRunId.get(runId);
3026
- if (!meta) continue;
3027
- if (meta.retryOf) {
3028
- retries.push({
3029
- runId,
3030
- retryOf: meta.retryOf,
3031
- attempt: meta.attempt,
3032
- source: "manual",
3033
- confidence: "explicit"
3034
- });
3035
- continue;
3036
- }
3037
- if (meta.attempt !== void 0 && meta.attempt > 1) {
3038
- retries.push({
3039
- runId,
3040
- attempt: meta.attempt,
3041
- source: "inferred",
3042
- confidence: "correlated"
3043
- });
3044
- warnings.push({
3045
- code: "ambiguous-retry-link",
3046
- message: "attempt > 1 without retryOf; retry link is correlated only.",
3047
- runId,
3048
- sessionId
3049
- });
3050
- }
3051
- }
3052
- return retries.sort((a, b) => a.runId.localeCompare(b.runId));
3053
- }
3054
- function buildCriticalPath(runs, handoffs) {
3055
- const runById = new Map(runs.map((run) => [run.runId, run]));
3056
- const explicitTargets = new Set(
3057
- handoffs.filter((edge) => edge.confidence === "explicit").map((edge) => edge.to)
3058
- );
3059
- const explicitSources = new Set(
3060
- handoffs.filter((edge) => edge.confidence === "explicit").map((edge) => edge.from)
3061
- );
3062
- const ordered = [...runs].sort(compareRuns);
3063
- const path20 = [];
3064
- const visited = /* @__PURE__ */ new Set();
3065
- const pushRun = (run, confidence, source) => {
3066
- if (visited.has(run.runId)) return;
3067
- visited.add(run.runId);
3068
- path20.push({
3069
- runId: run.runId,
3070
- name: run.name,
3071
- startedAt: run.startedAt,
3072
- durationMs: run.durationMs,
3073
- confidence,
3074
- source
3075
- });
3076
- };
3077
- for (const edge of handoffs) {
3078
- if (edge.confidence !== "explicit") continue;
3079
- const fromRun = [...runById.values()].find(
3080
- (run) => run.runId === edge.from || metaRunIdMatches(run, edge.from, runById)
3081
- );
3082
- const toRun = [...runById.values()].find(
3083
- (run) => run.runId === edge.to || metaRunIdMatches(run, edge.to, runById)
3084
- );
3085
- if (fromRun) pushRun(fromRun, "explicit", "manual");
3086
- if (toRun) pushRun(toRun, "explicit", "manual");
3087
- }
3088
- for (const run of ordered) {
3089
- if (visited.has(run.runId)) continue;
3090
- const confidence = explicitTargets.has(run.runId) || explicitSources.has(run.runId) ? "explicit" : "correlated";
3091
- pushRun(run, confidence, confidence === "explicit" ? "manual" : "inferred");
3092
- }
3093
- return path20;
3094
- }
3095
- function metaRunIdMatches(run, token, runById) {
3096
- const meta = extractSessionWorkflowMetadata(run.metadata);
3097
- return meta?.subAgentId === token || meta?.groupId === token || runById.has(token);
3098
- }
3099
- function buildSessionIndex(inputRuns, options = {}) {
3100
- const warnings = [];
3101
- const runs = [...inputRuns].sort(compareRuns);
3102
- const metaByRunId = /* @__PURE__ */ new Map();
3103
- for (const run of runs) {
3104
- metaByRunId.set(run.runId, extractSessionWorkflowMetadata(run.metadata));
3105
- }
3106
- const sessionsByKey = /* @__PURE__ */ new Map();
3107
- const unscopedRunIds = [];
3108
- for (const run of runs) {
3109
- const meta = metaByRunId.get(run.runId);
3110
- const key = sessionKeyForRun(meta, {
3111
- correlateByGroupId: options.correlateByGroupId === true
3112
- });
3113
- if (!key) {
3114
- unscopedRunIds.push(run.runId);
3115
- continue;
3116
- }
3117
- const bucket = sessionsByKey.get(key) ?? [];
3118
- bucket.push(run);
3119
- sessionsByKey.set(key, bucket);
3120
- }
3121
- const sessions = [...sessionsByKey.entries()].sort(([a], [b]) => a.localeCompare(b)).map(([sessionId, sessionRuns]) => {
3122
- const runIds = sessionRuns.map((run) => run.runId).sort();
3123
- const handoffs = buildHandoffs(runIds, metaByRunId, warnings, sessionId);
3124
- const retries = buildRetries(runIds, metaByRunId, warnings, sessionId);
3125
- const groups = buildGroups(runIds, metaByRunId);
3126
- const criticalPath = buildCriticalPath(sessionRuns, handoffs);
3127
- const confidences = new Set(handoffs.map((edge) => edge.confidence));
3128
- if (confidences.has("explicit") && confidences.has("correlated")) {
3129
- warnings.push({
3130
- code: "mixed-confidence-group",
3131
- message: "Session aggregates explicit and correlated handoff edges.",
3132
- sessionId
3133
- });
3134
- }
3135
- return {
3136
- sessionId,
3137
- runIds,
3138
- groups,
3139
- handoffs,
3140
- retries,
3141
- criticalPath
3142
- };
3143
- });
3144
- if (sessions.length === 0 && runs.length > 0) {
3145
- warnings.push({
3146
- code: "missing-session-id",
3147
- message: "No sessionId (or correlated groupId) found on input runs."
3148
- });
3149
- }
3150
- warnings.sort((a, b) => {
3151
- const code = a.code.localeCompare(b.code);
3152
- if (code !== 0) return code;
3153
- return (a.runId ?? "").localeCompare(b.runId ?? "");
3154
- });
3155
- return {
3156
- runs,
3157
- sessions,
3158
- unscopedRunIds: unscopedRunIds.sort(),
3159
- warnings
3160
- };
3161
- }
3162
- var KNOWN_EVENTS = /* @__PURE__ */ new Set([
3163
- "run_started",
3164
- "run_completed",
3165
- "step_started",
3166
- "step_completed"
3167
- ]);
3168
- function isRecord6(value) {
3169
- return typeof value === "object" && value !== null && !Array.isArray(value);
3170
- }
3171
- function safeParse(line) {
3172
- try {
3173
- return JSON.parse(line);
3174
- } catch {
3175
- return void 0;
3176
- }
3177
- }
3178
- async function isAgentInspectTrace(filePath) {
3179
- try {
3180
- const rl = createInterface({
3181
- input: createReadStream(filePath, { encoding: "utf8" }),
3182
- crlfDelay: Infinity
3183
- });
3184
- let checked = 0;
3185
- for await (const line of rl) {
3186
- const trimmed = line.trim();
3187
- if (trimmed === "") continue;
3188
- const parsed = safeParse(trimmed);
3189
- if (!parsed) continue;
3190
- if (!isRecord6(parsed)) continue;
3191
- checked += 1;
3192
- if (isTraceEvent(parsed)) return true;
3193
- const ev = parsed.event;
3194
- const runId = parsed.runId;
3195
- if (typeof ev === "string" && KNOWN_EVENTS.has(ev) && typeof runId === "string") {
3196
- return true;
3197
- }
3198
- if (checked >= 20) break;
3199
- }
3200
- return false;
3201
- } catch {
3202
- return false;
3203
- }
3204
- }
14
+ var version = "4.1.0";
3205
15
 
3206
16
  // packages/cli/src/trace-dir-scale.ts
3207
17
  var TRACE_COUNT_WARN = 1e3;
@@ -3276,7 +86,7 @@ function statusIcon(status) {
3276
86
  function durationCell(status, durationMs2) {
3277
87
  if (status === "running" || status === "unknown") return "-";
3278
88
  if (durationMs2 !== void 0 && Number.isFinite(durationMs2)) {
3279
- return formatDuration2(durationMs2);
89
+ return formatDuration(durationMs2);
3280
90
  }
3281
91
  return "-";
3282
92
  }
@@ -3372,8 +182,8 @@ function stableSortNewestFirst(a, b) {
3372
182
  return a.runId.localeCompare(b.runId);
3373
183
  }
3374
184
  async function confirmDeletion(count) {
3375
- const { createInterface: createInterface2 } = await import('readline/promises');
3376
- const rl = createInterface2({ input: stdin, output: stdout });
185
+ const { createInterface } = await import('readline/promises');
186
+ const rl = createInterface({ input: stdin, output: stdout });
3377
187
  try {
3378
188
  const answer = await rl.question(
3379
189
  `Delete ${count} AgentInspect trace file(s)? Type "yes" to continue: `
@@ -3506,14 +316,14 @@ async function clean(options = {}) {
3506
316
  }
3507
317
 
3508
318
  // packages/core/src/persisted/token-usage.ts
3509
- function isRecord7(value) {
319
+ function isRecord(value) {
3510
320
  return typeof value === "object" && value !== null && !Array.isArray(value);
3511
321
  }
3512
322
  function nonNegativeFinite(value) {
3513
323
  return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
3514
324
  }
3515
325
  function normalizeTokenUsage(value) {
3516
- if (!isRecord7(value)) return void 0;
326
+ if (!isRecord(value)) return void 0;
3517
327
  const input3 = nonNegativeFinite(value.input);
3518
328
  const output2 = nonNegativeFinite(value.output);
3519
329
  const suppliedTotal = nonNegativeFinite(value.total);
@@ -3748,7 +558,7 @@ function compactAttributes2(entries) {
3748
558
  }
3749
559
  return Object.keys(out).length > 0 ? out : void 0;
3750
560
  }
3751
- function parseIsoToMs3(iso) {
561
+ function parseIsoToMs(iso) {
3752
562
  const parsed = Date.parse(iso);
3753
563
  if (!Number.isFinite(parsed)) {
3754
564
  return { ms: 0, invalidTimestamp: true };
@@ -3829,7 +639,7 @@ function persistedInspectEventToInspectEvent(event) {
3829
639
  if (!isPersistedInspectEvent(event)) {
3830
640
  throw new Error("Invalid PersistedInspectEvent: failed isPersistedInspectEvent");
3831
641
  }
3832
- const ts = parseIsoToMs3(event.timestamp);
642
+ const ts = parseIsoToMs(event.timestamp);
3833
643
  const attrs = buildInspectAttributes(event);
3834
644
  if (ts.invalidTimestamp) {
3835
645
  attrs.invalidTimestamp = true;
@@ -4085,7 +895,7 @@ function findReaderByFormat(format, readers) {
4085
895
  }
4086
896
  async function jsonlFilesInDirectory(dirPath) {
4087
897
  const entries = await readdir(dirPath, { withFileTypes: true });
4088
- return entries.filter((entry) => entry.isFile() && entry.name.endsWith(".jsonl")).map((entry) => path14.join(dirPath, entry.name)).sort((a, b) => a.localeCompare(b));
898
+ return entries.filter((entry) => entry.isFile() && entry.name.endsWith(".jsonl")).map((entry) => path10.join(dirPath, entry.name)).sort((a, b) => a.localeCompare(b));
4089
899
  }
4090
900
  async function resolveInput(input3) {
4091
901
  const cached = resolvedInputCache.get(input3);
@@ -4234,28 +1044,28 @@ function persistedEventsForParsedTrace(parsed) {
4234
1044
  sourceName: "agent-inspect-jsonl-reader"
4235
1045
  });
4236
1046
  }
4237
- function isRecord8(value) {
1047
+ function isRecord2(value) {
4238
1048
  return typeof value === "object" && value !== null && !Array.isArray(value);
4239
1049
  }
4240
- function isNonEmptyString4(value) {
1050
+ function isNonEmptyString(value) {
4241
1051
  return typeof value === "string" && value.trim() !== "";
4242
1052
  }
4243
1053
  function readStringField(record, keys) {
4244
1054
  for (const key of keys) {
4245
1055
  const value = record[key];
4246
- if (isNonEmptyString4(value)) return value;
1056
+ if (isNonEmptyString(value)) return value;
4247
1057
  }
4248
1058
  return void 0;
4249
1059
  }
4250
1060
  function readRecordField(record, key) {
4251
1061
  const value = record[key];
4252
- return isRecord8(value) ? value : void 0;
1062
+ return isRecord2(value) ? value : void 0;
4253
1063
  }
4254
1064
  function parseJsonDocument(content) {
4255
1065
  return JSON.parse(content);
4256
1066
  }
4257
1067
  function looksLikeOpenInferenceSpan(value) {
4258
- if (!isRecord8(value)) return false;
1068
+ if (!isRecord2(value)) return false;
4259
1069
  const attributes = readRecordField(value, "attributes");
4260
1070
  return readStringField(value, ["trace_id", "traceId"]) !== void 0 && readStringField(value, ["span_id", "spanId"]) !== void 0 && (readStringField(value, ["name"]) !== void 0 || attributes?.["openinference.span.kind"] !== void 0);
4261
1071
  }
@@ -4280,7 +1090,7 @@ function extractOpenInferenceDocument(root) {
4280
1090
  unsupportedFields
4281
1091
  };
4282
1092
  }
4283
- if (!isRecord8(root)) return void 0;
1093
+ if (!isRecord2(root)) return void 0;
4284
1094
  const rootFormat = root.format;
4285
1095
  const rootCompatibility = root.compatibility;
4286
1096
  const version2 = typeof root.version === "string" && root.version.trim() !== "" ? root.version : void 0;
@@ -4377,7 +1187,7 @@ function parseUnixNanoToIso(value) {
4377
1187
  return void 0;
4378
1188
  }
4379
1189
  function parseIsoTime(value) {
4380
- if (!isNonEmptyString4(value)) return void 0;
1190
+ if (!isNonEmptyString(value)) return void 0;
4381
1191
  const ms = Date.parse(value);
4382
1192
  if (!Number.isFinite(ms)) return void 0;
4383
1193
  return new Date(ms).toISOString();
@@ -4420,7 +1230,7 @@ function summarizeAttributeValue(value) {
4420
1230
  if (Array.isArray(value)) {
4421
1231
  return { type: "array", length: value.length };
4422
1232
  }
4423
- if (isRecord8(value)) {
1233
+ if (isRecord2(value)) {
4424
1234
  return { type: "object", keyCount: Object.keys(value).length };
4425
1235
  }
4426
1236
  if (value === null) {
@@ -4507,7 +1317,7 @@ function mapOpenInferenceKind(span, attributes, pathPrefix) {
4507
1317
  }
4508
1318
  }
4509
1319
  function mapOpenInferenceStatus(status) {
4510
- if (!isRecord8(status)) return void 0;
1320
+ if (!isRecord2(status)) return void 0;
4511
1321
  const rawCode = status.code;
4512
1322
  if (typeof rawCode !== "string") return void 0;
4513
1323
  switch (rawCode.toUpperCase()) {
@@ -4607,7 +1417,7 @@ function mapOpenInferenceSpan(span, index, version2) {
4607
1417
  warnings.push(...kindWarnings);
4608
1418
  const status = mapOpenInferenceStatus(span.status);
4609
1419
  const tokenUsage = readOpenInferenceTokenUsage(rawAttributes);
4610
- const errorMessage = isRecord8(span.status) && typeof span.status.message === "string" ? span.status.message : void 0;
1420
+ const errorMessage = isRecord2(span.status) && typeof span.status.message === "string" ? span.status.message : void 0;
4611
1421
  const event = {
4612
1422
  schemaVersion: "0.2",
4613
1423
  eventId: typeof rawAttributes["agent_inspect.event_id"] === "string" ? rawAttributes["agent_inspect.event_id"] : spanId,
@@ -4753,7 +1563,7 @@ var openInferenceJsonReader = {
4753
1563
  }
4754
1564
  };
4755
1565
  function parseOtlpAnyValue(value, field, warnings, unsupportedFields) {
4756
- if (!isRecord8(value)) {
1566
+ if (!isRecord2(value)) {
4757
1567
  unsupportedFields.push(field);
4758
1568
  warnings.push({
4759
1569
  code: "otlp_attribute_value_invalid",
@@ -4775,15 +1585,15 @@ function parseOtlpAnyValue(value, field, warnings, unsupportedFields) {
4775
1585
  if (typeof value.doubleValue === "number" && Number.isFinite(value.doubleValue)) {
4776
1586
  return value.doubleValue;
4777
1587
  }
4778
- if (isRecord8(value.arrayValue) && Array.isArray(value.arrayValue.values)) {
1588
+ if (isRecord2(value.arrayValue) && Array.isArray(value.arrayValue.values)) {
4779
1589
  return value.arrayValue.values.map(
4780
1590
  (item, index) => parseOtlpAnyValue(item, `${field}.arrayValue.values[${index}]`, warnings, unsupportedFields)
4781
1591
  );
4782
1592
  }
4783
- if (isRecord8(value.kvlistValue) && Array.isArray(value.kvlistValue.values)) {
1593
+ if (isRecord2(value.kvlistValue) && Array.isArray(value.kvlistValue.values)) {
4784
1594
  const out = {};
4785
1595
  for (const [index, item] of value.kvlistValue.values.entries()) {
4786
- if (!isRecord8(item) || typeof item.key !== "string") {
1596
+ if (!isRecord2(item) || typeof item.key !== "string") {
4787
1597
  unsupportedFields.push(`${field}.kvlistValue.values[${index}]`);
4788
1598
  continue;
4789
1599
  }
@@ -4834,7 +1644,7 @@ function parseOtlpAttributes(value, pathPrefix) {
4834
1644
  }
4835
1645
  for (const [index, item] of value.entries()) {
4836
1646
  const field = `${pathPrefix}[${index}]`;
4837
- if (!isRecord8(item) || typeof item.key !== "string") {
1647
+ if (!isRecord2(item) || typeof item.key !== "string") {
4838
1648
  unsupportedFields.push(field);
4839
1649
  warnings.push({
4840
1650
  code: "otlp_attribute_invalid",
@@ -4857,16 +1667,16 @@ function parseOtlpAttributes(value, pathPrefix) {
4857
1667
  return { attributes, warnings, unsupportedFields };
4858
1668
  }
4859
1669
  function looksLikeOtlpSpan(value) {
4860
- return isRecord8(value) && readStringField(value, ["traceId"]) !== void 0 && readStringField(value, ["spanId"]) !== void 0 && readStringField(value, ["name"]) !== void 0;
1670
+ return isRecord2(value) && readStringField(value, ["traceId"]) !== void 0 && readStringField(value, ["spanId"]) !== void 0 && readStringField(value, ["name"]) !== void 0;
4861
1671
  }
4862
1672
  function extractOtlpDocument(root) {
4863
- if (!isRecord8(root) || !Array.isArray(root.resourceSpans)) return void 0;
1673
+ if (!isRecord2(root) || !Array.isArray(root.resourceSpans)) return void 0;
4864
1674
  const spans = [];
4865
1675
  const warnings = [];
4866
1676
  const unsupportedFields = [];
4867
1677
  for (const [resourceIndex, resourceSpan] of root.resourceSpans.entries()) {
4868
1678
  const resourcePath = `resourceSpans[${resourceIndex}]`;
4869
- if (!isRecord8(resourceSpan)) {
1679
+ if (!isRecord2(resourceSpan)) {
4870
1680
  unsupportedFields.push(resourcePath);
4871
1681
  continue;
4872
1682
  }
@@ -4889,7 +1699,7 @@ function extractOtlpDocument(root) {
4889
1699
  }
4890
1700
  for (const [scopeIndex, scopeSpan] of resourceSpan.scopeSpans.entries()) {
4891
1701
  const scopePath = `${resourcePath}.scopeSpans[${scopeIndex}]`;
4892
- if (!isRecord8(scopeSpan)) {
1702
+ if (!isRecord2(scopeSpan)) {
4893
1703
  unsupportedFields.push(scopePath);
4894
1704
  continue;
4895
1705
  }
@@ -4956,7 +1766,7 @@ function extractOtlpDocument(root) {
4956
1766
  };
4957
1767
  }
4958
1768
  function mapOtlpStatus(status) {
4959
- if (!isRecord8(status)) return void 0;
1769
+ if (!isRecord2(status)) return void 0;
4960
1770
  const rawCode = status.code;
4961
1771
  if (typeof rawCode !== "string") return void 0;
4962
1772
  switch (rawCode.toUpperCase()) {
@@ -5056,7 +1866,7 @@ function mapOtlpEvents(value, pathPrefix) {
5056
1866
  const events = [];
5057
1867
  for (const [index, event] of value.entries()) {
5058
1868
  const eventPath = `${pathPrefix}[${index}]`;
5059
- if (!isRecord8(event)) {
1869
+ if (!isRecord2(event)) {
5060
1870
  unsupportedFields.push(eventPath);
5061
1871
  continue;
5062
1872
  }
@@ -5194,7 +2004,7 @@ function mapOtlpSpan(context) {
5194
2004
  warnings.push(...kindWarnings);
5195
2005
  const status = mapOtlpStatus(span.status);
5196
2006
  const tokenUsage = readOtlpTokenUsage(parsedSpanAttributes.attributes);
5197
- const errorMessage = isRecord8(span.status) && typeof span.status.message === "string" ? span.status.message : void 0;
2007
+ const errorMessage = isRecord2(span.status) && typeof span.status.message === "string" ? span.status.message : void 0;
5198
2008
  const event = {
5199
2009
  schemaVersion: "0.2",
5200
2010
  eventId: typeof parsedSpanAttributes.attributes["agent_inspect.event_id"] === "string" ? parsedSpanAttributes.attributes["agent_inspect.event_id"] : spanId,
@@ -5659,7 +2469,7 @@ function printSummary(summary) {
5659
2469
  console.log(`Name: ${summary.name ?? "unnamed"}`);
5660
2470
  console.log(`Status: ${summary.status}`);
5661
2471
  console.log(
5662
- `Duration: ${summary.durationMs !== void 0 ? formatDuration2(summary.durationMs) : "-"}`
2472
+ `Duration: ${summary.durationMs !== void 0 ? formatDuration(summary.durationMs) : "-"}`
5663
2473
  );
5664
2474
  console.log(`Total steps: ${summary.totalSteps}`);
5665
2475
  console.log(`LLM steps: ${summary.llmSteps}`);
@@ -5669,7 +2479,7 @@ function printSummary(summary) {
5669
2479
  console.log(`Max depth: ${summary.maxDepth}`);
5670
2480
  if (summary.longestStep) {
5671
2481
  console.log(
5672
- `Longest step: ${summary.longestStep.name} (${formatDuration2(
2482
+ `Longest step: ${summary.longestStep.name} (${formatDuration(
5673
2483
  summary.longestStep.durationMs
5674
2484
  )}, ${summary.longestStep.type})`
5675
2485
  );
@@ -5687,7 +2497,7 @@ function printMetadata(meta) {
5687
2497
  `Ended: ${meta.endedAt !== void 0 ? formatTimestamp(meta.endedAt) : "-"}`
5688
2498
  );
5689
2499
  console.log(
5690
- `Duration: ${meta.durationMs !== void 0 ? formatDuration2(meta.durationMs) : "-"}`
2500
+ `Duration: ${meta.durationMs !== void 0 ? formatDuration(meta.durationMs) : "-"}`
5691
2501
  );
5692
2502
  console.log(`Event count: ${meta.eventCount}`);
5693
2503
  console.log(`File path: ${meta.filePath}`);
@@ -5798,7 +2608,7 @@ async function view(runId, options = {}) {
5798
2608
  );
5799
2609
  const last = completed[completed.length - 1];
5800
2610
  const status = last ? last.status : "running";
5801
- const durationLine = last !== void 0 && Number.isFinite(last.durationMs) ? formatDuration2(last.durationMs) : "-";
2611
+ const durationLine = last !== void 0 && Number.isFinite(last.durationMs) ? formatDuration(last.durationMs) : "-";
5802
2612
  const startedTs = Number.isFinite(started.startTime) ? started.startTime : started.timestamp;
5803
2613
  const startedLabel = formatTimestamp(startedTs);
5804
2614
  console.log(`AgentInspect Run: ${started.name}`);
@@ -5822,7 +2632,7 @@ async function view(runId, options = {}) {
5822
2632
  process.exitCode = 1;
5823
2633
  }
5824
2634
  }
5825
- function isRecord9(v) {
2635
+ function isRecord3(v) {
5826
2636
  return typeof v === "object" && v !== null && !Array.isArray(v);
5827
2637
  }
5828
2638
  function isNonEmptyStringArray(v) {
@@ -5834,7 +2644,7 @@ function validateRedact(redact2) {
5834
2644
  }
5835
2645
  for (const r of redact2) {
5836
2646
  if (typeof r === "string") continue;
5837
- if (!isRecord9(r)) {
2647
+ if (!isRecord3(r)) {
5838
2648
  throw new Error("Invalid config: redact entries must be strings or objects");
5839
2649
  }
5840
2650
  if (typeof r.key !== "string" || r.key.trim() === "") {
@@ -5853,7 +2663,7 @@ function validateRedact(redact2) {
5853
2663
  }
5854
2664
  }
5855
2665
  function validateMappings(mappings) {
5856
- if (!isRecord9(mappings)) {
2666
+ if (!isRecord3(mappings)) {
5857
2667
  throw new Error("Invalid config: mappings must be an object");
5858
2668
  }
5859
2669
  }
@@ -5903,7 +2713,7 @@ async function loadLogIngestConfig(configPath) {
5903
2713
  const msg = e instanceof Error ? e.message : String(e);
5904
2714
  throw new Error(`Invalid JSON in config file: ${configPath} (${msg})`);
5905
2715
  }
5906
- if (!isRecord9(parsed)) {
2716
+ if (!isRecord3(parsed)) {
5907
2717
  throw new Error("Invalid config: expected a JSON object at top-level");
5908
2718
  }
5909
2719
  const user = parsed;
@@ -5940,7 +2750,7 @@ async function loadLogIngestConfig(configPath) {
5940
2750
  }
5941
2751
  return mergeLogIngestConfig(DEFAULT_LOG_INGEST_CONFIG, user);
5942
2752
  }
5943
- function isRecord10(v) {
2753
+ function isRecord4(v) {
5944
2754
  return typeof v === "object" && v !== null && !Array.isArray(v);
5945
2755
  }
5946
2756
  var JsonLogParser = class {
@@ -5965,7 +2775,7 @@ var JsonLogParser = class {
5965
2775
  });
5966
2776
  continue;
5967
2777
  }
5968
- if (!isRecord10(parsed)) {
2778
+ if (!isRecord4(parsed)) {
5969
2779
  warnings.push({
5970
2780
  code: "MALFORMED_JSON",
5971
2781
  message: "JSON log line must be an object",
@@ -5996,7 +2806,7 @@ var JsonLogParser = class {
5996
2806
  return this.parseLines(lines, filePath);
5997
2807
  }
5998
2808
  };
5999
- function isRecord11(v) {
2809
+ function isRecord5(v) {
6000
2810
  return typeof v === "object" && v !== null && !Array.isArray(v);
6001
2811
  }
6002
2812
  function findLastJsonObjectSubstring(line) {
@@ -6072,7 +2882,7 @@ var Log4jsParser = class {
6072
2882
  });
6073
2883
  continue;
6074
2884
  }
6075
- if (!isRecord11(parsed)) {
2885
+ if (!isRecord5(parsed)) {
6076
2886
  warnings.push({
6077
2887
  code: "UNSUPPORTED_LOG4JS_PAYLOAD",
6078
2888
  message: "Embedded JSON payload must be an object",
@@ -6143,7 +2953,7 @@ function matchMapping(eventName, mappings) {
6143
2953
  }
6144
2954
 
6145
2955
  // packages/core/src/logs/normalizer.ts
6146
- function isFiniteNumber2(v) {
2956
+ function isFiniteNumber(v) {
6147
2957
  return typeof v === "number" && Number.isFinite(v);
6148
2958
  }
6149
2959
  function safeString(v) {
@@ -6152,7 +2962,7 @@ function safeString(v) {
6152
2962
  return t === "" ? void 0 : t;
6153
2963
  }
6154
2964
  function parseTimestamp(v) {
6155
- if (isFiniteNumber2(v)) return v;
2965
+ if (isFiniteNumber(v)) return v;
6156
2966
  if (typeof v === "string") {
6157
2967
  const t = Date.parse(v);
6158
2968
  if (Number.isFinite(t)) return t;
@@ -6235,8 +3045,8 @@ var EventNormalizer = class {
6235
3045
  const durationKey = cfg.durationKey;
6236
3046
  if (durationKey) {
6237
3047
  const v = raw[durationKey];
6238
- if (isFiniteNumber2(v)) durationMs2 = v;
6239
- } else if (isFiniteNumber2(raw.durationMs)) {
3048
+ if (isFiniteNumber(v)) durationMs2 = v;
3049
+ } else if (isFiniteNumber(raw.durationMs)) {
6240
3050
  durationMs2 = raw.durationMs;
6241
3051
  }
6242
3052
  let status;
@@ -6720,8 +3530,8 @@ function sleep(ms) {
6720
3530
  return new Promise((resolve) => setTimeout(resolve, ms));
6721
3531
  }
6722
3532
  async function* readStdinLines() {
6723
- const { createInterface: createInterface2 } = await import('readline');
6724
- const rl = createInterface2({ input: stdin, crlfDelay: Infinity });
3533
+ const { createInterface } = await import('readline');
3534
+ const rl = createInterface({ input: stdin, crlfDelay: Infinity });
6725
3535
  try {
6726
3536
  for await (const line of rl) {
6727
3537
  yield line;
@@ -6929,7 +3739,7 @@ async function tail(options = {}) {
6929
3739
  var EXPORT_PAYLOAD_VERSION = "0.1.2";
6930
3740
 
6931
3741
  // packages/core/src/exporters/redact-export.ts
6932
- function isRecord12(value) {
3742
+ function isRecord6(value) {
6933
3743
  return typeof value === "object" && value !== null && !Array.isArray(value);
6934
3744
  }
6935
3745
  function deepClone(value) {
@@ -7003,7 +3813,7 @@ function redactEventAttributes(attrs, redactor, maxMetadataValueLength, maxPrevi
7003
3813
  0
7004
3814
  );
7005
3815
  const err = bounded.error;
7006
- if (isRecord12(err) && typeof err.message === "string") {
3816
+ if (isRecord6(err) && typeof err.message === "string") {
7007
3817
  bounded.error = {
7008
3818
  ...err,
7009
3819
  message: truncateStringForProfile(
@@ -7033,7 +3843,7 @@ function redactErrorInfo(error, redactor, maxMetadataValueLength, maxPreviewLeng
7033
3843
  maxPreviewLength
7034
3844
  );
7035
3845
  const redacted = record?.error;
7036
- if (!isRecord12(redacted) || typeof redacted.message !== "string") {
3846
+ if (!isRecord6(redacted) || typeof redacted.message !== "string") {
7037
3847
  return void 0;
7038
3848
  }
7039
3849
  return {
@@ -8214,9 +5024,9 @@ Trace directory: ${traceDir}`);
8214
5024
  if (validation !== void 0 && !validation.ok) {
8215
5025
  process.exitCode = 1;
8216
5026
  }
8217
- const outPath = options.output !== void 0 && options.output.trim() !== "" ? path14.resolve(options.output.trim()) : void 0;
5027
+ const outPath = options.output !== void 0 && options.output.trim() !== "" ? path10.resolve(options.output.trim()) : void 0;
8218
5028
  if (outPath !== void 0) {
8219
- await mkdir(path14.dirname(outPath), { recursive: true });
5029
+ await mkdir(path10.dirname(outPath), { recursive: true });
8220
5030
  await writeFile(outPath, result.content, "utf-8");
8221
5031
  const vlabel = validation !== void 0 ? validation.ok ? "ok" : "failed" : "skipped";
8222
5032
  console.log(`Wrote ${result.fileExtension} export to ${outPath} (validation: ${vlabel})`);
@@ -8393,13 +5203,13 @@ function pairSteps(left, right) {
8393
5203
  return pairs;
8394
5204
  }
8395
5205
  function compareLeafSteps(L, R, segments, opts, out) {
8396
- const path20 = buildPath(segments);
5206
+ const path17 = buildPath(segments);
8397
5207
  if (L.name !== R.name) {
8398
5208
  out.push({
8399
5209
  kind: "structure",
8400
5210
  severity: "warning",
8401
5211
  message: "Step name differs",
8402
- path: path20,
5212
+ path: path17,
8403
5213
  left: L.name,
8404
5214
  right: R.name
8405
5215
  });
@@ -8409,7 +5219,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
8409
5219
  kind: "step-type",
8410
5220
  severity: "warning",
8411
5221
  message: "Step type differs",
8412
- path: path20,
5222
+ path: path17,
8413
5223
  left: L.type,
8414
5224
  right: R.type
8415
5225
  });
@@ -8419,7 +5229,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
8419
5229
  kind: "step-status",
8420
5230
  severity: "warning",
8421
5231
  message: "Step status differs",
8422
- path: path20,
5232
+ path: path17,
8423
5233
  left: L.status,
8424
5234
  right: R.status
8425
5235
  });
@@ -8431,7 +5241,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
8431
5241
  kind: "error",
8432
5242
  severity: "error",
8433
5243
  message: "Step error message differs",
8434
- path: path20,
5244
+ path: path17,
8435
5245
  left: le || void 0,
8436
5246
  right: re || void 0
8437
5247
  });
@@ -8449,7 +5259,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
8449
5259
  kind: "duration",
8450
5260
  severity: "info",
8451
5261
  message: "Step duration differs",
8452
- path: path20,
5262
+ path: path17,
8453
5263
  left: ld,
8454
5264
  right: rd
8455
5265
  });
@@ -8462,7 +5272,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
8462
5272
  kind: "metadata",
8463
5273
  severity: "info",
8464
5274
  message: "Step metadata differs",
8465
- path: path20,
5275
+ path: path17,
8466
5276
  left: L.metadata,
8467
5277
  right: R.metadata
8468
5278
  });
@@ -8474,7 +5284,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
8474
5284
  kind: "output",
8475
5285
  severity: "info",
8476
5286
  message: "Output preview differs",
8477
- path: path20,
5287
+ path: path17,
8478
5288
  left: L.outputPreview,
8479
5289
  right: R.outputPreview
8480
5290
  });
@@ -8634,11 +5444,11 @@ function diffRuns(left, right, options) {
8634
5444
  }
8635
5445
 
8636
5446
  // packages/core/src/diff/renderer.ts
8637
- function formatPath(path20) {
8638
- if (path20 === void 0 || path20.path.length === 0) {
5447
+ function formatPath(path17) {
5448
+ if (path17 === void 0 || path17.path.length === 0) {
8639
5449
  return "(run)";
8640
5450
  }
8641
- return path20.path.map((s) => s.name).join(" > ");
5451
+ return path17.path.map((s) => s.name).join(" > ");
8642
5452
  }
8643
5453
  function formatValue(v, verbose) {
8644
5454
  if (v === void 0) return "(undefined)";
@@ -9271,9 +6081,9 @@ async function reportCommand(runId, options = {}) {
9271
6081
  redactionProfile,
9272
6082
  correlation: !options.noCorrelation
9273
6083
  });
9274
- const outPath = options.output !== void 0 && options.output.trim() !== "" ? path14.resolve(options.output.trim()) : void 0;
6084
+ const outPath = options.output !== void 0 && options.output.trim() !== "" ? path10.resolve(options.output.trim()) : void 0;
9275
6085
  if (outPath !== void 0) {
9276
- await mkdir(path14.dirname(outPath), { recursive: true });
6086
+ await mkdir(path10.dirname(outPath), { recursive: true });
9277
6087
  await writeFile(outPath, result.content, "utf-8");
9278
6088
  console.log(`Wrote ${result.fileExtension} report to ${outPath}`);
9279
6089
  }
@@ -9302,7 +6112,7 @@ var DEFAULT_REDACT_KEYS2 = [
9302
6112
  "secret",
9303
6113
  "email"
9304
6114
  ];
9305
- var SHARE_PROFILE_EXTRA_KEYS2 = [
6115
+ var SHARE_PROFILE_EXTRA_KEYS = [
9306
6116
  "userEmail",
9307
6117
  "customerEmail",
9308
6118
  "phone",
@@ -9325,7 +6135,7 @@ var SHARE_PROFILE_EXTRA_KEYS2 = [
9325
6135
  "spanId",
9326
6136
  "parentSpanId"
9327
6137
  ];
9328
- var STRICT_PROFILE_EXTRA_KEYS2 = [
6138
+ var STRICT_PROFILE_EXTRA_KEYS = [
9329
6139
  "prompt",
9330
6140
  "completion",
9331
6141
  "input",
@@ -9343,13 +6153,13 @@ var STRICT_PROFILE_EXTRA_KEYS2 = [
9343
6153
  "retrieval",
9344
6154
  "query"
9345
6155
  ];
9346
- function isRecord13(value) {
6156
+ function isRecord7(value) {
9347
6157
  return typeof value === "object" && value !== null && !Array.isArray(value);
9348
6158
  }
9349
- function toKey2(key) {
6159
+ function toKey(key) {
9350
6160
  return key.toLowerCase();
9351
6161
  }
9352
- function stableHash2(value) {
6162
+ function stableHash(value) {
9353
6163
  const hash = crypto.createHash("sha256").update(value, "utf8").digest("hex");
9354
6164
  return hash.slice(0, 8);
9355
6165
  }
@@ -9471,10 +6281,10 @@ function builtInDetectorsForProfile(profile) {
9471
6281
  if (profile === "local") return credentialDetectors;
9472
6282
  return [...credentialDetectors, ...identifierDetectors];
9473
6283
  }
9474
- function compileRules2(rules, extraKeys) {
6284
+ function compileRules(rules, extraKeys) {
9475
6285
  const out = /* @__PURE__ */ new Map();
9476
6286
  const set = (rule) => {
9477
- const key = toKey2(rule.key);
6287
+ const key = toKey(rule.key);
9478
6288
  out.set(key, { ...rule, key });
9479
6289
  };
9480
6290
  for (const key of DEFAULT_REDACT_KEYS2) {
@@ -9516,21 +6326,21 @@ function applyRule(rule, value, replacement) {
9516
6326
  }
9517
6327
  if (rule.strategy === "hash") {
9518
6328
  if (asString === void 0) return "[HASH:unknown]";
9519
- return `[HASH:${stableHash2(asString)}]`;
6329
+ return `[HASH:${stableHash(asString)}]`;
9520
6330
  }
9521
6331
  return value;
9522
6332
  }
9523
- function childPath(path20, key) {
6333
+ function childPath(path17, key) {
9524
6334
  if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key)) {
9525
- return path20 ? `${path20}.${key}` : key;
6335
+ return path17 ? `${path17}.${key}` : key;
9526
6336
  }
9527
- return `${path20 || "$"}[${JSON.stringify(key)}]`;
6337
+ return `${path17 || "$"}[${JSON.stringify(key)}]`;
9528
6338
  }
9529
- function indexPath(path20, index) {
9530
- return `${path20 || "$"}[${index}]`;
6339
+ function indexPath(path17, index) {
6340
+ return `${path17 || "$"}[${index}]`;
9531
6341
  }
9532
- function makeFinding(path20, detector, action, matchKind, severity = "warning", preview) {
9533
- return preview === void 0 ? { path: path20, detector, action, severity, matchKind } : { path: path20, detector, action, severity, matchKind, preview };
6342
+ function makeFinding(path17, detector, action, matchKind, severity = "warning", preview) {
6343
+ return preview === void 0 ? { path: path17, detector, action, severity, matchKind } : { path: path17, detector, action, severity, matchKind, preview };
9534
6344
  }
9535
6345
  function createRedactionProfile(profile = "local") {
9536
6346
  switch (profile) {
@@ -9539,14 +6349,14 @@ function createRedactionProfile(profile = "local") {
9539
6349
  case "share":
9540
6350
  return {
9541
6351
  profile: "share",
9542
- extraKeys: SHARE_PROFILE_EXTRA_KEYS2,
6352
+ extraKeys: SHARE_PROFILE_EXTRA_KEYS,
9543
6353
  maxMetadataValueLengthCap: 500,
9544
6354
  maxPreviewLengthCap: 200
9545
6355
  };
9546
6356
  case "strict":
9547
6357
  return {
9548
6358
  profile: "strict",
9549
- extraKeys: [...SHARE_PROFILE_EXTRA_KEYS2, ...STRICT_PROFILE_EXTRA_KEYS2],
6359
+ extraKeys: [...SHARE_PROFILE_EXTRA_KEYS, ...STRICT_PROFILE_EXTRA_KEYS],
9550
6360
  maxMetadataValueLengthCap: 200,
9551
6361
  maxPreviewLengthCap: 80
9552
6362
  };
@@ -9562,7 +6372,7 @@ var Redactor2 = class {
9562
6372
  constructor(options) {
9563
6373
  const resolved = createRedactionProfile(options?.profile ?? "local");
9564
6374
  this.#profile = resolved.profile;
9565
- this.#rules = compileRules2(options?.rules, [
6375
+ this.#rules = compileRules(options?.rules, [
9566
6376
  ...resolved.extraKeys,
9567
6377
  ...options?.extraKeys ?? []
9568
6378
  ]);
@@ -9599,32 +6409,32 @@ var Redactor2 = class {
9599
6409
  #recordFinding(state, finding) {
9600
6410
  if (this.#collectFindings) state.findings.push(finding);
9601
6411
  }
9602
- #redactValue(value, key, path20, depth, state) {
6412
+ #redactValue(value, key, path17, depth, state) {
9603
6413
  if (depth > this.#maxDepth) {
9604
6414
  this.#recordFinding(
9605
6415
  state,
9606
- makeFinding(path20, "structure.maxDepth", "truncate", "value", "warning")
6416
+ makeFinding(path17, "structure.maxDepth", "truncate", "value", "warning")
9607
6417
  );
9608
6418
  return "[Truncated]";
9609
6419
  }
9610
6420
  if (key !== void 0) {
9611
- const rule = this.#rules.find((candidate) => candidate.key === toKey2(key));
6421
+ const rule = this.#rules.find((candidate) => candidate.key === toKey(key));
9612
6422
  if (rule) {
9613
6423
  this.#recordFinding(
9614
6424
  state,
9615
- makeFinding(path20, `key.${rule.key}`, actionForRule(rule), "key", "warning")
6425
+ makeFinding(path17, `key.${rule.key}`, actionForRule(rule), "key", "warning")
9616
6426
  );
9617
6427
  return applyRule(rule, value, this.#replacement);
9618
6428
  }
9619
6429
  }
9620
6430
  for (const detector of this.#detectors) {
9621
- const detections = detector.detect({ path: path20, key, value });
6431
+ const detections = detector.detect({ path: path17, key, value });
9622
6432
  for (const detection of detections) {
9623
6433
  const action = detection.action ?? "replace";
9624
6434
  this.#recordFinding(
9625
6435
  state,
9626
6436
  makeFinding(
9627
- path20,
6437
+ path17,
9628
6438
  detector.id,
9629
6439
  action,
9630
6440
  detection.matchKind ?? detector.matchKind ?? "custom",
@@ -9642,11 +6452,11 @@ var Redactor2 = class {
9642
6452
  const out = [];
9643
6453
  state.seen.set(value, out);
9644
6454
  value.forEach((item, index) => {
9645
- out[index] = this.#redactValue(item, void 0, indexPath(path20, index), depth + 1, state);
6455
+ out[index] = this.#redactValue(item, void 0, indexPath(path17, index), depth + 1, state);
9646
6456
  });
9647
6457
  return out;
9648
6458
  }
9649
- if (isRecord13(value)) {
6459
+ if (isRecord7(value)) {
9650
6460
  if (state.seen.has(value)) return state.seen.get(value);
9651
6461
  const out = {};
9652
6462
  state.seen.set(value, out);
@@ -9654,7 +6464,7 @@ var Redactor2 = class {
9654
6464
  out[entryKey] = this.#redactValue(
9655
6465
  entryValue,
9656
6466
  entryKey,
9657
- childPath(path20 === "$" ? "" : path20, entryKey),
6467
+ childPath(path17 === "$" ? "" : path17, entryKey),
9658
6468
  depth + 1,
9659
6469
  state
9660
6470
  );
@@ -9842,8 +6652,8 @@ function renderHuman(result) {
9842
6652
  "",
9843
6653
  "Facts:"
9844
6654
  ];
9845
- for (const fact2 of result.facts) {
9846
- lines.push(`- ${fact2.id}: ${JSON.stringify(fact2.value)}`);
6655
+ for (const fact of result.facts) {
6656
+ lines.push(`- ${fact.id}: ${JSON.stringify(fact.value)}`);
9847
6657
  }
9848
6658
  lines.push("", "Inferences:");
9849
6659
  if (result.inferences.length === 0) {
@@ -9975,7 +6785,7 @@ function printWarnings(result) {
9975
6785
  function printNode(node, depth) {
9976
6786
  const ev = node.event;
9977
6787
  const status = ev.status !== void 0 ? ` ${ev.status}` : "";
9978
- const duration = ev.durationMs !== void 0 ? ` ${formatDuration2(ev.durationMs)}` : "";
6788
+ const duration = ev.durationMs !== void 0 ? ` ${formatDuration(ev.durationMs)}` : "";
9979
6789
  console.log(`${getIndent(depth)}${ev.kind.toLowerCase()}: ${ev.name}${status}${duration}`);
9980
6790
  for (const child of node.children) {
9981
6791
  printNode(child, depth + 1);
@@ -9990,7 +6800,7 @@ function printRun(result, run) {
9990
6800
  console.log(`Started: ${formatTimestamp(run.startedAt)}`);
9991
6801
  }
9992
6802
  if (run.durationMs !== void 0) {
9993
- console.log(`Duration: ${formatDuration2(run.durationMs)}`);
6803
+ console.log(`Duration: ${formatDuration(run.durationMs)}`);
9994
6804
  }
9995
6805
  console.log(`Events: ${run.metadata.totalEvents}`);
9996
6806
  for (const node of run.children) {
@@ -10079,7 +6889,7 @@ async function openCommand(input3, options = {}, stdin = process.stdin) {
10079
6889
  }
10080
6890
  }
10081
6891
  }
10082
- function isRecord14(value) {
6892
+ function isRecord8(value) {
10083
6893
  return typeof value === "object" && value !== null && !Array.isArray(value);
10084
6894
  }
10085
6895
  function parseTarget(value) {
@@ -10088,7 +6898,7 @@ function parseTarget(value) {
10088
6898
  throw new Error('Unsupported migration target. Use "--to 1.0".');
10089
6899
  }
10090
6900
  function formatOf(value) {
10091
- if (!isRecord14(value)) return "unknown";
6901
+ if (!isRecord8(value)) return "unknown";
10092
6902
  if (value.schemaVersion === "0.1") return "0.1";
10093
6903
  if (value.schemaVersion === "0.2") return "0.2";
10094
6904
  if (value.schemaVersion === "1.0") return "1.0";
@@ -10101,14 +6911,14 @@ function uniqueSorted(values) {
10101
6911
  return [...new Set(values)].sort();
10102
6912
  }
10103
6913
  function isWithinDirectory(child, parent) {
10104
- const relative = path14.relative(parent, child);
10105
- return relative === "" || !relative.startsWith("..") && !path14.isAbsolute(relative);
6914
+ const relative = path10.relative(parent, child);
6915
+ return relative === "" || !relative.startsWith("..") && !path10.isAbsolute(relative);
10106
6916
  }
10107
6917
  async function resolveOutputPath(inputPath, output2, force) {
10108
6918
  if (output2 === void 0 || output2.trim() === "") return void 0;
10109
- const inputAbs = path14.resolve(inputPath);
10110
- const outputAbs = path14.resolve(output2.trim());
10111
- const inputDir = path14.dirname(inputAbs);
6919
+ const inputAbs = path10.resolve(inputPath);
6920
+ const outputAbs = path10.resolve(output2.trim());
6921
+ const inputDir = path10.dirname(inputAbs);
10112
6922
  if (!isWithinDirectory(outputAbs, inputDir)) {
10113
6923
  throw new Error("Refusing to write migrated output outside the input directory.");
10114
6924
  }
@@ -10229,7 +7039,7 @@ async function migrateCommand(input3, options = {}) {
10229
7039
  process.exitCode = 1;
10230
7040
  return;
10231
7041
  }
10232
- const inputPath = path14.resolve(input3.trim());
7042
+ const inputPath = path10.resolve(input3.trim());
10233
7043
  const dryRun = options.dryRun === true;
10234
7044
  if (!dryRun && (options.output === void 0 || options.output.trim() === "")) {
10235
7045
  console.error("migrate requires --dry-run or --output <path>.");
@@ -10248,7 +7058,7 @@ async function migrateCommand(input3, options = {}) {
10248
7058
  );
10249
7059
  const result = await buildMigration(inputPath, outputPath);
10250
7060
  if (!dryRun && outputPath !== void 0) {
10251
- await mkdir(path14.dirname(outputPath), { recursive: true });
7061
+ await mkdir(path10.dirname(outputPath), { recursive: true });
10252
7062
  await writeFile(outputPath, result.content, "utf-8");
10253
7063
  }
10254
7064
  printSummary2(result, dryRun);
@@ -10325,7 +7135,7 @@ function diagnostic(code, message, ruleId) {
10325
7135
  ...ruleId ? { ruleId } : {}
10326
7136
  };
10327
7137
  }
10328
- function emptySummary2() {
7138
+ function emptySummary() {
10329
7139
  return {
10330
7140
  passed: 0,
10331
7141
  failed: 0,
@@ -10340,7 +7150,7 @@ function errorResult(input3, diagnostics, selectedRun) {
10340
7150
  format: input3.read.format,
10341
7151
  ...selectedRun ? { runId: selectedRun.runId } : {},
10342
7152
  summary: {
10343
- ...emptySummary2(),
7153
+ ...emptySummary(),
10344
7154
  errors: diagnostics.filter((item) => item.severity === "error").length
10345
7155
  },
10346
7156
  findings: [],
@@ -10350,7 +7160,7 @@ function errorResult(input3, diagnostics, selectedRun) {
10350
7160
  function flattenNodes(nodes) {
10351
7161
  return nodes.flatMap((node) => [node, ...flattenNodes(node.children)]);
10352
7162
  }
10353
- function buildFacts2(input3, selectedRun) {
7163
+ function buildFacts(input3, selectedRun) {
10354
7164
  const scopedRuns = selectedRun ? [selectedRun] : input3.read.runs;
10355
7165
  const scopedRunIds = new Set(scopedRuns.map((run) => run.runId));
10356
7166
  const scopedEvents = selectedRun === void 0 ? input3.read.events : input3.read.events.filter((event) => scopedRunIds.has(event.runId));
@@ -10526,7 +7336,7 @@ function stripPrefix(name, prefixes) {
10526
7336
  }
10527
7337
  return name;
10528
7338
  }
10529
- function eventEvidence(event, path20) {
7339
+ function eventEvidence(event, path17) {
10530
7340
  return {
10531
7341
  runId: event.runId,
10532
7342
  eventId: event.eventId,
@@ -10536,7 +7346,7 @@ function eventEvidence(event, path20) {
10536
7346
  kind: event.kind,
10537
7347
  name: event.name,
10538
7348
  status: event.status,
10539
- ...path20 ? { path: path20 } : {}
7349
+ ...path17 ? { path: path17 } : {}
10540
7350
  };
10541
7351
  }
10542
7352
  function runEvidence(run) {
@@ -10573,7 +7383,7 @@ function finishedEvents(context, kind) {
10573
7383
  (event) => (kind === void 0 || event.kind === kind) && event.status !== "running"
10574
7384
  );
10575
7385
  }
10576
- function isRecord15(value) {
7386
+ function isRecord9(value) {
10577
7387
  return typeof value === "object" && value !== null && !Array.isArray(value);
10578
7388
  }
10579
7389
  function eventMap(events) {
@@ -10599,9 +7409,9 @@ function eventEndMs(event) {
10599
7409
  function normalizedKey(value) {
10600
7410
  return value.toLowerCase().replace(/[^a-z0-9_]/g, "");
10601
7411
  }
10602
- function lastPathSegment(path20) {
10603
- const parts = path20.split(".");
10604
- return parts[parts.length - 1] ?? path20;
7412
+ function lastPathSegment(path17) {
7413
+ const parts = path17.split(".");
7414
+ return parts[parts.length - 1] ?? path17;
10605
7415
  }
10606
7416
  function valueType(value) {
10607
7417
  if (Array.isArray(value)) return "array";
@@ -10615,22 +7425,22 @@ function serializedByteLength(value) {
10615
7425
  return void 0;
10616
7426
  }
10617
7427
  }
10618
- function pushValueEntries(entries, event, value, path20, key, depth = 0) {
10619
- entries.push({ event, path: path20, key, value });
7428
+ function pushValueEntries(entries, event, value, path17, key, depth = 0) {
7429
+ entries.push({ event, path: path17, key, value });
10620
7430
  if (depth >= 8) return;
10621
7431
  if (Array.isArray(value)) {
10622
7432
  for (const [index, item] of value.entries()) {
10623
- pushValueEntries(entries, event, item, `${path20}.${index}`, String(index), depth + 1);
7433
+ pushValueEntries(entries, event, item, `${path17}.${index}`, String(index), depth + 1);
10624
7434
  }
10625
7435
  return;
10626
7436
  }
10627
- if (!isRecord15(value)) return;
7437
+ if (!isRecord9(value)) return;
10628
7438
  for (const nestedKey of Object.keys(value).sort((a, b) => a.localeCompare(b))) {
10629
7439
  pushValueEntries(
10630
7440
  entries,
10631
7441
  event,
10632
7442
  value[nestedKey],
10633
- `${path20}.${nestedKey}`,
7443
+ `${path17}.${nestedKey}`,
10634
7444
  nestedKey,
10635
7445
  depth + 1
10636
7446
  );
@@ -10711,9 +7521,9 @@ function eventDurationMs(event) {
10711
7521
  }
10712
7522
  function treeShape(nodes) {
10713
7523
  const lines = [];
10714
- const visit = (node, path20) => {
10715
- lines.push(`${path20}:${node.event.kind}:${node.event.name}:${node.event.status ?? "unknown"}`);
10716
- node.children.forEach((child, index) => visit(child, `${path20}.${index}`));
7524
+ const visit = (node, path17) => {
7525
+ lines.push(`${path17}:${node.event.kind}:${node.event.name}:${node.event.status ?? "unknown"}`);
7526
+ node.children.forEach((child, index) => visit(child, `${path17}.${index}`));
10717
7527
  };
10718
7528
  nodes.forEach((node, index) => visit(node, String(index)));
10719
7529
  return lines;
@@ -10762,9 +7572,9 @@ function retrievalShape(context) {
10762
7572
  function guardrailShape(context) {
10763
7573
  return guardrailEvents(context).map((event) => signalName(event, ["guardrailName", "guardrail", "guardrailId"], ["guardrail:"])).sort((a, b) => a.localeCompare(b));
10764
7574
  }
10765
- function firstEvidenceForKind(context, kind, path20) {
7575
+ function firstEvidenceForKind(context, kind, path17) {
10766
7576
  const event = context.events.find((candidate) => candidate.kind === kind);
10767
- return event ? [eventEvidence(event, path20)] : runEvidence(context.selectedRun);
7577
+ return event ? [eventEvidence(event, path17)] : runEvidence(context.selectedRun);
10768
7578
  }
10769
7579
  function baselineDiffFinding(message, evidence, expected, actual) {
10770
7580
  return failFinding("baseline.regression", message, evidence, expected, actual);
@@ -11114,13 +7924,13 @@ function createStructureCycleRule() {
11114
7924
  const seenCycles = /* @__PURE__ */ new Set();
11115
7925
  const findings = [];
11116
7926
  for (const event of [...context.events].sort((a, b) => a.eventId.localeCompare(b.eventId))) {
11117
- const path20 = [];
7927
+ const path17 = [];
11118
7928
  const seenAt = /* @__PURE__ */ new Map();
11119
7929
  let current = event;
11120
7930
  while (current) {
11121
7931
  const existing = seenAt.get(current.eventId);
11122
7932
  if (existing !== void 0) {
11123
- const cycle = path20.slice(existing);
7933
+ const cycle = path17.slice(existing);
11124
7934
  const key = cycle.map((item) => item.eventId).sort().join("\0");
11125
7935
  if (!seenCycles.has(key)) {
11126
7936
  seenCycles.add(key);
@@ -11136,8 +7946,8 @@ function createStructureCycleRule() {
11136
7946
  }
11137
7947
  break;
11138
7948
  }
11139
- seenAt.set(current.eventId, path20.length);
11140
- path20.push(current);
7949
+ seenAt.set(current.eventId, path17.length);
7950
+ path17.push(current);
11141
7951
  current = current.parentId ? byId.get(current.parentId) : void 0;
11142
7952
  }
11143
7953
  }
@@ -11411,7 +8221,7 @@ function createSafetyOversizedAttributeRule(options) {
11411
8221
  )
11412
8222
  );
11413
8223
  }
11414
- if (isRecord15(entry.value) && options.maxObjectKeys !== void 0 && Object.keys(entry.value).length > options.maxObjectKeys) {
8224
+ if (isRecord9(entry.value) && options.maxObjectKeys !== void 0 && Object.keys(entry.value).length > options.maxObjectKeys) {
11415
8225
  findings.push(
11416
8226
  failFinding(
11417
8227
  "safety.oversizedAttribute",
@@ -11460,7 +8270,7 @@ function createBaselineRegressionRule(options) {
11460
8270
  )
11461
8271
  ];
11462
8272
  }
11463
- const baselineFacts = buildFacts2(options.baseline, baselineSelection.run);
8273
+ const baselineFacts = buildFacts(options.baseline, baselineSelection.run);
11464
8274
  const baselineContext = {
11465
8275
  ...baselineFacts,
11466
8276
  selectedRun: baselineSelection.run,
@@ -11579,7 +8389,7 @@ function runTraceChecks(input3, options = {}) {
11579
8389
  if (rules.diagnostics.length > 0) {
11580
8390
  return errorResult(input3, rules.diagnostics, selected.run);
11581
8391
  }
11582
- const facts = buildFacts2(input3, selected.run);
8392
+ const facts = buildFacts(input3, selected.run);
11583
8393
  const context = {
11584
8394
  ...facts,
11585
8395
  ...selected.run ? { selectedRun: selected.run } : {},
@@ -11934,23 +8744,23 @@ function evaluatePromptInjection(text, options = {}) {
11934
8744
  }
11935
8745
  return fail(ruleId, `Matched ${evidence.length} injection pattern(s).`, evidence, "warning");
11936
8746
  }
11937
- function validateSchemaField(value, field, path20, evidence) {
8747
+ function validateSchemaField(value, field, path17, evidence) {
11938
8748
  const ruleId = "guardrail.structured-output";
11939
8749
  if (field.type) {
11940
8750
  const actual = value === null ? "null" : Array.isArray(value) ? "array" : typeof value;
11941
8751
  if (actual !== field.type) {
11942
- evidence.push({ ruleId, path: path20, preview: `expected ${field.type}, got ${actual}` });
8752
+ evidence.push({ ruleId, path: path17, preview: `expected ${field.type}, got ${actual}` });
11943
8753
  return;
11944
8754
  }
11945
8755
  }
11946
8756
  if (field.enum && !field.enum.some((item) => Object.is(item, value))) {
11947
- evidence.push({ ruleId, path: path20, preview: "value not in enum" });
8757
+ evidence.push({ ruleId, path: path17, preview: "value not in enum" });
11948
8758
  }
11949
8759
  if (field.type === "object" && field.required && value && typeof value === "object" && !Array.isArray(value)) {
11950
8760
  const record = value;
11951
8761
  for (const key of field.required) {
11952
8762
  if (!(key in record)) {
11953
- evidence.push({ ruleId, path: `${path20}.${key}`, preview: "missing required key" });
8763
+ evidence.push({ ruleId, path: `${path17}.${key}`, preview: "missing required key" });
11954
8764
  }
11955
8765
  }
11956
8766
  }
@@ -12277,7 +9087,7 @@ function asConfig(value) {
12277
9087
  }
12278
9088
  async function loadConfig(configPath) {
12279
9089
  if (configPath === void 0) return {};
12280
- const extension = path14.extname(configPath);
9090
+ const extension = path10.extname(configPath);
12281
9091
  if (TS_CONFIG_EXTENSIONS.has(extension)) {
12282
9092
  throw new Error(
12283
9093
  "TypeScript check configs require an explicit precompiled JavaScript config or future --config-loader support."
@@ -12286,7 +9096,7 @@ async function loadConfig(configPath) {
12286
9096
  if (!CONFIG_EXTENSIONS.has(extension)) {
12287
9097
  throw new Error("Unsupported check config extension. Use .json, .js, .mjs, or .cjs.");
12288
9098
  }
12289
- const absolute = path14.resolve(configPath);
9099
+ const absolute = path10.resolve(configPath);
12290
9100
  if (extension === ".json") {
12291
9101
  const raw = await readFile(absolute, "utf-8");
12292
9102
  return asConfig(JSON.parse(raw));
@@ -12435,10 +9245,10 @@ function printHuman(result) {
12435
9245
  console.log(`- ${diagnostic4.code}: ${diagnostic4.message}`);
12436
9246
  }
12437
9247
  for (const finding of result.findings) {
12438
- const path20 = finding.evidence[0]?.path;
9248
+ const path17 = finding.evidence[0]?.path;
12439
9249
  const run = finding.evidence[0]?.runId;
12440
9250
  const runPrefix = run ? `[${run}] ` : "";
12441
- console.log(`- ${runPrefix}${finding.ruleId}: ${finding.message}${path20 ? ` (${path20})` : ""}`);
9251
+ console.log(`- ${runPrefix}${finding.ruleId}: ${finding.message}${path17 ? ` (${path17})` : ""}`);
12442
9252
  }
12443
9253
  }
12444
9254
  function readErrorResult(error) {
@@ -12638,7 +9448,7 @@ function createViewerServer(options = {}) {
12638
9448
  return sendJson(res, 200, {
12639
9449
  ok: true,
12640
9450
  readOnly: true,
12641
- traceDir: path14.resolve(traceDir)
9451
+ traceDir: path10.resolve(traceDir)
12642
9452
  });
12643
9453
  }
12644
9454
  const td = new TraceDirectory({ dir: traceDir });
@@ -12656,7 +9466,7 @@ function createViewerServer(options = {}) {
12656
9466
  runId: meta.runId,
12657
9467
  name: meta.name,
12658
9468
  status: meta.status,
12659
- file: path14.basename(meta.filePath),
9469
+ file: path10.basename(meta.filePath),
12660
9470
  startedAt: meta.startedAt,
12661
9471
  durationMs: meta.durationMs
12662
9472
  }))
@@ -12771,7 +9581,7 @@ function startViewerServer(options = {}) {
12771
9581
  resolve({
12772
9582
  host,
12773
9583
  port: resolvedPort,
12774
- traceDir: path14.resolve(traceDir),
9584
+ traceDir: path10.resolve(traceDir),
12775
9585
  url: `http://${host}:${resolvedPort}`
12776
9586
  });
12777
9587
  });
@@ -12849,8 +9659,8 @@ function diagnosticFromError(error) {
12849
9659
  message: error instanceof Error ? error.message : String(error)
12850
9660
  };
12851
9661
  }
12852
- function flatten2(nodes) {
12853
- return nodes.flatMap((node) => [node, ...flatten2(node.children)]);
9662
+ function flatten(nodes) {
9663
+ return nodes.flatMap((node) => [node, ...flatten(node.children)]);
12854
9664
  }
12855
9665
  function selectRun3(read, runId) {
12856
9666
  if (runId !== void 0) {
@@ -12943,7 +9753,7 @@ async function evalRun(input3, options = {}) {
12943
9753
  const context = {
12944
9754
  format: resolved.read.format,
12945
9755
  run: selected.run,
12946
- nodes: flatten2(selected.run.children),
9756
+ nodes: flatten(selected.run.children),
12947
9757
  events: resolved.read.events.filter((event) => event.runId === selected.run?.runId)
12948
9758
  };
12949
9759
  const diagnostics = [];
@@ -12976,10 +9786,10 @@ async function evalRun(input3, options = {}) {
12976
9786
  diagnostics: []
12977
9787
  };
12978
9788
  }
12979
- function evidenceForRun(run, path20) {
12980
- return [{ runId: run.runId, ...path20 !== void 0 ? { path: path20 } : {} }];
9789
+ function evidenceForRun(run, path17) {
9790
+ return [{ runId: run.runId, ...path17 !== void 0 ? { path: path17 } : {} }];
12981
9791
  }
12982
- function evidenceForEvent(event, path20) {
9792
+ function evidenceForEvent(event, path17) {
12983
9793
  return [
12984
9794
  {
12985
9795
  runId: event.runId,
@@ -12987,7 +9797,7 @@ function evidenceForEvent(event, path20) {
12987
9797
  ...event.parentId !== void 0 ? { parentId: event.parentId } : {},
12988
9798
  kind: event.kind,
12989
9799
  name: event.name,
12990
- ...path20 !== void 0 ? { path: path20 } : {}
9800
+ ...path17 !== void 0 ? { path: path17 } : {}
12991
9801
  }
12992
9802
  ];
12993
9803
  }
@@ -13145,9 +9955,9 @@ function collectTextFields(nodes, keys, preferredKinds = []) {
13145
9955
  function tokenize(text) {
13146
9956
  return [...text.toLowerCase().matchAll(/[a-z0-9][a-z0-9'-]{2,}/g)].map((match) => match[0].replace(/^['-]+|['-]+$/g, "")).filter((token) => token.length > 2 && !STOP_WORDS.has(token));
13147
9957
  }
13148
- function firstEvidence(fields, run, path20) {
9958
+ function firstEvidence(fields, run, path17) {
13149
9959
  const first = fields[0];
13150
- return first === void 0 ? evidenceForRun(run, path20) : evidenceForEvent(first.node.event, first.path);
9960
+ return first === void 0 ? evidenceForRun(run, path17) : evidenceForEvent(first.node.event, first.path);
13151
9961
  }
13152
9962
  function collectSourceIds(nodes, keys) {
13153
9963
  const wanted = keySet(keys);
@@ -13524,8 +10334,8 @@ function renderEvalMarkdown(result) {
13524
10334
  if (result.findings.length > 0) {
13525
10335
  lines.push("", "## Findings");
13526
10336
  for (const finding of result.findings) {
13527
- const path20 = finding.evidence[0]?.path;
13528
- lines.push(`- ${finding.ruleId}: ${finding.message}${path20 ? ` (${path20})` : ""}`);
10337
+ const path17 = finding.evidence[0]?.path;
10338
+ lines.push(`- ${finding.ruleId}: ${finding.message}${path17 ? ` (${path17})` : ""}`);
13529
10339
  }
13530
10340
  }
13531
10341
  return `${lines.join("\n")}
@@ -13572,7 +10382,7 @@ function asConfig2(value) {
13572
10382
  }
13573
10383
  async function loadConfig2(configPath) {
13574
10384
  if (configPath === void 0) return {};
13575
- const extension = path14.extname(configPath);
10385
+ const extension = path10.extname(configPath);
13576
10386
  if (TS_CONFIG_EXTENSIONS2.has(extension)) {
13577
10387
  throw new Error(
13578
10388
  "TypeScript eval configs require an explicit precompiled JavaScript config or future --config-loader support."
@@ -13581,7 +10391,7 @@ async function loadConfig2(configPath) {
13581
10391
  if (!CONFIG_EXTENSIONS2.has(extension)) {
13582
10392
  throw new Error("Unsupported eval config extension. Use .json, .js, .mjs, or .cjs.");
13583
10393
  }
13584
- const absolute = path14.resolve(configPath);
10394
+ const absolute = path10.resolve(configPath);
13585
10395
  if (extension === ".json") {
13586
10396
  const raw = await readFile(absolute, "utf-8");
13587
10397
  return asConfig2(JSON.parse(raw));
@@ -13718,8 +10528,8 @@ function printHuman2(result) {
13718
10528
  console.log(`- ${diagnostic4.code}: ${diagnostic4.message}`);
13719
10529
  }
13720
10530
  for (const finding of result.findings) {
13721
- const path20 = finding.evidence[0]?.path;
13722
- console.log(`- ${finding.ruleId}: ${finding.message}${path20 ? ` (${path20})` : ""}`);
10531
+ const path17 = finding.evidence[0]?.path;
10532
+ console.log(`- ${finding.ruleId}: ${finding.message}${path17 ? ` (${path17})` : ""}`);
13723
10533
  }
13724
10534
  }
13725
10535
  function readErrorResult2(error) {
@@ -13957,8 +10767,8 @@ function printHuman3(result) {
13957
10767
  console.log(`- ${diagnostic4.code}: ${diagnostic4.message}`);
13958
10768
  }
13959
10769
  for (const finding of result.findings) {
13960
- const path20 = finding.evidence[0]?.path;
13961
- console.log(`- ${finding.ruleId}: ${finding.message}${path20 ? ` (${path20})` : ""}`);
10770
+ const path17 = finding.evidence[0]?.path;
10771
+ console.log(`- ${finding.ruleId}: ${finding.message}${path17 ? ` (${path17})` : ""}`);
13962
10772
  }
13963
10773
  console.log(`Note: ${result.note}`);
13964
10774
  }
@@ -14077,8 +10887,8 @@ function renderCheckSection(result) {
14077
10887
  `Diagnostics: ${result.diagnostics.length}`
14078
10888
  ];
14079
10889
  for (const finding of result.findings.slice(0, 10)) {
14080
- const path20 = finding.evidence[0]?.path ?? "(run)";
14081
- lines.push(`- ${finding.ruleId}: ${finding.message} (${path20})`);
10890
+ const path17 = finding.evidence[0]?.path ?? "(run)";
10891
+ lines.push(`- ${finding.ruleId}: ${finding.message} (${path17})`);
14082
10892
  }
14083
10893
  for (const diagnostic4 of result.diagnostics.slice(0, 10)) {
14084
10894
  lines.push(`- ${diagnostic4.code}: ${diagnostic4.message}`);
@@ -14156,8 +10966,8 @@ function renderHtml(trace, check, diff) {
14156
10966
  `;
14157
10967
  }
14158
10968
  async function writeArtifact(outputDir, relativePath, content, files) {
14159
- const outPath = path14.join(outputDir, relativePath);
14160
- await mkdir(path14.dirname(outPath), { recursive: true });
10969
+ const outPath = path10.join(outputDir, relativePath);
10970
+ await mkdir(path10.dirname(outPath), { recursive: true });
14161
10971
  await writeFile(outPath, content, "utf-8");
14162
10972
  files.push(relativePath);
14163
10973
  }
@@ -14173,7 +10983,7 @@ function manifestStatus(check, diff) {
14173
10983
  return "ok";
14174
10984
  }
14175
10985
  async function artifactsCommand(target, options = {}, stdin = process.stdin) {
14176
- const outputDir = options.outputDir !== void 0 && options.outputDir.trim() !== "" ? path14.resolve(options.outputDir.trim()) : "";
10986
+ const outputDir = options.outputDir !== void 0 && options.outputDir.trim() !== "" ? path10.resolve(options.outputDir.trim()) : "";
14177
10987
  if (outputDir === "") {
14178
10988
  console.error("--output-dir is required.");
14179
10989
  process.exitCode = 1;
@@ -14239,8 +11049,8 @@ async function artifactsCommand(target, options = {}, stdin = process.stdin) {
14239
11049
  await writeArtifact(outputDir, "report.html", renderHtml(trace, check, diff), files);
14240
11050
  const summaryTarget = options.githubSummary ?? process.env.GITHUB_STEP_SUMMARY;
14241
11051
  if (summaryTarget !== void 0 && summaryTarget.trim() !== "") {
14242
- await mkdir(path14.dirname(path14.resolve(summaryTarget)), { recursive: true });
14243
- await appendFile(path14.resolve(summaryTarget), `
11052
+ await mkdir(path10.dirname(path10.resolve(summaryTarget)), { recursive: true });
11053
+ await appendFile(path10.resolve(summaryTarget), `
14244
11054
  ${renderMarkdown(trace, check, diff)}`, "utf-8");
14245
11055
  }
14246
11056
  const manifestFiles = [...files, "manifest.json"].sort((a, b) => a.localeCompare(b));
@@ -14259,10 +11069,10 @@ ${renderMarkdown(trace, check, diff)}`, "utf-8");
14259
11069
  findings: diff?.findings.length ?? 0,
14260
11070
  diagnostics: diff?.diagnostics.length ?? 0
14261
11071
  },
14262
- ...summaryTarget !== void 0 && summaryTarget.trim() !== "" ? { githubSummary: path14.resolve(summaryTarget) } : {},
11072
+ ...summaryTarget !== void 0 && summaryTarget.trim() !== "" ? { githubSummary: path10.resolve(summaryTarget) } : {},
14263
11073
  note: NOTE
14264
11074
  };
14265
- await writeFile(path14.join(outputDir, "manifest.json"), writeJson3(manifest), "utf-8");
11075
+ await writeFile(path10.join(outputDir, "manifest.json"), writeJson3(manifest), "utf-8");
14266
11076
  if (options.json === true) {
14267
11077
  console.log(writeJson3(manifest).trimEnd());
14268
11078
  } else {
@@ -14274,7 +11084,7 @@ ${renderMarkdown(trace, check, diff)}`, "utf-8");
14274
11084
  }
14275
11085
  }
14276
11086
  function validateReporterArtifactPath(options) {
14277
- const outputDir = path14.resolve(options.outputDir);
11087
+ const outputDir = path10.resolve(options.outputDir);
14278
11088
  const diagnostics = [];
14279
11089
  const rawPath = options.relativePath;
14280
11090
  if (rawPath.length === 0) {
@@ -14294,7 +11104,7 @@ function validateReporterArtifactPath(options) {
14294
11104
  });
14295
11105
  return { ok: false, outputDir, diagnostics };
14296
11106
  }
14297
- if (path14.isAbsolute(rawPath) || path14.win32.isAbsolute(rawPath)) {
11107
+ if (path10.isAbsolute(rawPath) || path10.win32.isAbsolute(rawPath)) {
14298
11108
  diagnostics.push({
14299
11109
  code: "artifact_path_absolute",
14300
11110
  severity: "error",
@@ -14303,7 +11113,7 @@ function validateReporterArtifactPath(options) {
14303
11113
  });
14304
11114
  return { ok: false, outputDir, diagnostics };
14305
11115
  }
14306
- const normalized = path14.posix.normalize(rawPath.replace(/\\/g, "/"));
11116
+ const normalized = path10.posix.normalize(rawPath.replace(/\\/g, "/"));
14307
11117
  const segments = normalized.split("/");
14308
11118
  if (normalized === "." || normalized.startsWith("../") || segments.some((segment) => segment === "..")) {
14309
11119
  diagnostics.push({
@@ -14314,9 +11124,9 @@ function validateReporterArtifactPath(options) {
14314
11124
  });
14315
11125
  return { ok: false, outputDir, diagnostics };
14316
11126
  }
14317
- const absolutePath = path14.resolve(outputDir, normalized);
14318
- const relFromOutput = path14.relative(outputDir, absolutePath);
14319
- if (relFromOutput.length === 0 || relFromOutput.startsWith("..") || path14.isAbsolute(relFromOutput)) {
11127
+ const absolutePath = path10.resolve(outputDir, normalized);
11128
+ const relFromOutput = path10.relative(outputDir, absolutePath);
11129
+ if (relFromOutput.length === 0 || relFromOutput.startsWith("..") || path10.isAbsolute(relFromOutput)) {
14320
11130
  diagnostics.push({
14321
11131
  code: "artifact_path_escape",
14322
11132
  severity: "error",
@@ -14462,23 +11272,23 @@ function readManifestDocument(value) {
14462
11272
  };
14463
11273
  }
14464
11274
  function cwdRelative(filePath) {
14465
- const relative = path14.relative(process.cwd(), path14.resolve(filePath)).replace(/\\/g, "/");
14466
- if (relative === "" || relative.startsWith("../") || path14.isAbsolute(relative)) {
14467
- return path14.basename(filePath);
11275
+ const relative = path10.relative(process.cwd(), path10.resolve(filePath)).replace(/\\/g, "/");
11276
+ if (relative === "" || relative.startsWith("../") || path10.isAbsolute(relative)) {
11277
+ return path10.basename(filePath);
14468
11278
  }
14469
11279
  return relative;
14470
11280
  }
14471
11281
  async function readReporterManifest(filePath) {
14472
- const absolute = path14.resolve(filePath);
11282
+ const absolute = path10.resolve(filePath);
14473
11283
  const raw = await readFile(absolute, "utf-8");
14474
11284
  const document = readManifestDocument(JSON.parse(raw));
14475
11285
  const manifest = document.manifest;
14476
11286
  const results = manifest.results.map((result) => ({
14477
11287
  testId: safeText(result.testId),
14478
11288
  name: safeText(result.name),
14479
- ...result.file === void 0 ? {} : { file: safeText(path14.basename(result.file)) },
11289
+ ...result.file === void 0 ? {} : { file: safeText(path10.basename(result.file)) },
14480
11290
  status: result.status,
14481
- ...result.tracePath === void 0 ? {} : { tracePath: safeText(path14.basename(result.tracePath)) },
11291
+ ...result.tracePath === void 0 ? {} : { tracePath: safeText(path10.basename(result.tracePath)) },
14482
11292
  artifacts: result.artifacts,
14483
11293
  diagnostics: result.diagnostics
14484
11294
  }));
@@ -14617,15 +11427,15 @@ async function ciSummaryCommand(manifestPaths, options = {}) {
14617
11427
  return;
14618
11428
  }
14619
11429
  const markdown = renderMarkdown2(result);
14620
- const outputPath = options.output !== void 0 && options.output.trim() !== "" ? path14.resolve(options.output.trim()) : void 0;
11430
+ const outputPath = options.output !== void 0 && options.output.trim() !== "" ? path10.resolve(options.output.trim()) : void 0;
14621
11431
  if (outputPath !== void 0) {
14622
- await mkdir(path14.dirname(outputPath), { recursive: true });
11432
+ await mkdir(path10.dirname(outputPath), { recursive: true });
14623
11433
  await writeFile(outputPath, markdown, "utf-8");
14624
11434
  }
14625
11435
  const summaryTarget = options.githubSummary ?? process.env.GITHUB_STEP_SUMMARY;
14626
11436
  if (summaryTarget !== void 0 && summaryTarget.trim() !== "") {
14627
- const summaryPath = path14.resolve(summaryTarget);
14628
- await mkdir(path14.dirname(summaryPath), { recursive: true });
11437
+ const summaryPath = path10.resolve(summaryTarget);
11438
+ await mkdir(path10.dirname(summaryPath), { recursive: true });
14629
11439
  await appendFile(summaryPath, `
14630
11440
  ${markdown}`, "utf-8");
14631
11441
  }
@@ -14773,8 +11583,8 @@ jobs:
14773
11583
  }
14774
11584
  async function planInit(options = {}) {
14775
11585
  const framework = normalizeFramework(options.framework);
14776
- const cwd = path14.resolve(options.cwd ?? process.cwd());
14777
- const demoPath = framework === "custom" ? path14.join("examples", "agent-inspect-demo.mjs") : path14.join("examples", `agent-inspect-${framework}-demo.mjs`);
11586
+ const cwd = path10.resolve(options.cwd ?? process.cwd());
11587
+ const demoPath = framework === "custom" ? path10.join("examples", "agent-inspect-demo.mjs") : path10.join("examples", `agent-inspect-${framework}-demo.mjs`);
14778
11588
  const candidates = [
14779
11589
  { rel: CONFIG_FILE, content: configTemplate(framework) },
14780
11590
  { rel: GITKEEP, content: "" },
@@ -14788,7 +11598,7 @@ async function planInit(options = {}) {
14788
11598
  }
14789
11599
  const files = [];
14790
11600
  for (const candidate of candidates) {
14791
- const abs = path14.join(cwd, candidate.rel);
11601
+ const abs = path10.join(cwd, candidate.rel);
14792
11602
  try {
14793
11603
  await access(abs);
14794
11604
  files.push({
@@ -14809,12 +11619,12 @@ async function writePlannedFiles(plan, cwd, options) {
14809
11619
  if (entry.action === "skip") {
14810
11620
  continue;
14811
11621
  }
14812
- const abs = path14.join(cwd, entry.path);
11622
+ const abs = path10.join(cwd, entry.path);
14813
11623
  if (options.dryRun) {
14814
11624
  written.push(entry.path);
14815
11625
  continue;
14816
11626
  }
14817
- await mkdir(path14.dirname(abs), { recursive: true });
11627
+ await mkdir(path10.dirname(abs), { recursive: true });
14818
11628
  const content = entry.path === CONFIG_FILE ? configTemplate(plan.framework) : entry.path === GITKEEP ? "" : entry.path.endsWith(".yml") ? githubWorkflowTemplate() : demoTemplate(plan.framework);
14819
11629
  await writeFile(abs, content, "utf-8");
14820
11630
  written.push(entry.path);
@@ -14822,7 +11632,7 @@ async function writePlannedFiles(plan, cwd, options) {
14822
11632
  return written;
14823
11633
  }
14824
11634
  async function initCommand(options = {}) {
14825
- const cwd = path14.resolve(options.cwd ?? process.cwd());
11635
+ const cwd = path10.resolve(options.cwd ?? process.cwd());
14826
11636
  try {
14827
11637
  const plan = await planInit({ ...options, cwd });
14828
11638
  const toWrite = plan.files.filter((file) => file.action === "create").map((f) => f.path);
@@ -14878,25 +11688,25 @@ var OPTIONAL_PACKAGES = {
14878
11688
  langchain: ["@agent-inspect/langchain"]
14879
11689
  };
14880
11690
  function nodeVersionCheck() {
14881
- const major = Number(process3.versions.node.split(".")[0]);
11691
+ const major = Number(process2.versions.node.split(".")[0]);
14882
11692
  if (Number.isNaN(major) || major < 20) {
14883
11693
  return {
14884
11694
  id: "node-version",
14885
11695
  status: "fail",
14886
- message: `Node ${process3.versions.node} is below the supported minimum (20).`,
11696
+ message: `Node ${process2.versions.node} is below the supported minimum (20).`,
14887
11697
  remediation: "Upgrade to Node 20 LTS or newer.",
14888
- evidence: process3.versions.node
11698
+ evidence: process2.versions.node
14889
11699
  };
14890
11700
  }
14891
11701
  return {
14892
11702
  id: "node-version",
14893
11703
  status: "pass",
14894
- message: `Node ${process3.versions.node} meets the minimum (>=20).`,
14895
- evidence: process3.versions.node
11704
+ message: `Node ${process2.versions.node} meets the minimum (>=20).`,
11705
+ evidence: process2.versions.node
14896
11706
  };
14897
11707
  }
14898
11708
  function envCheck(name, optional = true) {
14899
- const value = process3.env[name];
11709
+ const value = process2.env[name];
14900
11710
  if (value === void 0 || value.trim() === "") {
14901
11711
  return {
14902
11712
  id: `env-${name.toLowerCase()}`,
@@ -14913,7 +11723,7 @@ function envCheck(name, optional = true) {
14913
11723
  };
14914
11724
  }
14915
11725
  async function traceDirWritable(traceDir) {
14916
- const resolved = path14.resolve(traceDir);
11726
+ const resolved = path10.resolve(traceDir);
14917
11727
  try {
14918
11728
  await mkdir(resolved, { recursive: true });
14919
11729
  await access(resolved, constants.W_OK);
@@ -14934,7 +11744,7 @@ async function traceDirWritable(traceDir) {
14934
11744
  }
14935
11745
  }
14936
11746
  function resolvePackage(cwd, name) {
14937
- const require2 = createRequire(path14.join(cwd, "package.json"));
11747
+ const require2 = createRequire(path10.join(cwd, "package.json"));
14938
11748
  try {
14939
11749
  const pkgPath = require2.resolve(`${name}/package.json`);
14940
11750
  const pkg = require2(pkgPath);
@@ -14945,7 +11755,7 @@ function resolvePackage(cwd, name) {
14945
11755
  }
14946
11756
  function importSmoke(cwd) {
14947
11757
  const results = [];
14948
- const require2 = createRequire(path14.join(cwd, "package.json"));
11758
+ const require2 = createRequire(path10.join(cwd, "package.json"));
14949
11759
  try {
14950
11760
  require2.resolve("agent-inspect");
14951
11761
  results.push({
@@ -15028,8 +11838,8 @@ function versionMismatchCheck(cwd) {
15028
11838
  };
15029
11839
  }
15030
11840
  async function runDoctorChecks(options = {}) {
15031
- const cwd = path14.resolve(options.cwd ?? process3.cwd());
15032
- const traceDir = options.traceDir?.trim() || process3.env.AGENT_INSPECT_TRACE_DIR?.trim() || ".agent-inspect";
11841
+ const cwd = path10.resolve(options.cwd ?? process2.cwd());
11842
+ const traceDir = options.traceDir?.trim() || process2.env.AGENT_INSPECT_TRACE_DIR?.trim() || ".agent-inspect";
15033
11843
  const checks2 = [
15034
11844
  nodeVersionCheck(),
15035
11845
  {
@@ -15066,7 +11876,7 @@ async function doctorCommand(options = {}) {
15066
11876
  2
15067
11877
  )
15068
11878
  );
15069
- if (failed > 0) process3.exitCode = 1;
11879
+ if (failed > 0) process2.exitCode = 1;
15070
11880
  return;
15071
11881
  }
15072
11882
  console.log("AgentInspect doctor");
@@ -15077,7 +11887,7 @@ async function doctorCommand(options = {}) {
15077
11887
  }
15078
11888
  console.log(`
15079
11889
  Summary: ${failed} failed, ${warned} warnings`);
15080
- if (failed > 0) process3.exitCode = 1;
11890
+ if (failed > 0) process2.exitCode = 1;
15081
11891
  }
15082
11892
 
15083
11893
  // packages/adapter-sdk/src/indexer.ts
@@ -15140,7 +11950,7 @@ function createTraceDirectoryIndexer() {
15140
11950
  // packages/cli/src/index-cmd.ts
15141
11951
  var INDEX_FILENAME = ".agent-inspect-index.json";
15142
11952
  function traceIndexPath(traceDir) {
15143
- return path14.join(traceDir, INDEX_FILENAME);
11953
+ return path10.join(traceDir, INDEX_FILENAME);
15144
11954
  }
15145
11955
  function parseMaxEntries(raw) {
15146
11956
  if (raw === void 0 || raw.trim() === "") return void 0;
@@ -15247,6 +12057,141 @@ async function indexCleanCommand(options = {}) {
15247
12057
  process.exitCode = 1;
15248
12058
  }
15249
12059
  }
12060
+ var PACKAGE = "@agent-inspect/index-sqlite";
12061
+ function isModuleNotFound2(e) {
12062
+ return e !== null && typeof e === "object" && "code" in e && (e.code === "ERR_MODULE_NOT_FOUND" || e.code === "MODULE_NOT_FOUND");
12063
+ }
12064
+ async function loadIndexSqlite() {
12065
+ try {
12066
+ return await import('./src-DUGEOAZ7.mjs');
12067
+ } catch (e) {
12068
+ if (isModuleNotFound2(e)) {
12069
+ console.error(
12070
+ `The optional SQLite index is not installed. Run: npm install ${PACKAGE}`
12071
+ );
12072
+ process.exitCode = 1;
12073
+ return null;
12074
+ }
12075
+ const msg = e instanceof Error ? e.message : String(e);
12076
+ console.error(`[AgentInspect] failed to load ${PACKAGE}: ${msg}`);
12077
+ process.exitCode = 1;
12078
+ return null;
12079
+ }
12080
+ }
12081
+ function parsePositiveInt(raw, flag) {
12082
+ if (raw === void 0 || raw.trim() === "") return void 0;
12083
+ const parsed = Number.parseInt(raw, 10);
12084
+ if (!Number.isFinite(parsed) || parsed <= 0) {
12085
+ throw new Error(`${flag} must be a positive integer.`);
12086
+ }
12087
+ return parsed;
12088
+ }
12089
+ async function newestTraceMtimeMs(traceDir) {
12090
+ let newest = 0;
12091
+ try {
12092
+ const files = await readdir(traceDir);
12093
+ for (const file of files) {
12094
+ if (!file.endsWith(".jsonl")) continue;
12095
+ try {
12096
+ const s = await stat(path10.join(traceDir, file));
12097
+ if (s.mtimeMs > newest) newest = s.mtimeMs;
12098
+ } catch {
12099
+ }
12100
+ }
12101
+ } catch {
12102
+ }
12103
+ return newest;
12104
+ }
12105
+ async function indexSqliteBuildCommand(options = {}) {
12106
+ const mod = await loadIndexSqlite();
12107
+ if (!mod) return;
12108
+ const result = await mod.buildIndex({
12109
+ traceDir: options.dir,
12110
+ maxRuns: parsePositiveInt(options.maxRuns, "--max-runs")
12111
+ });
12112
+ if (options.json) {
12113
+ console.log(JSON.stringify({ ok: true, ...result }, null, 2));
12114
+ return;
12115
+ }
12116
+ console.log(`Built SQLite index: ${result.dbPath}`);
12117
+ console.log(`Runs: ${result.runs} Steps: ${result.steps} Errors: ${result.errors}`);
12118
+ for (const warning of result.warnings) console.log(`warning: ${warning}`);
12119
+ }
12120
+ async function indexSqliteStatusCommand(options = {}) {
12121
+ const mod = await loadIndexSqlite();
12122
+ if (!mod) return;
12123
+ const traceDir = resolveTraceDir({ dir: options.dir });
12124
+ const dbPath = mod.resolveIndexDbPath(traceDir);
12125
+ const status = mod.indexStatus(dbPath);
12126
+ const stale = mod.isIndexStale(dbPath, await newestTraceMtimeMs(traceDir));
12127
+ if (options.json) {
12128
+ console.log(JSON.stringify({ ok: true, traceDir, stale, ...status }, null, 2));
12129
+ return;
12130
+ }
12131
+ if (!status.exists) {
12132
+ console.log(`No SQLite index at ${dbPath}`);
12133
+ console.log("Run: agent-inspect index sqlite build");
12134
+ return;
12135
+ }
12136
+ console.log(`Index: ${status.dbPath}`);
12137
+ console.log(`Healthy: ${status.healthy ? "yes" : "no"}`);
12138
+ console.log(`Built: ${status.builtAt ?? "unknown"}`);
12139
+ console.log(`Runs: ${status.runs} Steps: ${status.steps}`);
12140
+ console.log(`Stale: ${stale ? "yes" : "no"}`);
12141
+ }
12142
+ async function indexSqliteQueryCommand(options = {}) {
12143
+ const mod = await loadIndexSqlite();
12144
+ if (!mod) return;
12145
+ const traceDir = resolveTraceDir({ dir: options.dir });
12146
+ const dbPath = mod.resolveIndexDbPath(traceDir);
12147
+ const status = mod.indexStatus(dbPath);
12148
+ if (!status.exists || !status.healthy) {
12149
+ if (options.json) {
12150
+ console.log(JSON.stringify({ ok: false, reason: "index-missing", dbPath }, null, 2));
12151
+ } else {
12152
+ console.log("No usable SQLite index. Run: agent-inspect index sqlite build");
12153
+ }
12154
+ process.exitCode = 1;
12155
+ return;
12156
+ }
12157
+ const rows = mod.queryRuns(dbPath, {
12158
+ status: options.status,
12159
+ sessionId: options.session,
12160
+ name: options.name,
12161
+ kind: options.kind,
12162
+ tool: options.tool,
12163
+ limit: parsePositiveInt(options.limit, "--limit")
12164
+ });
12165
+ if (options.json) {
12166
+ console.log(JSON.stringify({ ok: true, count: rows.length, runs: rows }, null, 2));
12167
+ return;
12168
+ }
12169
+ if (rows.length === 0) {
12170
+ console.log("No matching runs.");
12171
+ return;
12172
+ }
12173
+ for (const run of rows) {
12174
+ const parts = [
12175
+ run.runId,
12176
+ run.status ?? "unknown",
12177
+ run.name ?? "",
12178
+ run.durationMs != null ? `${run.durationMs}ms` : ""
12179
+ ].filter((p) => p !== "");
12180
+ console.log(parts.join(" "));
12181
+ }
12182
+ }
12183
+ async function indexSqliteCleanCommand(options = {}) {
12184
+ const mod = await loadIndexSqlite();
12185
+ if (!mod) return;
12186
+ const traceDir = resolveTraceDir({ dir: options.dir });
12187
+ const dbPath = mod.resolveIndexDbPath(traceDir);
12188
+ await mod.cleanIndex(dbPath);
12189
+ if (options.json) {
12190
+ console.log(JSON.stringify({ ok: true, removed: dbPath }, null, 2));
12191
+ return;
12192
+ }
12193
+ console.log(`Removed SQLite index: ${dbPath}`);
12194
+ }
15250
12195
 
15251
12196
  // packages/core/src/workspace/types.ts
15252
12197
  var WORKSPACE_SCHEMA_VERSION = "1.0";
@@ -15427,19 +12372,19 @@ function serializeWorkspaceManifest(manifest) {
15427
12372
  }
15428
12373
  var INDEX_DIR_NAME = "index";
15429
12374
  function resolveWorkspaceLocation(cwd = process.cwd()) {
15430
- const projectRoot = path14.resolve(cwd);
15431
- const workspaceDir = path14.join(projectRoot, WORKSPACE_DIR_NAME);
12375
+ const projectRoot = path10.resolve(cwd);
12376
+ const workspaceDir = path10.join(projectRoot, WORKSPACE_DIR_NAME);
15432
12377
  return {
15433
12378
  projectRoot,
15434
12379
  workspaceDir,
15435
- manifestPath: path14.join(workspaceDir, WORKSPACE_MANIFEST_FILENAME)
12380
+ manifestPath: path10.join(workspaceDir, WORKSPACE_MANIFEST_FILENAME)
15436
12381
  };
15437
12382
  }
15438
12383
  function resolveInsideWorkspace(workspaceDir, relative) {
15439
- const base = path14.resolve(workspaceDir);
15440
- const resolved = path14.resolve(base, relative);
15441
- const rel = path14.relative(base, resolved);
15442
- if (rel === "" || rel === "." || !rel.startsWith("..") && !path14.isAbsolute(rel)) {
12384
+ const base = path10.resolve(workspaceDir);
12385
+ const resolved = path10.resolve(base, relative);
12386
+ const rel = path10.relative(base, resolved);
12387
+ if (rel === "" || rel === "." || !rel.startsWith("..") && !path10.isAbsolute(rel)) {
15443
12388
  return resolved;
15444
12389
  }
15445
12390
  throw new Error(
@@ -15508,7 +12453,7 @@ async function createWorkspace(options = {}) {
15508
12453
  created = false;
15509
12454
  adopted = true;
15510
12455
  } else {
15511
- const project = options.project?.trim() || path14.basename(location.projectRoot) || "workspace";
12456
+ const project = options.project?.trim() || path10.basename(location.projectRoot) || "workspace";
15512
12457
  const traceDirs = detectedExistingTraces ? ["runs", "."] : ["runs"];
15513
12458
  manifest = createDefaultWorkspaceManifest({
15514
12459
  project,
@@ -15647,7 +12592,7 @@ async function doctorWorkspace(location) {
15647
12592
  const abs = resolveInsideWorkspace(location.workspaceDir, rel);
15648
12593
  for (const file of await listJsonl(abs)) {
15649
12594
  try {
15650
- const s = await stat(path14.join(abs, file));
12595
+ const s = await stat(path10.join(abs, file));
15651
12596
  newestTraceMtime = Math.max(newestTraceMtime, s.mtimeMs);
15652
12597
  } catch {
15653
12598
  checks2.push({ id: "trace-readability", status: "warn", message: `cannot stat ${rel}/${file}` });
@@ -15695,7 +12640,7 @@ async function cleanWorkspace(location, manifest, options = {}) {
15695
12640
  const relPath = `${rel}/${entry}`;
15696
12641
  removed.push(relPath);
15697
12642
  if (!dryRun) {
15698
- await rm(path14.join(abs, entry), { recursive: true, force: true });
12643
+ await rm(path10.join(abs, entry), { recursive: true, force: true });
15699
12644
  }
15700
12645
  }
15701
12646
  }
@@ -16181,6 +13126,31 @@ function createCliProgram() {
16181
13126
  indexCmd.command("clean").description("Remove the local index file").option("--dir <path>", "trace directory").option("--json", "print JSON result").action((opts) => {
16182
13127
  runCommand(() => indexCleanCommand(opts));
16183
13128
  });
13129
+ const sqliteCmd = indexCmd.command("sqlite").description(
13130
+ "Optional SQLite-backed trace index (requires @agent-inspect/index-sqlite)"
13131
+ );
13132
+ sqliteCmd.command("build").description("Build or rebuild the local SQLite index").option("--dir <path>", "trace directory").option("--max-runs <n>", "cap indexed trace files (default 10000)").option("--json", "print JSON result").action((opts) => {
13133
+ runCommand(() => indexSqliteBuildCommand(opts));
13134
+ });
13135
+ sqliteCmd.command("rebuild").description("Alias for build (full, idempotent rebuild)").option("--dir <path>", "trace directory").option("--max-runs <n>", "cap indexed trace files (default 10000)").option("--json", "print JSON result").action((opts) => {
13136
+ runCommand(() => indexSqliteBuildCommand(opts));
13137
+ });
13138
+ sqliteCmd.command("status").description("Show SQLite index health, counts, and staleness").option("--dir <path>", "trace directory").option("--json", "print JSON result").action((opts) => {
13139
+ runCommand(() => indexSqliteStatusCommand(opts));
13140
+ });
13141
+ sqliteCmd.command("query").description("Query indexed runs (fast; falls back with a hint if absent)").option("--dir <path>", "trace directory").addOption(
13142
+ new Option("--status <status>", "filter by run status").choices([
13143
+ "success",
13144
+ "error",
13145
+ "running",
13146
+ "unknown"
13147
+ ])
13148
+ ).option("--session <id>", "filter by session id").option("--name <query>", "substring match on run name").option("--kind <kind>", "match runs containing a step of this kind").option("--tool <query>", "match runs containing a tool step (substring)").option("--limit <n>", "max results (default 100)").option("--json", "print JSON result").action((opts) => {
13149
+ runCommand(() => indexSqliteQueryCommand(opts));
13150
+ });
13151
+ sqliteCmd.command("clean").description("Remove the SQLite index (traces are never touched)").option("--dir <path>", "trace directory").option("--json", "print JSON result").action((opts) => {
13152
+ runCommand(() => indexSqliteCleanCommand(opts));
13153
+ });
16184
13154
  const workspaceCmd = program.command("workspace").description("Manage a project-local AgentInspect workspace (.agent-inspect)");
16185
13155
  workspaceCmd.command("init").description("Create or adopt a local workspace (never deletes traces)").option("--project <name>", "project name (default: directory name)").addOption(
16186
13156
  new Option("--redaction-profile <profile>", "default redaction posture").choices([
@@ -16210,9 +13180,9 @@ function isPrimaryModule() {
16210
13180
  if (!entry) return false;
16211
13181
  const selfPath = fileURLToPath(import.meta.url);
16212
13182
  try {
16213
- return realpathSync(path14.resolve(entry)) === realpathSync(path14.resolve(selfPath));
13183
+ return realpathSync(path10.resolve(entry)) === realpathSync(path10.resolve(selfPath));
16214
13184
  } catch {
16215
- return path14.resolve(entry) === path14.resolve(selfPath);
13185
+ return path10.resolve(entry) === path10.resolve(selfPath);
16216
13186
  }
16217
13187
  }
16218
13188
  if (isPrimaryModule()) {