agent-inspect 6.0.0 → 6.3.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 +18 -0
- package/package.json +1 -1
- package/packages/cli/dist/index.cjs +491 -89
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +452 -50
- package/packages/cli/dist/index.mjs.map +1 -1
|
@@ -3786,12 +3786,12 @@ function buildCriticalPath(runs, handoffs) {
|
|
|
3786
3786
|
handoffs.filter((edge) => edge.confidence === "explicit").map((edge) => edge.from)
|
|
3787
3787
|
);
|
|
3788
3788
|
const ordered = [...runs].sort(compareRuns);
|
|
3789
|
-
const
|
|
3789
|
+
const path37 = [];
|
|
3790
3790
|
const visited = /* @__PURE__ */ new Set();
|
|
3791
3791
|
const pushRun = (run, confidence, source) => {
|
|
3792
3792
|
if (visited.has(run.runId)) return;
|
|
3793
3793
|
visited.add(run.runId);
|
|
3794
|
-
|
|
3794
|
+
path37.push({
|
|
3795
3795
|
runId: run.runId,
|
|
3796
3796
|
name: run.name,
|
|
3797
3797
|
startedAt: run.startedAt,
|
|
@@ -3816,7 +3816,7 @@ function buildCriticalPath(runs, handoffs) {
|
|
|
3816
3816
|
const confidence = explicitTargets.has(run.runId) || explicitSources.has(run.runId) ? "explicit" : "correlated";
|
|
3817
3817
|
pushRun(run, confidence, confidence === "explicit" ? "manual" : "inferred");
|
|
3818
3818
|
}
|
|
3819
|
-
return
|
|
3819
|
+
return path37;
|
|
3820
3820
|
}
|
|
3821
3821
|
function metaRunIdMatches(run, token, runById) {
|
|
3822
3822
|
const meta2 = extractSessionWorkflowMetadata(run.metadata);
|
|
@@ -4716,7 +4716,7 @@ function stripPrefix(name, prefixes) {
|
|
|
4716
4716
|
}
|
|
4717
4717
|
return name;
|
|
4718
4718
|
}
|
|
4719
|
-
function eventEvidence(event,
|
|
4719
|
+
function eventEvidence(event, path37) {
|
|
4720
4720
|
return {
|
|
4721
4721
|
runId: event.runId,
|
|
4722
4722
|
eventId: event.eventId,
|
|
@@ -4726,7 +4726,7 @@ function eventEvidence(event, path35) {
|
|
|
4726
4726
|
kind: event.kind,
|
|
4727
4727
|
name: event.name,
|
|
4728
4728
|
status: event.status,
|
|
4729
|
-
...
|
|
4729
|
+
...path37 ? { path: path37 } : {}
|
|
4730
4730
|
};
|
|
4731
4731
|
}
|
|
4732
4732
|
function runEvidence(run) {
|
|
@@ -4789,9 +4789,9 @@ function eventEndMs(event) {
|
|
|
4789
4789
|
function normalizedKey(value) {
|
|
4790
4790
|
return value.toLowerCase().replace(/[^a-z0-9_]/g, "");
|
|
4791
4791
|
}
|
|
4792
|
-
function lastPathSegment(
|
|
4793
|
-
const parts =
|
|
4794
|
-
return parts[parts.length - 1] ??
|
|
4792
|
+
function lastPathSegment(path37) {
|
|
4793
|
+
const parts = path37.split(".");
|
|
4794
|
+
return parts[parts.length - 1] ?? path37;
|
|
4795
4795
|
}
|
|
4796
4796
|
function valueType(value) {
|
|
4797
4797
|
if (Array.isArray(value)) return "array";
|
|
@@ -4805,12 +4805,12 @@ function serializedByteLength(value) {
|
|
|
4805
4805
|
return void 0;
|
|
4806
4806
|
}
|
|
4807
4807
|
}
|
|
4808
|
-
function pushValueEntries(entries, event, value,
|
|
4809
|
-
entries.push({ event, path:
|
|
4808
|
+
function pushValueEntries(entries, event, value, path37, key, depth = 0) {
|
|
4809
|
+
entries.push({ event, path: path37, key, value });
|
|
4810
4810
|
if (depth >= 8) return;
|
|
4811
4811
|
if (Array.isArray(value)) {
|
|
4812
4812
|
for (const [index, item] of value.entries()) {
|
|
4813
|
-
pushValueEntries(entries, event, item, `${
|
|
4813
|
+
pushValueEntries(entries, event, item, `${path37}.${index}`, String(index), depth + 1);
|
|
4814
4814
|
}
|
|
4815
4815
|
return;
|
|
4816
4816
|
}
|
|
@@ -4820,7 +4820,7 @@ function pushValueEntries(entries, event, value, path35, key, depth = 0) {
|
|
|
4820
4820
|
entries,
|
|
4821
4821
|
event,
|
|
4822
4822
|
value[nestedKey],
|
|
4823
|
-
`${
|
|
4823
|
+
`${path37}.${nestedKey}`,
|
|
4824
4824
|
nestedKey,
|
|
4825
4825
|
depth + 1
|
|
4826
4826
|
);
|
|
@@ -4901,9 +4901,9 @@ function eventDurationMs(event) {
|
|
|
4901
4901
|
}
|
|
4902
4902
|
function treeShape(nodes) {
|
|
4903
4903
|
const lines = [];
|
|
4904
|
-
const visit = (node,
|
|
4905
|
-
lines.push(`${
|
|
4906
|
-
node.children.forEach((child, index) => visit(child, `${
|
|
4904
|
+
const visit = (node, path37) => {
|
|
4905
|
+
lines.push(`${path37}:${node.event.kind}:${node.event.name}:${node.event.status ?? "unknown"}`);
|
|
4906
|
+
node.children.forEach((child, index) => visit(child, `${path37}.${index}`));
|
|
4907
4907
|
};
|
|
4908
4908
|
nodes.forEach((node, index) => visit(node, String(index)));
|
|
4909
4909
|
return lines;
|
|
@@ -4952,9 +4952,9 @@ function retrievalShape(context) {
|
|
|
4952
4952
|
function guardrailShape(context) {
|
|
4953
4953
|
return guardrailEvents(context).map((event) => signalName(event, ["guardrailName", "guardrail", "guardrailId"], ["guardrail:"])).sort((a, b) => a.localeCompare(b));
|
|
4954
4954
|
}
|
|
4955
|
-
function firstEvidenceForKind(context, kind,
|
|
4955
|
+
function firstEvidenceForKind(context, kind, path37) {
|
|
4956
4956
|
const event = context.events.find((candidate) => candidate.kind === kind);
|
|
4957
|
-
return event ? [eventEvidence(event,
|
|
4957
|
+
return event ? [eventEvidence(event, path37)] : runEvidence(context.selectedRun);
|
|
4958
4958
|
}
|
|
4959
4959
|
function baselineDiffFinding(message, evidence, expected, actual) {
|
|
4960
4960
|
return failFinding("baseline.regression", message, evidence, expected, actual);
|
|
@@ -5304,13 +5304,13 @@ function createStructureCycleRule() {
|
|
|
5304
5304
|
const seenCycles = /* @__PURE__ */ new Set();
|
|
5305
5305
|
const findings = [];
|
|
5306
5306
|
for (const event of [...context.events].sort((a, b) => a.eventId.localeCompare(b.eventId))) {
|
|
5307
|
-
const
|
|
5307
|
+
const path37 = [];
|
|
5308
5308
|
const seenAt = /* @__PURE__ */ new Map();
|
|
5309
5309
|
let current = event;
|
|
5310
5310
|
while (current) {
|
|
5311
5311
|
const existing = seenAt.get(current.eventId);
|
|
5312
5312
|
if (existing !== void 0) {
|
|
5313
|
-
const cycle =
|
|
5313
|
+
const cycle = path37.slice(existing);
|
|
5314
5314
|
const key = cycle.map((item) => item.eventId).sort().join("\0");
|
|
5315
5315
|
if (!seenCycles.has(key)) {
|
|
5316
5316
|
seenCycles.add(key);
|
|
@@ -5326,8 +5326,8 @@ function createStructureCycleRule() {
|
|
|
5326
5326
|
}
|
|
5327
5327
|
break;
|
|
5328
5328
|
}
|
|
5329
|
-
seenAt.set(current.eventId,
|
|
5330
|
-
|
|
5329
|
+
seenAt.set(current.eventId, path37.length);
|
|
5330
|
+
path37.push(current);
|
|
5331
5331
|
current = current.parentId ? byId.get(current.parentId) : void 0;
|
|
5332
5332
|
}
|
|
5333
5333
|
}
|
|
@@ -9599,19 +9599,19 @@ var require_file_uri_to_path = __commonJS({
|
|
|
9599
9599
|
var rest = decodeURI(uri.substring(7));
|
|
9600
9600
|
var firstSlash = rest.indexOf("/");
|
|
9601
9601
|
var host = rest.substring(0, firstSlash);
|
|
9602
|
-
var
|
|
9602
|
+
var path37 = rest.substring(firstSlash + 1);
|
|
9603
9603
|
if ("localhost" == host) host = "";
|
|
9604
9604
|
if (host) {
|
|
9605
9605
|
host = sep + sep + host;
|
|
9606
9606
|
}
|
|
9607
|
-
|
|
9607
|
+
path37 = path37.replace(/^(.+)\|/, "$1:");
|
|
9608
9608
|
if (sep == "\\") {
|
|
9609
|
-
|
|
9609
|
+
path37 = path37.replace(/\//g, "\\");
|
|
9610
9610
|
}
|
|
9611
|
-
if (/^.+\:/.test(
|
|
9612
|
-
|
|
9611
|
+
if (/^.+\:/.test(path37)) ; else {
|
|
9612
|
+
path37 = sep + path37;
|
|
9613
9613
|
}
|
|
9614
|
-
return host +
|
|
9614
|
+
return host + path37;
|
|
9615
9615
|
}
|
|
9616
9616
|
}
|
|
9617
9617
|
});
|
|
@@ -9620,18 +9620,18 @@ var require_file_uri_to_path = __commonJS({
|
|
|
9620
9620
|
var require_bindings = __commonJS({
|
|
9621
9621
|
"node_modules/.pnpm/bindings@1.5.0/node_modules/bindings/bindings.js"(exports$1, module) {
|
|
9622
9622
|
var fs = __require("fs");
|
|
9623
|
-
var
|
|
9623
|
+
var path37 = __require("path");
|
|
9624
9624
|
var fileURLToPath2 = require_file_uri_to_path();
|
|
9625
|
-
var join =
|
|
9626
|
-
var dirname =
|
|
9627
|
-
var exists2 = fs.accessSync && function(
|
|
9625
|
+
var join = path37.join;
|
|
9626
|
+
var dirname = path37.dirname;
|
|
9627
|
+
var exists2 = fs.accessSync && function(path38) {
|
|
9628
9628
|
try {
|
|
9629
|
-
fs.accessSync(
|
|
9629
|
+
fs.accessSync(path38);
|
|
9630
9630
|
} catch (e) {
|
|
9631
9631
|
return false;
|
|
9632
9632
|
}
|
|
9633
9633
|
return true;
|
|
9634
|
-
} || fs.existsSync ||
|
|
9634
|
+
} || fs.existsSync || path37.existsSync;
|
|
9635
9635
|
var defaults = {
|
|
9636
9636
|
arrow: process.env.NODE_BINDINGS_ARROW || " \u2192 ",
|
|
9637
9637
|
compiled: process.env.NODE_BINDINGS_COMPILED_DIR || "compiled",
|
|
@@ -9676,7 +9676,7 @@ var require_bindings = __commonJS({
|
|
|
9676
9676
|
if (!opts.module_root) {
|
|
9677
9677
|
opts.module_root = exports$1.getRoot(exports$1.getFileName());
|
|
9678
9678
|
}
|
|
9679
|
-
if (
|
|
9679
|
+
if (path37.extname(opts.bindings) != ".node") {
|
|
9680
9680
|
opts.bindings += ".node";
|
|
9681
9681
|
}
|
|
9682
9682
|
var requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
|
|
@@ -9911,7 +9911,7 @@ var require_pragma = __commonJS({
|
|
|
9911
9911
|
var require_backup = __commonJS({
|
|
9912
9912
|
"node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/methods/backup.js"(exports$1, module) {
|
|
9913
9913
|
var fs = __require("fs");
|
|
9914
|
-
var
|
|
9914
|
+
var path37 = __require("path");
|
|
9915
9915
|
var { promisify } = __require("util");
|
|
9916
9916
|
var { cppdb } = require_util();
|
|
9917
9917
|
var fsAccess = promisify(fs.access);
|
|
@@ -9927,7 +9927,7 @@ var require_backup = __commonJS({
|
|
|
9927
9927
|
if (typeof attachedName !== "string") throw new TypeError('Expected the "attached" option to be a string');
|
|
9928
9928
|
if (!attachedName) throw new TypeError('The "attached" option cannot be an empty string');
|
|
9929
9929
|
if (handler != null && typeof handler !== "function") throw new TypeError('Expected the "progress" option to be a function');
|
|
9930
|
-
await fsAccess(
|
|
9930
|
+
await fsAccess(path37.dirname(filename)).catch(() => {
|
|
9931
9931
|
throw new TypeError("Cannot save backup because the directory does not exist");
|
|
9932
9932
|
});
|
|
9933
9933
|
const isNewFile = await fsAccess(filename).then(() => false, () => true);
|
|
@@ -10227,7 +10227,7 @@ var require_inspect = __commonJS({
|
|
|
10227
10227
|
var require_database = __commonJS({
|
|
10228
10228
|
"node_modules/.pnpm/better-sqlite3@11.10.0/node_modules/better-sqlite3/lib/database.js"(exports$1, module) {
|
|
10229
10229
|
var fs = __require("fs");
|
|
10230
|
-
var
|
|
10230
|
+
var path37 = __require("path");
|
|
10231
10231
|
var util = require_util();
|
|
10232
10232
|
var SqliteError = require_sqlite_error();
|
|
10233
10233
|
var DEFAULT_ADDON;
|
|
@@ -10263,7 +10263,7 @@ var require_database = __commonJS({
|
|
|
10263
10263
|
addon = DEFAULT_ADDON || (DEFAULT_ADDON = require_bindings()("better_sqlite3.node"));
|
|
10264
10264
|
} else if (typeof nativeBinding === "string") {
|
|
10265
10265
|
const requireFunc = typeof __non_webpack_require__ === "function" ? __non_webpack_require__ : __require;
|
|
10266
|
-
addon = requireFunc(
|
|
10266
|
+
addon = requireFunc(path37.resolve(nativeBinding).replace(/(\.node)?$/, ".node"));
|
|
10267
10267
|
} else {
|
|
10268
10268
|
addon = nativeBinding;
|
|
10269
10269
|
}
|
|
@@ -10271,7 +10271,7 @@ var require_database = __commonJS({
|
|
|
10271
10271
|
addon.setErrorConstructor(SqliteError);
|
|
10272
10272
|
addon.isInitialized = true;
|
|
10273
10273
|
}
|
|
10274
|
-
if (!anonymous && !fs.existsSync(
|
|
10274
|
+
if (!anonymous && !fs.existsSync(path37.dirname(filename))) {
|
|
10275
10275
|
throw new TypeError("Cannot open database because the directory does not exist");
|
|
10276
10276
|
}
|
|
10277
10277
|
Object.defineProperties(this, {
|
|
@@ -10729,7 +10729,7 @@ var init_src = __esm({
|
|
|
10729
10729
|
});
|
|
10730
10730
|
|
|
10731
10731
|
// package.json
|
|
10732
|
-
var version = "6.
|
|
10732
|
+
var version = "6.3.0";
|
|
10733
10733
|
|
|
10734
10734
|
// packages/cli/src/list.ts
|
|
10735
10735
|
init_advanced();
|
|
@@ -13913,13 +13913,13 @@ function pairSteps(left, right) {
|
|
|
13913
13913
|
return pairs;
|
|
13914
13914
|
}
|
|
13915
13915
|
function compareLeafSteps(L, R, segments, opts, out) {
|
|
13916
|
-
const
|
|
13916
|
+
const path37 = buildPath(segments);
|
|
13917
13917
|
if (L.name !== R.name) {
|
|
13918
13918
|
out.push({
|
|
13919
13919
|
kind: "structure",
|
|
13920
13920
|
severity: "warning",
|
|
13921
13921
|
message: "Step name differs",
|
|
13922
|
-
path:
|
|
13922
|
+
path: path37,
|
|
13923
13923
|
left: L.name,
|
|
13924
13924
|
right: R.name
|
|
13925
13925
|
});
|
|
@@ -13929,7 +13929,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
|
|
|
13929
13929
|
kind: "step-type",
|
|
13930
13930
|
severity: "warning",
|
|
13931
13931
|
message: "Step type differs",
|
|
13932
|
-
path:
|
|
13932
|
+
path: path37,
|
|
13933
13933
|
left: L.type,
|
|
13934
13934
|
right: R.type
|
|
13935
13935
|
});
|
|
@@ -13939,7 +13939,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
|
|
|
13939
13939
|
kind: "step-status",
|
|
13940
13940
|
severity: "warning",
|
|
13941
13941
|
message: "Step status differs",
|
|
13942
|
-
path:
|
|
13942
|
+
path: path37,
|
|
13943
13943
|
left: L.status,
|
|
13944
13944
|
right: R.status
|
|
13945
13945
|
});
|
|
@@ -13951,7 +13951,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
|
|
|
13951
13951
|
kind: "error",
|
|
13952
13952
|
severity: "error",
|
|
13953
13953
|
message: "Step error message differs",
|
|
13954
|
-
path:
|
|
13954
|
+
path: path37,
|
|
13955
13955
|
left: le || void 0,
|
|
13956
13956
|
right: re || void 0
|
|
13957
13957
|
});
|
|
@@ -13969,7 +13969,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
|
|
|
13969
13969
|
kind: "duration",
|
|
13970
13970
|
severity: "info",
|
|
13971
13971
|
message: "Step duration differs",
|
|
13972
|
-
path:
|
|
13972
|
+
path: path37,
|
|
13973
13973
|
left: ld,
|
|
13974
13974
|
right: rd
|
|
13975
13975
|
});
|
|
@@ -13982,7 +13982,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
|
|
|
13982
13982
|
kind: "metadata",
|
|
13983
13983
|
severity: "info",
|
|
13984
13984
|
message: "Step metadata differs",
|
|
13985
|
-
path:
|
|
13985
|
+
path: path37,
|
|
13986
13986
|
left: L.metadata,
|
|
13987
13987
|
right: R.metadata
|
|
13988
13988
|
});
|
|
@@ -13994,7 +13994,7 @@ function compareLeafSteps(L, R, segments, opts, out) {
|
|
|
13994
13994
|
kind: "output",
|
|
13995
13995
|
severity: "info",
|
|
13996
13996
|
message: "Output preview differs",
|
|
13997
|
-
path:
|
|
13997
|
+
path: path37,
|
|
13998
13998
|
left: L.outputPreview,
|
|
13999
13999
|
right: R.outputPreview
|
|
14000
14000
|
});
|
|
@@ -14155,11 +14155,11 @@ function diffRuns(left, right, options) {
|
|
|
14155
14155
|
|
|
14156
14156
|
// packages/core/src/diff/renderer.ts
|
|
14157
14157
|
init_source();
|
|
14158
|
-
function formatPath(
|
|
14159
|
-
if (
|
|
14158
|
+
function formatPath(path37) {
|
|
14159
|
+
if (path37 === void 0 || path37.path.length === 0) {
|
|
14160
14160
|
return "(run)";
|
|
14161
14161
|
}
|
|
14162
|
-
return
|
|
14162
|
+
return path37.path.map((s) => s.name).join(" > ");
|
|
14163
14163
|
}
|
|
14164
14164
|
function formatValue(v, verbose) {
|
|
14165
14165
|
if (v === void 0) return "(undefined)";
|
|
@@ -15280,17 +15280,17 @@ function applyRule(rule, value, replacement) {
|
|
|
15280
15280
|
}
|
|
15281
15281
|
return value;
|
|
15282
15282
|
}
|
|
15283
|
-
function childPath(
|
|
15283
|
+
function childPath(path37, key) {
|
|
15284
15284
|
if (/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key)) {
|
|
15285
|
-
return
|
|
15285
|
+
return path37 ? `${path37}.${key}` : key;
|
|
15286
15286
|
}
|
|
15287
|
-
return `${
|
|
15287
|
+
return `${path37 || "$"}[${JSON.stringify(key)}]`;
|
|
15288
15288
|
}
|
|
15289
|
-
function indexPath(
|
|
15290
|
-
return `${
|
|
15289
|
+
function indexPath(path37, index) {
|
|
15290
|
+
return `${path37 || "$"}[${index}]`;
|
|
15291
15291
|
}
|
|
15292
|
-
function makeFinding(
|
|
15293
|
-
return preview === void 0 ? { path:
|
|
15292
|
+
function makeFinding(path37, detector, action, matchKind, severity = "warning", preview) {
|
|
15293
|
+
return preview === void 0 ? { path: path37, detector, action, severity, matchKind } : { path: path37, detector, action, severity, matchKind, preview };
|
|
15294
15294
|
}
|
|
15295
15295
|
function createRedactionProfile(profile = "local") {
|
|
15296
15296
|
switch (profile) {
|
|
@@ -15359,11 +15359,11 @@ var Redactor2 = class {
|
|
|
15359
15359
|
#recordFinding(state, finding) {
|
|
15360
15360
|
if (this.#collectFindings) state.findings.push(finding);
|
|
15361
15361
|
}
|
|
15362
|
-
#redactValue(value, key,
|
|
15362
|
+
#redactValue(value, key, path37, depth, state) {
|
|
15363
15363
|
if (depth > this.#maxDepth) {
|
|
15364
15364
|
this.#recordFinding(
|
|
15365
15365
|
state,
|
|
15366
|
-
makeFinding(
|
|
15366
|
+
makeFinding(path37, "structure.maxDepth", "truncate", "value", "warning")
|
|
15367
15367
|
);
|
|
15368
15368
|
return "[Truncated]";
|
|
15369
15369
|
}
|
|
@@ -15372,19 +15372,19 @@ var Redactor2 = class {
|
|
|
15372
15372
|
if (rule) {
|
|
15373
15373
|
this.#recordFinding(
|
|
15374
15374
|
state,
|
|
15375
|
-
makeFinding(
|
|
15375
|
+
makeFinding(path37, `key.${rule.key}`, actionForRule(rule), "key", "warning")
|
|
15376
15376
|
);
|
|
15377
15377
|
return applyRule(rule, value, this.#replacement);
|
|
15378
15378
|
}
|
|
15379
15379
|
}
|
|
15380
15380
|
for (const detector of this.#detectors) {
|
|
15381
|
-
const detections = detector.detect({ path:
|
|
15381
|
+
const detections = detector.detect({ path: path37, key, value });
|
|
15382
15382
|
for (const detection of detections) {
|
|
15383
15383
|
const action = detection.action ?? "replace";
|
|
15384
15384
|
this.#recordFinding(
|
|
15385
15385
|
state,
|
|
15386
15386
|
makeFinding(
|
|
15387
|
-
|
|
15387
|
+
path37,
|
|
15388
15388
|
detector.id,
|
|
15389
15389
|
action,
|
|
15390
15390
|
detection.matchKind ?? detector.matchKind ?? "custom",
|
|
@@ -15402,7 +15402,7 @@ var Redactor2 = class {
|
|
|
15402
15402
|
const out = [];
|
|
15403
15403
|
state.seen.set(value, out);
|
|
15404
15404
|
value.forEach((item, index) => {
|
|
15405
|
-
out[index] = this.#redactValue(item, void 0, indexPath(
|
|
15405
|
+
out[index] = this.#redactValue(item, void 0, indexPath(path37, index), depth + 1, state);
|
|
15406
15406
|
});
|
|
15407
15407
|
return out;
|
|
15408
15408
|
}
|
|
@@ -15414,7 +15414,7 @@ var Redactor2 = class {
|
|
|
15414
15414
|
out[entryKey] = this.#redactValue(
|
|
15415
15415
|
entryValue,
|
|
15416
15416
|
entryKey,
|
|
15417
|
-
childPath(
|
|
15417
|
+
childPath(path37 === "$" ? "" : path37, entryKey),
|
|
15418
15418
|
depth + 1,
|
|
15419
15419
|
state
|
|
15420
15420
|
);
|
|
@@ -16355,23 +16355,23 @@ function evaluatePromptInjection(text, options = {}) {
|
|
|
16355
16355
|
}
|
|
16356
16356
|
return fail(ruleId, `Matched ${evidence.length} injection pattern(s).`, evidence, "warning");
|
|
16357
16357
|
}
|
|
16358
|
-
function validateSchemaField(value, field,
|
|
16358
|
+
function validateSchemaField(value, field, path37, evidence) {
|
|
16359
16359
|
const ruleId = "guardrail.structured-output";
|
|
16360
16360
|
if (field.type) {
|
|
16361
16361
|
const actual = value === null ? "null" : Array.isArray(value) ? "array" : typeof value;
|
|
16362
16362
|
if (actual !== field.type) {
|
|
16363
|
-
evidence.push({ ruleId, path:
|
|
16363
|
+
evidence.push({ ruleId, path: path37, preview: `expected ${field.type}, got ${actual}` });
|
|
16364
16364
|
return;
|
|
16365
16365
|
}
|
|
16366
16366
|
}
|
|
16367
16367
|
if (field.enum && !field.enum.some((item) => Object.is(item, value))) {
|
|
16368
|
-
evidence.push({ ruleId, path:
|
|
16368
|
+
evidence.push({ ruleId, path: path37, preview: "value not in enum" });
|
|
16369
16369
|
}
|
|
16370
16370
|
if (field.type === "object" && field.required && value && typeof value === "object" && !Array.isArray(value)) {
|
|
16371
16371
|
const record = value;
|
|
16372
16372
|
for (const key of field.required) {
|
|
16373
16373
|
if (!(key in record)) {
|
|
16374
|
-
evidence.push({ ruleId, path: `${
|
|
16374
|
+
evidence.push({ ruleId, path: `${path37}.${key}`, preview: "missing required key" });
|
|
16375
16375
|
}
|
|
16376
16376
|
}
|
|
16377
16377
|
}
|
|
@@ -16872,10 +16872,10 @@ function printHuman(result) {
|
|
|
16872
16872
|
console.log(`- ${diagnostic7.code}: ${diagnostic7.message}`);
|
|
16873
16873
|
}
|
|
16874
16874
|
for (const finding of result.findings) {
|
|
16875
|
-
const
|
|
16875
|
+
const path37 = finding.evidence[0]?.path;
|
|
16876
16876
|
const run = finding.evidence[0]?.runId;
|
|
16877
16877
|
const runPrefix = run ? `[${run}] ` : "";
|
|
16878
|
-
console.log(`- ${runPrefix}${finding.ruleId}: ${finding.message}${
|
|
16878
|
+
console.log(`- ${runPrefix}${finding.ruleId}: ${finding.message}${path37 ? ` (${path37})` : ""}`);
|
|
16879
16879
|
}
|
|
16880
16880
|
}
|
|
16881
16881
|
function readErrorResult(error) {
|
|
@@ -17929,9 +17929,103 @@ function parsePort2(value) {
|
|
|
17929
17929
|
}
|
|
17930
17930
|
return parsed;
|
|
17931
17931
|
}
|
|
17932
|
+
function summarizeFileDropResult(result) {
|
|
17933
|
+
if (result.skipped) {
|
|
17934
|
+
console.log(`[AgentInspect studio] file-drop skipped: ${result.reason ?? "disabled"}`);
|
|
17935
|
+
return;
|
|
17936
|
+
}
|
|
17937
|
+
console.log(
|
|
17938
|
+
`[AgentInspect studio] file-drop scanned=${result.scanned} imported=${result.imported} skipped=${result.skippedFiles}`
|
|
17939
|
+
);
|
|
17940
|
+
for (const warning of result.warnings) {
|
|
17941
|
+
console.warn(`[AgentInspect studio] ${warning}`);
|
|
17942
|
+
}
|
|
17943
|
+
for (const error of result.errors) {
|
|
17944
|
+
console.error(`[AgentInspect studio] ${error}`);
|
|
17945
|
+
}
|
|
17946
|
+
}
|
|
17947
|
+
function summarizeGitHubResult(result) {
|
|
17948
|
+
if (result.skipped) {
|
|
17949
|
+
console.log(`[AgentInspect studio] github import skipped: ${result.reason ?? "disabled"}`);
|
|
17950
|
+
return;
|
|
17951
|
+
}
|
|
17952
|
+
if (result.imported) {
|
|
17953
|
+
console.log(
|
|
17954
|
+
`[AgentInspect studio] github artifact imported to ${result.destPath ?? "(unknown)"}`
|
|
17955
|
+
);
|
|
17956
|
+
} else if (result.destPath) {
|
|
17957
|
+
console.log(`[AgentInspect studio] github artifact unchanged: ${result.destPath}`);
|
|
17958
|
+
}
|
|
17959
|
+
for (const warning of result.registryImportWarnings) {
|
|
17960
|
+
console.warn(`[AgentInspect studio] ${warning}`);
|
|
17961
|
+
}
|
|
17962
|
+
for (const error of result.errors) {
|
|
17963
|
+
console.error(`[AgentInspect studio] ${error}`);
|
|
17964
|
+
}
|
|
17965
|
+
}
|
|
17966
|
+
async function studioImportBundleCommand(options) {
|
|
17967
|
+
const mod = await loadStudio();
|
|
17968
|
+
if (!mod) return;
|
|
17969
|
+
const result = await mod.runStudioBundleUploadImport({
|
|
17970
|
+
...options.workspace !== void 0 ? { workspacePath: options.workspace } : {},
|
|
17971
|
+
...options.db !== void 0 ? { dbPath: options.db } : {},
|
|
17972
|
+
bundlePath: options.path,
|
|
17973
|
+
...options.cwd !== void 0 ? { cwd: options.cwd } : {}
|
|
17974
|
+
});
|
|
17975
|
+
if (result.skipped) {
|
|
17976
|
+
console.log(`[AgentInspect studio] bundle import skipped: ${result.reason ?? "disabled"}`);
|
|
17977
|
+
} else if (result.imported) {
|
|
17978
|
+
console.log(`[AgentInspect studio] bundle imported to ${result.destPath ?? "(unknown)"}`);
|
|
17979
|
+
} else if (result.destPath) {
|
|
17980
|
+
console.log(`[AgentInspect studio] bundle unchanged: ${result.destPath}`);
|
|
17981
|
+
}
|
|
17982
|
+
for (const warning of result.registryImportWarnings) {
|
|
17983
|
+
console.warn(`[AgentInspect studio] ${warning}`);
|
|
17984
|
+
}
|
|
17985
|
+
for (const error of result.errors) {
|
|
17986
|
+
console.error(`[AgentInspect studio] ${error}`);
|
|
17987
|
+
}
|
|
17988
|
+
if (result.errors.length > 0) process.exitCode = 1;
|
|
17989
|
+
}
|
|
17990
|
+
async function studioImportGitHubCommand(options) {
|
|
17991
|
+
const mod = await loadStudio();
|
|
17992
|
+
if (!mod) return;
|
|
17993
|
+
const result = await mod.runStudioGitHubArtifactImport({
|
|
17994
|
+
...options.workspace !== void 0 ? { workspacePath: options.workspace } : {},
|
|
17995
|
+
...options.db !== void 0 ? { dbPath: options.db } : {},
|
|
17996
|
+
repo: options.repo,
|
|
17997
|
+
runId: options.runId,
|
|
17998
|
+
artifact: options.artifact,
|
|
17999
|
+
...options.tokenEnv !== void 0 ? { tokenEnv: options.tokenEnv } : {},
|
|
18000
|
+
...options.cwd !== void 0 ? { cwd: options.cwd } : {}
|
|
18001
|
+
});
|
|
18002
|
+
summarizeGitHubResult(result);
|
|
18003
|
+
if (result.errors.length > 0) {
|
|
18004
|
+
process.exitCode = 1;
|
|
18005
|
+
}
|
|
18006
|
+
}
|
|
18007
|
+
async function studioImportDropCommand(options = {}) {
|
|
18008
|
+
const mod = await loadStudio();
|
|
18009
|
+
if (!mod) return;
|
|
18010
|
+
const result = await mod.runStudioFileDropImport({
|
|
18011
|
+
...options.workspace !== void 0 ? { workspacePath: options.workspace } : {},
|
|
18012
|
+
...options.db !== void 0 ? { dbPath: options.db } : {},
|
|
18013
|
+
...options.dir !== void 0 ? { dropDir: options.dir } : {},
|
|
18014
|
+
...options.archive === true ? { archiveAfterImport: true } : {},
|
|
18015
|
+
...options.cwd !== void 0 ? { cwd: options.cwd } : {}
|
|
18016
|
+
});
|
|
18017
|
+
summarizeFileDropResult(result);
|
|
18018
|
+
if (result.errors.length > 0) {
|
|
18019
|
+
process.exitCode = 1;
|
|
18020
|
+
}
|
|
18021
|
+
}
|
|
17932
18022
|
async function studioCommand(options = {}) {
|
|
17933
18023
|
const mod = await loadStudio();
|
|
17934
18024
|
if (!mod) return;
|
|
18025
|
+
const ingest = options.ingest?.trim();
|
|
18026
|
+
if (ingest && ingest !== "file-drop" && ingest !== "http") {
|
|
18027
|
+
throw new Error(`Unsupported --ingest channel: ${ingest}. Supported: file-drop, http`);
|
|
18028
|
+
}
|
|
17935
18029
|
const port = parsePort2(options.port);
|
|
17936
18030
|
const host = options.host?.trim();
|
|
17937
18031
|
const info = await mod.startStudioServer({
|
|
@@ -17942,8 +18036,18 @@ async function studioCommand(options = {}) {
|
|
|
17942
18036
|
...options.server === true ? { server: true } : {},
|
|
17943
18037
|
...options.cwd !== void 0 ? { cwd: options.cwd } : {},
|
|
17944
18038
|
...options.auth === "basic" ? { auth: "basic" } : {},
|
|
17945
|
-
...options.passwordEnv !== void 0 ? { passwordEnv: options.passwordEnv } : {}
|
|
18039
|
+
...options.passwordEnv !== void 0 ? { passwordEnv: options.passwordEnv } : {},
|
|
18040
|
+
...ingest === "file-drop" ? { ingestFileDrop: true } : {},
|
|
18041
|
+
...ingest === "http" ? { ingestHttp: true } : {},
|
|
18042
|
+
...options.ingestTokenEnv !== void 0 ? { ingestTokenEnv: options.ingestTokenEnv } : {},
|
|
18043
|
+
...options.archiveFileDrop === true ? { archiveFileDrop: true } : {}
|
|
17946
18044
|
});
|
|
18045
|
+
if (ingest === "file-drop") {
|
|
18046
|
+
console.log(`[AgentInspect studio] file-drop ingest enabled for startup scan`);
|
|
18047
|
+
}
|
|
18048
|
+
if (ingest === "http") {
|
|
18049
|
+
console.log(`[AgentInspect studio] HTTP ingest enabled (token required on POST routes)`);
|
|
18050
|
+
}
|
|
17947
18051
|
console.log(`AgentInspect studio (read-only): ${info.url}`);
|
|
17948
18052
|
if (options.open === true && info.host !== "127.0.0.1" && info.host !== "localhost") {
|
|
17949
18053
|
console.warn("Skipping browser open for non-local host binding.");
|
|
@@ -18124,10 +18228,10 @@ async function evalRun(input3, options = {}) {
|
|
|
18124
18228
|
diagnostics: []
|
|
18125
18229
|
};
|
|
18126
18230
|
}
|
|
18127
|
-
function evidenceForRun(run,
|
|
18128
|
-
return [{ runId: run.runId, ...
|
|
18231
|
+
function evidenceForRun(run, path37) {
|
|
18232
|
+
return [{ runId: run.runId, ...path37 !== void 0 ? { path: path37 } : {} }];
|
|
18129
18233
|
}
|
|
18130
|
-
function evidenceForEvent(event,
|
|
18234
|
+
function evidenceForEvent(event, path37) {
|
|
18131
18235
|
return [
|
|
18132
18236
|
{
|
|
18133
18237
|
runId: event.runId,
|
|
@@ -18135,7 +18239,7 @@ function evidenceForEvent(event, path35) {
|
|
|
18135
18239
|
...event.parentId !== void 0 ? { parentId: event.parentId } : {},
|
|
18136
18240
|
kind: event.kind,
|
|
18137
18241
|
name: event.name,
|
|
18138
|
-
...
|
|
18242
|
+
...path37 !== void 0 ? { path: path37 } : {}
|
|
18139
18243
|
}
|
|
18140
18244
|
];
|
|
18141
18245
|
}
|
|
@@ -18293,9 +18397,9 @@ function collectTextFields(nodes, keys, preferredKinds = []) {
|
|
|
18293
18397
|
function tokenize(text) {
|
|
18294
18398
|
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));
|
|
18295
18399
|
}
|
|
18296
|
-
function firstEvidence(fields, run,
|
|
18400
|
+
function firstEvidence(fields, run, path37) {
|
|
18297
18401
|
const first = fields[0];
|
|
18298
|
-
return first === void 0 ? evidenceForRun(run,
|
|
18402
|
+
return first === void 0 ? evidenceForRun(run, path37) : evidenceForEvent(first.node.event, first.path);
|
|
18299
18403
|
}
|
|
18300
18404
|
function collectSourceIds(nodes, keys) {
|
|
18301
18405
|
const wanted = keySet(keys);
|
|
@@ -18672,8 +18776,8 @@ function renderEvalMarkdown(result) {
|
|
|
18672
18776
|
if (result.findings.length > 0) {
|
|
18673
18777
|
lines.push("", "## Findings");
|
|
18674
18778
|
for (const finding of result.findings) {
|
|
18675
|
-
const
|
|
18676
|
-
lines.push(`- ${finding.ruleId}: ${finding.message}${
|
|
18779
|
+
const path37 = finding.evidence[0]?.path;
|
|
18780
|
+
lines.push(`- ${finding.ruleId}: ${finding.message}${path37 ? ` (${path37})` : ""}`);
|
|
18677
18781
|
}
|
|
18678
18782
|
}
|
|
18679
18783
|
return `${lines.join("\n")}
|
|
@@ -18866,8 +18970,8 @@ function printHuman2(result) {
|
|
|
18866
18970
|
console.log(`- ${diagnostic7.code}: ${diagnostic7.message}`);
|
|
18867
18971
|
}
|
|
18868
18972
|
for (const finding of result.findings) {
|
|
18869
|
-
const
|
|
18870
|
-
console.log(`- ${finding.ruleId}: ${finding.message}${
|
|
18973
|
+
const path37 = finding.evidence[0]?.path;
|
|
18974
|
+
console.log(`- ${finding.ruleId}: ${finding.message}${path37 ? ` (${path37})` : ""}`);
|
|
18871
18975
|
}
|
|
18872
18976
|
}
|
|
18873
18977
|
function readErrorResult2(error) {
|
|
@@ -19105,8 +19209,8 @@ function printHuman3(result) {
|
|
|
19105
19209
|
console.log(`- ${diagnostic7.code}: ${diagnostic7.message}`);
|
|
19106
19210
|
}
|
|
19107
19211
|
for (const finding of result.findings) {
|
|
19108
|
-
const
|
|
19109
|
-
console.log(`- ${finding.ruleId}: ${finding.message}${
|
|
19212
|
+
const path37 = finding.evidence[0]?.path;
|
|
19213
|
+
console.log(`- ${finding.ruleId}: ${finding.message}${path37 ? ` (${path37})` : ""}`);
|
|
19110
19214
|
}
|
|
19111
19215
|
console.log(`Note: ${result.note}`);
|
|
19112
19216
|
}
|
|
@@ -19257,8 +19361,8 @@ function renderCheckSection(result) {
|
|
|
19257
19361
|
`Diagnostics: ${result.diagnostics.length}`
|
|
19258
19362
|
];
|
|
19259
19363
|
for (const finding of result.findings.slice(0, 10)) {
|
|
19260
|
-
const
|
|
19261
|
-
lines.push(`- ${finding.ruleId}: ${finding.message} (${
|
|
19364
|
+
const path37 = finding.evidence[0]?.path ?? "(run)";
|
|
19365
|
+
lines.push(`- ${finding.ruleId}: ${finding.message} (${path37})`);
|
|
19262
19366
|
}
|
|
19263
19367
|
for (const diagnostic7 of result.diagnostics.slice(0, 10)) {
|
|
19264
19368
|
lines.push(`- ${diagnostic7.code}: ${diagnostic7.message}`);
|
|
@@ -20586,6 +20690,176 @@ Summary: ${failed} failed, ${warned} warnings`);
|
|
|
20586
20690
|
if (failed > 0) process3__default.default.exitCode = 1;
|
|
20587
20691
|
}
|
|
20588
20692
|
|
|
20693
|
+
// packages/adapter-sdk/src/privacy.ts
|
|
20694
|
+
var PRIVACY_CHECKLIST_ITEMS = [
|
|
20695
|
+
{
|
|
20696
|
+
id: "capture-metadata-only-default",
|
|
20697
|
+
label: "Default capture is metadata-only (no full prompts/outputs on disk)",
|
|
20698
|
+
required: true
|
|
20699
|
+
},
|
|
20700
|
+
{
|
|
20701
|
+
id: "no-network-by-default",
|
|
20702
|
+
label: "Adapter tests and defaults do not call external networks",
|
|
20703
|
+
required: true
|
|
20704
|
+
},
|
|
20705
|
+
{
|
|
20706
|
+
id: "no-upload",
|
|
20707
|
+
label: "Adapter does not upload traces or logs to vendors by default",
|
|
20708
|
+
required: true
|
|
20709
|
+
},
|
|
20710
|
+
{
|
|
20711
|
+
id: "redaction-documented",
|
|
20712
|
+
label: "Redaction/capture modes are documented for adapter users",
|
|
20713
|
+
required: true
|
|
20714
|
+
},
|
|
20715
|
+
{
|
|
20716
|
+
id: "framework-deps-scoped",
|
|
20717
|
+
label: "Framework SDK dependencies stay in the optional adapter package",
|
|
20718
|
+
required: true
|
|
20719
|
+
}
|
|
20720
|
+
];
|
|
20721
|
+
function runPrivacyChecklist(input3 = {}) {
|
|
20722
|
+
const captureMode = input3.captureMode ?? "metadata-only";
|
|
20723
|
+
const items = [
|
|
20724
|
+
{
|
|
20725
|
+
id: "capture-metadata-only-default",
|
|
20726
|
+
ok: captureMode === "metadata-only",
|
|
20727
|
+
detail: captureMode === "metadata-only" ? void 0 : `captureMode is ${captureMode}; metadata-only is required by default`
|
|
20728
|
+
},
|
|
20729
|
+
{
|
|
20730
|
+
id: "no-network-by-default",
|
|
20731
|
+
ok: input3.networkAllowed !== true,
|
|
20732
|
+
detail: input3.networkAllowed ? "network must be disabled in adapter defaults" : void 0
|
|
20733
|
+
},
|
|
20734
|
+
{
|
|
20735
|
+
id: "no-upload",
|
|
20736
|
+
ok: input3.uploadAllowed !== true,
|
|
20737
|
+
detail: input3.uploadAllowed ? "upload must not be enabled by default" : void 0
|
|
20738
|
+
},
|
|
20739
|
+
{
|
|
20740
|
+
id: "redaction-documented",
|
|
20741
|
+
ok: input3.redactionDocumented !== false,
|
|
20742
|
+
detail: input3.redactionDocumented === false ? "document capture/redaction behavior in adapter README" : void 0
|
|
20743
|
+
},
|
|
20744
|
+
{
|
|
20745
|
+
id: "framework-deps-scoped",
|
|
20746
|
+
ok: input3.frameworkDepsPackageScoped !== false,
|
|
20747
|
+
detail: input3.frameworkDepsPackageScoped === false ? "keep framework SDK deps out of agent-inspect root/core" : void 0
|
|
20748
|
+
}
|
|
20749
|
+
];
|
|
20750
|
+
const requiredFailed = items.some(
|
|
20751
|
+
(item) => PRIVACY_CHECKLIST_ITEMS.find((def) => def.id === item.id)?.required && !item.ok
|
|
20752
|
+
);
|
|
20753
|
+
return { ok: !requiredFailed, items };
|
|
20754
|
+
}
|
|
20755
|
+
var PLUGIN_MANIFEST_FILENAME = "agent-inspect-plugin.manifest.json";
|
|
20756
|
+
var PLUGIN_NAME_PREFIXES = [
|
|
20757
|
+
"agent-inspect-plugin-",
|
|
20758
|
+
"agent-inspect-adapter-",
|
|
20759
|
+
"agent-inspect-renderer-",
|
|
20760
|
+
"agent-inspect-check-",
|
|
20761
|
+
"agent-inspect-importer-"
|
|
20762
|
+
];
|
|
20763
|
+
function isPlainObject2(value) {
|
|
20764
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20765
|
+
}
|
|
20766
|
+
function isPluginPackageName(name) {
|
|
20767
|
+
return PLUGIN_NAME_PREFIXES.some((prefix) => name.startsWith(prefix));
|
|
20768
|
+
}
|
|
20769
|
+
function inferPluginTypeFromName(name) {
|
|
20770
|
+
if (name.startsWith("agent-inspect-adapter-")) return "adapter";
|
|
20771
|
+
if (name.startsWith("agent-inspect-renderer-")) return "renderer";
|
|
20772
|
+
if (name.startsWith("agent-inspect-check-")) return "check";
|
|
20773
|
+
if (name.startsWith("agent-inspect-importer-")) return "importer";
|
|
20774
|
+
if (name.startsWith("agent-inspect-plugin-")) return "plugin";
|
|
20775
|
+
return void 0;
|
|
20776
|
+
}
|
|
20777
|
+
function parsePluginManifest(input3) {
|
|
20778
|
+
const errors = [];
|
|
20779
|
+
const warnings = [];
|
|
20780
|
+
if (!isPlainObject2(input3)) {
|
|
20781
|
+
return { ok: false, errors: ["manifest must be a JSON object"], warnings };
|
|
20782
|
+
}
|
|
20783
|
+
if (input3.schemaVersion !== "1.0") {
|
|
20784
|
+
errors.push('schemaVersion must be "1.0"');
|
|
20785
|
+
}
|
|
20786
|
+
const id = typeof input3.id === "string" ? input3.id.trim() : "";
|
|
20787
|
+
if (!id || !isPluginPackageName(id)) {
|
|
20788
|
+
errors.push("id must use an agent-inspect plugin naming prefix");
|
|
20789
|
+
}
|
|
20790
|
+
const type = typeof input3.type === "string" ? input3.type.trim() : "";
|
|
20791
|
+
const allowedTypes = [
|
|
20792
|
+
"plugin",
|
|
20793
|
+
"adapter",
|
|
20794
|
+
"renderer",
|
|
20795
|
+
"check",
|
|
20796
|
+
"importer"
|
|
20797
|
+
];
|
|
20798
|
+
if (!allowedTypes.includes(type)) {
|
|
20799
|
+
errors.push(`type must be one of: ${allowedTypes.join(", ")}`);
|
|
20800
|
+
}
|
|
20801
|
+
const name = typeof input3.name === "string" ? input3.name.trim() : "";
|
|
20802
|
+
if (!name) errors.push("name must be a non-empty string");
|
|
20803
|
+
const version2 = typeof input3.version === "string" ? input3.version.trim() : "";
|
|
20804
|
+
if (!version2) errors.push("version must be a non-empty string");
|
|
20805
|
+
let privacy;
|
|
20806
|
+
if (input3.privacy !== void 0) {
|
|
20807
|
+
if (!isPlainObject2(input3.privacy)) {
|
|
20808
|
+
errors.push("privacy must be an object");
|
|
20809
|
+
} else {
|
|
20810
|
+
privacy = {};
|
|
20811
|
+
if (input3.privacy.captureMode !== void 0) {
|
|
20812
|
+
privacy.captureMode = String(input3.privacy.captureMode);
|
|
20813
|
+
}
|
|
20814
|
+
if (input3.privacy.networkAllowed !== void 0) {
|
|
20815
|
+
privacy.networkAllowed = Boolean(input3.privacy.networkAllowed);
|
|
20816
|
+
}
|
|
20817
|
+
if (input3.privacy.uploadAllowed !== void 0) {
|
|
20818
|
+
privacy.uploadAllowed = Boolean(input3.privacy.uploadAllowed);
|
|
20819
|
+
}
|
|
20820
|
+
if (input3.privacy.redactionDocumented !== void 0) {
|
|
20821
|
+
privacy.redactionDocumented = Boolean(input3.privacy.redactionDocumented);
|
|
20822
|
+
}
|
|
20823
|
+
if (input3.privacy.frameworkDepsPackageScoped !== void 0) {
|
|
20824
|
+
privacy.frameworkDepsPackageScoped = Boolean(input3.privacy.frameworkDepsPackageScoped);
|
|
20825
|
+
}
|
|
20826
|
+
if (privacy.networkAllowed === true || privacy.uploadAllowed === true) {
|
|
20827
|
+
warnings.push("plugin declares network or upload \u2014 review before install");
|
|
20828
|
+
}
|
|
20829
|
+
}
|
|
20830
|
+
} else {
|
|
20831
|
+
warnings.push("privacy block missing; plugins doctor will assume conservative defaults");
|
|
20832
|
+
}
|
|
20833
|
+
if (errors.length > 0) return { ok: false, errors, warnings };
|
|
20834
|
+
return {
|
|
20835
|
+
ok: true,
|
|
20836
|
+
manifest: {
|
|
20837
|
+
schemaVersion: "1.0",
|
|
20838
|
+
id,
|
|
20839
|
+
type,
|
|
20840
|
+
name,
|
|
20841
|
+
version: version2,
|
|
20842
|
+
...privacy ? { privacy } : {}
|
|
20843
|
+
},
|
|
20844
|
+
errors: [],
|
|
20845
|
+
warnings
|
|
20846
|
+
};
|
|
20847
|
+
}
|
|
20848
|
+
async function readPluginManifestFile(packageDir) {
|
|
20849
|
+
const manifestPath = path26__default.default.join(packageDir, PLUGIN_MANIFEST_FILENAME);
|
|
20850
|
+
try {
|
|
20851
|
+
const raw = await promises.readFile(manifestPath, "utf8");
|
|
20852
|
+
const parsed = parsePluginManifest(JSON.parse(raw));
|
|
20853
|
+
return { ...parsed, path: manifestPath };
|
|
20854
|
+
} catch (error) {
|
|
20855
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
20856
|
+
return { ok: false, path: manifestPath, errors: [message], warnings: [] };
|
|
20857
|
+
}
|
|
20858
|
+
}
|
|
20859
|
+
function validatePluginPrivacy(manifest) {
|
|
20860
|
+
return runPrivacyChecklist(manifest.privacy ?? {});
|
|
20861
|
+
}
|
|
20862
|
+
|
|
20589
20863
|
// packages/adapter-sdk/src/indexer.ts
|
|
20590
20864
|
init_advanced();
|
|
20591
20865
|
function defineIndexer(indexer) {
|
|
@@ -20644,7 +20918,115 @@ function createTraceDirectoryIndexer() {
|
|
|
20644
20918
|
});
|
|
20645
20919
|
}
|
|
20646
20920
|
|
|
20647
|
-
// packages/cli/src/
|
|
20921
|
+
// packages/cli/src/plugins.ts
|
|
20922
|
+
async function readPackageName(packageDir) {
|
|
20923
|
+
try {
|
|
20924
|
+
const raw = await promises.readFile(path26__default.default.join(packageDir, "package.json"), "utf8");
|
|
20925
|
+
const parsed = JSON.parse(raw);
|
|
20926
|
+
return typeof parsed.name === "string" ? parsed.name : void 0;
|
|
20927
|
+
} catch {
|
|
20928
|
+
return void 0;
|
|
20929
|
+
}
|
|
20930
|
+
}
|
|
20931
|
+
async function discoverPlugins(cwd = process.cwd()) {
|
|
20932
|
+
const nodeModules = path26__default.default.join(cwd, "node_modules");
|
|
20933
|
+
const found = [];
|
|
20934
|
+
let entries;
|
|
20935
|
+
try {
|
|
20936
|
+
entries = await promises.readdir(nodeModules);
|
|
20937
|
+
} catch {
|
|
20938
|
+
return found;
|
|
20939
|
+
}
|
|
20940
|
+
for (const entry of entries.sort()) {
|
|
20941
|
+
if (entry.startsWith("@")) continue;
|
|
20942
|
+
if (!isPluginPackageName(entry)) continue;
|
|
20943
|
+
const packageDir = path26__default.default.join(nodeModules, entry);
|
|
20944
|
+
const manifestRead = await readPluginManifestFile(packageDir);
|
|
20945
|
+
found.push({
|
|
20946
|
+
packageName: entry,
|
|
20947
|
+
packageDir,
|
|
20948
|
+
...manifestRead.manifest ? { manifest: manifestRead.manifest } : {},
|
|
20949
|
+
manifestErrors: manifestRead.errors,
|
|
20950
|
+
warnings: manifestRead.warnings
|
|
20951
|
+
});
|
|
20952
|
+
}
|
|
20953
|
+
return found;
|
|
20954
|
+
}
|
|
20955
|
+
async function validatePluginPackage(packageRef, cwd = process.cwd()) {
|
|
20956
|
+
const packageDir = path26__default.default.isAbsolute(packageRef) ? packageRef : path26__default.default.join(cwd, "node_modules", packageRef);
|
|
20957
|
+
const packageName = await readPackageName(packageDir) ?? packageRef;
|
|
20958
|
+
const errors = [];
|
|
20959
|
+
const warnings = [];
|
|
20960
|
+
if (!isPluginPackageName(packageName)) {
|
|
20961
|
+
errors.push(`package name ${packageName} does not match plugin naming convention`);
|
|
20962
|
+
}
|
|
20963
|
+
const manifestRead = await readPluginManifestFile(packageDir);
|
|
20964
|
+
errors.push(...manifestRead.errors);
|
|
20965
|
+
warnings.push(...manifestRead.warnings);
|
|
20966
|
+
if (manifestRead.manifest) {
|
|
20967
|
+
const inferred = inferPluginTypeFromName(packageName);
|
|
20968
|
+
if (inferred && inferred !== manifestRead.manifest.type) {
|
|
20969
|
+
warnings.push(`manifest type ${manifestRead.manifest.type} differs from name prefix (${inferred})`);
|
|
20970
|
+
}
|
|
20971
|
+
const privacy = validatePluginPrivacy(manifestRead.manifest);
|
|
20972
|
+
if (!privacy.ok) {
|
|
20973
|
+
errors.push(
|
|
20974
|
+
...privacy.items.filter((item) => !item.ok).map((item) => item.detail ?? item.id)
|
|
20975
|
+
);
|
|
20976
|
+
}
|
|
20977
|
+
} else if (manifestRead.errors.some((e) => e.includes("ENOENT"))) {
|
|
20978
|
+
warnings.push(`missing ${PLUGIN_MANIFEST_FILENAME}; add manifest for doctor/validate`);
|
|
20979
|
+
}
|
|
20980
|
+
return {
|
|
20981
|
+
ok: errors.length === 0,
|
|
20982
|
+
packageName,
|
|
20983
|
+
packageDir,
|
|
20984
|
+
errors,
|
|
20985
|
+
warnings,
|
|
20986
|
+
manifest: manifestRead.manifest
|
|
20987
|
+
};
|
|
20988
|
+
}
|
|
20989
|
+
async function pluginsListCommand(cwd) {
|
|
20990
|
+
const plugins = await discoverPlugins(cwd);
|
|
20991
|
+
if (plugins.length === 0) {
|
|
20992
|
+
console.log("No agent-inspect plugins found in node_modules.");
|
|
20993
|
+
return;
|
|
20994
|
+
}
|
|
20995
|
+
for (const plugin of plugins) {
|
|
20996
|
+
const type = plugin.manifest?.type ?? inferPluginTypeFromName(plugin.packageName) ?? "unknown";
|
|
20997
|
+
console.log(`${plugin.packageName} (${type})`);
|
|
20998
|
+
}
|
|
20999
|
+
}
|
|
21000
|
+
async function pluginsDoctorCommand(cwd) {
|
|
21001
|
+
const plugins = await discoverPlugins(cwd);
|
|
21002
|
+
if (plugins.length === 0) {
|
|
21003
|
+
console.log("No agent-inspect plugins found.");
|
|
21004
|
+
return;
|
|
21005
|
+
}
|
|
21006
|
+
let issues = 0;
|
|
21007
|
+
for (const plugin of plugins) {
|
|
21008
|
+
const result = await validatePluginPackage(plugin.packageName, cwd);
|
|
21009
|
+
if (result.ok && result.warnings.length === 0) {
|
|
21010
|
+
console.log(`OK ${plugin.packageName}`);
|
|
21011
|
+
continue;
|
|
21012
|
+
}
|
|
21013
|
+
issues += 1;
|
|
21014
|
+
console.log(`WARN ${plugin.packageName}`);
|
|
21015
|
+
for (const warning of result.warnings) console.log(` - ${warning}`);
|
|
21016
|
+
for (const error of result.errors) console.log(` ! ${error}`);
|
|
21017
|
+
}
|
|
21018
|
+
if (issues > 0) process.exitCode = 1;
|
|
21019
|
+
}
|
|
21020
|
+
async function pluginsValidateCommand(packageRef, cwd) {
|
|
21021
|
+
const result = await validatePluginPackage(packageRef, cwd);
|
|
21022
|
+
for (const warning of result.warnings) console.warn(`warning: ${warning}`);
|
|
21023
|
+
if (!result.ok) {
|
|
21024
|
+
for (const error of result.errors) console.error(`error: ${error}`);
|
|
21025
|
+
process.exitCode = 1;
|
|
21026
|
+
return;
|
|
21027
|
+
}
|
|
21028
|
+
console.log(`Valid: ${result.packageName}`);
|
|
21029
|
+
}
|
|
20648
21030
|
init_advanced();
|
|
20649
21031
|
var INDEX_FILENAME = ".agent-inspect-index.json";
|
|
20650
21032
|
function traceIndexPath(traceDir) {
|
|
@@ -21622,11 +22004,21 @@ function createCliProgram() {
|
|
|
21622
22004
|
program.command("viewer").description("Start localhost read-only viewer (traces, suite, or workspace) (v5.3+)").option("--dir <path>", "trace directory (trace mode)").option("--suite", "suite evidence mode").option("--workspace", "workspace mode").option("--config <path>", "suite config path (suite mode)").option("--host <host>", "bind host (default 127.0.0.1)", "127.0.0.1").option("--port <number>", "bind port (default 7337)", "7337").option("--open", "open browser locally when host is localhost").action((opts) => {
|
|
21623
22005
|
runCommand(() => serveCommand(opts));
|
|
21624
22006
|
});
|
|
21625
|
-
program.command("studio").description(
|
|
22007
|
+
const studioCmd = program.command("studio").description(
|
|
21626
22008
|
"Start self-hosted read-only Studio analyzer (requires @agent-inspect/studio) (v6.0+)"
|
|
21627
|
-
).option("--workspace <path>", "studio registry manifest path").option("--db <path>", "studio database path (sqlite file or postgres URL)").option("--host <host>", "bind host (default 127.0.0.1)", "127.0.0.1").option("--port <number>", "bind port (default 7340)", "7340").option("--server", "bind for network access (0.0.0.0; requires explicit opt-in)").option("--auth <mode>", "auth mode: none or basic", "none").option("--password-env <name>", "env var for basic-auth password").option("--open", "open browser locally when host is localhost").action((opts) => {
|
|
22009
|
+
).option("--workspace <path>", "studio registry manifest path").option("--db <path>", "studio database path (sqlite file or postgres URL)").option("--host <host>", "bind host (default 127.0.0.1)", "127.0.0.1").option("--port <number>", "bind port (default 7340)", "7340").option("--server", "bind for network access (0.0.0.0; requires explicit opt-in)").option("--auth <mode>", "auth mode: none or basic", "none").option("--password-env <name>", "env var for basic-auth password").option("--ingest <channel>", "enable ingest channel on startup (file-drop, http)").option("--ingest-token-env <name>", "env var for HTTP ingest token (default STUDIO_INGEST_TOKEN)").option("--archive-file-drop", "archive file-drop sources after successful import").option("--open", "open browser locally when host is localhost").action((opts) => {
|
|
21628
22010
|
runCommand(() => studioCommand(opts));
|
|
21629
22011
|
});
|
|
22012
|
+
const studioImportCmd = studioCmd.command("import").description("Import external evidence into Studio (v6.1+)");
|
|
22013
|
+
studioImportCmd.command("drop").description("Import allowlisted files from a file-drop directory").option("--workspace <path>", "studio registry manifest path").option("--db <path>", "studio database path (sqlite file or postgres URL)").option("--dir <path>", "file-drop directory (defaults to registry import.fileDropDir)").option("--archive", "move imported files into .imported/ under the drop dir").action((opts) => {
|
|
22014
|
+
runCommand(() => studioImportDropCommand(opts));
|
|
22015
|
+
});
|
|
22016
|
+
studioImportCmd.command("github").description("Download a GitHub Actions artifact into the studio import dirs").requiredOption("--repo <owner/name>", "GitHub repository").requiredOption("--run-id <id>", "workflow run id").requiredOption("--artifact <name>", "artifact name").option("--workspace <path>", "studio registry manifest path").option("--db <path>", "studio database path (sqlite file or postgres URL)").option("--token-env <name>", "env var for GitHub token (default GITHUB_TOKEN)").action((opts) => {
|
|
22017
|
+
runCommand(() => studioImportGitHubCommand(opts));
|
|
22018
|
+
});
|
|
22019
|
+
studioImportCmd.command("bundle").description("Import a local share-safe bundle directory into Studio").requiredOption("--path <dir>", "bundle directory path").option("--workspace <path>", "studio registry manifest path").option("--db <path>", "studio database path (sqlite file or postgres URL)").action((opts) => {
|
|
22020
|
+
runCommand(() => studioImportBundleCommand(opts));
|
|
22021
|
+
});
|
|
21630
22022
|
program.command("eval").description("Run deterministic local evals against a trace").argument("<trace-path-or-run-id>", "trace file, directory, stdin -, or run id").option("--dir <path>", "trace directory for run-id lookup").addOption(
|
|
21631
22023
|
new commander.Option("--format <format>", "trace input format").choices([
|
|
21632
22024
|
"agent-inspect-jsonl",
|
|
@@ -21840,6 +22232,16 @@ function createCliProgram() {
|
|
|
21840
22232
|
).action((opts) => {
|
|
21841
22233
|
runCommand(() => doctorCommand(opts));
|
|
21842
22234
|
});
|
|
22235
|
+
const pluginsCmd = program.command("plugins").description("List and validate explicit-install agent-inspect plugins (v6.2+)");
|
|
22236
|
+
pluginsCmd.command("list").description("List installed plugin packages in node_modules").action(() => {
|
|
22237
|
+
runCommand(() => pluginsListCommand());
|
|
22238
|
+
});
|
|
22239
|
+
pluginsCmd.command("doctor").description("Validate plugin manifests and privacy checklists").action(() => {
|
|
22240
|
+
runCommand(() => pluginsDoctorCommand());
|
|
22241
|
+
});
|
|
22242
|
+
pluginsCmd.command("validate").description("Validate one plugin package by name or path").argument("<package>", "plugin package name or directory path").action((packageRef) => {
|
|
22243
|
+
runCommand(() => pluginsValidateCommand(packageRef));
|
|
22244
|
+
});
|
|
21843
22245
|
const indexCmd = program.command("index").description("Optional local trace directory index (rebuildable metadata cache)");
|
|
21844
22246
|
indexCmd.command("build").description("Build or refresh .agent-inspect-index.json").option("--dir <path>", "trace directory").option("--json", "print JSON result").option("--max-entries <n>", "cap indexed entries (default 10000)").action((opts) => {
|
|
21845
22247
|
runCommand(() => indexBuildCommand(opts));
|