agent-inspect 6.17.4 → 6.17.5
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 +6 -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 +5 -2
- 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 +480 -80
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +399 -68
- 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';
|
|
@@ -12,7 +12,7 @@ import { spawn } from 'child_process';
|
|
|
12
12
|
import { createRequire } from 'module';
|
|
13
13
|
|
|
14
14
|
// package.json
|
|
15
|
-
var version = "6.17.
|
|
15
|
+
var version = "6.17.5";
|
|
16
16
|
|
|
17
17
|
// packages/cli/src/trace-dir-scale.ts
|
|
18
18
|
var TRACE_COUNT_WARN = 1e3;
|
|
@@ -1540,6 +1540,11 @@ async function followFile(filePath, options, onLine, shouldStop) {
|
|
|
1540
1540
|
const msg = e instanceof Error ? e.message : String(e);
|
|
1541
1541
|
throw new Error(`Failed to stat file: ${filePath} (${msg})`);
|
|
1542
1542
|
}
|
|
1543
|
+
if (next.size < pos) {
|
|
1544
|
+
pos = 0;
|
|
1545
|
+
carry = "";
|
|
1546
|
+
lineNumber = 0;
|
|
1547
|
+
}
|
|
1543
1548
|
if (next.size > pos) {
|
|
1544
1549
|
const fh = await open(filePath, "r");
|
|
1545
1550
|
try {
|
|
@@ -3347,7 +3352,7 @@ async function newestTraceMtimeMs(traceDir) {
|
|
|
3347
3352
|
}
|
|
3348
3353
|
async function loadSessionRuns(traceDir) {
|
|
3349
3354
|
try {
|
|
3350
|
-
const mod = await import('./src-
|
|
3355
|
+
const mod = await import('./src-OYGG7QAZ.mjs');
|
|
3351
3356
|
const dbPath = mod.resolveIndexDbPath(traceDir);
|
|
3352
3357
|
const status = mod.indexStatus(dbPath);
|
|
3353
3358
|
if (!status.healthy) {
|
|
@@ -5143,8 +5148,11 @@ function checkResultToEvidenceJson(result, runIds) {
|
|
|
5143
5148
|
status,
|
|
5144
5149
|
errors: result.summary.errors,
|
|
5145
5150
|
warnings: result.summary.warnings,
|
|
5146
|
-
findings: result.findings.length
|
|
5151
|
+
findings: result.findings.length,
|
|
5152
|
+
rulesEvaluated: result.summary.rulesEvaluated ?? 0
|
|
5147
5153
|
})),
|
|
5154
|
+
rulesEvaluated: result.summary.rulesEvaluated ?? 0,
|
|
5155
|
+
evaluatedRuleIds: (result.ruleExecutions ?? []).map((item) => item.ruleId),
|
|
5148
5156
|
findings: result.findings,
|
|
5149
5157
|
diagnostics: result.diagnostics
|
|
5150
5158
|
});
|
|
@@ -5769,9 +5777,11 @@ function mergeSafetyExtensions(result, read, options) {
|
|
|
5769
5777
|
passed,
|
|
5770
5778
|
failed,
|
|
5771
5779
|
warnings,
|
|
5772
|
-
errors: result.summary.errors
|
|
5780
|
+
errors: result.summary.errors,
|
|
5781
|
+
rulesEvaluated: result.summary.rulesEvaluated ?? 0
|
|
5773
5782
|
},
|
|
5774
|
-
findings
|
|
5783
|
+
findings,
|
|
5784
|
+
ruleExecutions: result.ruleExecutions ?? []
|
|
5775
5785
|
};
|
|
5776
5786
|
}
|
|
5777
5787
|
|
|
@@ -5891,10 +5901,12 @@ function errorResult(code, message, format = "unknown") {
|
|
|
5891
5901
|
passed: 0,
|
|
5892
5902
|
failed: 0,
|
|
5893
5903
|
warnings: 0,
|
|
5894
|
-
errors: 1
|
|
5904
|
+
errors: 1,
|
|
5905
|
+
rulesEvaluated: 0
|
|
5895
5906
|
},
|
|
5896
5907
|
findings: [],
|
|
5897
|
-
diagnostics
|
|
5908
|
+
diagnostics,
|
|
5909
|
+
ruleExecutions: []
|
|
5898
5910
|
};
|
|
5899
5911
|
}
|
|
5900
5912
|
function parseNumber(value, label) {
|
|
@@ -5912,36 +5924,329 @@ function asStringArray(value) {
|
|
|
5912
5924
|
}
|
|
5913
5925
|
return value;
|
|
5914
5926
|
}
|
|
5915
|
-
|
|
5927
|
+
var CHECKS_KEYS = /* @__PURE__ */ new Set(["select", "run", "tool", "llm", "structure", "safety"]);
|
|
5928
|
+
var RUN_KEYS = /* @__PURE__ */ new Set(["expected", "allowIncomplete", "maxDurationMs", "maxDepth"]);
|
|
5929
|
+
var TOOL_KEYS = /* @__PURE__ */ new Set(["required", "forbidden", "allowed", "minCount", "maxCount"]);
|
|
5930
|
+
var LLM_KEYS = /* @__PURE__ */ new Set([
|
|
5931
|
+
"allowedModels",
|
|
5932
|
+
"allowedProviders",
|
|
5933
|
+
"finishReasons",
|
|
5934
|
+
"maxCalls",
|
|
5935
|
+
"maxTotalTokens",
|
|
5936
|
+
"maxInputTokens",
|
|
5937
|
+
"maxOutputTokens",
|
|
5938
|
+
"maxCachedTokens"
|
|
5939
|
+
]);
|
|
5940
|
+
var STRUCTURE_KEYS = /* @__PURE__ */ new Set([
|
|
5941
|
+
"minConfidence",
|
|
5942
|
+
"requireParentBeforeChild",
|
|
5943
|
+
"requireTraceParentSpan",
|
|
5944
|
+
"orphan",
|
|
5945
|
+
"cycle",
|
|
5946
|
+
"maxChildren",
|
|
5947
|
+
"maxConcurrent"
|
|
5948
|
+
]);
|
|
5949
|
+
var SAFETY_KEYS = /* @__PURE__ */ new Set([
|
|
5950
|
+
"redaction",
|
|
5951
|
+
"rawContent",
|
|
5952
|
+
"secretPattern",
|
|
5953
|
+
"maxStringLength",
|
|
5954
|
+
"maxArrayLength",
|
|
5955
|
+
"maxObjectKeys",
|
|
5956
|
+
"maxSerializedBytes",
|
|
5957
|
+
"maxFindings"
|
|
5958
|
+
]);
|
|
5959
|
+
var RUN_EXPECTED = /* @__PURE__ */ new Set(["ok", "error", "running"]);
|
|
5960
|
+
var CONFIDENCE_VALUES = /* @__PURE__ */ new Set(["exact", "high", "medium", "low", "inferred"]);
|
|
5961
|
+
var CheckConfigError = class extends Error {
|
|
5962
|
+
code;
|
|
5963
|
+
constructor(code, message) {
|
|
5964
|
+
super(message);
|
|
5965
|
+
this.name = "CheckConfigError";
|
|
5966
|
+
this.code = code;
|
|
5967
|
+
}
|
|
5968
|
+
};
|
|
5969
|
+
function closestKey(unknown, known) {
|
|
5970
|
+
const lower = unknown.toLowerCase();
|
|
5971
|
+
let best;
|
|
5972
|
+
let bestDistance = Number.POSITIVE_INFINITY;
|
|
5973
|
+
for (const candidate of known) {
|
|
5974
|
+
if (candidate.toLowerCase() === lower) return candidate;
|
|
5975
|
+
let distance = Math.abs(candidate.length - unknown.length);
|
|
5976
|
+
const max = Math.max(candidate.length, unknown.length);
|
|
5977
|
+
for (let i = 0; i < Math.min(candidate.length, unknown.length); i += 1) {
|
|
5978
|
+
if (candidate[i].toLowerCase() !== unknown[i].toLowerCase()) distance += 1;
|
|
5979
|
+
}
|
|
5980
|
+
if (distance < bestDistance && distance <= Math.max(2, Math.floor(max / 3))) {
|
|
5981
|
+
bestDistance = distance;
|
|
5982
|
+
best = candidate;
|
|
5983
|
+
}
|
|
5984
|
+
}
|
|
5985
|
+
return best;
|
|
5986
|
+
}
|
|
5987
|
+
function rejectUnknownKeys(record, allowed, pathPrefix) {
|
|
5988
|
+
for (const key of Object.keys(record)) {
|
|
5989
|
+
if (allowed.has(key)) continue;
|
|
5990
|
+
const suggestion = closestKey(key, [...allowed]);
|
|
5991
|
+
const hint = suggestion ? ` Did you mean "${suggestion}"?` : "";
|
|
5992
|
+
throw new CheckConfigError(
|
|
5993
|
+
"AI_CHECK_CONFIG_UNKNOWN_KEY",
|
|
5994
|
+
`Unknown check config key "${pathPrefix}.${key}".${hint}`
|
|
5995
|
+
);
|
|
5996
|
+
}
|
|
5997
|
+
}
|
|
5998
|
+
function requireObject(value, pathPrefix) {
|
|
5999
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
6000
|
+
throw new CheckConfigError(
|
|
6001
|
+
"AI_CHECK_CONFIG_INVALID_VALUE",
|
|
6002
|
+
`${pathPrefix} must be an object.`
|
|
6003
|
+
);
|
|
6004
|
+
}
|
|
6005
|
+
return value;
|
|
6006
|
+
}
|
|
6007
|
+
function requireStringArray(value, pathPrefix) {
|
|
6008
|
+
if (!Array.isArray(value) || value.some((item) => typeof item !== "string" || item.trim() === "")) {
|
|
6009
|
+
throw new CheckConfigError(
|
|
6010
|
+
"AI_CHECK_CONFIG_INVALID_VALUE",
|
|
6011
|
+
`${pathPrefix} must be an array of non-empty strings.`
|
|
6012
|
+
);
|
|
6013
|
+
}
|
|
6014
|
+
return value;
|
|
6015
|
+
}
|
|
6016
|
+
function requireNonNegativeNumber(value, pathPrefix) {
|
|
6017
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
|
|
6018
|
+
throw new CheckConfigError(
|
|
6019
|
+
"AI_CHECK_CONFIG_INVALID_VALUE",
|
|
6020
|
+
`${pathPrefix} must be a finite non-negative number.`
|
|
6021
|
+
);
|
|
6022
|
+
}
|
|
6023
|
+
return value;
|
|
6024
|
+
}
|
|
6025
|
+
function requireBoolean(value, pathPrefix) {
|
|
6026
|
+
if (typeof value !== "boolean") {
|
|
6027
|
+
throw new CheckConfigError(
|
|
6028
|
+
"AI_CHECK_CONFIG_INVALID_VALUE",
|
|
6029
|
+
`${pathPrefix} must be a boolean.`
|
|
6030
|
+
);
|
|
6031
|
+
}
|
|
6032
|
+
return value;
|
|
6033
|
+
}
|
|
6034
|
+
function parseRunSection(value) {
|
|
6035
|
+
const record = requireObject(value, "checks.run");
|
|
6036
|
+
rejectUnknownKeys(record, RUN_KEYS, "checks.run");
|
|
6037
|
+
const out = {};
|
|
6038
|
+
if (record.expected !== void 0) {
|
|
6039
|
+
if (typeof record.expected !== "string" || !RUN_EXPECTED.has(record.expected)) {
|
|
6040
|
+
throw new CheckConfigError(
|
|
6041
|
+
"AI_CHECK_CONFIG_INVALID_VALUE",
|
|
6042
|
+
`checks.run.expected must be one of: ok, error, running.`
|
|
6043
|
+
);
|
|
6044
|
+
}
|
|
6045
|
+
out.expected = record.expected;
|
|
6046
|
+
}
|
|
6047
|
+
if (record.allowIncomplete !== void 0) {
|
|
6048
|
+
out.allowIncomplete = requireBoolean(record.allowIncomplete, "checks.run.allowIncomplete");
|
|
6049
|
+
}
|
|
6050
|
+
if (record.maxDurationMs !== void 0) {
|
|
6051
|
+
out.maxDurationMs = requireNonNegativeNumber(record.maxDurationMs, "checks.run.maxDurationMs");
|
|
6052
|
+
}
|
|
6053
|
+
if (record.maxDepth !== void 0) {
|
|
6054
|
+
out.maxDepth = requireNonNegativeNumber(record.maxDepth, "checks.run.maxDepth");
|
|
6055
|
+
}
|
|
6056
|
+
return out;
|
|
6057
|
+
}
|
|
6058
|
+
function parseToolSection(value) {
|
|
6059
|
+
const record = requireObject(value, "checks.tool");
|
|
6060
|
+
rejectUnknownKeys(record, TOOL_KEYS, "checks.tool");
|
|
6061
|
+
const out = {};
|
|
6062
|
+
if (record.required !== void 0) out.required = requireStringArray(record.required, "checks.tool.required");
|
|
6063
|
+
if (record.forbidden !== void 0) out.forbidden = requireStringArray(record.forbidden, "checks.tool.forbidden");
|
|
6064
|
+
if (record.allowed !== void 0) out.allowed = requireStringArray(record.allowed, "checks.tool.allowed");
|
|
6065
|
+
if (record.minCount !== void 0) out.minCount = requireNonNegativeNumber(record.minCount, "checks.tool.minCount");
|
|
6066
|
+
if (record.maxCount !== void 0) out.maxCount = requireNonNegativeNumber(record.maxCount, "checks.tool.maxCount");
|
|
6067
|
+
return out;
|
|
6068
|
+
}
|
|
6069
|
+
function parseLlmSection(value) {
|
|
6070
|
+
const record = requireObject(value, "checks.llm");
|
|
6071
|
+
rejectUnknownKeys(record, LLM_KEYS, "checks.llm");
|
|
6072
|
+
const out = {};
|
|
6073
|
+
if (record.allowedModels !== void 0) {
|
|
6074
|
+
out.allowedModels = requireStringArray(record.allowedModels, "checks.llm.allowedModels");
|
|
6075
|
+
}
|
|
6076
|
+
if (record.allowedProviders !== void 0) {
|
|
6077
|
+
out.allowedProviders = requireStringArray(record.allowedProviders, "checks.llm.allowedProviders");
|
|
6078
|
+
}
|
|
6079
|
+
if (record.finishReasons !== void 0) {
|
|
6080
|
+
out.finishReasons = requireStringArray(record.finishReasons, "checks.llm.finishReasons");
|
|
6081
|
+
}
|
|
6082
|
+
if (record.maxCalls !== void 0) out.maxCalls = requireNonNegativeNumber(record.maxCalls, "checks.llm.maxCalls");
|
|
6083
|
+
if (record.maxTotalTokens !== void 0) {
|
|
6084
|
+
out.maxTotalTokens = requireNonNegativeNumber(record.maxTotalTokens, "checks.llm.maxTotalTokens");
|
|
6085
|
+
}
|
|
6086
|
+
if (record.maxInputTokens !== void 0) {
|
|
6087
|
+
out.maxInputTokens = requireNonNegativeNumber(record.maxInputTokens, "checks.llm.maxInputTokens");
|
|
6088
|
+
}
|
|
6089
|
+
if (record.maxOutputTokens !== void 0) {
|
|
6090
|
+
out.maxOutputTokens = requireNonNegativeNumber(record.maxOutputTokens, "checks.llm.maxOutputTokens");
|
|
6091
|
+
}
|
|
6092
|
+
if (record.maxCachedTokens !== void 0) {
|
|
6093
|
+
out.maxCachedTokens = requireNonNegativeNumber(record.maxCachedTokens, "checks.llm.maxCachedTokens");
|
|
6094
|
+
}
|
|
6095
|
+
return out;
|
|
6096
|
+
}
|
|
6097
|
+
function parseStructureSection(value) {
|
|
6098
|
+
const record = requireObject(value, "checks.structure");
|
|
6099
|
+
rejectUnknownKeys(record, STRUCTURE_KEYS, "checks.structure");
|
|
6100
|
+
const out = {};
|
|
6101
|
+
if (record.minConfidence !== void 0) {
|
|
6102
|
+
if (typeof record.minConfidence !== "string" || !CONFIDENCE_VALUES.has(record.minConfidence)) {
|
|
6103
|
+
throw new CheckConfigError(
|
|
6104
|
+
"AI_CHECK_CONFIG_INVALID_VALUE",
|
|
6105
|
+
`checks.structure.minConfidence must be one of: exact, high, medium, low, inferred.`
|
|
6106
|
+
);
|
|
6107
|
+
}
|
|
6108
|
+
out.minConfidence = record.minConfidence;
|
|
6109
|
+
}
|
|
6110
|
+
if (record.requireParentBeforeChild !== void 0) {
|
|
6111
|
+
out.requireParentBeforeChild = requireBoolean(
|
|
6112
|
+
record.requireParentBeforeChild,
|
|
6113
|
+
"checks.structure.requireParentBeforeChild"
|
|
6114
|
+
);
|
|
6115
|
+
}
|
|
6116
|
+
if (record.requireTraceParentSpan !== void 0) {
|
|
6117
|
+
out.requireTraceParentSpan = requireBoolean(
|
|
6118
|
+
record.requireTraceParentSpan,
|
|
6119
|
+
"checks.structure.requireTraceParentSpan"
|
|
6120
|
+
);
|
|
6121
|
+
}
|
|
6122
|
+
if (record.orphan !== void 0) out.orphan = requireBoolean(record.orphan, "checks.structure.orphan");
|
|
6123
|
+
if (record.cycle !== void 0) out.cycle = requireBoolean(record.cycle, "checks.structure.cycle");
|
|
6124
|
+
if (record.maxChildren !== void 0) {
|
|
6125
|
+
out.maxChildren = requireNonNegativeNumber(record.maxChildren, "checks.structure.maxChildren");
|
|
6126
|
+
}
|
|
6127
|
+
if (record.maxConcurrent !== void 0) {
|
|
6128
|
+
out.maxConcurrent = requireNonNegativeNumber(record.maxConcurrent, "checks.structure.maxConcurrent");
|
|
6129
|
+
}
|
|
6130
|
+
return out;
|
|
6131
|
+
}
|
|
6132
|
+
function parseSafetySection(value) {
|
|
6133
|
+
const record = requireObject(value, "checks.safety");
|
|
6134
|
+
rejectUnknownKeys(record, SAFETY_KEYS, "checks.safety");
|
|
6135
|
+
const out = {};
|
|
6136
|
+
if (record.redaction !== void 0) out.redaction = requireBoolean(record.redaction, "checks.safety.redaction");
|
|
6137
|
+
if (record.rawContent !== void 0) out.rawContent = requireBoolean(record.rawContent, "checks.safety.rawContent");
|
|
6138
|
+
if (record.secretPattern !== void 0) {
|
|
6139
|
+
out.secretPattern = requireBoolean(record.secretPattern, "checks.safety.secretPattern");
|
|
6140
|
+
}
|
|
6141
|
+
if (record.maxStringLength !== void 0) {
|
|
6142
|
+
out.maxStringLength = requireNonNegativeNumber(record.maxStringLength, "checks.safety.maxStringLength");
|
|
6143
|
+
}
|
|
6144
|
+
if (record.maxArrayLength !== void 0) {
|
|
6145
|
+
out.maxArrayLength = requireNonNegativeNumber(record.maxArrayLength, "checks.safety.maxArrayLength");
|
|
6146
|
+
}
|
|
6147
|
+
if (record.maxObjectKeys !== void 0) {
|
|
6148
|
+
out.maxObjectKeys = requireNonNegativeNumber(record.maxObjectKeys, "checks.safety.maxObjectKeys");
|
|
6149
|
+
}
|
|
6150
|
+
if (record.maxSerializedBytes !== void 0) {
|
|
6151
|
+
out.maxSerializedBytes = requireNonNegativeNumber(
|
|
6152
|
+
record.maxSerializedBytes,
|
|
6153
|
+
"checks.safety.maxSerializedBytes"
|
|
6154
|
+
);
|
|
6155
|
+
}
|
|
6156
|
+
if (record.maxFindings !== void 0) {
|
|
6157
|
+
out.maxFindings = requireNonNegativeNumber(record.maxFindings, "checks.safety.maxFindings");
|
|
6158
|
+
}
|
|
6159
|
+
return out;
|
|
6160
|
+
}
|
|
6161
|
+
function sectionHasEffect(section) {
|
|
6162
|
+
if (section === void 0) return false;
|
|
6163
|
+
return Object.keys(section).length > 0;
|
|
6164
|
+
}
|
|
6165
|
+
function checkConfigHasEffect(config) {
|
|
6166
|
+
const checks2 = config.checks;
|
|
6167
|
+
if (checks2 === void 0) return false;
|
|
6168
|
+
if ((checks2.select?.length ?? 0) > 0) return true;
|
|
6169
|
+
if (sectionHasEffect(checks2.run)) return true;
|
|
6170
|
+
if (sectionHasEffect(checks2.tool)) return true;
|
|
6171
|
+
if (sectionHasEffect(checks2.llm)) return true;
|
|
6172
|
+
if (sectionHasEffect(checks2.structure)) return true;
|
|
6173
|
+
if (sectionHasEffect(checks2.safety)) return true;
|
|
6174
|
+
return false;
|
|
6175
|
+
}
|
|
6176
|
+
function parseCheckConfig(value) {
|
|
5916
6177
|
if (value === void 0 || value === null) return {};
|
|
5917
6178
|
if (typeof value !== "object" || Array.isArray(value)) {
|
|
5918
|
-
throw new
|
|
6179
|
+
throw new CheckConfigError("AI_CHECK_CONFIG_INVALID_VALUE", "Config must export an object.");
|
|
5919
6180
|
}
|
|
5920
|
-
|
|
6181
|
+
const root = value;
|
|
6182
|
+
if ("contract" in root) {
|
|
6183
|
+
throw new CheckConfigError(
|
|
6184
|
+
"AI_CHECK_CONFIG_UNKNOWN_KEY",
|
|
6185
|
+
'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`.'
|
|
6186
|
+
);
|
|
6187
|
+
}
|
|
6188
|
+
const rootKeys = Object.keys(root);
|
|
6189
|
+
for (const key of rootKeys) {
|
|
6190
|
+
if (key === "checks") continue;
|
|
6191
|
+
const suggestion = closestKey(key, ["checks"]);
|
|
6192
|
+
const hint = suggestion ? ` Did you mean "${suggestion}"?` : "";
|
|
6193
|
+
throw new CheckConfigError(
|
|
6194
|
+
"AI_CHECK_CONFIG_UNKNOWN_KEY",
|
|
6195
|
+
`Unknown top-level check config key "${key}". Allowed: checks.${hint}`
|
|
6196
|
+
);
|
|
6197
|
+
}
|
|
6198
|
+
if (!("checks" in root)) return {};
|
|
6199
|
+
const checksRecord = requireObject(root.checks, "checks");
|
|
6200
|
+
rejectUnknownKeys(checksRecord, CHECKS_KEYS, "checks");
|
|
6201
|
+
const checks2 = {};
|
|
6202
|
+
if (checksRecord.select !== void 0) {
|
|
6203
|
+
checks2.select = requireStringArray(checksRecord.select, "checks.select");
|
|
6204
|
+
}
|
|
6205
|
+
if (checksRecord.run !== void 0) checks2.run = parseRunSection(checksRecord.run);
|
|
6206
|
+
if (checksRecord.tool !== void 0) checks2.tool = parseToolSection(checksRecord.tool);
|
|
6207
|
+
if (checksRecord.llm !== void 0) checks2.llm = parseLlmSection(checksRecord.llm);
|
|
6208
|
+
if (checksRecord.structure !== void 0) {
|
|
6209
|
+
checks2.structure = parseStructureSection(checksRecord.structure);
|
|
6210
|
+
}
|
|
6211
|
+
if (checksRecord.safety !== void 0) checks2.safety = parseSafetySection(checksRecord.safety);
|
|
6212
|
+
return { checks: checks2 };
|
|
5921
6213
|
}
|
|
5922
6214
|
async function loadConfig(configPath) {
|
|
5923
6215
|
if (configPath === void 0) return {};
|
|
5924
6216
|
const extension = path18.extname(configPath);
|
|
5925
6217
|
if (TS_CONFIG_EXTENSIONS.has(extension)) {
|
|
5926
|
-
throw new
|
|
6218
|
+
throw new CheckConfigError(
|
|
6219
|
+
"AI_CHECK_CONFIG_LOAD_FAILED",
|
|
5927
6220
|
"TypeScript check configs require an explicit precompiled JavaScript config or future --config-loader support."
|
|
5928
6221
|
);
|
|
5929
6222
|
}
|
|
5930
6223
|
if (!CONFIG_EXTENSIONS.has(extension)) {
|
|
5931
|
-
throw new
|
|
6224
|
+
throw new CheckConfigError(
|
|
6225
|
+
"AI_CHECK_CONFIG_LOAD_FAILED",
|
|
6226
|
+
"Unsupported check config extension. Use .json, .js, .mjs, or .cjs."
|
|
6227
|
+
);
|
|
5932
6228
|
}
|
|
5933
6229
|
const absolute = path18.resolve(configPath);
|
|
5934
|
-
|
|
5935
|
-
|
|
5936
|
-
|
|
6230
|
+
try {
|
|
6231
|
+
if (extension === ".json") {
|
|
6232
|
+
const raw = await readFile(absolute, "utf-8");
|
|
6233
|
+
return parseCheckConfig(JSON.parse(raw));
|
|
6234
|
+
}
|
|
6235
|
+
const mod = await import(pathToFileURL(absolute).href);
|
|
6236
|
+
return parseCheckConfig("default" in mod ? mod.default : mod);
|
|
6237
|
+
} catch (error) {
|
|
6238
|
+
if (error instanceof CheckConfigError) throw error;
|
|
6239
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
6240
|
+
throw new CheckConfigError(
|
|
6241
|
+
"AI_CHECK_CONFIG_LOAD_FAILED",
|
|
6242
|
+
`Failed to load check config: ${message}`
|
|
6243
|
+
);
|
|
5937
6244
|
}
|
|
5938
|
-
const mod = await import(pathToFileURL(absolute).href);
|
|
5939
|
-
return asConfig("default" in mod ? mod.default : mod);
|
|
5940
6245
|
}
|
|
5941
6246
|
function normalizeConfig(config) {
|
|
5942
6247
|
if (config.checks === void 0) return {};
|
|
5943
6248
|
if (typeof config.checks !== "object" || Array.isArray(config.checks)) {
|
|
5944
|
-
throw new
|
|
6249
|
+
throw new CheckConfigError("AI_CHECK_CONFIG_INVALID_VALUE", "checks config must be an object.");
|
|
5945
6250
|
}
|
|
5946
6251
|
return config.checks;
|
|
5947
6252
|
}
|
|
@@ -6019,7 +6324,7 @@ function buildRules(config, options, presetSelect = []) {
|
|
|
6019
6324
|
}
|
|
6020
6325
|
throw new Error(`unsupported status "${value}"`);
|
|
6021
6326
|
});
|
|
6022
|
-
rules.push(createObservedOutcomeRule({ failOn: statuses }));
|
|
6327
|
+
rules.push(createObservedOutcomeRule({ failOn: statuses, requireAny: true }));
|
|
6023
6328
|
} catch (error) {
|
|
6024
6329
|
const message = error instanceof Error ? error.message : String(error);
|
|
6025
6330
|
diagnostics.push(
|
|
@@ -6091,7 +6396,7 @@ function exitCodeFor(result) {
|
|
|
6091
6396
|
return 3;
|
|
6092
6397
|
}
|
|
6093
6398
|
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"
|
|
6399
|
+
(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
6400
|
)) {
|
|
6096
6401
|
return 2;
|
|
6097
6402
|
}
|
|
@@ -6158,6 +6463,7 @@ function printHuman(result, options = {}) {
|
|
|
6158
6463
|
console.log(
|
|
6159
6464
|
`Summary: ${result.summary.failed} failed, ${result.summary.warnings} warning(s), ${result.summary.errors} error(s)`
|
|
6160
6465
|
);
|
|
6466
|
+
console.log(`Rules evaluated: ${result.summary.rulesEvaluated ?? result.ruleExecutions?.length ?? 0}`);
|
|
6161
6467
|
for (const diagnostic3 of result.diagnostics) {
|
|
6162
6468
|
console.log(`- ${diagnostic3.code}: ${diagnostic3.message}`);
|
|
6163
6469
|
}
|
|
@@ -6189,6 +6495,16 @@ async function checkCommand(target, options = {}, stdin = process.stdin) {
|
|
|
6189
6495
|
const useSessionScope = Boolean(sessionId || groupId);
|
|
6190
6496
|
try {
|
|
6191
6497
|
let config = await loadConfig(options.config);
|
|
6498
|
+
if (options.config !== void 0 && !checkConfigHasEffect(config)) {
|
|
6499
|
+
result = errorResult(
|
|
6500
|
+
"AI_CHECK_CONFIG_NO_EFFECTIVE_RULES",
|
|
6501
|
+
"Explicit --config has no effective check rules. Configure checks.select, checks.run, checks.tool, checks.llm, checks.structure, or checks.safety."
|
|
6502
|
+
);
|
|
6503
|
+
if (options.json) printJson(result);
|
|
6504
|
+
else printHuman(result, options);
|
|
6505
|
+
process.exitCode = exitCodeFor(result);
|
|
6506
|
+
return;
|
|
6507
|
+
}
|
|
6192
6508
|
let effectiveOptions = options;
|
|
6193
6509
|
const resolved = resolvePreset(options.preset, {
|
|
6194
6510
|
hasToolRules: hasToolRulesConfigured(config, options)
|
|
@@ -6308,12 +6624,13 @@ async function checkCommand(target, options = {}, stdin = process.stdin) {
|
|
|
6308
6624
|
}
|
|
6309
6625
|
} catch (error) {
|
|
6310
6626
|
if (phase === "config") {
|
|
6311
|
-
|
|
6312
|
-
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
message
|
|
6316
|
-
|
|
6627
|
+
if (error instanceof CheckConfigError) {
|
|
6628
|
+
result = errorResult(error.code, error.message);
|
|
6629
|
+
} else {
|
|
6630
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
6631
|
+
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";
|
|
6632
|
+
result = errorResult(code, message);
|
|
6633
|
+
}
|
|
6317
6634
|
} else {
|
|
6318
6635
|
result = readErrorResult(error);
|
|
6319
6636
|
}
|
|
@@ -7235,6 +7552,42 @@ function startViewerServer(options = {}) {
|
|
|
7235
7552
|
});
|
|
7236
7553
|
});
|
|
7237
7554
|
}
|
|
7555
|
+
function openInDefaultBrowser(target) {
|
|
7556
|
+
const platform = process.platform;
|
|
7557
|
+
const command = platform === "darwin" ? "open" : platform === "win32" ? "cmd" : "xdg-open";
|
|
7558
|
+
const args = platform === "win32" ? ["/c", "start", "", target] : [target];
|
|
7559
|
+
return new Promise((resolve) => {
|
|
7560
|
+
try {
|
|
7561
|
+
const child = spawn(command, args, {
|
|
7562
|
+
detached: true,
|
|
7563
|
+
stdio: "ignore",
|
|
7564
|
+
windowsHide: platform === "win32"
|
|
7565
|
+
});
|
|
7566
|
+
child.once("spawn", () => {
|
|
7567
|
+
try {
|
|
7568
|
+
child.unref();
|
|
7569
|
+
resolve({ ok: true });
|
|
7570
|
+
} catch (error) {
|
|
7571
|
+
resolve({
|
|
7572
|
+
ok: false,
|
|
7573
|
+
detail: error instanceof Error ? error.message : String(error)
|
|
7574
|
+
});
|
|
7575
|
+
}
|
|
7576
|
+
});
|
|
7577
|
+
child.once("error", (error) => {
|
|
7578
|
+
resolve({
|
|
7579
|
+
ok: false,
|
|
7580
|
+
detail: error instanceof Error ? error.message : String(error)
|
|
7581
|
+
});
|
|
7582
|
+
});
|
|
7583
|
+
} catch (error) {
|
|
7584
|
+
resolve({
|
|
7585
|
+
ok: false,
|
|
7586
|
+
detail: error instanceof Error ? error.message : String(error)
|
|
7587
|
+
});
|
|
7588
|
+
}
|
|
7589
|
+
});
|
|
7590
|
+
}
|
|
7238
7591
|
|
|
7239
7592
|
// packages/cli/src/serve.ts
|
|
7240
7593
|
function parsePort(value) {
|
|
@@ -7264,9 +7617,11 @@ async function serveCommand(options = {}) {
|
|
|
7264
7617
|
if (options.open === true && host !== "127.0.0.1" && host !== "localhost") {
|
|
7265
7618
|
console.warn("Skipping browser open for non-local host binding.");
|
|
7266
7619
|
} else if (options.open === true) {
|
|
7267
|
-
const
|
|
7268
|
-
|
|
7269
|
-
|
|
7620
|
+
const opened = await openInDefaultBrowser(info.url);
|
|
7621
|
+
if (!opened.ok) {
|
|
7622
|
+
console.warn("Viewer started, but the browser could not be opened automatically.");
|
|
7623
|
+
console.warn(`Open manually: ${info.url}`);
|
|
7624
|
+
}
|
|
7270
7625
|
}
|
|
7271
7626
|
await new Promise(() => {
|
|
7272
7627
|
});
|
|
@@ -7425,9 +7780,11 @@ async function studioCommand(options = {}) {
|
|
|
7425
7780
|
if (options.open === true && info.host !== "127.0.0.1" && info.host !== "localhost") {
|
|
7426
7781
|
console.warn("Skipping browser open for non-local host binding.");
|
|
7427
7782
|
} else if (options.open === true) {
|
|
7428
|
-
const
|
|
7429
|
-
|
|
7430
|
-
|
|
7783
|
+
const opened = await openInDefaultBrowser(info.url);
|
|
7784
|
+
if (!opened.ok) {
|
|
7785
|
+
console.warn("Studio started, but the browser could not be opened automatically.");
|
|
7786
|
+
console.warn(`Open manually: ${info.url}`);
|
|
7787
|
+
}
|
|
7431
7788
|
}
|
|
7432
7789
|
await new Promise(() => {
|
|
7433
7790
|
});
|
|
@@ -8186,7 +8543,7 @@ function asStringArray2(value, label) {
|
|
|
8186
8543
|
}
|
|
8187
8544
|
return value;
|
|
8188
8545
|
}
|
|
8189
|
-
function
|
|
8546
|
+
function asConfig(value) {
|
|
8190
8547
|
if (value === void 0 || value === null) return {};
|
|
8191
8548
|
if (typeof value !== "object" || Array.isArray(value)) {
|
|
8192
8549
|
throw new Error("Config must export an object.");
|
|
@@ -8207,10 +8564,10 @@ async function loadConfig2(configPath) {
|
|
|
8207
8564
|
const absolute = path18.resolve(configPath);
|
|
8208
8565
|
if (extension === ".json") {
|
|
8209
8566
|
const raw = await readFile(absolute, "utf-8");
|
|
8210
|
-
return
|
|
8567
|
+
return asConfig(JSON.parse(raw));
|
|
8211
8568
|
}
|
|
8212
8569
|
const mod = await import(pathToFileURL(absolute).href);
|
|
8213
|
-
return
|
|
8570
|
+
return asConfig("default" in mod ? mod.default : mod);
|
|
8214
8571
|
}
|
|
8215
8572
|
function normalizeConfig2(config) {
|
|
8216
8573
|
if (config.eval === void 0) return {};
|
|
@@ -9715,33 +10072,6 @@ async function resolveHtmlPath(root) {
|
|
|
9715
10072
|
`No evidence.html found under ${root}. Pass a bundle directory or .html path.`
|
|
9716
10073
|
);
|
|
9717
10074
|
}
|
|
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
10075
|
async function bundleOpenCommand(targetPath, options = {}) {
|
|
9746
10076
|
const root = path18.resolve(targetPath.trim() || ".");
|
|
9747
10077
|
try {
|
|
@@ -9811,23 +10141,24 @@ async function bundleOpenCommand(targetPath, options = {}) {
|
|
|
9811
10141
|
await readFile(path18.join(path18.dirname(htmlPath), "evidence.json"), "utf-8");
|
|
9812
10142
|
} catch {
|
|
9813
10143
|
}
|
|
9814
|
-
const
|
|
10144
|
+
const fileUrl = pathToFileURL(htmlPath).href;
|
|
10145
|
+
const opened = await openInDefaultBrowser(fileUrl);
|
|
9815
10146
|
if (options.json) {
|
|
9816
10147
|
console.log(
|
|
9817
10148
|
writeJson6({
|
|
9818
10149
|
ok: opened.ok,
|
|
9819
10150
|
path: htmlPath,
|
|
9820
10151
|
opened: opened.ok,
|
|
9821
|
-
detail: opened.detail
|
|
10152
|
+
detail: opened.ok ? fileUrl : `${opened.detail ?? "unknown error"}; open manually: ${fileUrl}`
|
|
9822
10153
|
}).trimEnd()
|
|
9823
10154
|
);
|
|
9824
10155
|
} else if (opened.ok) {
|
|
9825
10156
|
console.log(`Opened local Evidence: ${htmlPath}`);
|
|
9826
|
-
console.log(`URL: ${
|
|
10157
|
+
console.log(`URL: ${fileUrl}`);
|
|
9827
10158
|
} else {
|
|
9828
10159
|
console.error(`[AgentInspect] Could not open browser automatically.`);
|
|
9829
10160
|
console.error(`Open this file locally: ${htmlPath}`);
|
|
9830
|
-
console.error(opened.detail);
|
|
10161
|
+
console.error(`${opened.detail ?? "unknown error"}; open manually: ${fileUrl}`);
|
|
9831
10162
|
}
|
|
9832
10163
|
if (!opened.ok) {
|
|
9833
10164
|
process.exitCode = 0;
|
|
@@ -11260,7 +11591,7 @@ function isModuleNotFound4(e) {
|
|
|
11260
11591
|
}
|
|
11261
11592
|
async function loadIndexSqlite() {
|
|
11262
11593
|
try {
|
|
11263
|
-
return await import('./src-
|
|
11594
|
+
return await import('./src-OYGG7QAZ.mjs');
|
|
11264
11595
|
} catch (e) {
|
|
11265
11596
|
if (isModuleNotFound4(e)) {
|
|
11266
11597
|
console.error(
|