agent-inspect 4.1.0 → 4.2.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.
@@ -4,7 +4,7 @@
4
4
  var crypto = require('crypto');
5
5
  var promises = require('fs/promises');
6
6
  var os = require('os');
7
- var path14 = require('path');
7
+ var path16 = require('path');
8
8
  var async_hooks = require('async_hooks');
9
9
  var process3 = require('process');
10
10
  var tty = require('tty');
@@ -20,7 +20,7 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
20
20
 
21
21
  var crypto__default = /*#__PURE__*/_interopDefault(crypto);
22
22
  var os__default = /*#__PURE__*/_interopDefault(os);
23
- var path14__default = /*#__PURE__*/_interopDefault(path14);
23
+ var path16__default = /*#__PURE__*/_interopDefault(path16);
24
24
  var process3__default = /*#__PURE__*/_interopDefault(process3);
25
25
  var tty__default = /*#__PURE__*/_interopDefault(tty);
26
26
 
@@ -859,7 +859,7 @@ function getDefaultTraceDir() {
859
859
  if (typeof home !== "string" || home.trim() === "") {
860
860
  return FALLBACK_TRACE_DIR;
861
861
  }
862
- return path14__default.default.join(home, DEFAULT_TRACE_DIR_NAME, RUNS_DIR_NAME);
862
+ return path16__default.default.join(home, DEFAULT_TRACE_DIR_NAME, RUNS_DIR_NAME);
863
863
  } catch {
864
864
  return FALLBACK_TRACE_DIR;
865
865
  }
@@ -867,11 +867,11 @@ function getDefaultTraceDir() {
867
867
  function getTraceFilePath(runId, traceDir) {
868
868
  const baseDir = traceDir ?? getDefaultTraceDir();
869
869
  let safeId = typeof runId === "string" && runId.trim() !== "" ? runId.trim() : "run_unknown";
870
- safeId = path14__default.default.basename(safeId);
870
+ safeId = path16__default.default.basename(safeId);
871
871
  if (safeId === "" || safeId === "." || safeId === "..") {
872
872
  safeId = "run_unknown";
873
873
  }
874
- return path14__default.default.join(baseDir, `${safeId}.jsonl`);
874
+ return path16__default.default.join(baseDir, `${safeId}.jsonl`);
875
875
  }
876
876
  function formatError(error) {
877
877
  if (error instanceof Error) {
@@ -928,7 +928,7 @@ var init_utils = __esm({
928
928
  init_duration();
929
929
  DEFAULT_TRACE_DIR_NAME = ".agent-inspect";
930
930
  RUNS_DIR_NAME = "runs";
931
- FALLBACK_TRACE_DIR = path14__default.default.join(
931
+ FALLBACK_TRACE_DIR = path16__default.default.join(
932
932
  os__default.default.tmpdir(),
933
933
  "agent-inspect",
934
934
  RUNS_DIR_NAME
@@ -1723,7 +1723,7 @@ var init_trace_directory = __esm({
1723
1723
  this.#dir = resolveTraceDir(options);
1724
1724
  }
1725
1725
  getPath(filename) {
1726
- return filename ? path14__default.default.join(this.#dir, filename) : this.#dir;
1726
+ return filename ? path16__default.default.join(this.#dir, filename) : this.#dir;
1727
1727
  }
1728
1728
  async list() {
1729
1729
  try {
@@ -1752,7 +1752,7 @@ function parseIsoToMs2(value) {
1752
1752
  }
1753
1753
  async function extractMetadata(filePath, _quickScan) {
1754
1754
  const stats = await promises.stat(filePath);
1755
- let runIdFromFile = path14__default.default.basename(filePath);
1755
+ let runIdFromFile = path16__default.default.basename(filePath);
1756
1756
  if (runIdFromFile.endsWith(".jsonl")) {
1757
1757
  runIdFromFile = runIdFromFile.slice(0, -".jsonl".length);
1758
1758
  }
@@ -2960,6 +2960,262 @@ var init_metadata = __esm({
2960
2960
  }
2961
2961
  });
2962
2962
 
2963
+ // packages/core/src/sessions/status.ts
2964
+ function isExplicitSessionStatus(value) {
2965
+ return typeof value === "string" && EXPLICIT_SESSION_STATUSES.has(value);
2966
+ }
2967
+ function activityMs(run) {
2968
+ return run.endedAt ?? run.startedAt ?? 0;
2969
+ }
2970
+ function latestActivityMs(runs) {
2971
+ let latest = 0;
2972
+ for (const run of runs) {
2973
+ const ms = activityMs(run);
2974
+ if (ms > latest) latest = ms;
2975
+ }
2976
+ return latest;
2977
+ }
2978
+ function earliestStart(runs) {
2979
+ let earliest;
2980
+ for (const run of runs) {
2981
+ if (run.startedAt === void 0) continue;
2982
+ if (earliest === void 0 || run.startedAt < earliest) {
2983
+ earliest = run.startedAt;
2984
+ }
2985
+ }
2986
+ return earliest;
2987
+ }
2988
+ function latestEndWhenAllEnded(runs) {
2989
+ if (runs.length === 0) return void 0;
2990
+ let latest;
2991
+ for (const run of runs) {
2992
+ if (run.endedAt === void 0) return void 0;
2993
+ if (latest === void 0 || run.endedAt > latest) latest = run.endedAt;
2994
+ }
2995
+ return latest;
2996
+ }
2997
+ function pickExplicitStatus(runs) {
2998
+ let best;
2999
+ let bestPriority = 0;
3000
+ for (const run of runs) {
3001
+ const raw = run.metadata?.sessionStatus;
3002
+ if (!isExplicitSessionStatus(raw)) continue;
3003
+ const priority = EXPLICIT_STATUS_PRIORITY[raw] ?? 0;
3004
+ if (priority > bestPriority) {
3005
+ bestPriority = priority;
3006
+ best = raw;
3007
+ }
3008
+ }
3009
+ return best;
3010
+ }
3011
+ function deriveLastError(runs) {
3012
+ const errorRuns = runs.filter((run) => run.status === "error").sort((a, b) => activityMs(b) - activityMs(a));
3013
+ const latest = errorRuns[0];
3014
+ if (!latest) return void 0;
3015
+ const meta2 = latest.metadata ?? {};
3016
+ const message = typeof meta2.errorMessage === "string" && meta2.errorMessage.trim() !== "" ? meta2.errorMessage.trim() : latest.name ?? latest.runId;
3017
+ const code = typeof meta2.errorCode === "string" && meta2.errorCode.trim() !== "" ? meta2.errorCode.trim() : void 0;
3018
+ return { runId: latest.runId, message, code };
3019
+ }
3020
+ function deriveCheckSummary(runs) {
3021
+ let pass2 = 0;
3022
+ let fail4 = 0;
3023
+ let warn2 = 0;
3024
+ let found = false;
3025
+ for (const run of runs) {
3026
+ const summary = run.metadata?.checkSummary;
3027
+ if (!summary || typeof summary !== "object") continue;
3028
+ const record = summary;
3029
+ if (typeof record.pass === "number") {
3030
+ pass2 += record.pass;
3031
+ found = true;
3032
+ }
3033
+ if (typeof record.fail === "number") {
3034
+ fail4 += record.fail;
3035
+ found = true;
3036
+ }
3037
+ if (typeof record.warn === "number") {
3038
+ warn2 += record.warn;
3039
+ found = true;
3040
+ }
3041
+ }
3042
+ return found ? { pass: pass2, fail: fail4, warn: warn2 } : void 0;
3043
+ }
3044
+ function deriveObservationSummary(runs) {
3045
+ for (const run of [...runs].sort((a, b) => activityMs(b) - activityMs(a))) {
3046
+ const value = run.metadata?.observationSummary;
3047
+ if (typeof value === "string" && value.trim() !== "") {
3048
+ return value.trim();
3049
+ }
3050
+ }
3051
+ return void 0;
3052
+ }
3053
+ function deriveSessionStatus(runs, options = {}) {
3054
+ if (runs.length === 0) return "unknown";
3055
+ if (runs.some((run) => run.status === "running")) return "running";
3056
+ const explicit = pickExplicitStatus(runs);
3057
+ if (explicit && explicit !== "running") return explicit;
3058
+ if (runs.some((run) => run.status === "error")) return "error";
3059
+ if (runs.every((run) => run.status === "success")) return "completed";
3060
+ const nowMs = options.nowMs ?? Date.now();
3061
+ const staleThresholdMs = options.staleThresholdMs ?? DEFAULT_STALE_THRESHOLD_MS;
3062
+ const lastMs = latestActivityMs(runs);
3063
+ if (lastMs > 0 && nowMs - lastMs > staleThresholdMs) return "stale";
3064
+ return "unknown";
3065
+ }
3066
+ function enrichSessionSummary(summary, runs, options = {}) {
3067
+ const sessionRuns = runs.filter((run) => summary.runIds.includes(run.runId)).sort((a, b) => a.runId.localeCompare(b.runId));
3068
+ const startedAt = earliestStart(sessionRuns);
3069
+ const endedAt = latestEndWhenAllEnded(sessionRuns);
3070
+ const durationMs2 = startedAt !== void 0 && endedAt !== void 0 ? endedAt - startedAt : void 0;
3071
+ let correlationId;
3072
+ let jobId;
3073
+ let workflowId;
3074
+ for (const run of sessionRuns) {
3075
+ const meta2 = extractSessionWorkflowMetadata(run.metadata);
3076
+ if (!correlationId && meta2?.correlationId) correlationId = meta2.correlationId;
3077
+ if (!jobId && meta2?.jobId) jobId = meta2.jobId;
3078
+ if (!workflowId && meta2?.workflowName) workflowId = meta2.workflowName;
3079
+ else if (!workflowId && meta2?.workflowStep) workflowId = meta2.workflowStep;
3080
+ }
3081
+ const lastMs = latestActivityMs(sessionRuns);
3082
+ const lastActivity = lastMs > 0 ? new Date(lastMs).toISOString() : (/* @__PURE__ */ new Date(0)).toISOString();
3083
+ const retryCount2 = summary.retries.filter(
3084
+ (retry) => retry.retryOf !== void 0 || (retry.attempt ?? 0) > 1
3085
+ ).length;
3086
+ return {
3087
+ ...summary,
3088
+ status: deriveSessionStatus(sessionRuns, options),
3089
+ startedAt,
3090
+ endedAt,
3091
+ durationMs: durationMs2,
3092
+ correlationId,
3093
+ jobId,
3094
+ workflowId,
3095
+ lastError: deriveLastError(sessionRuns),
3096
+ lastActivity,
3097
+ retryCount: retryCount2,
3098
+ observationSummary: deriveObservationSummary(sessionRuns),
3099
+ checkSummary: deriveCheckSummary(sessionRuns)
3100
+ };
3101
+ }
3102
+ var DEFAULT_STALE_THRESHOLD_MS, EXPLICIT_STATUS_PRIORITY, EXPLICIT_SESSION_STATUSES;
3103
+ var init_status = __esm({
3104
+ "packages/core/src/sessions/status.ts"() {
3105
+ init_metadata();
3106
+ DEFAULT_STALE_THRESHOLD_MS = 864e5;
3107
+ EXPLICIT_STATUS_PRIORITY = {
3108
+ error: 5,
3109
+ waiting_input: 4,
3110
+ idle: 3,
3111
+ stale: 2,
3112
+ completed: 1
3113
+ };
3114
+ EXPLICIT_SESSION_STATUSES = /* @__PURE__ */ new Set([
3115
+ "running",
3116
+ "waiting_input",
3117
+ "idle",
3118
+ "completed",
3119
+ "error",
3120
+ "stale",
3121
+ "unknown"
3122
+ ]);
3123
+ }
3124
+ });
3125
+
3126
+ // packages/core/src/sessions/activity.ts
3127
+ function statusLine(session) {
3128
+ const name = session.workflowId ?? session.correlationId ?? session.sessionId;
3129
+ const status = session.status;
3130
+ if (session.lastError) {
3131
+ return `${name} session ${session.sessionId} failed at ${session.lastError.message}`;
3132
+ }
3133
+ if (session.observationSummary) {
3134
+ return `${name} session ${session.sessionId} ${status} with observation warning`;
3135
+ }
3136
+ return `${name} session ${session.sessionId} ${status}`;
3137
+ }
3138
+ function parseSinceMs(since, nowMs) {
3139
+ if (!since || since.trim() === "") return nowMs - 7 * 864e5;
3140
+ const trimmed = since.trim().toLowerCase();
3141
+ const match = /^(\d+)([smhd])$/.exec(trimmed);
3142
+ if (!match) return nowMs - 7 * 864e5;
3143
+ const amount = Number.parseInt(match[1], 10);
3144
+ const unit = match[2];
3145
+ const mult = unit === "s" ? 1e3 : unit === "m" ? 6e4 : unit === "h" ? 36e5 : 864e5;
3146
+ return nowMs - amount * mult;
3147
+ }
3148
+ function isFailed(status) {
3149
+ return status === "error";
3150
+ }
3151
+ function isStale(status) {
3152
+ return status === "stale";
3153
+ }
3154
+ function guardrailWarnings(session) {
3155
+ const summary = session.checkSummary;
3156
+ if (!summary) return 0;
3157
+ return summary.warn;
3158
+ }
3159
+ function buildActivitySummary(index, options = {}) {
3160
+ const nowMs = options.nowMs ?? Date.now();
3161
+ const sinceMs = parseSinceMs(options.since, nowMs);
3162
+ const sinceIso = new Date(sinceMs).toISOString();
3163
+ const limit = Number.isInteger(options.limit) && options.limit > 0 ? options.limit : 20;
3164
+ const inWindow = index.sessions.filter((session) => {
3165
+ const activityMs2 = Date.parse(session.lastActivity);
3166
+ return Number.isFinite(activityMs2) && activityMs2 >= sinceMs;
3167
+ });
3168
+ const entries = [...inWindow].sort((a, b) => Date.parse(b.lastActivity) - Date.parse(a.lastActivity)).slice(0, limit).map((session) => ({
3169
+ sessionId: session.sessionId,
3170
+ status: session.status,
3171
+ summary: statusLine(session),
3172
+ lastActivity: session.lastActivity,
3173
+ runCount: session.runIds.length
3174
+ }));
3175
+ let failed = 0;
3176
+ let stale = 0;
3177
+ let guardrailWarningTotal = 0;
3178
+ for (const session of inWindow) {
3179
+ if (isFailed(session.status)) failed += 1;
3180
+ if (isStale(session.status)) stale += 1;
3181
+ guardrailWarningTotal += guardrailWarnings(session);
3182
+ }
3183
+ return {
3184
+ since: sinceIso,
3185
+ sessions: inWindow.length,
3186
+ failed,
3187
+ stale,
3188
+ guardrailWarnings: guardrailWarningTotal,
3189
+ entries
3190
+ };
3191
+ }
3192
+ function renderActivitySummaryHuman(summary) {
3193
+ const lines = [];
3194
+ const todayStart = /* @__PURE__ */ new Date();
3195
+ todayStart.setHours(0, 0, 0, 0);
3196
+ const todayMs = todayStart.getTime();
3197
+ const today = summary.entries.filter(
3198
+ (entry) => Date.parse(entry.lastActivity) >= todayMs
3199
+ );
3200
+ if (today.length > 0) {
3201
+ lines.push("Today");
3202
+ for (const entry of today) {
3203
+ lines.push(` ${entry.summary}`);
3204
+ }
3205
+ lines.push("");
3206
+ }
3207
+ lines.push(`Since ${summary.since}`);
3208
+ lines.push(` ${summary.sessions} sessions`);
3209
+ lines.push(` ${summary.failed} failed`);
3210
+ lines.push(` ${summary.stale} stale`);
3211
+ lines.push(` ${summary.guardrailWarnings} guardrail warnings`);
3212
+ return lines.join("\n");
3213
+ }
3214
+ var init_activity = __esm({
3215
+ "packages/core/src/sessions/activity.ts"() {
3216
+ }
3217
+ });
3218
+
2963
3219
  // packages/core/src/sessions/types.ts
2964
3220
  var init_types2 = __esm({
2965
3221
  "packages/core/src/sessions/types.ts"() {
@@ -3306,12 +3562,12 @@ function buildCriticalPath(runs, handoffs) {
3306
3562
  handoffs.filter((edge) => edge.confidence === "explicit").map((edge) => edge.from)
3307
3563
  );
3308
3564
  const ordered = [...runs].sort(compareRuns);
3309
- const path22 = [];
3565
+ const path23 = [];
3310
3566
  const visited = /* @__PURE__ */ new Set();
3311
3567
  const pushRun = (run, confidence, source) => {
3312
3568
  if (visited.has(run.runId)) return;
3313
3569
  visited.add(run.runId);
3314
- path22.push({
3570
+ path23.push({
3315
3571
  runId: run.runId,
3316
3572
  name: run.name,
3317
3573
  startedAt: run.startedAt,
@@ -3336,7 +3592,7 @@ function buildCriticalPath(runs, handoffs) {
3336
3592
  const confidence = explicitTargets.has(run.runId) || explicitSources.has(run.runId) ? "explicit" : "correlated";
3337
3593
  pushRun(run, confidence, confidence === "explicit" ? "manual" : "inferred");
3338
3594
  }
3339
- return path22;
3595
+ return path23;
3340
3596
  }
3341
3597
  function metaRunIdMatches(run, token, runById) {
3342
3598
  const meta2 = extractSessionWorkflowMetadata(run.metadata);
@@ -3378,14 +3634,21 @@ function buildSessionIndex(inputRuns, options = {}) {
3378
3634
  sessionId
3379
3635
  });
3380
3636
  }
3381
- return {
3382
- sessionId,
3383
- runIds,
3384
- groups,
3385
- handoffs,
3386
- retries,
3387
- criticalPath
3388
- };
3637
+ return enrichSessionSummary(
3638
+ {
3639
+ sessionId,
3640
+ runIds,
3641
+ groups,
3642
+ handoffs,
3643
+ retries,
3644
+ criticalPath
3645
+ },
3646
+ runs,
3647
+ {
3648
+ nowMs: options.nowMs,
3649
+ staleThresholdMs: options.staleThresholdMs
3650
+ }
3651
+ );
3389
3652
  });
3390
3653
  if (sessions.length === 0 && runs.length > 0) {
3391
3654
  warnings.push({
@@ -3408,7 +3671,10 @@ function buildSessionIndex(inputRuns, options = {}) {
3408
3671
  var init_sessions = __esm({
3409
3672
  "packages/core/src/sessions/index.ts"() {
3410
3673
  init_metadata();
3674
+ init_status();
3411
3675
  init_metadata();
3676
+ init_status();
3677
+ init_activity();
3412
3678
  init_types2();
3413
3679
  init_load();
3414
3680
  init_scope();
@@ -3573,19 +3839,19 @@ var require_file_uri_to_path = __commonJS({
3573
3839
  var rest = decodeURI(uri.substring(7));
3574
3840
  var firstSlash = rest.indexOf("/");
3575
3841
  var host = rest.substring(0, firstSlash);
3576
- var path22 = rest.substring(firstSlash + 1);
3842
+ var path23 = rest.substring(firstSlash + 1);
3577
3843
  if ("localhost" == host) host = "";
3578
3844
  if (host) {
3579
3845
  host = sep + sep + host;
3580
3846
  }
3581
- path22 = path22.replace(/^(.+)\|/, "$1:");
3847
+ path23 = path23.replace(/^(.+)\|/, "$1:");
3582
3848
  if (sep == "\\") {
3583
- path22 = path22.replace(/\//g, "\\");
3849
+ path23 = path23.replace(/\//g, "\\");
3584
3850
  }
3585
- if (/^.+\:/.test(path22)) ; else {
3586
- path22 = sep + path22;
3851
+ if (/^.+\:/.test(path23)) ; else {
3852
+ path23 = sep + path23;
3587
3853
  }
3588
- return host + path22;
3854
+ return host + path23;
3589
3855
  }
3590
3856
  }
3591
3857
  });
@@ -3594,18 +3860,18 @@ var require_file_uri_to_path = __commonJS({
3594
3860
  var require_bindings = __commonJS({
3595
3861
  "node_modules/.pnpm/bindings@1.5.0/node_modules/bindings/bindings.js"(exports$1, module) {
3596
3862
  var fs = __require("fs");
3597
- var path22 = __require("path");
3863
+ var path23 = __require("path");
3598
3864
  var fileURLToPath2 = require_file_uri_to_path();
3599
- var join = path22.join;
3600
- var dirname = path22.dirname;
3601
- var exists = fs.accessSync && function(path23) {
3865
+ var join = path23.join;
3866
+ var dirname = path23.dirname;
3867
+ var exists = fs.accessSync && function(path24) {
3602
3868
  try {
3603
- fs.accessSync(path23);
3869
+ fs.accessSync(path24);
3604
3870
  } catch (e) {
3605
3871
  return false;
3606
3872
  }
3607
3873
  return true;
3608
- } || fs.existsSync || path22.existsSync;
3874
+ } || fs.existsSync || path23.existsSync;
3609
3875
  var defaults = {
3610
3876
  arrow: process.env.NODE_BINDINGS_ARROW || " \u2192 ",
3611
3877
  compiled: process.env.NODE_BINDINGS_COMPILED_DIR || "compiled",
@@ -3650,7 +3916,7 @@ var require_bindings = __commonJS({
3650
3916
  if (!opts.module_root) {
3651
3917
  opts.module_root = exports$1.getRoot(exports$1.getFileName());
3652
3918
  }
3653
- if (path22.extname(opts.bindings) != ".node") {
3919
+ if (path23.extname(opts.bindings) != ".node") {
3654
3920
  opts.bindings += ".node";
3655
3921
  }
3656
3922
  var requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
@@ -3885,7 +4151,7 @@ var require_pragma = __commonJS({
3885
4151
  var require_backup = __commonJS({
3886
4152
  "node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/backup.js"(exports$1, module) {
3887
4153
  var fs = __require("fs");
3888
- var path22 = __require("path");
4154
+ var path23 = __require("path");
3889
4155
  var { promisify } = __require("util");
3890
4156
  var { cppdb } = require_util();
3891
4157
  var fsAccess = promisify(fs.access);
@@ -3901,7 +4167,7 @@ var require_backup = __commonJS({
3901
4167
  if (typeof attachedName !== "string") throw new TypeError('Expected the "attached" option to be a string');
3902
4168
  if (!attachedName) throw new TypeError('The "attached" option cannot be an empty string');
3903
4169
  if (handler != null && typeof handler !== "function") throw new TypeError('Expected the "progress" option to be a function');
3904
- await fsAccess(path22.dirname(filename)).catch(() => {
4170
+ await fsAccess(path23.dirname(filename)).catch(() => {
3905
4171
  throw new TypeError("Cannot save backup because the directory does not exist");
3906
4172
  });
3907
4173
  const isNewFile = await fsAccess(filename).then(() => false, () => true);
@@ -4201,7 +4467,7 @@ var require_inspect = __commonJS({
4201
4467
  var require_database = __commonJS({
4202
4468
  "node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/database.js"(exports$1, module) {
4203
4469
  var fs = __require("fs");
4204
- var path22 = __require("path");
4470
+ var path23 = __require("path");
4205
4471
  var util = require_util();
4206
4472
  var SqliteError = require_sqlite_error();
4207
4473
  var DEFAULT_ADDON;
@@ -4237,7 +4503,7 @@ var require_database = __commonJS({
4237
4503
  addon = DEFAULT_ADDON || (DEFAULT_ADDON = require_bindings()("better_sqlite3.node"));
4238
4504
  } else if (typeof nativeBinding === "string") {
4239
4505
  const requireFunc = typeof __non_webpack_require__ === "function" ? __non_webpack_require__ : __require;
4240
- addon = requireFunc(path22.resolve(nativeBinding).replace(/(\.node)?$/, ".node"));
4506
+ addon = requireFunc(path23.resolve(nativeBinding).replace(/(\.node)?$/, ".node"));
4241
4507
  } else {
4242
4508
  addon = nativeBinding;
4243
4509
  }
@@ -4245,7 +4511,7 @@ var require_database = __commonJS({
4245
4511
  addon.setErrorConstructor(SqliteError);
4246
4512
  addon.isInitialized = true;
4247
4513
  }
4248
- if (!anonymous && !fs.existsSync(path22.dirname(filename))) {
4514
+ if (!anonymous && !fs.existsSync(path23.dirname(filename))) {
4249
4515
  throw new TypeError("Cannot open database because the directory does not exist");
4250
4516
  }
4251
4517
  Object.defineProperties(this, {
@@ -4372,8 +4638,8 @@ GROUP BY session_id;
4372
4638
  }
4373
4639
  });
4374
4640
  function resolveIndexDbPath(traceDir, dbPath) {
4375
- if (dbPath && dbPath.trim() !== "") return path14__default.default.resolve(dbPath);
4376
- return path14__default.default.join(path14__default.default.resolve(traceDir), INDEX_DB_FILENAME);
4641
+ if (dbPath && dbPath.trim() !== "") return path16__default.default.resolve(dbPath);
4642
+ return path16__default.default.join(path16__default.default.resolve(traceDir), INDEX_DB_FILENAME);
4377
4643
  }
4378
4644
  function str(value) {
4379
4645
  return typeof value === "string" && value !== "" ? value : null;
@@ -4465,7 +4731,7 @@ async function buildIndex(options = {}) {
4465
4731
  warnings.push(`index.unreadable: ${file}`);
4466
4732
  }
4467
4733
  }
4468
- await promises.mkdir(path14__default.default.dirname(dbPath), { recursive: true });
4734
+ await promises.mkdir(path16__default.default.dirname(dbPath), { recursive: true });
4469
4735
  await promises.rm(dbPath, { force: true });
4470
4736
  const db = new import_better_sqlite3.default(dbPath);
4471
4737
  let runCount = 0;
@@ -4608,7 +4874,7 @@ function indexStatus(dbPath) {
4608
4874
  db.close();
4609
4875
  }
4610
4876
  }
4611
- function isIndexStale(dbPath, newestTraceMtimeMs2) {
4877
+ function isIndexStale(dbPath, newestTraceMtimeMs3) {
4612
4878
  const opened = openHealthy(dbPath);
4613
4879
  if (!opened) return true;
4614
4880
  try {
@@ -4616,7 +4882,7 @@ function isIndexStale(dbPath, newestTraceMtimeMs2) {
4616
4882
  if (!builtAt) return true;
4617
4883
  const builtMs = Date.parse(builtAt);
4618
4884
  if (Number.isNaN(builtMs)) return true;
4619
- return newestTraceMtimeMs2 > builtMs;
4885
+ return newestTraceMtimeMs3 > builtMs;
4620
4886
  } finally {
4621
4887
  opened.db.close();
4622
4888
  }
@@ -4703,7 +4969,7 @@ var init_src = __esm({
4703
4969
  });
4704
4970
 
4705
4971
  // package.json
4706
- var version = "4.1.0";
4972
+ var version = "4.2.0";
4707
4973
 
4708
4974
  // packages/cli/src/list.ts
4709
4975
  init_advanced();
@@ -5612,7 +5878,7 @@ function findReaderByFormat(format, readers) {
5612
5878
  }
5613
5879
  async function jsonlFilesInDirectory(dirPath) {
5614
5880
  const entries = await promises.readdir(dirPath, { withFileTypes: true });
5615
- return entries.filter((entry) => entry.isFile() && entry.name.endsWith(".jsonl")).map((entry) => path14__default.default.join(dirPath, entry.name)).sort((a, b) => a.localeCompare(b));
5881
+ return entries.filter((entry) => entry.isFile() && entry.name.endsWith(".jsonl")).map((entry) => path16__default.default.join(dirPath, entry.name)).sort((a, b) => a.localeCompare(b));
5616
5882
  }
5617
5883
  async function resolveInput(input3) {
5618
5884
  const cached = resolvedInputCache.get(input3);
@@ -9754,9 +10020,9 @@ Trace directory: ${traceDir}`);
9754
10020
  if (validation !== void 0 && !validation.ok) {
9755
10021
  process.exitCode = 1;
9756
10022
  }
9757
- const outPath = options.output !== void 0 && options.output.trim() !== "" ? path14__default.default.resolve(options.output.trim()) : void 0;
10023
+ const outPath = options.output !== void 0 && options.output.trim() !== "" ? path16__default.default.resolve(options.output.trim()) : void 0;
9758
10024
  if (outPath !== void 0) {
9759
- await promises.mkdir(path14__default.default.dirname(outPath), { recursive: true });
10025
+ await promises.mkdir(path16__default.default.dirname(outPath), { recursive: true });
9760
10026
  await promises.writeFile(outPath, result.content, "utf-8");
9761
10027
  const vlabel = validation !== void 0 ? validation.ok ? "ok" : "failed" : "skipped";
9762
10028
  console.log(`Wrote ${result.fileExtension} export to ${outPath} (validation: ${vlabel})`);
@@ -9936,13 +10202,13 @@ function pairSteps(left, right) {
9936
10202
  return pairs;
9937
10203
  }
9938
10204
  function compareLeafSteps(L, R, segments, opts, out) {
9939
- const path22 = buildPath(segments);
10205
+ const path23 = buildPath(segments);
9940
10206
  if (L.name !== R.name) {
9941
10207
  out.push({
9942
10208
  kind: "structure",
9943
10209
  severity: "warning",
9944
10210
  message: "Step name differs",
9945
- path: path22,
10211
+ path: path23,
9946
10212
  left: L.name,
9947
10213
  right: R.name
9948
10214
  });
@@ -9952,7 +10218,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
9952
10218
  kind: "step-type",
9953
10219
  severity: "warning",
9954
10220
  message: "Step type differs",
9955
- path: path22,
10221
+ path: path23,
9956
10222
  left: L.type,
9957
10223
  right: R.type
9958
10224
  });
@@ -9962,7 +10228,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
9962
10228
  kind: "step-status",
9963
10229
  severity: "warning",
9964
10230
  message: "Step status differs",
9965
- path: path22,
10231
+ path: path23,
9966
10232
  left: L.status,
9967
10233
  right: R.status
9968
10234
  });
@@ -9974,7 +10240,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
9974
10240
  kind: "error",
9975
10241
  severity: "error",
9976
10242
  message: "Step error message differs",
9977
- path: path22,
10243
+ path: path23,
9978
10244
  left: le || void 0,
9979
10245
  right: re || void 0
9980
10246
  });
@@ -9992,7 +10258,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
9992
10258
  kind: "duration",
9993
10259
  severity: "info",
9994
10260
  message: "Step duration differs",
9995
- path: path22,
10261
+ path: path23,
9996
10262
  left: ld,
9997
10263
  right: rd
9998
10264
  });
@@ -10005,7 +10271,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
10005
10271
  kind: "metadata",
10006
10272
  severity: "info",
10007
10273
  message: "Step metadata differs",
10008
- path: path22,
10274
+ path: path23,
10009
10275
  left: L.metadata,
10010
10276
  right: R.metadata
10011
10277
  });
@@ -10017,7 +10283,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
10017
10283
  kind: "output",
10018
10284
  severity: "info",
10019
10285
  message: "Output preview differs",
10020
- path: path22,
10286
+ path: path23,
10021
10287
  left: L.outputPreview,
10022
10288
  right: R.outputPreview
10023
10289
  });
@@ -10178,11 +10444,11 @@ function diffRuns(left, right, options) {
10178
10444
 
10179
10445
  // packages/core/src/diff/renderer.ts
10180
10446
  init_source();
10181
- function formatPath(path22) {
10182
- if (path22 === void 0 || path22.path.length === 0) {
10447
+ function formatPath(path23) {
10448
+ if (path23 === void 0 || path23.path.length === 0) {
10183
10449
  return "(run)";
10184
10450
  }
10185
- return path22.path.map((s) => s.name).join(" > ");
10451
+ return path23.path.map((s) => s.name).join(" > ");
10186
10452
  }
10187
10453
  function formatValue(v, verbose) {
10188
10454
  if (v === void 0) return "(undefined)";
@@ -10550,7 +10816,31 @@ async function searchCommand(options = {}) {
10550
10816
 
10551
10817
  // packages/cli/src/sessions.ts
10552
10818
  init_advanced();
10553
- async function loadSessionIndex(traceDir, correlateGroup) {
10819
+
10820
+ // packages/cli/src/sessions-load.ts
10821
+ init_advanced();
10822
+ function isModuleNotFound2(e) {
10823
+ return e !== null && typeof e === "object" && "code" in e && (e.code === "ERR_MODULE_NOT_FOUND" || e.code === "MODULE_NOT_FOUND");
10824
+ }
10825
+ function toStatus(raw) {
10826
+ if (raw === "success" || raw === "error" || raw === "running") return raw;
10827
+ return "unknown";
10828
+ }
10829
+ function indexedToMetadata(row, traceDir) {
10830
+ return {
10831
+ runId: row.runId,
10832
+ name: row.name ?? void 0,
10833
+ status: toStatus(row.status),
10834
+ startedAt: row.startedAt ?? void 0,
10835
+ endedAt: row.endedAt ?? void 0,
10836
+ durationMs: row.durationMs ?? void 0,
10837
+ eventCount: 0,
10838
+ filePath: path16__default.default.join(traceDir, row.file),
10839
+ fileSize: 0,
10840
+ createdAt: new Date(row.mtimeMs)
10841
+ };
10842
+ }
10843
+ async function loadFromScan(traceDir) {
10554
10844
  const td = new TraceDirectory({ dir: traceDir });
10555
10845
  const files = await td.list();
10556
10846
  const metas = await loadTraceMetadataList(
@@ -10558,12 +10848,77 @@ async function loadSessionIndex(traceDir, correlateGroup) {
10558
10848
  files,
10559
10849
  (fileName) => td.getPath(fileName)
10560
10850
  );
10561
- const runs = await loadSessionRunRecords(metas);
10562
- return buildSessionIndex(runs, { correlateByGroupId: correlateGroup === true });
10851
+ return loadSessionRunRecords(metas);
10852
+ }
10853
+ async function newestTraceMtimeMs(traceDir) {
10854
+ const td = new TraceDirectory({ dir: traceDir });
10855
+ let newest = 0;
10856
+ for (const file of await td.list()) {
10857
+ try {
10858
+ const stats = await td.getFileStats(file);
10859
+ if (stats.mtimeMs > newest) newest = stats.mtimeMs;
10860
+ } catch {
10861
+ }
10862
+ }
10863
+ return newest;
10864
+ }
10865
+ async function loadSessionRuns(traceDir) {
10866
+ try {
10867
+ const mod = await Promise.resolve().then(() => (init_src(), src_exports));
10868
+ const dbPath = mod.resolveIndexDbPath(traceDir);
10869
+ const status = mod.indexStatus(dbPath);
10870
+ if (!status.healthy) {
10871
+ return { runs: await loadFromScan(traceDir), source: "scan" };
10872
+ }
10873
+ const newest = await newestTraceMtimeMs(traceDir);
10874
+ if (mod.isIndexStale(dbPath, newest)) {
10875
+ return { runs: await loadFromScan(traceDir), source: "scan" };
10876
+ }
10877
+ const indexed = mod.queryRuns(dbPath, { limit: 1e4 });
10878
+ if (indexed.length === 0) {
10879
+ return { runs: await loadFromScan(traceDir), source: "scan" };
10880
+ }
10881
+ const runs = [];
10882
+ for (const row of indexed) {
10883
+ runs.push(await enrichSessionRunRecord(indexedToMetadata(row, traceDir)));
10884
+ }
10885
+ runs.sort((a, b) => (a.startedAt ?? 0) - (b.startedAt ?? 0));
10886
+ return { runs, source: "index" };
10887
+ } catch (e) {
10888
+ if (!isModuleNotFound2(e)) ;
10889
+ return { runs: await loadFromScan(traceDir), source: "scan" };
10890
+ }
10891
+ }
10892
+
10893
+ // packages/cli/src/sessions.ts
10894
+ async function loadSessionIndex(traceDir, options = {}) {
10895
+ const { runs } = await loadSessionRuns(traceDir);
10896
+ const staleThresholdMs = options.staleAfter && options.staleAfter.trim() !== "" ? parseDuration(options.staleAfter.trim()) : void 0;
10897
+ return buildSessionIndex(runs, {
10898
+ correlateByGroupId: options.correlateGroup === true,
10899
+ staleThresholdMs
10900
+ });
10563
10901
  }
10564
10902
  function findSession(index, sessionId) {
10565
10903
  return index.sessions.find((session) => session.sessionId === sessionId);
10566
10904
  }
10905
+ function latestSession(index) {
10906
+ if (index.sessions.length === 0) return void 0;
10907
+ return [...index.sessions].sort(
10908
+ (a, b) => Date.parse(b.lastActivity) - Date.parse(a.lastActivity)
10909
+ )[0];
10910
+ }
10911
+ function parseSinceCutoff(since) {
10912
+ if (!since || since.trim() === "") return void 0;
10913
+ return Date.now() - parseDuration(since.trim());
10914
+ }
10915
+ function sessionsInSinceWindow(index, since) {
10916
+ const cutoff = parseSinceCutoff(since);
10917
+ if (cutoff === void 0) return index.sessions;
10918
+ return index.sessions.filter(
10919
+ (session) => Date.parse(session.lastActivity) >= cutoff
10920
+ );
10921
+ }
10567
10922
  function renderSessionsHuman(index, traceDir) {
10568
10923
  if (index.sessions.length === 0) {
10569
10924
  console.log("No sessions found");
@@ -10577,13 +10932,9 @@ function renderSessionsHuman(index, traceDir) {
10577
10932
  }
10578
10933
  console.log("Sessions:");
10579
10934
  for (const session of index.sessions) {
10580
- const firstRun = index.runs.find(
10581
- (run) => session.runIds.includes(run.runId)
10582
- );
10583
- const workflowName = firstRun?.metadata && typeof firstRun.metadata.workflowName === "string" ? firstRun.metadata.workflowName : void 0;
10584
- const suffix = workflowName ? ` workflow=${workflowName}` : "";
10935
+ const suffix = session.workflowId ? ` workflow=${session.workflowId}` : "";
10585
10936
  console.log(
10586
- ` ${session.sessionId} (${session.runIds.length} run${session.runIds.length === 1 ? "" : "s"})${suffix}`
10937
+ ` ${session.sessionId} [${session.status}] (${session.runIds.length} run${session.runIds.length === 1 ? "" : "s"})${suffix}`
10587
10938
  );
10588
10939
  }
10589
10940
  if (index.unscopedRunIds.length > 0) {
@@ -10595,7 +10946,14 @@ function renderSessionsHuman(index, traceDir) {
10595
10946
  }
10596
10947
  function renderSessionHuman(session, index, options) {
10597
10948
  console.log(`Session: ${session.sessionId}`);
10949
+ console.log(`Status: ${session.status}`);
10598
10950
  console.log(`Runs: ${session.runIds.join(", ")}`);
10951
+ if (session.lastActivity) console.log(`Last activity: ${session.lastActivity}`);
10952
+ if (session.lastError) {
10953
+ console.log(
10954
+ `Last error: ${session.lastError.message} (run ${session.lastError.runId})`
10955
+ );
10956
+ }
10599
10957
  if (session.handoffs.length > 0) {
10600
10958
  console.log("");
10601
10959
  console.log("Handoffs:");
@@ -10640,10 +10998,29 @@ function renderSessionHuman(session, index, options) {
10640
10998
  }
10641
10999
  }
10642
11000
  }
11001
+ function collectHandoffs(index, sessionId) {
11002
+ const sessions = sessionId ? index.sessions.filter((s) => s.sessionId === sessionId) : index.sessions;
11003
+ const out = [];
11004
+ for (const session of sessions) {
11005
+ for (const edge of session.handoffs) {
11006
+ out.push({ ...edge, sessionId: session.sessionId });
11007
+ }
11008
+ }
11009
+ return out.sort((a, b) => {
11010
+ const session = a.sessionId.localeCompare(b.sessionId);
11011
+ if (session !== 0) return session;
11012
+ const from = a.from.localeCompare(b.from);
11013
+ if (from !== 0) return from;
11014
+ return a.to.localeCompare(b.to);
11015
+ });
11016
+ }
10643
11017
  async function sessionsCommand(options = {}) {
10644
11018
  try {
10645
11019
  const traceDir = resolveTraceDir({ dir: options.dir });
10646
- const index = await loadSessionIndex(traceDir, options.correlateGroup);
11020
+ const index = await loadSessionIndex(traceDir, {
11021
+ correlateGroup: options.correlateGroup,
11022
+ staleAfter: options.staleAfter
11023
+ });
10647
11024
  if (options.json) {
10648
11025
  console.log(
10649
11026
  JSON.stringify(
@@ -10666,6 +11043,121 @@ async function sessionsCommand(options = {}) {
10666
11043
  process.exitCode = 1;
10667
11044
  }
10668
11045
  }
11046
+ async function sessionsLatestCommand(options = {}) {
11047
+ try {
11048
+ const traceDir = resolveTraceDir({ dir: options.dir });
11049
+ const index = await loadSessionIndex(traceDir, {
11050
+ correlateGroup: options.correlateGroup,
11051
+ staleAfter: options.staleAfter
11052
+ });
11053
+ const latest = latestSession(index);
11054
+ if (!latest) {
11055
+ if (options.json) {
11056
+ console.log(JSON.stringify({ ok: false, traceDir, reason: "no-sessions" }, null, 2));
11057
+ } else {
11058
+ console.log("No sessions found");
11059
+ console.log(`Trace directory: ${traceDir}`);
11060
+ }
11061
+ process.exitCode = 1;
11062
+ return;
11063
+ }
11064
+ if (options.json) {
11065
+ console.log(JSON.stringify({ ok: true, traceDir, session: latest }, null, 2));
11066
+ return;
11067
+ }
11068
+ console.log(`Latest session: ${latest.sessionId}`);
11069
+ console.log(`Status: ${latest.status}`);
11070
+ console.log(`Last activity: ${latest.lastActivity}`);
11071
+ console.log(`Runs: ${latest.runIds.join(", ")}`);
11072
+ } catch (e) {
11073
+ const msg = e instanceof Error ? e.message : String(e);
11074
+ console.error(`[AgentInspect] sessions latest failed: ${msg}`);
11075
+ process.exitCode = 1;
11076
+ }
11077
+ }
11078
+ async function sessionsActivityCommand(options = {}) {
11079
+ try {
11080
+ const traceDir = resolveTraceDir({ dir: options.dir });
11081
+ const index = await loadSessionIndex(traceDir, {
11082
+ correlateGroup: options.correlateGroup,
11083
+ staleAfter: options.staleAfter
11084
+ });
11085
+ const summary = buildActivitySummary(index, { since: options.since });
11086
+ if (options.json) {
11087
+ console.log(JSON.stringify({ ok: true, traceDir, ...summary }, null, 2));
11088
+ return;
11089
+ }
11090
+ console.log(renderActivitySummaryHuman(summary));
11091
+ } catch (e) {
11092
+ const msg = e instanceof Error ? e.message : String(e);
11093
+ console.error(`[AgentInspect] sessions activity failed: ${msg}`);
11094
+ process.exitCode = 1;
11095
+ }
11096
+ }
11097
+ async function sessionsHandoffsCommand(options = {}) {
11098
+ try {
11099
+ const traceDir = resolveTraceDir({ dir: options.dir });
11100
+ const index = await loadSessionIndex(traceDir, {
11101
+ correlateGroup: options.correlateGroup
11102
+ });
11103
+ const handoffs = collectHandoffs(index, options.session);
11104
+ if (options.json) {
11105
+ console.log(
11106
+ JSON.stringify({ ok: true, traceDir, count: handoffs.length, handoffs }, null, 2)
11107
+ );
11108
+ return;
11109
+ }
11110
+ if (handoffs.length === 0) {
11111
+ console.log("No handoffs found");
11112
+ return;
11113
+ }
11114
+ for (const edge of handoffs) {
11115
+ console.log(
11116
+ `${edge.sessionId}: ${edge.from} -> ${edge.to} (${edge.confidence})`
11117
+ );
11118
+ }
11119
+ } catch (e) {
11120
+ const msg = e instanceof Error ? e.message : String(e);
11121
+ console.error(`[AgentInspect] sessions handoffs failed: ${msg}`);
11122
+ process.exitCode = 1;
11123
+ }
11124
+ }
11125
+ async function sessionsErrorsCommand(options = {}) {
11126
+ try {
11127
+ const traceDir = resolveTraceDir({ dir: options.dir });
11128
+ const index = await loadSessionIndex(traceDir, {
11129
+ correlateGroup: options.correlateGroup,
11130
+ staleAfter: options.staleAfter
11131
+ });
11132
+ const scoped = sessionsInSinceWindow(index, options.since);
11133
+ const errors = scoped.filter((session) => session.status === "error");
11134
+ if (options.json) {
11135
+ console.log(
11136
+ JSON.stringify(
11137
+ { ok: true, traceDir, count: errors.length, sessions: errors },
11138
+ null,
11139
+ 2
11140
+ )
11141
+ );
11142
+ return;
11143
+ }
11144
+ if (errors.length === 0) {
11145
+ console.log("No error sessions found");
11146
+ return;
11147
+ }
11148
+ for (const session of errors) {
11149
+ const detail = session.lastError?.message ?? "error";
11150
+ console.log(`${session.sessionId} ${detail} (${session.runIds.length} runs)`);
11151
+ }
11152
+ } catch (e) {
11153
+ const msg = e instanceof Error ? e.message : String(e);
11154
+ console.error(`[AgentInspect] sessions errors failed: ${msg}`);
11155
+ process.exitCode = 1;
11156
+ }
11157
+ }
11158
+ async function sessionsShowCommand(sessionId, options = {}) {
11159
+ await sessionCommand(sessionId, options);
11160
+ }
10669
11161
  async function sessionCommand(sessionId, options = {}) {
10670
11162
  const id = typeof sessionId === "string" && sessionId.trim() !== "" ? sessionId.trim() : "";
10671
11163
  if (id === "") {
@@ -10823,9 +11315,9 @@ async function reportCommand(runId, options = {}) {
10823
11315
  redactionProfile,
10824
11316
  correlation: !options.noCorrelation
10825
11317
  });
10826
- const outPath = options.output !== void 0 && options.output.trim() !== "" ? path14__default.default.resolve(options.output.trim()) : void 0;
11318
+ const outPath = options.output !== void 0 && options.output.trim() !== "" ? path16__default.default.resolve(options.output.trim()) : void 0;
10827
11319
  if (outPath !== void 0) {
10828
- await promises.mkdir(path14__default.default.dirname(outPath), { recursive: true });
11320
+ await promises.mkdir(path16__default.default.dirname(outPath), { recursive: true });
10829
11321
  await promises.writeFile(outPath, result.content, "utf-8");
10830
11322
  console.log(`Wrote ${result.fileExtension} report to ${outPath}`);
10831
11323
  }
@@ -11075,17 +11567,17 @@ function applyRule(rule, value, replacement) {
11075
11567
  }
11076
11568
  return value;
11077
11569
  }
11078
- function childPath(path22, key) {
11570
+ function childPath(path23, key) {
11079
11571
  if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key)) {
11080
- return path22 ? `${path22}.${key}` : key;
11572
+ return path23 ? `${path23}.${key}` : key;
11081
11573
  }
11082
- return `${path22 || "$"}[${JSON.stringify(key)}]`;
11574
+ return `${path23 || "$"}[${JSON.stringify(key)}]`;
11083
11575
  }
11084
- function indexPath(path22, index) {
11085
- return `${path22 || "$"}[${index}]`;
11576
+ function indexPath(path23, index) {
11577
+ return `${path23 || "$"}[${index}]`;
11086
11578
  }
11087
- function makeFinding(path22, detector, action, matchKind, severity = "warning", preview) {
11088
- return preview === void 0 ? { path: path22, detector, action, severity, matchKind } : { path: path22, detector, action, severity, matchKind, preview };
11579
+ function makeFinding(path23, detector, action, matchKind, severity = "warning", preview) {
11580
+ return preview === void 0 ? { path: path23, detector, action, severity, matchKind } : { path: path23, detector, action, severity, matchKind, preview };
11089
11581
  }
11090
11582
  function createRedactionProfile(profile = "local") {
11091
11583
  switch (profile) {
@@ -11154,11 +11646,11 @@ var Redactor2 = class {
11154
11646
  #recordFinding(state, finding) {
11155
11647
  if (this.#collectFindings) state.findings.push(finding);
11156
11648
  }
11157
- #redactValue(value, key, path22, depth, state) {
11649
+ #redactValue(value, key, path23, depth, state) {
11158
11650
  if (depth > this.#maxDepth) {
11159
11651
  this.#recordFinding(
11160
11652
  state,
11161
- makeFinding(path22, "structure.maxDepth", "truncate", "value", "warning")
11653
+ makeFinding(path23, "structure.maxDepth", "truncate", "value", "warning")
11162
11654
  );
11163
11655
  return "[Truncated]";
11164
11656
  }
@@ -11167,19 +11659,19 @@ var Redactor2 = class {
11167
11659
  if (rule) {
11168
11660
  this.#recordFinding(
11169
11661
  state,
11170
- makeFinding(path22, `key.${rule.key}`, actionForRule(rule), "key", "warning")
11662
+ makeFinding(path23, `key.${rule.key}`, actionForRule(rule), "key", "warning")
11171
11663
  );
11172
11664
  return applyRule(rule, value, this.#replacement);
11173
11665
  }
11174
11666
  }
11175
11667
  for (const detector of this.#detectors) {
11176
- const detections = detector.detect({ path: path22, key, value });
11668
+ const detections = detector.detect({ path: path23, key, value });
11177
11669
  for (const detection of detections) {
11178
11670
  const action = detection.action ?? "replace";
11179
11671
  this.#recordFinding(
11180
11672
  state,
11181
11673
  makeFinding(
11182
- path22,
11674
+ path23,
11183
11675
  detector.id,
11184
11676
  action,
11185
11677
  detection.matchKind ?? detector.matchKind ?? "custom",
@@ -11197,7 +11689,7 @@ var Redactor2 = class {
11197
11689
  const out = [];
11198
11690
  state.seen.set(value, out);
11199
11691
  value.forEach((item, index) => {
11200
- out[index] = this.#redactValue(item, void 0, indexPath(path22, index), depth + 1, state);
11692
+ out[index] = this.#redactValue(item, void 0, indexPath(path23, index), depth + 1, state);
11201
11693
  });
11202
11694
  return out;
11203
11695
  }
@@ -11209,7 +11701,7 @@ var Redactor2 = class {
11209
11701
  out[entryKey] = this.#redactValue(
11210
11702
  entryValue,
11211
11703
  entryKey,
11212
- childPath(path22 === "$" ? "" : path22, entryKey),
11704
+ childPath(path23 === "$" ? "" : path23, entryKey),
11213
11705
  depth + 1,
11214
11706
  state
11215
11707
  );
@@ -11666,14 +12158,14 @@ function uniqueSorted(values) {
11666
12158
  return [...new Set(values)].sort();
11667
12159
  }
11668
12160
  function isWithinDirectory(child, parent) {
11669
- const relative = path14__default.default.relative(parent, child);
11670
- return relative === "" || !relative.startsWith("..") && !path14__default.default.isAbsolute(relative);
12161
+ const relative = path16__default.default.relative(parent, child);
12162
+ return relative === "" || !relative.startsWith("..") && !path16__default.default.isAbsolute(relative);
11671
12163
  }
11672
12164
  async function resolveOutputPath(inputPath, output2, force) {
11673
12165
  if (output2 === void 0 || output2.trim() === "") return void 0;
11674
- const inputAbs = path14__default.default.resolve(inputPath);
11675
- const outputAbs = path14__default.default.resolve(output2.trim());
11676
- const inputDir = path14__default.default.dirname(inputAbs);
12166
+ const inputAbs = path16__default.default.resolve(inputPath);
12167
+ const outputAbs = path16__default.default.resolve(output2.trim());
12168
+ const inputDir = path16__default.default.dirname(inputAbs);
11677
12169
  if (!isWithinDirectory(outputAbs, inputDir)) {
11678
12170
  throw new Error("Refusing to write migrated output outside the input directory.");
11679
12171
  }
@@ -11794,7 +12286,7 @@ async function migrateCommand(input3, options = {}) {
11794
12286
  process.exitCode = 1;
11795
12287
  return;
11796
12288
  }
11797
- const inputPath = path14__default.default.resolve(input3.trim());
12289
+ const inputPath = path16__default.default.resolve(input3.trim());
11798
12290
  const dryRun = options.dryRun === true;
11799
12291
  if (!dryRun && (options.output === void 0 || options.output.trim() === "")) {
11800
12292
  console.error("migrate requires --dry-run or --output <path>.");
@@ -11813,7 +12305,7 @@ async function migrateCommand(input3, options = {}) {
11813
12305
  );
11814
12306
  const result = await buildMigration(inputPath, outputPath);
11815
12307
  if (!dryRun && outputPath !== void 0) {
11816
- await promises.mkdir(path14__default.default.dirname(outputPath), { recursive: true });
12308
+ await promises.mkdir(path16__default.default.dirname(outputPath), { recursive: true });
11817
12309
  await promises.writeFile(outputPath, result.content, "utf-8");
11818
12310
  }
11819
12311
  printSummary2(result, dryRun);
@@ -12092,7 +12584,7 @@ function stripPrefix(name, prefixes) {
12092
12584
  }
12093
12585
  return name;
12094
12586
  }
12095
- function eventEvidence(event, path22) {
12587
+ function eventEvidence(event, path23) {
12096
12588
  return {
12097
12589
  runId: event.runId,
12098
12590
  eventId: event.eventId,
@@ -12102,7 +12594,7 @@ function eventEvidence(event, path22) {
12102
12594
  kind: event.kind,
12103
12595
  name: event.name,
12104
12596
  status: event.status,
12105
- ...path22 ? { path: path22 } : {}
12597
+ ...path23 ? { path: path23 } : {}
12106
12598
  };
12107
12599
  }
12108
12600
  function runEvidence(run) {
@@ -12165,9 +12657,9 @@ function eventEndMs(event) {
12165
12657
  function normalizedKey(value) {
12166
12658
  return value.toLowerCase().replace(/[^a-z0-9_]/g, "");
12167
12659
  }
12168
- function lastPathSegment(path22) {
12169
- const parts = path22.split(".");
12170
- return parts[parts.length - 1] ?? path22;
12660
+ function lastPathSegment(path23) {
12661
+ const parts = path23.split(".");
12662
+ return parts[parts.length - 1] ?? path23;
12171
12663
  }
12172
12664
  function valueType(value) {
12173
12665
  if (Array.isArray(value)) return "array";
@@ -12181,12 +12673,12 @@ function serializedByteLength(value) {
12181
12673
  return void 0;
12182
12674
  }
12183
12675
  }
12184
- function pushValueEntries(entries, event, value, path22, key, depth = 0) {
12185
- entries.push({ event, path: path22, key, value });
12676
+ function pushValueEntries(entries, event, value, path23, key, depth = 0) {
12677
+ entries.push({ event, path: path23, key, value });
12186
12678
  if (depth >= 8) return;
12187
12679
  if (Array.isArray(value)) {
12188
12680
  for (const [index, item] of value.entries()) {
12189
- pushValueEntries(entries, event, item, `${path22}.${index}`, String(index), depth + 1);
12681
+ pushValueEntries(entries, event, item, `${path23}.${index}`, String(index), depth + 1);
12190
12682
  }
12191
12683
  return;
12192
12684
  }
@@ -12196,7 +12688,7 @@ function pushValueEntries(entries, event, value, path22, key, depth = 0) {
12196
12688
  entries,
12197
12689
  event,
12198
12690
  value[nestedKey],
12199
- `${path22}.${nestedKey}`,
12691
+ `${path23}.${nestedKey}`,
12200
12692
  nestedKey,
12201
12693
  depth + 1
12202
12694
  );
@@ -12277,9 +12769,9 @@ function eventDurationMs(event) {
12277
12769
  }
12278
12770
  function treeShape(nodes) {
12279
12771
  const lines = [];
12280
- const visit = (node, path22) => {
12281
- lines.push(`${path22}:${node.event.kind}:${node.event.name}:${node.event.status ?? "unknown"}`);
12282
- node.children.forEach((child, index) => visit(child, `${path22}.${index}`));
12772
+ const visit = (node, path23) => {
12773
+ lines.push(`${path23}:${node.event.kind}:${node.event.name}:${node.event.status ?? "unknown"}`);
12774
+ node.children.forEach((child, index) => visit(child, `${path23}.${index}`));
12283
12775
  };
12284
12776
  nodes.forEach((node, index) => visit(node, String(index)));
12285
12777
  return lines;
@@ -12328,9 +12820,9 @@ function retrievalShape(context) {
12328
12820
  function guardrailShape(context) {
12329
12821
  return guardrailEvents(context).map((event) => signalName(event, ["guardrailName", "guardrail", "guardrailId"], ["guardrail:"])).sort((a, b) => a.localeCompare(b));
12330
12822
  }
12331
- function firstEvidenceForKind(context, kind, path22) {
12823
+ function firstEvidenceForKind(context, kind, path23) {
12332
12824
  const event = context.events.find((candidate) => candidate.kind === kind);
12333
- return event ? [eventEvidence(event, path22)] : runEvidence(context.selectedRun);
12825
+ return event ? [eventEvidence(event, path23)] : runEvidence(context.selectedRun);
12334
12826
  }
12335
12827
  function baselineDiffFinding(message, evidence, expected, actual) {
12336
12828
  return failFinding("baseline.regression", message, evidence, expected, actual);
@@ -12680,13 +13172,13 @@ function createStructureCycleRule() {
12680
13172
  const seenCycles = /* @__PURE__ */ new Set();
12681
13173
  const findings = [];
12682
13174
  for (const event of [...context.events].sort((a, b) => a.eventId.localeCompare(b.eventId))) {
12683
- const path22 = [];
13175
+ const path23 = [];
12684
13176
  const seenAt = /* @__PURE__ */ new Map();
12685
13177
  let current = event;
12686
13178
  while (current) {
12687
13179
  const existing = seenAt.get(current.eventId);
12688
13180
  if (existing !== void 0) {
12689
- const cycle = path22.slice(existing);
13181
+ const cycle = path23.slice(existing);
12690
13182
  const key = cycle.map((item) => item.eventId).sort().join("\0");
12691
13183
  if (!seenCycles.has(key)) {
12692
13184
  seenCycles.add(key);
@@ -12702,8 +13194,8 @@ function createStructureCycleRule() {
12702
13194
  }
12703
13195
  break;
12704
13196
  }
12705
- seenAt.set(current.eventId, path22.length);
12706
- path22.push(current);
13197
+ seenAt.set(current.eventId, path23.length);
13198
+ path23.push(current);
12707
13199
  current = current.parentId ? byId.get(current.parentId) : void 0;
12708
13200
  }
12709
13201
  }
@@ -13500,23 +13992,23 @@ function evaluatePromptInjection(text, options = {}) {
13500
13992
  }
13501
13993
  return fail(ruleId, `Matched ${evidence.length} injection pattern(s).`, evidence, "warning");
13502
13994
  }
13503
- function validateSchemaField(value, field, path22, evidence) {
13995
+ function validateSchemaField(value, field, path23, evidence) {
13504
13996
  const ruleId = "guardrail.structured-output";
13505
13997
  if (field.type) {
13506
13998
  const actual = value === null ? "null" : Array.isArray(value) ? "array" : typeof value;
13507
13999
  if (actual !== field.type) {
13508
- evidence.push({ ruleId, path: path22, preview: `expected ${field.type}, got ${actual}` });
14000
+ evidence.push({ ruleId, path: path23, preview: `expected ${field.type}, got ${actual}` });
13509
14001
  return;
13510
14002
  }
13511
14003
  }
13512
14004
  if (field.enum && !field.enum.some((item) => Object.is(item, value))) {
13513
- evidence.push({ ruleId, path: path22, preview: "value not in enum" });
14005
+ evidence.push({ ruleId, path: path23, preview: "value not in enum" });
13514
14006
  }
13515
14007
  if (field.type === "object" && field.required && value && typeof value === "object" && !Array.isArray(value)) {
13516
14008
  const record = value;
13517
14009
  for (const key of field.required) {
13518
14010
  if (!(key in record)) {
13519
- evidence.push({ ruleId, path: `${path22}.${key}`, preview: "missing required key" });
14011
+ evidence.push({ ruleId, path: `${path23}.${key}`, preview: "missing required key" });
13520
14012
  }
13521
14013
  }
13522
14014
  }
@@ -13843,7 +14335,7 @@ function asConfig(value) {
13843
14335
  }
13844
14336
  async function loadConfig(configPath) {
13845
14337
  if (configPath === void 0) return {};
13846
- const extension = path14__default.default.extname(configPath);
14338
+ const extension = path16__default.default.extname(configPath);
13847
14339
  if (TS_CONFIG_EXTENSIONS.has(extension)) {
13848
14340
  throw new Error(
13849
14341
  "TypeScript check configs require an explicit precompiled JavaScript config or future --config-loader support."
@@ -13852,7 +14344,7 @@ async function loadConfig(configPath) {
13852
14344
  if (!CONFIG_EXTENSIONS.has(extension)) {
13853
14345
  throw new Error("Unsupported check config extension. Use .json, .js, .mjs, or .cjs.");
13854
14346
  }
13855
- const absolute = path14__default.default.resolve(configPath);
14347
+ const absolute = path16__default.default.resolve(configPath);
13856
14348
  if (extension === ".json") {
13857
14349
  const raw = await promises.readFile(absolute, "utf-8");
13858
14350
  return asConfig(JSON.parse(raw));
@@ -14001,10 +14493,10 @@ function printHuman(result) {
14001
14493
  console.log(`- ${diagnostic4.code}: ${diagnostic4.message}`);
14002
14494
  }
14003
14495
  for (const finding of result.findings) {
14004
- const path22 = finding.evidence[0]?.path;
14496
+ const path23 = finding.evidence[0]?.path;
14005
14497
  const run = finding.evidence[0]?.runId;
14006
14498
  const runPrefix = run ? `[${run}] ` : "";
14007
- console.log(`- ${runPrefix}${finding.ruleId}: ${finding.message}${path22 ? ` (${path22})` : ""}`);
14499
+ console.log(`- ${runPrefix}${finding.ruleId}: ${finding.message}${path23 ? ` (${path23})` : ""}`);
14008
14500
  }
14009
14501
  }
14010
14502
  function readErrorResult(error) {
@@ -14207,7 +14699,7 @@ function createViewerServer(options = {}) {
14207
14699
  return sendJson(res, 200, {
14208
14700
  ok: true,
14209
14701
  readOnly: true,
14210
- traceDir: path14__default.default.resolve(traceDir)
14702
+ traceDir: path16__default.default.resolve(traceDir)
14211
14703
  });
14212
14704
  }
14213
14705
  const td = new TraceDirectory({ dir: traceDir });
@@ -14225,7 +14717,7 @@ function createViewerServer(options = {}) {
14225
14717
  runId: meta2.runId,
14226
14718
  name: meta2.name,
14227
14719
  status: meta2.status,
14228
- file: path14__default.default.basename(meta2.filePath),
14720
+ file: path16__default.default.basename(meta2.filePath),
14229
14721
  startedAt: meta2.startedAt,
14230
14722
  durationMs: meta2.durationMs
14231
14723
  }))
@@ -14340,7 +14832,7 @@ function startViewerServer(options = {}) {
14340
14832
  resolve({
14341
14833
  host,
14342
14834
  port: resolvedPort,
14343
- traceDir: path14__default.default.resolve(traceDir),
14835
+ traceDir: path16__default.default.resolve(traceDir),
14344
14836
  url: `http://${host}:${resolvedPort}`
14345
14837
  });
14346
14838
  });
@@ -14545,10 +15037,10 @@ async function evalRun(input3, options = {}) {
14545
15037
  diagnostics: []
14546
15038
  };
14547
15039
  }
14548
- function evidenceForRun(run, path22) {
14549
- return [{ runId: run.runId, ...path22 !== void 0 ? { path: path22 } : {} }];
15040
+ function evidenceForRun(run, path23) {
15041
+ return [{ runId: run.runId, ...path23 !== void 0 ? { path: path23 } : {} }];
14550
15042
  }
14551
- function evidenceForEvent(event, path22) {
15043
+ function evidenceForEvent(event, path23) {
14552
15044
  return [
14553
15045
  {
14554
15046
  runId: event.runId,
@@ -14556,7 +15048,7 @@ function evidenceForEvent(event, path22) {
14556
15048
  ...event.parentId !== void 0 ? { parentId: event.parentId } : {},
14557
15049
  kind: event.kind,
14558
15050
  name: event.name,
14559
- ...path22 !== void 0 ? { path: path22 } : {}
15051
+ ...path23 !== void 0 ? { path: path23 } : {}
14560
15052
  }
14561
15053
  ];
14562
15054
  }
@@ -14714,9 +15206,9 @@ function collectTextFields(nodes, keys, preferredKinds = []) {
14714
15206
  function tokenize(text) {
14715
15207
  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));
14716
15208
  }
14717
- function firstEvidence(fields, run, path22) {
15209
+ function firstEvidence(fields, run, path23) {
14718
15210
  const first = fields[0];
14719
- return first === void 0 ? evidenceForRun(run, path22) : evidenceForEvent(first.node.event, first.path);
15211
+ return first === void 0 ? evidenceForRun(run, path23) : evidenceForEvent(first.node.event, first.path);
14720
15212
  }
14721
15213
  function collectSourceIds(nodes, keys) {
14722
15214
  const wanted = keySet(keys);
@@ -15093,8 +15585,8 @@ function renderEvalMarkdown(result) {
15093
15585
  if (result.findings.length > 0) {
15094
15586
  lines.push("", "## Findings");
15095
15587
  for (const finding of result.findings) {
15096
- const path22 = finding.evidence[0]?.path;
15097
- lines.push(`- ${finding.ruleId}: ${finding.message}${path22 ? ` (${path22})` : ""}`);
15588
+ const path23 = finding.evidence[0]?.path;
15589
+ lines.push(`- ${finding.ruleId}: ${finding.message}${path23 ? ` (${path23})` : ""}`);
15098
15590
  }
15099
15591
  }
15100
15592
  return `${lines.join("\n")}
@@ -15141,7 +15633,7 @@ function asConfig2(value) {
15141
15633
  }
15142
15634
  async function loadConfig2(configPath) {
15143
15635
  if (configPath === void 0) return {};
15144
- const extension = path14__default.default.extname(configPath);
15636
+ const extension = path16__default.default.extname(configPath);
15145
15637
  if (TS_CONFIG_EXTENSIONS2.has(extension)) {
15146
15638
  throw new Error(
15147
15639
  "TypeScript eval configs require an explicit precompiled JavaScript config or future --config-loader support."
@@ -15150,7 +15642,7 @@ async function loadConfig2(configPath) {
15150
15642
  if (!CONFIG_EXTENSIONS2.has(extension)) {
15151
15643
  throw new Error("Unsupported eval config extension. Use .json, .js, .mjs, or .cjs.");
15152
15644
  }
15153
- const absolute = path14__default.default.resolve(configPath);
15645
+ const absolute = path16__default.default.resolve(configPath);
15154
15646
  if (extension === ".json") {
15155
15647
  const raw = await promises.readFile(absolute, "utf-8");
15156
15648
  return asConfig2(JSON.parse(raw));
@@ -15287,8 +15779,8 @@ function printHuman2(result) {
15287
15779
  console.log(`- ${diagnostic4.code}: ${diagnostic4.message}`);
15288
15780
  }
15289
15781
  for (const finding of result.findings) {
15290
- const path22 = finding.evidence[0]?.path;
15291
- console.log(`- ${finding.ruleId}: ${finding.message}${path22 ? ` (${path22})` : ""}`);
15782
+ const path23 = finding.evidence[0]?.path;
15783
+ console.log(`- ${finding.ruleId}: ${finding.message}${path23 ? ` (${path23})` : ""}`);
15292
15784
  }
15293
15785
  }
15294
15786
  function readErrorResult2(error) {
@@ -15526,8 +16018,8 @@ function printHuman3(result) {
15526
16018
  console.log(`- ${diagnostic4.code}: ${diagnostic4.message}`);
15527
16019
  }
15528
16020
  for (const finding of result.findings) {
15529
- const path22 = finding.evidence[0]?.path;
15530
- console.log(`- ${finding.ruleId}: ${finding.message}${path22 ? ` (${path22})` : ""}`);
16021
+ const path23 = finding.evidence[0]?.path;
16022
+ console.log(`- ${finding.ruleId}: ${finding.message}${path23 ? ` (${path23})` : ""}`);
15531
16023
  }
15532
16024
  console.log(`Note: ${result.note}`);
15533
16025
  }
@@ -15646,8 +16138,8 @@ function renderCheckSection(result) {
15646
16138
  `Diagnostics: ${result.diagnostics.length}`
15647
16139
  ];
15648
16140
  for (const finding of result.findings.slice(0, 10)) {
15649
- const path22 = finding.evidence[0]?.path ?? "(run)";
15650
- lines.push(`- ${finding.ruleId}: ${finding.message} (${path22})`);
16141
+ const path23 = finding.evidence[0]?.path ?? "(run)";
16142
+ lines.push(`- ${finding.ruleId}: ${finding.message} (${path23})`);
15651
16143
  }
15652
16144
  for (const diagnostic4 of result.diagnostics.slice(0, 10)) {
15653
16145
  lines.push(`- ${diagnostic4.code}: ${diagnostic4.message}`);
@@ -15725,8 +16217,8 @@ function renderHtml(trace, check, diff) {
15725
16217
  `;
15726
16218
  }
15727
16219
  async function writeArtifact(outputDir, relativePath, content, files) {
15728
- const outPath = path14__default.default.join(outputDir, relativePath);
15729
- await promises.mkdir(path14__default.default.dirname(outPath), { recursive: true });
16220
+ const outPath = path16__default.default.join(outputDir, relativePath);
16221
+ await promises.mkdir(path16__default.default.dirname(outPath), { recursive: true });
15730
16222
  await promises.writeFile(outPath, content, "utf-8");
15731
16223
  files.push(relativePath);
15732
16224
  }
@@ -15742,7 +16234,7 @@ function manifestStatus(check, diff) {
15742
16234
  return "ok";
15743
16235
  }
15744
16236
  async function artifactsCommand(target, options = {}, stdin = process.stdin) {
15745
- const outputDir = options.outputDir !== void 0 && options.outputDir.trim() !== "" ? path14__default.default.resolve(options.outputDir.trim()) : "";
16237
+ const outputDir = options.outputDir !== void 0 && options.outputDir.trim() !== "" ? path16__default.default.resolve(options.outputDir.trim()) : "";
15746
16238
  if (outputDir === "") {
15747
16239
  console.error("--output-dir is required.");
15748
16240
  process.exitCode = 1;
@@ -15808,8 +16300,8 @@ async function artifactsCommand(target, options = {}, stdin = process.stdin) {
15808
16300
  await writeArtifact(outputDir, "report.html", renderHtml(trace, check, diff), files);
15809
16301
  const summaryTarget = options.githubSummary ?? process.env.GITHUB_STEP_SUMMARY;
15810
16302
  if (summaryTarget !== void 0 && summaryTarget.trim() !== "") {
15811
- await promises.mkdir(path14__default.default.dirname(path14__default.default.resolve(summaryTarget)), { recursive: true });
15812
- await promises.appendFile(path14__default.default.resolve(summaryTarget), `
16303
+ await promises.mkdir(path16__default.default.dirname(path16__default.default.resolve(summaryTarget)), { recursive: true });
16304
+ await promises.appendFile(path16__default.default.resolve(summaryTarget), `
15813
16305
  ${renderMarkdown(trace, check, diff)}`, "utf-8");
15814
16306
  }
15815
16307
  const manifestFiles = [...files, "manifest.json"].sort((a, b) => a.localeCompare(b));
@@ -15828,10 +16320,10 @@ ${renderMarkdown(trace, check, diff)}`, "utf-8");
15828
16320
  findings: diff?.findings.length ?? 0,
15829
16321
  diagnostics: diff?.diagnostics.length ?? 0
15830
16322
  },
15831
- ...summaryTarget !== void 0 && summaryTarget.trim() !== "" ? { githubSummary: path14__default.default.resolve(summaryTarget) } : {},
16323
+ ...summaryTarget !== void 0 && summaryTarget.trim() !== "" ? { githubSummary: path16__default.default.resolve(summaryTarget) } : {},
15832
16324
  note: NOTE
15833
16325
  };
15834
- await promises.writeFile(path14__default.default.join(outputDir, "manifest.json"), writeJson3(manifest), "utf-8");
16326
+ await promises.writeFile(path16__default.default.join(outputDir, "manifest.json"), writeJson3(manifest), "utf-8");
15835
16327
  if (options.json === true) {
15836
16328
  console.log(writeJson3(manifest).trimEnd());
15837
16329
  } else {
@@ -15843,7 +16335,7 @@ ${renderMarkdown(trace, check, diff)}`, "utf-8");
15843
16335
  }
15844
16336
  }
15845
16337
  function validateReporterArtifactPath(options) {
15846
- const outputDir = path14__default.default.resolve(options.outputDir);
16338
+ const outputDir = path16__default.default.resolve(options.outputDir);
15847
16339
  const diagnostics = [];
15848
16340
  const rawPath = options.relativePath;
15849
16341
  if (rawPath.length === 0) {
@@ -15863,7 +16355,7 @@ function validateReporterArtifactPath(options) {
15863
16355
  });
15864
16356
  return { ok: false, outputDir, diagnostics };
15865
16357
  }
15866
- if (path14__default.default.isAbsolute(rawPath) || path14__default.default.win32.isAbsolute(rawPath)) {
16358
+ if (path16__default.default.isAbsolute(rawPath) || path16__default.default.win32.isAbsolute(rawPath)) {
15867
16359
  diagnostics.push({
15868
16360
  code: "artifact_path_absolute",
15869
16361
  severity: "error",
@@ -15872,7 +16364,7 @@ function validateReporterArtifactPath(options) {
15872
16364
  });
15873
16365
  return { ok: false, outputDir, diagnostics };
15874
16366
  }
15875
- const normalized = path14__default.default.posix.normalize(rawPath.replace(/\\/g, "/"));
16367
+ const normalized = path16__default.default.posix.normalize(rawPath.replace(/\\/g, "/"));
15876
16368
  const segments = normalized.split("/");
15877
16369
  if (normalized === "." || normalized.startsWith("../") || segments.some((segment) => segment === "..")) {
15878
16370
  diagnostics.push({
@@ -15883,9 +16375,9 @@ function validateReporterArtifactPath(options) {
15883
16375
  });
15884
16376
  return { ok: false, outputDir, diagnostics };
15885
16377
  }
15886
- const absolutePath = path14__default.default.resolve(outputDir, normalized);
15887
- const relFromOutput = path14__default.default.relative(outputDir, absolutePath);
15888
- if (relFromOutput.length === 0 || relFromOutput.startsWith("..") || path14__default.default.isAbsolute(relFromOutput)) {
16378
+ const absolutePath = path16__default.default.resolve(outputDir, normalized);
16379
+ const relFromOutput = path16__default.default.relative(outputDir, absolutePath);
16380
+ if (relFromOutput.length === 0 || relFromOutput.startsWith("..") || path16__default.default.isAbsolute(relFromOutput)) {
15889
16381
  diagnostics.push({
15890
16382
  code: "artifact_path_escape",
15891
16383
  severity: "error",
@@ -16031,23 +16523,23 @@ function readManifestDocument(value) {
16031
16523
  };
16032
16524
  }
16033
16525
  function cwdRelative(filePath) {
16034
- const relative = path14__default.default.relative(process.cwd(), path14__default.default.resolve(filePath)).replace(/\\/g, "/");
16035
- if (relative === "" || relative.startsWith("../") || path14__default.default.isAbsolute(relative)) {
16036
- return path14__default.default.basename(filePath);
16526
+ const relative = path16__default.default.relative(process.cwd(), path16__default.default.resolve(filePath)).replace(/\\/g, "/");
16527
+ if (relative === "" || relative.startsWith("../") || path16__default.default.isAbsolute(relative)) {
16528
+ return path16__default.default.basename(filePath);
16037
16529
  }
16038
16530
  return relative;
16039
16531
  }
16040
16532
  async function readReporterManifest(filePath) {
16041
- const absolute = path14__default.default.resolve(filePath);
16533
+ const absolute = path16__default.default.resolve(filePath);
16042
16534
  const raw = await promises.readFile(absolute, "utf-8");
16043
16535
  const document = readManifestDocument(JSON.parse(raw));
16044
16536
  const manifest = document.manifest;
16045
16537
  const results = manifest.results.map((result) => ({
16046
16538
  testId: safeText(result.testId),
16047
16539
  name: safeText(result.name),
16048
- ...result.file === void 0 ? {} : { file: safeText(path14__default.default.basename(result.file)) },
16540
+ ...result.file === void 0 ? {} : { file: safeText(path16__default.default.basename(result.file)) },
16049
16541
  status: result.status,
16050
- ...result.tracePath === void 0 ? {} : { tracePath: safeText(path14__default.default.basename(result.tracePath)) },
16542
+ ...result.tracePath === void 0 ? {} : { tracePath: safeText(path16__default.default.basename(result.tracePath)) },
16051
16543
  artifacts: result.artifacts,
16052
16544
  diagnostics: result.diagnostics
16053
16545
  }));
@@ -16186,15 +16678,15 @@ async function ciSummaryCommand(manifestPaths, options = {}) {
16186
16678
  return;
16187
16679
  }
16188
16680
  const markdown = renderMarkdown2(result);
16189
- const outputPath = options.output !== void 0 && options.output.trim() !== "" ? path14__default.default.resolve(options.output.trim()) : void 0;
16681
+ const outputPath = options.output !== void 0 && options.output.trim() !== "" ? path16__default.default.resolve(options.output.trim()) : void 0;
16190
16682
  if (outputPath !== void 0) {
16191
- await promises.mkdir(path14__default.default.dirname(outputPath), { recursive: true });
16683
+ await promises.mkdir(path16__default.default.dirname(outputPath), { recursive: true });
16192
16684
  await promises.writeFile(outputPath, markdown, "utf-8");
16193
16685
  }
16194
16686
  const summaryTarget = options.githubSummary ?? process.env.GITHUB_STEP_SUMMARY;
16195
16687
  if (summaryTarget !== void 0 && summaryTarget.trim() !== "") {
16196
- const summaryPath = path14__default.default.resolve(summaryTarget);
16197
- await promises.mkdir(path14__default.default.dirname(summaryPath), { recursive: true });
16688
+ const summaryPath = path16__default.default.resolve(summaryTarget);
16689
+ await promises.mkdir(path16__default.default.dirname(summaryPath), { recursive: true });
16198
16690
  await promises.appendFile(summaryPath, `
16199
16691
  ${markdown}`, "utf-8");
16200
16692
  }
@@ -16342,8 +16834,8 @@ jobs:
16342
16834
  }
16343
16835
  async function planInit(options = {}) {
16344
16836
  const framework = normalizeFramework(options.framework);
16345
- const cwd = path14__default.default.resolve(options.cwd ?? process.cwd());
16346
- const demoPath = framework === "custom" ? path14__default.default.join("examples", "agent-inspect-demo.mjs") : path14__default.default.join("examples", `agent-inspect-${framework}-demo.mjs`);
16837
+ const cwd = path16__default.default.resolve(options.cwd ?? process.cwd());
16838
+ const demoPath = framework === "custom" ? path16__default.default.join("examples", "agent-inspect-demo.mjs") : path16__default.default.join("examples", `agent-inspect-${framework}-demo.mjs`);
16347
16839
  const candidates = [
16348
16840
  { rel: CONFIG_FILE, content: configTemplate(framework) },
16349
16841
  { rel: GITKEEP, content: "" },
@@ -16357,7 +16849,7 @@ async function planInit(options = {}) {
16357
16849
  }
16358
16850
  const files = [];
16359
16851
  for (const candidate of candidates) {
16360
- const abs = path14__default.default.join(cwd, candidate.rel);
16852
+ const abs = path16__default.default.join(cwd, candidate.rel);
16361
16853
  try {
16362
16854
  await promises.access(abs);
16363
16855
  files.push({
@@ -16378,12 +16870,12 @@ async function writePlannedFiles(plan, cwd, options) {
16378
16870
  if (entry.action === "skip") {
16379
16871
  continue;
16380
16872
  }
16381
- const abs = path14__default.default.join(cwd, entry.path);
16873
+ const abs = path16__default.default.join(cwd, entry.path);
16382
16874
  if (options.dryRun) {
16383
16875
  written.push(entry.path);
16384
16876
  continue;
16385
16877
  }
16386
- await promises.mkdir(path14__default.default.dirname(abs), { recursive: true });
16878
+ await promises.mkdir(path16__default.default.dirname(abs), { recursive: true });
16387
16879
  const content = entry.path === CONFIG_FILE ? configTemplate(plan.framework) : entry.path === GITKEEP ? "" : entry.path.endsWith(".yml") ? githubWorkflowTemplate() : demoTemplate(plan.framework);
16388
16880
  await promises.writeFile(abs, content, "utf-8");
16389
16881
  written.push(entry.path);
@@ -16391,7 +16883,7 @@ async function writePlannedFiles(plan, cwd, options) {
16391
16883
  return written;
16392
16884
  }
16393
16885
  async function initCommand(options = {}) {
16394
- const cwd = path14__default.default.resolve(options.cwd ?? process.cwd());
16886
+ const cwd = path16__default.default.resolve(options.cwd ?? process.cwd());
16395
16887
  try {
16396
16888
  const plan = await planInit({ ...options, cwd });
16397
16889
  const toWrite = plan.files.filter((file) => file.action === "create").map((f) => f.path);
@@ -16482,7 +16974,7 @@ function envCheck(name, optional = true) {
16482
16974
  };
16483
16975
  }
16484
16976
  async function traceDirWritable(traceDir) {
16485
- const resolved = path14__default.default.resolve(traceDir);
16977
+ const resolved = path16__default.default.resolve(traceDir);
16486
16978
  try {
16487
16979
  await promises.mkdir(resolved, { recursive: true });
16488
16980
  await promises.access(resolved, promises.constants.W_OK);
@@ -16503,7 +16995,7 @@ async function traceDirWritable(traceDir) {
16503
16995
  }
16504
16996
  }
16505
16997
  function resolvePackage(cwd, name) {
16506
- const require2 = module$1.createRequire(path14__default.default.join(cwd, "package.json"));
16998
+ const require2 = module$1.createRequire(path16__default.default.join(cwd, "package.json"));
16507
16999
  try {
16508
17000
  const pkgPath = require2.resolve(`${name}/package.json`);
16509
17001
  const pkg = require2(pkgPath);
@@ -16514,7 +17006,7 @@ function resolvePackage(cwd, name) {
16514
17006
  }
16515
17007
  function importSmoke(cwd) {
16516
17008
  const results = [];
16517
- const require2 = module$1.createRequire(path14__default.default.join(cwd, "package.json"));
17009
+ const require2 = module$1.createRequire(path16__default.default.join(cwd, "package.json"));
16518
17010
  try {
16519
17011
  require2.resolve("agent-inspect");
16520
17012
  results.push({
@@ -16597,7 +17089,7 @@ function versionMismatchCheck(cwd) {
16597
17089
  };
16598
17090
  }
16599
17091
  async function runDoctorChecks(options = {}) {
16600
- const cwd = path14__default.default.resolve(options.cwd ?? process3__default.default.cwd());
17092
+ const cwd = path16__default.default.resolve(options.cwd ?? process3__default.default.cwd());
16601
17093
  const traceDir = options.traceDir?.trim() || process3__default.default.env.AGENT_INSPECT_TRACE_DIR?.trim() || ".agent-inspect";
16602
17094
  const checks2 = [
16603
17095
  nodeVersionCheck(),
@@ -16711,7 +17203,7 @@ function createTraceDirectoryIndexer() {
16711
17203
  init_advanced();
16712
17204
  var INDEX_FILENAME = ".agent-inspect-index.json";
16713
17205
  function traceIndexPath(traceDir) {
16714
- return path14__default.default.join(traceDir, INDEX_FILENAME);
17206
+ return path16__default.default.join(traceDir, INDEX_FILENAME);
16715
17207
  }
16716
17208
  function parseMaxEntries(raw) {
16717
17209
  if (raw === void 0 || raw.trim() === "") return void 0;
@@ -16822,14 +17314,14 @@ async function indexCleanCommand(options = {}) {
16822
17314
  // packages/cli/src/index-sqlite-cmd.ts
16823
17315
  init_advanced();
16824
17316
  var PACKAGE = "@agent-inspect/index-sqlite";
16825
- function isModuleNotFound2(e) {
17317
+ function isModuleNotFound3(e) {
16826
17318
  return e !== null && typeof e === "object" && "code" in e && (e.code === "ERR_MODULE_NOT_FOUND" || e.code === "MODULE_NOT_FOUND");
16827
17319
  }
16828
17320
  async function loadIndexSqlite() {
16829
17321
  try {
16830
17322
  return await Promise.resolve().then(() => (init_src(), src_exports));
16831
17323
  } catch (e) {
16832
- if (isModuleNotFound2(e)) {
17324
+ if (isModuleNotFound3(e)) {
16833
17325
  console.error(
16834
17326
  `The optional SQLite index is not installed. Run: npm install ${PACKAGE}`
16835
17327
  );
@@ -16850,14 +17342,14 @@ function parsePositiveInt(raw, flag) {
16850
17342
  }
16851
17343
  return parsed;
16852
17344
  }
16853
- async function newestTraceMtimeMs(traceDir) {
17345
+ async function newestTraceMtimeMs2(traceDir) {
16854
17346
  let newest = 0;
16855
17347
  try {
16856
17348
  const files = await promises.readdir(traceDir);
16857
17349
  for (const file of files) {
16858
17350
  if (!file.endsWith(".jsonl")) continue;
16859
17351
  try {
16860
- const s = await promises.stat(path14__default.default.join(traceDir, file));
17352
+ const s = await promises.stat(path16__default.default.join(traceDir, file));
16861
17353
  if (s.mtimeMs > newest) newest = s.mtimeMs;
16862
17354
  } catch {
16863
17355
  }
@@ -16887,7 +17379,7 @@ async function indexSqliteStatusCommand(options = {}) {
16887
17379
  const traceDir = resolveTraceDir({ dir: options.dir });
16888
17380
  const dbPath = mod.resolveIndexDbPath(traceDir);
16889
17381
  const status = mod.indexStatus(dbPath);
16890
- const stale = mod.isIndexStale(dbPath, await newestTraceMtimeMs(traceDir));
17382
+ const stale = mod.isIndexStale(dbPath, await newestTraceMtimeMs2(traceDir));
16891
17383
  if (options.json) {
16892
17384
  console.log(JSON.stringify({ ok: true, traceDir, stale, ...status }, null, 2));
16893
17385
  return;
@@ -17136,19 +17628,19 @@ function serializeWorkspaceManifest(manifest) {
17136
17628
  }
17137
17629
  var INDEX_DIR_NAME = "index";
17138
17630
  function resolveWorkspaceLocation(cwd = process.cwd()) {
17139
- const projectRoot = path14__default.default.resolve(cwd);
17140
- const workspaceDir = path14__default.default.join(projectRoot, WORKSPACE_DIR_NAME);
17631
+ const projectRoot = path16__default.default.resolve(cwd);
17632
+ const workspaceDir = path16__default.default.join(projectRoot, WORKSPACE_DIR_NAME);
17141
17633
  return {
17142
17634
  projectRoot,
17143
17635
  workspaceDir,
17144
- manifestPath: path14__default.default.join(workspaceDir, WORKSPACE_MANIFEST_FILENAME)
17636
+ manifestPath: path16__default.default.join(workspaceDir, WORKSPACE_MANIFEST_FILENAME)
17145
17637
  };
17146
17638
  }
17147
17639
  function resolveInsideWorkspace(workspaceDir, relative) {
17148
- const base = path14__default.default.resolve(workspaceDir);
17149
- const resolved = path14__default.default.resolve(base, relative);
17150
- const rel = path14__default.default.relative(base, resolved);
17151
- if (rel === "" || rel === "." || !rel.startsWith("..") && !path14__default.default.isAbsolute(rel)) {
17640
+ const base = path16__default.default.resolve(workspaceDir);
17641
+ const resolved = path16__default.default.resolve(base, relative);
17642
+ const rel = path16__default.default.relative(base, resolved);
17643
+ if (rel === "" || rel === "." || !rel.startsWith("..") && !path16__default.default.isAbsolute(rel)) {
17152
17644
  return resolved;
17153
17645
  }
17154
17646
  throw new Error(
@@ -17217,7 +17709,7 @@ async function createWorkspace(options = {}) {
17217
17709
  created = false;
17218
17710
  adopted = true;
17219
17711
  } else {
17220
- const project = options.project?.trim() || path14__default.default.basename(location.projectRoot) || "workspace";
17712
+ const project = options.project?.trim() || path16__default.default.basename(location.projectRoot) || "workspace";
17221
17713
  const traceDirs = detectedExistingTraces ? ["runs", "."] : ["runs"];
17222
17714
  manifest = createDefaultWorkspaceManifest({
17223
17715
  project,
@@ -17356,7 +17848,7 @@ async function doctorWorkspace(location) {
17356
17848
  const abs = resolveInsideWorkspace(location.workspaceDir, rel);
17357
17849
  for (const file of await listJsonl(abs)) {
17358
17850
  try {
17359
- const s = await promises.stat(path14__default.default.join(abs, file));
17851
+ const s = await promises.stat(path16__default.default.join(abs, file));
17360
17852
  newestTraceMtime = Math.max(newestTraceMtime, s.mtimeMs);
17361
17853
  } catch {
17362
17854
  checks2.push({ id: "trace-readability", status: "warn", message: `cannot stat ${rel}/${file}` });
@@ -17404,7 +17896,7 @@ async function cleanWorkspace(location, manifest, options = {}) {
17404
17896
  const relPath = `${rel}/${entry}`;
17405
17897
  removed.push(relPath);
17406
17898
  if (!dryRun) {
17407
- await promises.rm(path14__default.default.join(abs, entry), { recursive: true, force: true });
17899
+ await promises.rm(path16__default.default.join(abs, entry), { recursive: true, force: true });
17408
17900
  }
17409
17901
  }
17410
17902
  }
@@ -17810,12 +18302,32 @@ function createCliProgram() {
17810
18302
  ).option("--json", "print results as JSON").action((opts) => {
17811
18303
  runCommand(() => searchCommand(opts));
17812
18304
  });
17813
- program.command("sessions").description("List workflow sessions grouped from local trace metadata (read-only)").option("--dir <path>", "trace directory").option(
18305
+ const sessionsCmd = program.command("sessions").description(
18306
+ "Workflow sessions and activity from local trace metadata (read-only, v4.2+)"
18307
+ ).option("--dir <path>", "trace directory").option(
17814
18308
  "--correlate-group",
17815
18309
  "treat shared groupId as a synthetic session when sessionId is absent"
17816
- ).option("--json", "print sessions index as JSON").action((opts) => {
18310
+ ).option("--json", "print JSON output").option(
18311
+ "--stale-after <duration>",
18312
+ "mark sessions stale after inactivity (e.g. 24h, 7d)"
18313
+ ).action((opts) => {
17817
18314
  runCommand(() => sessionsCommand(opts));
17818
18315
  });
18316
+ sessionsCmd.command("latest").description("Show the most recently active session").option("--dir <path>", "trace directory").option("--correlate-group", "include synthetic group: sessions").option("--stale-after <duration>", "staleness threshold for status derivation").option("--json", "print JSON result").action((opts) => {
18317
+ runCommand(() => sessionsLatestCommand(opts));
18318
+ });
18319
+ sessionsCmd.command("activity").description("Summarize recent session activity").option("--dir <path>", "trace directory").option("--since <duration>", "activity window (default 7d)").option("--correlate-group", "include synthetic group: sessions").option("--stale-after <duration>", "staleness threshold for status derivation").option("--json", "print JSON result").action((opts) => {
18320
+ runCommand(() => sessionsActivityCommand(opts));
18321
+ });
18322
+ sessionsCmd.command("show").description("Show one session (alias for session <id>)").argument("<session-id>", "session id").option("--dir <path>", "trace directory").option("--timeline", "include per-run timelines").option("--critical-path", "include critical path section").option("--diagnostics", "include ambiguity warnings").option("--json", "print JSON result").action((sessionId, opts) => {
18323
+ runCommand(() => sessionsShowCommand(sessionId, opts));
18324
+ });
18325
+ sessionsCmd.command("handoffs").description("List handoff edges across sessions").option("--dir <path>", "trace directory").option("--session <id>", "limit to one session").option("--correlate-group", "include synthetic group: sessions").option("--json", "print JSON result").action((opts) => {
18326
+ runCommand(() => sessionsHandoffsCommand(opts));
18327
+ });
18328
+ sessionsCmd.command("errors").description("List sessions with errors in a time window").option("--dir <path>", "trace directory").option("--since <duration>", "filter by last activity (default: all)").option("--correlate-group", "include synthetic group: sessions").option("--stale-after <duration>", "staleness threshold for status derivation").option("--json", "print JSON result").action((opts) => {
18329
+ runCommand(() => sessionsErrorsCommand(opts));
18330
+ });
17819
18331
  program.command("session").description("Inspect one workflow session: runs, handoffs, retries (read-only)").argument("<session-id>", "session id (from sessions output)").option("--dir <path>", "trace directory").option("--timeline", "include per-run timelines").option("--critical-path", "include critical path section").option("--diagnostics", "include ambiguity warnings").option("--json", "print session view as JSON").action((sessionId, opts) => {
17820
18332
  runCommand(() => sessionCommand(sessionId, opts));
17821
18333
  });
@@ -17944,9 +18456,9 @@ function isPrimaryModule() {
17944
18456
  if (!entry) return false;
17945
18457
  const selfPath = url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
17946
18458
  try {
17947
- return fs.realpathSync(path14__default.default.resolve(entry)) === fs.realpathSync(path14__default.default.resolve(selfPath));
18459
+ return fs.realpathSync(path16__default.default.resolve(entry)) === fs.realpathSync(path16__default.default.resolve(selfPath));
17948
18460
  } catch {
17949
- return path14__default.default.resolve(entry) === path14__default.default.resolve(selfPath);
18461
+ return path16__default.default.resolve(entry) === path16__default.default.resolve(selfPath);
17950
18462
  }
17951
18463
  }
17952
18464
  if (isPrimaryModule()) {