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.
- package/CHANGELOG.md +12 -0
- package/docs/CLI.md +17 -6
- package/package.json +1 -1
- package/packages/cli/dist/{chunk-MT5G7JFO.mjs → chunk-5VSPJEZ7.mjs} +264 -11
- package/packages/cli/dist/chunk-5VSPJEZ7.mjs.map +1 -0
- package/packages/cli/dist/index.cjs +700 -188
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +392 -151
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/cli/dist/{src-DUGEOAZ7.mjs → src-VQT7QLGV.mjs} +3 -3
- package/packages/cli/dist/{src-DUGEOAZ7.mjs.map → src-VQT7QLGV.mjs.map} +1 -1
- package/packages/core/dist/advanced.cjs +265 -8
- package/packages/core/dist/advanced.cjs.map +1 -1
- package/packages/core/dist/advanced.d.cts +79 -1
- package/packages/core/dist/advanced.d.ts +79 -1
- package/packages/core/dist/advanced.mjs +262 -9
- package/packages/core/dist/advanced.mjs.map +1 -1
- package/packages/cli/dist/chunk-MT5G7JFO.mjs.map +0 -1
|
@@ -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
|
|
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
|
|
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
|
|
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 =
|
|
870
|
+
safeId = path16__default.default.basename(safeId);
|
|
871
871
|
if (safeId === "" || safeId === "." || safeId === "..") {
|
|
872
872
|
safeId = "run_unknown";
|
|
873
873
|
}
|
|
874
|
-
return
|
|
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 =
|
|
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 ?
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
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
|
|
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
|
-
|
|
3847
|
+
path23 = path23.replace(/^(.+)\|/, "$1:");
|
|
3582
3848
|
if (sep == "\\") {
|
|
3583
|
-
|
|
3849
|
+
path23 = path23.replace(/\//g, "\\");
|
|
3584
3850
|
}
|
|
3585
|
-
if (/^.+\:/.test(
|
|
3586
|
-
|
|
3851
|
+
if (/^.+\:/.test(path23)) ; else {
|
|
3852
|
+
path23 = sep + path23;
|
|
3587
3853
|
}
|
|
3588
|
-
return host +
|
|
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
|
|
3863
|
+
var path23 = __require("path");
|
|
3598
3864
|
var fileURLToPath2 = require_file_uri_to_path();
|
|
3599
|
-
var join =
|
|
3600
|
-
var dirname =
|
|
3601
|
-
var exists = fs.accessSync && function(
|
|
3865
|
+
var join = path23.join;
|
|
3866
|
+
var dirname = path23.dirname;
|
|
3867
|
+
var exists = fs.accessSync && function(path24) {
|
|
3602
3868
|
try {
|
|
3603
|
-
fs.accessSync(
|
|
3869
|
+
fs.accessSync(path24);
|
|
3604
3870
|
} catch (e) {
|
|
3605
3871
|
return false;
|
|
3606
3872
|
}
|
|
3607
3873
|
return true;
|
|
3608
|
-
} || fs.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 (
|
|
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
|
|
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(
|
|
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
|
|
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(
|
|
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(
|
|
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
|
|
4376
|
-
return
|
|
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(
|
|
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,
|
|
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
|
|
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.
|
|
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) =>
|
|
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() !== "" ?
|
|
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(
|
|
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
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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(
|
|
10182
|
-
if (
|
|
10447
|
+
function formatPath(path23) {
|
|
10448
|
+
if (path23 === void 0 || path23.path.length === 0) {
|
|
10183
10449
|
return "(run)";
|
|
10184
10450
|
}
|
|
10185
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
10562
|
-
|
|
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
|
|
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,
|
|
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() !== "" ?
|
|
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(
|
|
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(
|
|
11570
|
+
function childPath(path23, key) {
|
|
11079
11571
|
if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key)) {
|
|
11080
|
-
return
|
|
11572
|
+
return path23 ? `${path23}.${key}` : key;
|
|
11081
11573
|
}
|
|
11082
|
-
return `${
|
|
11574
|
+
return `${path23 || "$"}[${JSON.stringify(key)}]`;
|
|
11083
11575
|
}
|
|
11084
|
-
function indexPath(
|
|
11085
|
-
return `${
|
|
11576
|
+
function indexPath(path23, index) {
|
|
11577
|
+
return `${path23 || "$"}[${index}]`;
|
|
11086
11578
|
}
|
|
11087
|
-
function makeFinding(
|
|
11088
|
-
return preview === void 0 ? { path:
|
|
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,
|
|
11649
|
+
#redactValue(value, key, path23, depth, state) {
|
|
11158
11650
|
if (depth > this.#maxDepth) {
|
|
11159
11651
|
this.#recordFinding(
|
|
11160
11652
|
state,
|
|
11161
|
-
makeFinding(
|
|
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(
|
|
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:
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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 =
|
|
11670
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
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 =
|
|
11675
|
-
const outputAbs =
|
|
11676
|
-
const inputDir =
|
|
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 =
|
|
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(
|
|
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,
|
|
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
|
-
...
|
|
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(
|
|
12169
|
-
const parts =
|
|
12170
|
-
return parts[parts.length - 1] ??
|
|
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,
|
|
12185
|
-
entries.push({ event, path:
|
|
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, `${
|
|
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
|
-
`${
|
|
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,
|
|
12281
|
-
lines.push(`${
|
|
12282
|
-
node.children.forEach((child, index) => visit(child, `${
|
|
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,
|
|
12823
|
+
function firstEvidenceForKind(context, kind, path23) {
|
|
12332
12824
|
const event = context.events.find((candidate) => candidate.kind === kind);
|
|
12333
|
-
return event ? [eventEvidence(event,
|
|
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
|
|
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 =
|
|
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,
|
|
12706
|
-
|
|
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,
|
|
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:
|
|
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:
|
|
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: `${
|
|
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 =
|
|
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 =
|
|
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
|
|
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}${
|
|
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:
|
|
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:
|
|
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:
|
|
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,
|
|
14549
|
-
return [{ runId: run.runId, ...
|
|
15040
|
+
function evidenceForRun(run, path23) {
|
|
15041
|
+
return [{ runId: run.runId, ...path23 !== void 0 ? { path: path23 } : {} }];
|
|
14550
15042
|
}
|
|
14551
|
-
function evidenceForEvent(event,
|
|
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
|
-
...
|
|
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,
|
|
15209
|
+
function firstEvidence(fields, run, path23) {
|
|
14718
15210
|
const first = fields[0];
|
|
14719
|
-
return first === void 0 ? evidenceForRun(run,
|
|
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
|
|
15097
|
-
lines.push(`- ${finding.ruleId}: ${finding.message}${
|
|
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 =
|
|
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 =
|
|
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
|
|
15291
|
-
console.log(`- ${finding.ruleId}: ${finding.message}${
|
|
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
|
|
15530
|
-
console.log(`- ${finding.ruleId}: ${finding.message}${
|
|
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
|
|
15650
|
-
lines.push(`- ${finding.ruleId}: ${finding.message} (${
|
|
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 =
|
|
15729
|
-
await promises.mkdir(
|
|
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() !== "" ?
|
|
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(
|
|
15812
|
-
await promises.appendFile(
|
|
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:
|
|
16323
|
+
...summaryTarget !== void 0 && summaryTarget.trim() !== "" ? { githubSummary: path16__default.default.resolve(summaryTarget) } : {},
|
|
15832
16324
|
note: NOTE
|
|
15833
16325
|
};
|
|
15834
|
-
await promises.writeFile(
|
|
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 =
|
|
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 (
|
|
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 =
|
|
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 =
|
|
15887
|
-
const relFromOutput =
|
|
15888
|
-
if (relFromOutput.length === 0 || relFromOutput.startsWith("..") ||
|
|
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 =
|
|
16035
|
-
if (relative === "" || relative.startsWith("../") ||
|
|
16036
|
-
return
|
|
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 =
|
|
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(
|
|
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(
|
|
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() !== "" ?
|
|
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(
|
|
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 =
|
|
16197
|
-
await promises.mkdir(
|
|
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 =
|
|
16346
|
-
const demoPath = framework === "custom" ?
|
|
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 =
|
|
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 =
|
|
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(
|
|
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 =
|
|
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 =
|
|
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(
|
|
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(
|
|
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 =
|
|
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
|
|
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
|
|
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 (
|
|
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
|
|
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(
|
|
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
|
|
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 =
|
|
17140
|
-
const workspaceDir =
|
|
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:
|
|
17636
|
+
manifestPath: path16__default.default.join(workspaceDir, WORKSPACE_MANIFEST_FILENAME)
|
|
17145
17637
|
};
|
|
17146
17638
|
}
|
|
17147
17639
|
function resolveInsideWorkspace(workspaceDir, relative) {
|
|
17148
|
-
const base =
|
|
17149
|
-
const resolved =
|
|
17150
|
-
const rel =
|
|
17151
|
-
if (rel === "" || rel === "." || !rel.startsWith("..") && !
|
|
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() ||
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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(
|
|
18459
|
+
return fs.realpathSync(path16__default.default.resolve(entry)) === fs.realpathSync(path16__default.default.resolve(selfPath));
|
|
17948
18460
|
} catch {
|
|
17949
|
-
return
|
|
18461
|
+
return path16__default.default.resolve(entry) === path16__default.default.resolve(selfPath);
|
|
17950
18462
|
}
|
|
17951
18463
|
}
|
|
17952
18464
|
if (isPrimaryModule()) {
|