agent-inspect 6.17.4 → 6.17.6
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/README.md +1 -1
- package/docs/ADAPTERS.md +3 -3
- package/docs/API.md +13 -7
- package/docs/CLI.md +2 -0
- package/docs/LIMITATIONS.md +1 -0
- package/docs/TRACE-CONTRACTS.md +90 -0
- package/package.json +8 -5
- package/packages/cli/dist/{chunk-YX6RFLV5.mjs → chunk-GOHYSE7W.mjs} +86 -17
- package/packages/cli/dist/chunk-GOHYSE7W.mjs.map +1 -0
- package/packages/cli/dist/index.cjs +522 -81
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +441 -69
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/cli/dist/{src-X6SLMBNH.mjs → src-OYGG7QAZ.mjs} +3 -3
- package/packages/cli/dist/{src-X6SLMBNH.mjs.map → src-OYGG7QAZ.mjs.map} +1 -1
- package/packages/core/dist/advanced.cjs +85 -16
- package/packages/core/dist/advanced.cjs.map +1 -1
- package/packages/core/dist/advanced.d.cts +1 -1
- package/packages/core/dist/advanced.d.ts +1 -1
- package/packages/core/dist/advanced.mjs +15 -5
- package/packages/core/dist/advanced.mjs.map +1 -1
- package/packages/core/dist/checks.cjs +119 -26
- package/packages/core/dist/checks.cjs.map +1 -1
- package/packages/core/dist/checks.d.cts +28 -2
- package/packages/core/dist/checks.d.ts +28 -2
- package/packages/core/dist/checks.mjs +1 -1
- package/packages/core/dist/{chunk-HN377P23.mjs → chunk-DIZPIPY2.mjs} +121 -28
- package/packages/core/dist/chunk-DIZPIPY2.mjs.map +1 -0
- package/packages/core/dist/{index-Xk9X-yjY.d.cts → index-DWu54Y28.d.cts} +107 -122
- package/packages/core/dist/{index-BsCcOKxy.d.ts → index-DlwbVqEs.d.ts} +107 -122
- package/packages/cli/dist/chunk-YX6RFLV5.mjs.map +0 -1
- package/packages/core/dist/chunk-HN377P23.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { createSafetyRawContentRule, createSafetyRedactionRule, createSafetySecretPatternRule, createSafetyOversizedAttributeRule, resolveTraceDir, parseDuration, buildSessionIndex, resolveBundleRunIds, getTraceFilePath, openTrace, sha256Hex, collectTraceSchemaVersions, aggregateBundleSafeStatus, bundleFailsOnSafety, bundleRunAssetRelativePath, buildPlaceholderArtifact, EVIDENCE_HTML_FILENAME, EVIDENCE_MANIFEST_FILENAME, buildBundleMetadata, buildBundleSummaryMarkdown, buildEvidenceHtmlShell, buildEvidenceProvenanceViewHtml, EVIDENCE_FORMAT_VERSION, inferEvidenceFileRole, buildEvidenceSafetyViewHtml, buildEvidenceDiffViewHtml, buildEvidenceCircuitViewHtml, buildEvidenceOutcomesViewHtml, buildEvidenceContractsViewHtml, buildEvidenceToolsLlmViewHtml, buildEvidenceCausalFailureViewHtml, buildEvidenceTimelineViewHtml, buildEvidenceTreeViewHtml, buildEvidenceManifest, serializeEvidenceManifest, buildZipArchive, assertBundlePathContained, enrichSessionRunRecord, normalizeBundleOutputPath, sanitizeBundleRunId, defaultBundleOutputPath, runTraceChecks, assertEvidenceRelativePath, TraceDirectory, loadTraceMetadataList, loadSessionRunRecords, TraceReadError, resolveRedactionProfile, applyProfileMetadataCaps, Redactor, flattenTree, escapeHtml, safeString, compactAttributes, stableJson, escapeMarkdown, truncateStringForProfile, extractMetadata, filterTraces, truncateName, buildRunSummary, formatDuration, formatTimestamp, isAgentInspectTrace, filterMetasBySessionScope, aggregateSessionCheckResults, createBaselineRegressionRule, summarizeSemanticParity, buildEvidenceCiPackage, verifyEvidenceDirectory, diffTraceEvents, renderRunDiff, buildRunTimeline, renderTimeline, buildTraceStats, renderTraceStats, parseDurationFilter, searchTraces, formatStepLabel, buildActivitySummary, renderActivitySummaryHuman, buildRunWhatSummary, renderRunWhat, buildLocalExplanation, resolveSuiteTemplate, defaultSuiteConfigTemplate, loadSuiteConfig, validateSuiteConfig, runSuite, renderSuiteReport, analyzeCohort, renderCohortReport, gateHasThresholds, runGate, renderGateReport, persistedInspectEventsToTraceEvents, renderStepLine, renderErrorLine, getIndent, TreeBuilder, zeroKinds, validateEvent, traceEventToPersistedInspectEvent, isPersistedInspectEvent, createRunStatusRule, createStructureOrphanRule, createStructureCycleRule, createRunDurationRule, createMaxStepDurationRule, createRequireCompletedRule, createStallDetectionRule, createObservedOutcomeRule, createRunDepthRule, createToolUsageRule, createLlmUsageRule, createStructureRelationshipRule, createStructureParallelWidthRule, summarizeObservedOutcomes, extractOutcomesFromTraceEvents, renderObservedOutcomesMarkdown, renderObservedOutcomesHtml, DEFAULT_SUITE_ARTIFACTS_DIR, parseCohortMetricList, COHORT_METRIC_IDS, parseGateList, nanoid, diffRuns, manualTraceEventsToComparableRun } from './chunk-
|
|
2
|
+
import { createSafetyRawContentRule, createSafetyRedactionRule, createSafetySecretPatternRule, createSafetyOversizedAttributeRule, resolveTraceDir, parseDuration, buildSessionIndex, resolveBundleRunIds, getTraceFilePath, openTrace, sha256Hex, collectTraceSchemaVersions, aggregateBundleSafeStatus, bundleFailsOnSafety, bundleRunAssetRelativePath, buildPlaceholderArtifact, EVIDENCE_HTML_FILENAME, EVIDENCE_MANIFEST_FILENAME, buildBundleMetadata, buildBundleSummaryMarkdown, buildEvidenceHtmlShell, buildEvidenceProvenanceViewHtml, EVIDENCE_FORMAT_VERSION, inferEvidenceFileRole, buildEvidenceSafetyViewHtml, buildEvidenceDiffViewHtml, buildEvidenceCircuitViewHtml, buildEvidenceOutcomesViewHtml, buildEvidenceContractsViewHtml, buildEvidenceToolsLlmViewHtml, buildEvidenceCausalFailureViewHtml, buildEvidenceTimelineViewHtml, buildEvidenceTreeViewHtml, buildEvidenceManifest, serializeEvidenceManifest, buildZipArchive, assertBundlePathContained, enrichSessionRunRecord, normalizeBundleOutputPath, sanitizeBundleRunId, defaultBundleOutputPath, runTraceChecks, assertEvidenceRelativePath, TraceDirectory, loadTraceMetadataList, loadSessionRunRecords, TraceReadError, resolveRedactionProfile, applyProfileMetadataCaps, Redactor, flattenTree, escapeHtml, safeString, compactAttributes, stableJson, escapeMarkdown, truncateStringForProfile, extractMetadata, filterTraces, truncateName, buildRunSummary, formatDuration, formatTimestamp, isAgentInspectTrace, filterMetasBySessionScope, aggregateSessionCheckResults, createBaselineRegressionRule, summarizeSemanticParity, buildEvidenceCiPackage, verifyEvidenceDirectory, diffTraceEvents, renderRunDiff, buildRunTimeline, renderTimeline, buildTraceStats, renderTraceStats, parseDurationFilter, searchTraces, formatStepLabel, buildActivitySummary, renderActivitySummaryHuman, buildRunWhatSummary, renderRunWhat, buildLocalExplanation, resolveSuiteTemplate, defaultSuiteConfigTemplate, loadSuiteConfig, validateSuiteConfig, runSuite, renderSuiteReport, analyzeCohort, renderCohortReport, gateHasThresholds, runGate, renderGateReport, persistedInspectEventsToTraceEvents, renderStepLine, renderErrorLine, getIndent, TreeBuilder, zeroKinds, validateEvent, traceEventToPersistedInspectEvent, isPersistedInspectEvent, createRunStatusRule, createStructureOrphanRule, createStructureCycleRule, createRunDurationRule, createMaxStepDurationRule, createRequireCompletedRule, createStallDetectionRule, createObservedOutcomeRule, createRunDepthRule, createToolUsageRule, createLlmUsageRule, createStructureRelationshipRule, createStructureParallelWidthRule, summarizeObservedOutcomes, extractOutcomesFromTraceEvents, renderObservedOutcomesMarkdown, renderObservedOutcomesHtml, DEFAULT_SUITE_ARTIFACTS_DIR, parseCohortMetricList, COHORT_METRIC_IDS, parseGateList, nanoid, diffRuns, manualTraceEventsToComparableRun } from './chunk-GOHYSE7W.mjs';
|
|
3
3
|
import { realpathSync, constants as constants$1, existsSync, readFileSync } from 'fs';
|
|
4
4
|
import path18 from 'path';
|
|
5
5
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
@@ -7,12 +7,13 @@ import { Command, Option } from 'commander';
|
|
|
7
7
|
import { readFile, stat, mkdir, writeFile, unlink, appendFile, access, rm, open, readdir, constants } from 'fs/promises';
|
|
8
8
|
import process2, { stdin, stdout } from 'process';
|
|
9
9
|
import crypto, { createHash } from 'crypto';
|
|
10
|
+
import { execFile, spawn } from 'child_process';
|
|
11
|
+
import { promisify } from 'util';
|
|
10
12
|
import { createServer } from 'http';
|
|
11
|
-
import { spawn } from 'child_process';
|
|
12
13
|
import { createRequire } from 'module';
|
|
13
14
|
|
|
14
15
|
// package.json
|
|
15
|
-
var version = "6.17.
|
|
16
|
+
var version = "6.17.6";
|
|
16
17
|
|
|
17
18
|
// packages/cli/src/trace-dir-scale.ts
|
|
18
19
|
var TRACE_COUNT_WARN = 1e3;
|
|
@@ -1540,6 +1541,11 @@ async function followFile(filePath, options, onLine, shouldStop) {
|
|
|
1540
1541
|
const msg = e instanceof Error ? e.message : String(e);
|
|
1541
1542
|
throw new Error(`Failed to stat file: ${filePath} (${msg})`);
|
|
1542
1543
|
}
|
|
1544
|
+
if (next.size < pos) {
|
|
1545
|
+
pos = 0;
|
|
1546
|
+
carry = "";
|
|
1547
|
+
lineNumber = 0;
|
|
1548
|
+
}
|
|
1543
1549
|
if (next.size > pos) {
|
|
1544
1550
|
const fh = await open(filePath, "r");
|
|
1545
1551
|
try {
|
|
@@ -3347,7 +3353,7 @@ async function newestTraceMtimeMs(traceDir) {
|
|
|
3347
3353
|
}
|
|
3348
3354
|
async function loadSessionRuns(traceDir) {
|
|
3349
3355
|
try {
|
|
3350
|
-
const mod = await import('./src-
|
|
3356
|
+
const mod = await import('./src-OYGG7QAZ.mjs');
|
|
3351
3357
|
const dbPath = mod.resolveIndexDbPath(traceDir);
|
|
3352
3358
|
const status = mod.indexStatus(dbPath);
|
|
3353
3359
|
if (!status.healthy) {
|
|
@@ -5143,8 +5149,11 @@ function checkResultToEvidenceJson(result, runIds) {
|
|
|
5143
5149
|
status,
|
|
5144
5150
|
errors: result.summary.errors,
|
|
5145
5151
|
warnings: result.summary.warnings,
|
|
5146
|
-
findings: result.findings.length
|
|
5152
|
+
findings: result.findings.length,
|
|
5153
|
+
rulesEvaluated: result.summary.rulesEvaluated ?? 0
|
|
5147
5154
|
})),
|
|
5155
|
+
rulesEvaluated: result.summary.rulesEvaluated ?? 0,
|
|
5156
|
+
evaluatedRuleIds: (result.ruleExecutions ?? []).map((item) => item.ruleId),
|
|
5148
5157
|
findings: result.findings,
|
|
5149
5158
|
diagnostics: result.diagnostics
|
|
5150
5159
|
});
|
|
@@ -5769,13 +5778,16 @@ function mergeSafetyExtensions(result, read, options) {
|
|
|
5769
5778
|
passed,
|
|
5770
5779
|
failed,
|
|
5771
5780
|
warnings,
|
|
5772
|
-
errors: result.summary.errors
|
|
5781
|
+
errors: result.summary.errors,
|
|
5782
|
+
rulesEvaluated: result.summary.rulesEvaluated ?? 0
|
|
5773
5783
|
},
|
|
5774
|
-
findings
|
|
5784
|
+
findings,
|
|
5785
|
+
ruleExecutions: result.ruleExecutions ?? []
|
|
5775
5786
|
};
|
|
5776
5787
|
}
|
|
5777
5788
|
|
|
5778
5789
|
// packages/cli/src/check.ts
|
|
5790
|
+
var execFileAsync = promisify(execFile);
|
|
5779
5791
|
var DEFAULT_SELECT = ["run.status"];
|
|
5780
5792
|
function uniqueSelectIds(ids) {
|
|
5781
5793
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -5891,10 +5903,12 @@ function errorResult(code, message, format = "unknown") {
|
|
|
5891
5903
|
passed: 0,
|
|
5892
5904
|
failed: 0,
|
|
5893
5905
|
warnings: 0,
|
|
5894
|
-
errors: 1
|
|
5906
|
+
errors: 1,
|
|
5907
|
+
rulesEvaluated: 0
|
|
5895
5908
|
},
|
|
5896
5909
|
findings: [],
|
|
5897
|
-
diagnostics
|
|
5910
|
+
diagnostics,
|
|
5911
|
+
ruleExecutions: []
|
|
5898
5912
|
};
|
|
5899
5913
|
}
|
|
5900
5914
|
function parseNumber(value, label) {
|
|
@@ -5912,36 +5926,368 @@ function asStringArray(value) {
|
|
|
5912
5926
|
}
|
|
5913
5927
|
return value;
|
|
5914
5928
|
}
|
|
5915
|
-
|
|
5929
|
+
var CHECKS_KEYS = /* @__PURE__ */ new Set(["select", "run", "tool", "llm", "structure", "safety"]);
|
|
5930
|
+
var RUN_KEYS = /* @__PURE__ */ new Set(["expected", "allowIncomplete", "maxDurationMs", "maxDepth"]);
|
|
5931
|
+
var TOOL_KEYS = /* @__PURE__ */ new Set(["required", "forbidden", "allowed", "minCount", "maxCount"]);
|
|
5932
|
+
var LLM_KEYS = /* @__PURE__ */ new Set([
|
|
5933
|
+
"allowedModels",
|
|
5934
|
+
"allowedProviders",
|
|
5935
|
+
"finishReasons",
|
|
5936
|
+
"maxCalls",
|
|
5937
|
+
"maxTotalTokens",
|
|
5938
|
+
"maxInputTokens",
|
|
5939
|
+
"maxOutputTokens",
|
|
5940
|
+
"maxCachedTokens"
|
|
5941
|
+
]);
|
|
5942
|
+
var STRUCTURE_KEYS = /* @__PURE__ */ new Set([
|
|
5943
|
+
"minConfidence",
|
|
5944
|
+
"requireParentBeforeChild",
|
|
5945
|
+
"requireTraceParentSpan",
|
|
5946
|
+
"orphan",
|
|
5947
|
+
"cycle",
|
|
5948
|
+
"maxChildren",
|
|
5949
|
+
"maxConcurrent"
|
|
5950
|
+
]);
|
|
5951
|
+
var SAFETY_KEYS = /* @__PURE__ */ new Set([
|
|
5952
|
+
"redaction",
|
|
5953
|
+
"rawContent",
|
|
5954
|
+
"secretPattern",
|
|
5955
|
+
"maxStringLength",
|
|
5956
|
+
"maxArrayLength",
|
|
5957
|
+
"maxObjectKeys",
|
|
5958
|
+
"maxSerializedBytes",
|
|
5959
|
+
"maxFindings"
|
|
5960
|
+
]);
|
|
5961
|
+
var RUN_EXPECTED = /* @__PURE__ */ new Set(["ok", "error", "running"]);
|
|
5962
|
+
var CONFIDENCE_VALUES = /* @__PURE__ */ new Set(["exact", "high", "medium", "low", "inferred"]);
|
|
5963
|
+
var CheckConfigError = class extends Error {
|
|
5964
|
+
code;
|
|
5965
|
+
constructor(code, message) {
|
|
5966
|
+
super(message);
|
|
5967
|
+
this.name = "CheckConfigError";
|
|
5968
|
+
this.code = code;
|
|
5969
|
+
}
|
|
5970
|
+
};
|
|
5971
|
+
function closestKey(unknown, known) {
|
|
5972
|
+
const lower = unknown.toLowerCase();
|
|
5973
|
+
let best;
|
|
5974
|
+
let bestDistance = Number.POSITIVE_INFINITY;
|
|
5975
|
+
for (const candidate of known) {
|
|
5976
|
+
if (candidate.toLowerCase() === lower) return candidate;
|
|
5977
|
+
let distance = Math.abs(candidate.length - unknown.length);
|
|
5978
|
+
const max = Math.max(candidate.length, unknown.length);
|
|
5979
|
+
for (let i = 0; i < Math.min(candidate.length, unknown.length); i += 1) {
|
|
5980
|
+
if (candidate[i].toLowerCase() !== unknown[i].toLowerCase()) distance += 1;
|
|
5981
|
+
}
|
|
5982
|
+
if (distance < bestDistance && distance <= Math.max(2, Math.floor(max / 3))) {
|
|
5983
|
+
bestDistance = distance;
|
|
5984
|
+
best = candidate;
|
|
5985
|
+
}
|
|
5986
|
+
}
|
|
5987
|
+
return best;
|
|
5988
|
+
}
|
|
5989
|
+
function rejectUnknownKeys(record, allowed, pathPrefix) {
|
|
5990
|
+
for (const key of Object.keys(record)) {
|
|
5991
|
+
if (allowed.has(key)) continue;
|
|
5992
|
+
const suggestion = closestKey(key, [...allowed]);
|
|
5993
|
+
const hint = suggestion ? ` Did you mean "${suggestion}"?` : "";
|
|
5994
|
+
throw new CheckConfigError(
|
|
5995
|
+
"AI_CHECK_CONFIG_UNKNOWN_KEY",
|
|
5996
|
+
`Unknown check config key "${pathPrefix}.${key}".${hint}`
|
|
5997
|
+
);
|
|
5998
|
+
}
|
|
5999
|
+
}
|
|
6000
|
+
function requireObject(value, pathPrefix) {
|
|
6001
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
6002
|
+
throw new CheckConfigError(
|
|
6003
|
+
"AI_CHECK_CONFIG_INVALID_VALUE",
|
|
6004
|
+
`${pathPrefix} must be an object.`
|
|
6005
|
+
);
|
|
6006
|
+
}
|
|
6007
|
+
return value;
|
|
6008
|
+
}
|
|
6009
|
+
function requireStringArray(value, pathPrefix) {
|
|
6010
|
+
if (!Array.isArray(value) || value.some((item) => typeof item !== "string" || item.trim() === "")) {
|
|
6011
|
+
throw new CheckConfigError(
|
|
6012
|
+
"AI_CHECK_CONFIG_INVALID_VALUE",
|
|
6013
|
+
`${pathPrefix} must be an array of non-empty strings.`
|
|
6014
|
+
);
|
|
6015
|
+
}
|
|
6016
|
+
return value;
|
|
6017
|
+
}
|
|
6018
|
+
function requireNonNegativeNumber(value, pathPrefix) {
|
|
6019
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
|
|
6020
|
+
throw new CheckConfigError(
|
|
6021
|
+
"AI_CHECK_CONFIG_INVALID_VALUE",
|
|
6022
|
+
`${pathPrefix} must be a finite non-negative number.`
|
|
6023
|
+
);
|
|
6024
|
+
}
|
|
6025
|
+
return value;
|
|
6026
|
+
}
|
|
6027
|
+
function requireBoolean(value, pathPrefix) {
|
|
6028
|
+
if (typeof value !== "boolean") {
|
|
6029
|
+
throw new CheckConfigError(
|
|
6030
|
+
"AI_CHECK_CONFIG_INVALID_VALUE",
|
|
6031
|
+
`${pathPrefix} must be a boolean.`
|
|
6032
|
+
);
|
|
6033
|
+
}
|
|
6034
|
+
return value;
|
|
6035
|
+
}
|
|
6036
|
+
function parseRunSection(value) {
|
|
6037
|
+
const record = requireObject(value, "checks.run");
|
|
6038
|
+
rejectUnknownKeys(record, RUN_KEYS, "checks.run");
|
|
6039
|
+
const out = {};
|
|
6040
|
+
if (record.expected !== void 0) {
|
|
6041
|
+
if (typeof record.expected !== "string" || !RUN_EXPECTED.has(record.expected)) {
|
|
6042
|
+
throw new CheckConfigError(
|
|
6043
|
+
"AI_CHECK_CONFIG_INVALID_VALUE",
|
|
6044
|
+
`checks.run.expected must be one of: ok, error, running.`
|
|
6045
|
+
);
|
|
6046
|
+
}
|
|
6047
|
+
out.expected = record.expected;
|
|
6048
|
+
}
|
|
6049
|
+
if (record.allowIncomplete !== void 0) {
|
|
6050
|
+
out.allowIncomplete = requireBoolean(record.allowIncomplete, "checks.run.allowIncomplete");
|
|
6051
|
+
}
|
|
6052
|
+
if (record.maxDurationMs !== void 0) {
|
|
6053
|
+
out.maxDurationMs = requireNonNegativeNumber(record.maxDurationMs, "checks.run.maxDurationMs");
|
|
6054
|
+
}
|
|
6055
|
+
if (record.maxDepth !== void 0) {
|
|
6056
|
+
out.maxDepth = requireNonNegativeNumber(record.maxDepth, "checks.run.maxDepth");
|
|
6057
|
+
}
|
|
6058
|
+
return out;
|
|
6059
|
+
}
|
|
6060
|
+
function parseToolSection(value) {
|
|
6061
|
+
const record = requireObject(value, "checks.tool");
|
|
6062
|
+
rejectUnknownKeys(record, TOOL_KEYS, "checks.tool");
|
|
6063
|
+
const out = {};
|
|
6064
|
+
if (record.required !== void 0) out.required = requireStringArray(record.required, "checks.tool.required");
|
|
6065
|
+
if (record.forbidden !== void 0) out.forbidden = requireStringArray(record.forbidden, "checks.tool.forbidden");
|
|
6066
|
+
if (record.allowed !== void 0) out.allowed = requireStringArray(record.allowed, "checks.tool.allowed");
|
|
6067
|
+
if (record.minCount !== void 0) out.minCount = requireNonNegativeNumber(record.minCount, "checks.tool.minCount");
|
|
6068
|
+
if (record.maxCount !== void 0) out.maxCount = requireNonNegativeNumber(record.maxCount, "checks.tool.maxCount");
|
|
6069
|
+
return out;
|
|
6070
|
+
}
|
|
6071
|
+
function parseLlmSection(value) {
|
|
6072
|
+
const record = requireObject(value, "checks.llm");
|
|
6073
|
+
rejectUnknownKeys(record, LLM_KEYS, "checks.llm");
|
|
6074
|
+
const out = {};
|
|
6075
|
+
if (record.allowedModels !== void 0) {
|
|
6076
|
+
out.allowedModels = requireStringArray(record.allowedModels, "checks.llm.allowedModels");
|
|
6077
|
+
}
|
|
6078
|
+
if (record.allowedProviders !== void 0) {
|
|
6079
|
+
out.allowedProviders = requireStringArray(record.allowedProviders, "checks.llm.allowedProviders");
|
|
6080
|
+
}
|
|
6081
|
+
if (record.finishReasons !== void 0) {
|
|
6082
|
+
out.finishReasons = requireStringArray(record.finishReasons, "checks.llm.finishReasons");
|
|
6083
|
+
}
|
|
6084
|
+
if (record.maxCalls !== void 0) out.maxCalls = requireNonNegativeNumber(record.maxCalls, "checks.llm.maxCalls");
|
|
6085
|
+
if (record.maxTotalTokens !== void 0) {
|
|
6086
|
+
out.maxTotalTokens = requireNonNegativeNumber(record.maxTotalTokens, "checks.llm.maxTotalTokens");
|
|
6087
|
+
}
|
|
6088
|
+
if (record.maxInputTokens !== void 0) {
|
|
6089
|
+
out.maxInputTokens = requireNonNegativeNumber(record.maxInputTokens, "checks.llm.maxInputTokens");
|
|
6090
|
+
}
|
|
6091
|
+
if (record.maxOutputTokens !== void 0) {
|
|
6092
|
+
out.maxOutputTokens = requireNonNegativeNumber(record.maxOutputTokens, "checks.llm.maxOutputTokens");
|
|
6093
|
+
}
|
|
6094
|
+
if (record.maxCachedTokens !== void 0) {
|
|
6095
|
+
out.maxCachedTokens = requireNonNegativeNumber(record.maxCachedTokens, "checks.llm.maxCachedTokens");
|
|
6096
|
+
}
|
|
6097
|
+
return out;
|
|
6098
|
+
}
|
|
6099
|
+
function parseStructureSection(value) {
|
|
6100
|
+
const record = requireObject(value, "checks.structure");
|
|
6101
|
+
rejectUnknownKeys(record, STRUCTURE_KEYS, "checks.structure");
|
|
6102
|
+
const out = {};
|
|
6103
|
+
if (record.minConfidence !== void 0) {
|
|
6104
|
+
if (typeof record.minConfidence !== "string" || !CONFIDENCE_VALUES.has(record.minConfidence)) {
|
|
6105
|
+
throw new CheckConfigError(
|
|
6106
|
+
"AI_CHECK_CONFIG_INVALID_VALUE",
|
|
6107
|
+
`checks.structure.minConfidence must be one of: exact, high, medium, low, inferred.`
|
|
6108
|
+
);
|
|
6109
|
+
}
|
|
6110
|
+
out.minConfidence = record.minConfidence;
|
|
6111
|
+
}
|
|
6112
|
+
if (record.requireParentBeforeChild !== void 0) {
|
|
6113
|
+
out.requireParentBeforeChild = requireBoolean(
|
|
6114
|
+
record.requireParentBeforeChild,
|
|
6115
|
+
"checks.structure.requireParentBeforeChild"
|
|
6116
|
+
);
|
|
6117
|
+
}
|
|
6118
|
+
if (record.requireTraceParentSpan !== void 0) {
|
|
6119
|
+
out.requireTraceParentSpan = requireBoolean(
|
|
6120
|
+
record.requireTraceParentSpan,
|
|
6121
|
+
"checks.structure.requireTraceParentSpan"
|
|
6122
|
+
);
|
|
6123
|
+
}
|
|
6124
|
+
if (record.orphan !== void 0) out.orphan = requireBoolean(record.orphan, "checks.structure.orphan");
|
|
6125
|
+
if (record.cycle !== void 0) out.cycle = requireBoolean(record.cycle, "checks.structure.cycle");
|
|
6126
|
+
if (record.maxChildren !== void 0) {
|
|
6127
|
+
out.maxChildren = requireNonNegativeNumber(record.maxChildren, "checks.structure.maxChildren");
|
|
6128
|
+
}
|
|
6129
|
+
if (record.maxConcurrent !== void 0) {
|
|
6130
|
+
out.maxConcurrent = requireNonNegativeNumber(record.maxConcurrent, "checks.structure.maxConcurrent");
|
|
6131
|
+
}
|
|
6132
|
+
return out;
|
|
6133
|
+
}
|
|
6134
|
+
function parseSafetySection(value) {
|
|
6135
|
+
const record = requireObject(value, "checks.safety");
|
|
6136
|
+
rejectUnknownKeys(record, SAFETY_KEYS, "checks.safety");
|
|
6137
|
+
const out = {};
|
|
6138
|
+
if (record.redaction !== void 0) out.redaction = requireBoolean(record.redaction, "checks.safety.redaction");
|
|
6139
|
+
if (record.rawContent !== void 0) out.rawContent = requireBoolean(record.rawContent, "checks.safety.rawContent");
|
|
6140
|
+
if (record.secretPattern !== void 0) {
|
|
6141
|
+
out.secretPattern = requireBoolean(record.secretPattern, "checks.safety.secretPattern");
|
|
6142
|
+
}
|
|
6143
|
+
if (record.maxStringLength !== void 0) {
|
|
6144
|
+
out.maxStringLength = requireNonNegativeNumber(record.maxStringLength, "checks.safety.maxStringLength");
|
|
6145
|
+
}
|
|
6146
|
+
if (record.maxArrayLength !== void 0) {
|
|
6147
|
+
out.maxArrayLength = requireNonNegativeNumber(record.maxArrayLength, "checks.safety.maxArrayLength");
|
|
6148
|
+
}
|
|
6149
|
+
if (record.maxObjectKeys !== void 0) {
|
|
6150
|
+
out.maxObjectKeys = requireNonNegativeNumber(record.maxObjectKeys, "checks.safety.maxObjectKeys");
|
|
6151
|
+
}
|
|
6152
|
+
if (record.maxSerializedBytes !== void 0) {
|
|
6153
|
+
out.maxSerializedBytes = requireNonNegativeNumber(
|
|
6154
|
+
record.maxSerializedBytes,
|
|
6155
|
+
"checks.safety.maxSerializedBytes"
|
|
6156
|
+
);
|
|
6157
|
+
}
|
|
6158
|
+
if (record.maxFindings !== void 0) {
|
|
6159
|
+
out.maxFindings = requireNonNegativeNumber(record.maxFindings, "checks.safety.maxFindings");
|
|
6160
|
+
}
|
|
6161
|
+
return out;
|
|
6162
|
+
}
|
|
6163
|
+
function sectionHasEffect(section) {
|
|
6164
|
+
if (section === void 0) return false;
|
|
6165
|
+
return Object.keys(section).length > 0;
|
|
6166
|
+
}
|
|
6167
|
+
function checkConfigHasEffect(config) {
|
|
6168
|
+
const checks2 = config.checks;
|
|
6169
|
+
if (checks2 === void 0) return false;
|
|
6170
|
+
if ((checks2.select?.length ?? 0) > 0) return true;
|
|
6171
|
+
if (sectionHasEffect(checks2.run)) return true;
|
|
6172
|
+
if (sectionHasEffect(checks2.tool)) return true;
|
|
6173
|
+
if (sectionHasEffect(checks2.llm)) return true;
|
|
6174
|
+
if (sectionHasEffect(checks2.structure)) return true;
|
|
6175
|
+
if (sectionHasEffect(checks2.safety)) return true;
|
|
6176
|
+
return false;
|
|
6177
|
+
}
|
|
6178
|
+
function parseCheckConfig(value) {
|
|
5916
6179
|
if (value === void 0 || value === null) return {};
|
|
5917
6180
|
if (typeof value !== "object" || Array.isArray(value)) {
|
|
5918
|
-
throw new
|
|
6181
|
+
throw new CheckConfigError("AI_CHECK_CONFIG_INVALID_VALUE", "Config must export an object.");
|
|
5919
6182
|
}
|
|
5920
|
-
|
|
6183
|
+
const root = value;
|
|
6184
|
+
if ("contract" in root) {
|
|
6185
|
+
throw new CheckConfigError(
|
|
6186
|
+
"AI_CHECK_CONFIG_UNKNOWN_KEY",
|
|
6187
|
+
'Top-level "contract" is not supported by `agent-inspect check --config`. Use the TraceContract TypeScript API (`defineTraceContract` / `evaluateTraceContract` from `agent-inspect/checks`), or express tool/run/llm rules under `checks`.'
|
|
6188
|
+
);
|
|
6189
|
+
}
|
|
6190
|
+
const rootKeys = Object.keys(root);
|
|
6191
|
+
for (const key of rootKeys) {
|
|
6192
|
+
if (key === "checks") continue;
|
|
6193
|
+
const suggestion = closestKey(key, ["checks"]);
|
|
6194
|
+
const hint = suggestion ? ` Did you mean "${suggestion}"?` : "";
|
|
6195
|
+
throw new CheckConfigError(
|
|
6196
|
+
"AI_CHECK_CONFIG_UNKNOWN_KEY",
|
|
6197
|
+
`Unknown top-level check config key "${key}". Allowed: checks.${hint}`
|
|
6198
|
+
);
|
|
6199
|
+
}
|
|
6200
|
+
if (!("checks" in root)) return {};
|
|
6201
|
+
const checksRecord = requireObject(root.checks, "checks");
|
|
6202
|
+
rejectUnknownKeys(checksRecord, CHECKS_KEYS, "checks");
|
|
6203
|
+
const checks2 = {};
|
|
6204
|
+
if (checksRecord.select !== void 0) {
|
|
6205
|
+
checks2.select = requireStringArray(checksRecord.select, "checks.select");
|
|
6206
|
+
}
|
|
6207
|
+
if (checksRecord.run !== void 0) checks2.run = parseRunSection(checksRecord.run);
|
|
6208
|
+
if (checksRecord.tool !== void 0) checks2.tool = parseToolSection(checksRecord.tool);
|
|
6209
|
+
if (checksRecord.llm !== void 0) checks2.llm = parseLlmSection(checksRecord.llm);
|
|
6210
|
+
if (checksRecord.structure !== void 0) {
|
|
6211
|
+
checks2.structure = parseStructureSection(checksRecord.structure);
|
|
6212
|
+
}
|
|
6213
|
+
if (checksRecord.safety !== void 0) checks2.safety = parseSafetySection(checksRecord.safety);
|
|
6214
|
+
return { checks: checks2 };
|
|
5921
6215
|
}
|
|
5922
6216
|
async function loadConfig(configPath) {
|
|
5923
6217
|
if (configPath === void 0) return {};
|
|
5924
6218
|
const extension = path18.extname(configPath);
|
|
5925
6219
|
if (TS_CONFIG_EXTENSIONS.has(extension)) {
|
|
5926
|
-
throw new
|
|
6220
|
+
throw new CheckConfigError(
|
|
6221
|
+
"AI_CHECK_CONFIG_LOAD_FAILED",
|
|
5927
6222
|
"TypeScript check configs require an explicit precompiled JavaScript config or future --config-loader support."
|
|
5928
6223
|
);
|
|
5929
6224
|
}
|
|
5930
6225
|
if (!CONFIG_EXTENSIONS.has(extension)) {
|
|
5931
|
-
throw new
|
|
6226
|
+
throw new CheckConfigError(
|
|
6227
|
+
"AI_CHECK_CONFIG_LOAD_FAILED",
|
|
6228
|
+
"Unsupported check config extension. Use .json, .js, .mjs, or .cjs."
|
|
6229
|
+
);
|
|
5932
6230
|
}
|
|
5933
6231
|
const absolute = path18.resolve(configPath);
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
|
|
6232
|
+
try {
|
|
6233
|
+
if (extension === ".json") {
|
|
6234
|
+
const raw = await readFile(absolute, "utf-8");
|
|
6235
|
+
return parseCheckConfig(JSON.parse(raw));
|
|
6236
|
+
}
|
|
6237
|
+
return parseCheckConfig(await importJsCheckConfig(absolute));
|
|
6238
|
+
} catch (error) {
|
|
6239
|
+
if (error instanceof CheckConfigError) throw error;
|
|
6240
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
6241
|
+
throw new CheckConfigError(
|
|
6242
|
+
"AI_CHECK_CONFIG_LOAD_FAILED",
|
|
6243
|
+
`Failed to load check config: ${message}`
|
|
6244
|
+
);
|
|
6245
|
+
}
|
|
6246
|
+
}
|
|
6247
|
+
async function importJsCheckConfig(absolute) {
|
|
6248
|
+
const href = pathToFileURL(absolute).href;
|
|
6249
|
+
if (!process.env.VITEST) {
|
|
6250
|
+
const mod = await import(
|
|
6251
|
+
/* @vite-ignore */
|
|
6252
|
+
href
|
|
6253
|
+
);
|
|
6254
|
+
return "default" in mod ? mod.default : mod;
|
|
6255
|
+
}
|
|
6256
|
+
const script = `
|
|
6257
|
+
const mod = await import(${JSON.stringify(href)});
|
|
6258
|
+
const value = "default" in mod ? mod.default : mod;
|
|
6259
|
+
process.stdout.write(JSON.stringify({ ok: true, value }));
|
|
6260
|
+
`;
|
|
6261
|
+
const env = { ...process.env };
|
|
6262
|
+
delete env.NODE_OPTIONS;
|
|
6263
|
+
delete env.VITEST;
|
|
6264
|
+
delete env.VITEST_WORKER_ID;
|
|
6265
|
+
const { stdout, stderr } = await execFileAsync(
|
|
6266
|
+
process.execPath,
|
|
6267
|
+
["--input-type=module", "--eval", script],
|
|
6268
|
+
{
|
|
6269
|
+
encoding: "utf8",
|
|
6270
|
+
maxBuffer: 4 * 1024 * 1024,
|
|
6271
|
+
env
|
|
6272
|
+
}
|
|
6273
|
+
);
|
|
6274
|
+
try {
|
|
6275
|
+
const parsed = JSON.parse(stdout);
|
|
6276
|
+
if (parsed.ok !== true) {
|
|
6277
|
+
throw new Error(stderr.trim() || "Check config module did not return a value");
|
|
6278
|
+
}
|
|
6279
|
+
return parsed.value;
|
|
6280
|
+
} catch (error) {
|
|
6281
|
+
if (stderr.trim()) {
|
|
6282
|
+
throw new Error(stderr.trim());
|
|
6283
|
+
}
|
|
6284
|
+
throw error instanceof Error ? error : new Error(String(error));
|
|
5937
6285
|
}
|
|
5938
|
-
const mod = await import(pathToFileURL(absolute).href);
|
|
5939
|
-
return asConfig("default" in mod ? mod.default : mod);
|
|
5940
6286
|
}
|
|
5941
6287
|
function normalizeConfig(config) {
|
|
5942
6288
|
if (config.checks === void 0) return {};
|
|
5943
6289
|
if (typeof config.checks !== "object" || Array.isArray(config.checks)) {
|
|
5944
|
-
throw new
|
|
6290
|
+
throw new CheckConfigError("AI_CHECK_CONFIG_INVALID_VALUE", "checks config must be an object.");
|
|
5945
6291
|
}
|
|
5946
6292
|
return config.checks;
|
|
5947
6293
|
}
|
|
@@ -6019,7 +6365,7 @@ function buildRules(config, options, presetSelect = []) {
|
|
|
6019
6365
|
}
|
|
6020
6366
|
throw new Error(`unsupported status "${value}"`);
|
|
6021
6367
|
});
|
|
6022
|
-
rules.push(createObservedOutcomeRule({ failOn: statuses }));
|
|
6368
|
+
rules.push(createObservedOutcomeRule({ failOn: statuses, requireAny: true }));
|
|
6023
6369
|
} catch (error) {
|
|
6024
6370
|
const message = error instanceof Error ? error.message : String(error);
|
|
6025
6371
|
diagnostics.push(
|
|
@@ -6091,7 +6437,7 @@ function exitCodeFor(result) {
|
|
|
6091
6437
|
return 3;
|
|
6092
6438
|
}
|
|
6093
6439
|
if (codes.some(
|
|
6094
|
-
(code) => code === "AI_CHECK_INVALID_ARGUMENTS" || code === "AI_CHECK_INVALID_CONFIG" || code === "AI_CHECK_CONFIG_LOAD_FAILED" || code === "AI_CHECK_RUN_SELECTION_REQUIRED"
|
|
6440
|
+
(code) => code === "AI_CHECK_INVALID_ARGUMENTS" || code === "AI_CHECK_INVALID_CONFIG" || code === "AI_CHECK_CONFIG_LOAD_FAILED" || code === "AI_CHECK_CONFIG_UNKNOWN_KEY" || code === "AI_CHECK_CONFIG_INVALID_VALUE" || code === "AI_CHECK_CONFIG_NO_EFFECTIVE_RULES" || code === "AI_CHECK_NO_RULES_EVALUATED" || code === "AI_CHECK_RUN_SELECTION_REQUIRED"
|
|
6095
6441
|
)) {
|
|
6096
6442
|
return 2;
|
|
6097
6443
|
}
|
|
@@ -6158,6 +6504,7 @@ function printHuman(result, options = {}) {
|
|
|
6158
6504
|
console.log(
|
|
6159
6505
|
`Summary: ${result.summary.failed} failed, ${result.summary.warnings} warning(s), ${result.summary.errors} error(s)`
|
|
6160
6506
|
);
|
|
6507
|
+
console.log(`Rules evaluated: ${result.summary.rulesEvaluated ?? result.ruleExecutions?.length ?? 0}`);
|
|
6161
6508
|
for (const diagnostic3 of result.diagnostics) {
|
|
6162
6509
|
console.log(`- ${diagnostic3.code}: ${diagnostic3.message}`);
|
|
6163
6510
|
}
|
|
@@ -6189,6 +6536,16 @@ async function checkCommand(target, options = {}, stdin = process.stdin) {
|
|
|
6189
6536
|
const useSessionScope = Boolean(sessionId || groupId);
|
|
6190
6537
|
try {
|
|
6191
6538
|
let config = await loadConfig(options.config);
|
|
6539
|
+
if (options.config !== void 0 && !checkConfigHasEffect(config)) {
|
|
6540
|
+
result = errorResult(
|
|
6541
|
+
"AI_CHECK_CONFIG_NO_EFFECTIVE_RULES",
|
|
6542
|
+
"Explicit --config has no effective check rules. Configure checks.select, checks.run, checks.tool, checks.llm, checks.structure, or checks.safety."
|
|
6543
|
+
);
|
|
6544
|
+
if (options.json) printJson(result);
|
|
6545
|
+
else printHuman(result, options);
|
|
6546
|
+
process.exitCode = exitCodeFor(result);
|
|
6547
|
+
return;
|
|
6548
|
+
}
|
|
6192
6549
|
let effectiveOptions = options;
|
|
6193
6550
|
const resolved = resolvePreset(options.preset, {
|
|
6194
6551
|
hasToolRules: hasToolRulesConfigured(config, options)
|
|
@@ -6308,12 +6665,13 @@ async function checkCommand(target, options = {}, stdin = process.stdin) {
|
|
|
6308
6665
|
}
|
|
6309
6666
|
} catch (error) {
|
|
6310
6667
|
if (phase === "config") {
|
|
6311
|
-
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
message
|
|
6316
|
-
|
|
6668
|
+
if (error instanceof CheckConfigError) {
|
|
6669
|
+
result = errorResult(error.code, error.message);
|
|
6670
|
+
} else {
|
|
6671
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
6672
|
+
const code = message.startsWith("--") || message.includes("Unknown --preset") ? "AI_CHECK_INVALID_ARGUMENTS" : error instanceof SyntaxError || message.includes("Unsupported check config extension") || message.includes("TypeScript check configs") || message.includes("Config must") || message.includes("checks config") || message.includes("Expected an array") ? "AI_CHECK_INVALID_CONFIG" : "AI_CHECK_CONFIG_LOAD_FAILED";
|
|
6673
|
+
result = errorResult(code, message);
|
|
6674
|
+
}
|
|
6317
6675
|
} else {
|
|
6318
6676
|
result = readErrorResult(error);
|
|
6319
6677
|
}
|
|
@@ -7235,6 +7593,42 @@ function startViewerServer(options = {}) {
|
|
|
7235
7593
|
});
|
|
7236
7594
|
});
|
|
7237
7595
|
}
|
|
7596
|
+
function openInDefaultBrowser(target) {
|
|
7597
|
+
const platform = process.platform;
|
|
7598
|
+
const command = platform === "darwin" ? "open" : platform === "win32" ? "cmd" : "xdg-open";
|
|
7599
|
+
const args = platform === "win32" ? ["/c", "start", "", target] : [target];
|
|
7600
|
+
return new Promise((resolve) => {
|
|
7601
|
+
try {
|
|
7602
|
+
const child = spawn(command, args, {
|
|
7603
|
+
detached: true,
|
|
7604
|
+
stdio: "ignore",
|
|
7605
|
+
windowsHide: platform === "win32"
|
|
7606
|
+
});
|
|
7607
|
+
child.once("spawn", () => {
|
|
7608
|
+
try {
|
|
7609
|
+
child.unref();
|
|
7610
|
+
resolve({ ok: true });
|
|
7611
|
+
} catch (error) {
|
|
7612
|
+
resolve({
|
|
7613
|
+
ok: false,
|
|
7614
|
+
detail: error instanceof Error ? error.message : String(error)
|
|
7615
|
+
});
|
|
7616
|
+
}
|
|
7617
|
+
});
|
|
7618
|
+
child.once("error", (error) => {
|
|
7619
|
+
resolve({
|
|
7620
|
+
ok: false,
|
|
7621
|
+
detail: error instanceof Error ? error.message : String(error)
|
|
7622
|
+
});
|
|
7623
|
+
});
|
|
7624
|
+
} catch (error) {
|
|
7625
|
+
resolve({
|
|
7626
|
+
ok: false,
|
|
7627
|
+
detail: error instanceof Error ? error.message : String(error)
|
|
7628
|
+
});
|
|
7629
|
+
}
|
|
7630
|
+
});
|
|
7631
|
+
}
|
|
7238
7632
|
|
|
7239
7633
|
// packages/cli/src/serve.ts
|
|
7240
7634
|
function parsePort(value) {
|
|
@@ -7264,9 +7658,11 @@ async function serveCommand(options = {}) {
|
|
|
7264
7658
|
if (options.open === true && host !== "127.0.0.1" && host !== "localhost") {
|
|
7265
7659
|
console.warn("Skipping browser open for non-local host binding.");
|
|
7266
7660
|
} else if (options.open === true) {
|
|
7267
|
-
const
|
|
7268
|
-
|
|
7269
|
-
|
|
7661
|
+
const opened = await openInDefaultBrowser(info.url);
|
|
7662
|
+
if (!opened.ok) {
|
|
7663
|
+
console.warn("Viewer started, but the browser could not be opened automatically.");
|
|
7664
|
+
console.warn(`Open manually: ${info.url}`);
|
|
7665
|
+
}
|
|
7270
7666
|
}
|
|
7271
7667
|
await new Promise(() => {
|
|
7272
7668
|
});
|
|
@@ -7425,9 +7821,11 @@ async function studioCommand(options = {}) {
|
|
|
7425
7821
|
if (options.open === true && info.host !== "127.0.0.1" && info.host !== "localhost") {
|
|
7426
7822
|
console.warn("Skipping browser open for non-local host binding.");
|
|
7427
7823
|
} else if (options.open === true) {
|
|
7428
|
-
const
|
|
7429
|
-
|
|
7430
|
-
|
|
7824
|
+
const opened = await openInDefaultBrowser(info.url);
|
|
7825
|
+
if (!opened.ok) {
|
|
7826
|
+
console.warn("Studio started, but the browser could not be opened automatically.");
|
|
7827
|
+
console.warn(`Open manually: ${info.url}`);
|
|
7828
|
+
}
|
|
7431
7829
|
}
|
|
7432
7830
|
await new Promise(() => {
|
|
7433
7831
|
});
|
|
@@ -8186,7 +8584,7 @@ function asStringArray2(value, label) {
|
|
|
8186
8584
|
}
|
|
8187
8585
|
return value;
|
|
8188
8586
|
}
|
|
8189
|
-
function
|
|
8587
|
+
function asConfig(value) {
|
|
8190
8588
|
if (value === void 0 || value === null) return {};
|
|
8191
8589
|
if (typeof value !== "object" || Array.isArray(value)) {
|
|
8192
8590
|
throw new Error("Config must export an object.");
|
|
@@ -8207,10 +8605,10 @@ async function loadConfig2(configPath) {
|
|
|
8207
8605
|
const absolute = path18.resolve(configPath);
|
|
8208
8606
|
if (extension === ".json") {
|
|
8209
8607
|
const raw = await readFile(absolute, "utf-8");
|
|
8210
|
-
return
|
|
8608
|
+
return asConfig(JSON.parse(raw));
|
|
8211
8609
|
}
|
|
8212
8610
|
const mod = await import(pathToFileURL(absolute).href);
|
|
8213
|
-
return
|
|
8611
|
+
return asConfig("default" in mod ? mod.default : mod);
|
|
8214
8612
|
}
|
|
8215
8613
|
function normalizeConfig2(config) {
|
|
8216
8614
|
if (config.eval === void 0) return {};
|
|
@@ -9715,33 +10113,6 @@ async function resolveHtmlPath(root) {
|
|
|
9715
10113
|
`No evidence.html found under ${root}. Pass a bundle directory or .html path.`
|
|
9716
10114
|
);
|
|
9717
10115
|
}
|
|
9718
|
-
function openLocalFile(filePath) {
|
|
9719
|
-
const fileUrl = pathToFileURL(filePath).href;
|
|
9720
|
-
const platform = process.platform;
|
|
9721
|
-
const command = platform === "darwin" ? "open" : platform === "win32" ? "cmd" : "xdg-open";
|
|
9722
|
-
const args = platform === "darwin" ? [filePath] : platform === "win32" ? ["/c", "start", "", filePath] : [filePath];
|
|
9723
|
-
return new Promise((resolve) => {
|
|
9724
|
-
try {
|
|
9725
|
-
const child = spawn(command, args, {
|
|
9726
|
-
detached: true,
|
|
9727
|
-
stdio: "ignore"
|
|
9728
|
-
});
|
|
9729
|
-
child.on("error", (error) => {
|
|
9730
|
-
resolve({
|
|
9731
|
-
ok: false,
|
|
9732
|
-
detail: `${error instanceof Error ? error.message : String(error)}; open manually: ${fileUrl}`
|
|
9733
|
-
});
|
|
9734
|
-
});
|
|
9735
|
-
child.unref();
|
|
9736
|
-
resolve({ ok: true, detail: fileUrl });
|
|
9737
|
-
} catch (error) {
|
|
9738
|
-
resolve({
|
|
9739
|
-
ok: false,
|
|
9740
|
-
detail: `${error instanceof Error ? error.message : String(error)}; open manually: ${fileUrl}`
|
|
9741
|
-
});
|
|
9742
|
-
}
|
|
9743
|
-
});
|
|
9744
|
-
}
|
|
9745
10116
|
async function bundleOpenCommand(targetPath, options = {}) {
|
|
9746
10117
|
const root = path18.resolve(targetPath.trim() || ".");
|
|
9747
10118
|
try {
|
|
@@ -9811,23 +10182,24 @@ async function bundleOpenCommand(targetPath, options = {}) {
|
|
|
9811
10182
|
await readFile(path18.join(path18.dirname(htmlPath), "evidence.json"), "utf-8");
|
|
9812
10183
|
} catch {
|
|
9813
10184
|
}
|
|
9814
|
-
const
|
|
10185
|
+
const fileUrl = pathToFileURL(htmlPath).href;
|
|
10186
|
+
const opened = await openInDefaultBrowser(fileUrl);
|
|
9815
10187
|
if (options.json) {
|
|
9816
10188
|
console.log(
|
|
9817
10189
|
writeJson6({
|
|
9818
10190
|
ok: opened.ok,
|
|
9819
10191
|
path: htmlPath,
|
|
9820
10192
|
opened: opened.ok,
|
|
9821
|
-
detail: opened.detail
|
|
10193
|
+
detail: opened.ok ? fileUrl : `${opened.detail ?? "unknown error"}; open manually: ${fileUrl}`
|
|
9822
10194
|
}).trimEnd()
|
|
9823
10195
|
);
|
|
9824
10196
|
} else if (opened.ok) {
|
|
9825
10197
|
console.log(`Opened local Evidence: ${htmlPath}`);
|
|
9826
|
-
console.log(`URL: ${
|
|
10198
|
+
console.log(`URL: ${fileUrl}`);
|
|
9827
10199
|
} else {
|
|
9828
10200
|
console.error(`[AgentInspect] Could not open browser automatically.`);
|
|
9829
10201
|
console.error(`Open this file locally: ${htmlPath}`);
|
|
9830
|
-
console.error(opened.detail);
|
|
10202
|
+
console.error(`${opened.detail ?? "unknown error"}; open manually: ${fileUrl}`);
|
|
9831
10203
|
}
|
|
9832
10204
|
if (!opened.ok) {
|
|
9833
10205
|
process.exitCode = 0;
|
|
@@ -11260,7 +11632,7 @@ function isModuleNotFound4(e) {
|
|
|
11260
11632
|
}
|
|
11261
11633
|
async function loadIndexSqlite() {
|
|
11262
11634
|
try {
|
|
11263
|
-
return await import('./src-
|
|
11635
|
+
return await import('./src-OYGG7QAZ.mjs');
|
|
11264
11636
|
} catch (e) {
|
|
11265
11637
|
if (isModuleNotFound4(e)) {
|
|
11266
11638
|
console.error(
|