agent-inspect 6.31.3 → 6.31.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 +14 -0
- package/README.md +1 -1
- package/SECURITY.md +2 -0
- package/docs/GETTING-STARTED.md +2 -0
- package/docs/SAFE-TRACE-SHARING.md +1 -0
- package/package.json +1 -1
- package/packages/cli/dist/{chunk-SJ6FRNOE.mjs → chunk-LKEPABND.mjs} +86 -80
- package/packages/cli/dist/chunk-LKEPABND.mjs.map +1 -0
- package/packages/cli/dist/index.cjs +449 -91
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +357 -14
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/cli/dist/{src-YNEJOPRA.mjs → src-4WYF5RFI.mjs} +3 -3
- package/packages/cli/dist/{src-YNEJOPRA.mjs.map → src-4WYF5RFI.mjs.map} +1 -1
- package/packages/core/dist/advanced.cjs +97 -30
- package/packages/core/dist/advanced.cjs.map +1 -1
- package/packages/core/dist/advanced.mjs +13 -13
- package/packages/core/dist/checks.cjs +51 -49
- package/packages/core/dist/checks.cjs.map +1 -1
- package/packages/core/dist/checks.mjs +5 -5
- package/packages/core/dist/{chunk-PBNBQRXV.mjs → chunk-2KJR6X4V.mjs} +9 -9
- package/packages/core/dist/chunk-2KJR6X4V.mjs.map +1 -0
- package/packages/core/dist/{chunk-26YJSETN.mjs → chunk-7DHSWDKB.mjs} +19 -6
- package/packages/core/dist/chunk-7DHSWDKB.mjs.map +1 -0
- package/packages/core/dist/{chunk-BGF5JDJN.mjs → chunk-INE5IWLN.mjs} +3 -3
- package/packages/core/dist/{chunk-BGF5JDJN.mjs.map → chunk-INE5IWLN.mjs.map} +1 -1
- package/packages/core/dist/{chunk-ZFJ2ICTC.mjs → chunk-MTMTXTJL.mjs} +5 -5
- package/packages/core/dist/{chunk-ZFJ2ICTC.mjs.map → chunk-MTMTXTJL.mjs.map} +1 -1
- package/packages/core/dist/{chunk-KWBO36PH.mjs → chunk-NY4ILMXK.mjs} +4 -4
- package/packages/core/dist/{chunk-KWBO36PH.mjs.map → chunk-NY4ILMXK.mjs.map} +1 -1
- package/packages/core/dist/{chunk-WN5PT4GV.mjs → chunk-OSGNGRHF.mjs} +3 -3
- package/packages/core/dist/{chunk-WN5PT4GV.mjs.map → chunk-OSGNGRHF.mjs.map} +1 -1
- package/packages/core/dist/{chunk-CBPWLHNQ.mjs → chunk-PKDBFBJ7.mjs} +5 -76
- package/packages/core/dist/chunk-PKDBFBJ7.mjs.map +1 -0
- package/packages/core/dist/{chunk-VU6O5QAH.mjs → chunk-VLVCLAPB.mjs} +83 -5
- package/packages/core/dist/chunk-VLVCLAPB.mjs.map +1 -0
- package/packages/core/dist/exporters.cjs +242 -6
- package/packages/core/dist/exporters.cjs.map +1 -1
- package/packages/core/dist/exporters.mjs +143 -9
- package/packages/core/dist/exporters.mjs.map +1 -1
- package/packages/core/dist/index.cjs +97 -8
- package/packages/core/dist/index.cjs.map +1 -1
- package/packages/core/dist/index.mjs +6 -6
- package/packages/core/dist/logs.cjs +80 -2
- package/packages/core/dist/logs.cjs.map +1 -1
- package/packages/core/dist/logs.d.cts +2 -0
- package/packages/core/dist/logs.d.ts +2 -0
- package/packages/core/dist/logs.mjs +2 -2
- package/packages/core/dist/readers.cjs +2 -0
- package/packages/core/dist/readers.cjs.map +1 -1
- package/packages/core/dist/readers.mjs +2 -2
- package/packages/core/dist/writers.cjs +96 -8
- package/packages/core/dist/writers.cjs.map +1 -1
- package/packages/core/dist/writers.mjs +7 -8
- package/packages/core/dist/writers.mjs.map +1 -1
- package/packages/cli/dist/chunk-SJ6FRNOE.mjs.map +0 -1
- package/packages/core/dist/chunk-26YJSETN.mjs.map +0 -1
- package/packages/core/dist/chunk-CBPWLHNQ.mjs.map +0 -1
- package/packages/core/dist/chunk-PBNBQRXV.mjs.map +0 -1
- package/packages/core/dist/chunk-VU6O5QAH.mjs.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { buildRunWhatSummary, renderRunWhat, renderTimeline, buildRunTimeline } from './chunk-
|
|
2
|
-
import { summarizeObservedOutcomes, extractOutcomesFromTraceEvents, renderObservedOutcomesMarkdown, renderObservedOutcomesHtml } from './chunk-
|
|
1
|
+
import { buildRunWhatSummary, renderRunWhat, renderTimeline, buildRunTimeline } from './chunk-NY4ILMXK.mjs';
|
|
2
|
+
import { summarizeObservedOutcomes, extractOutcomesFromTraceEvents, renderObservedOutcomesMarkdown, renderObservedOutcomesHtml } from './chunk-INE5IWLN.mjs';
|
|
3
3
|
import { escapeHtml, flattenTree, safeString, compactAttributes, stableJson, escapeMarkdown, zeroKinds } from './chunk-CAWPF22J.mjs';
|
|
4
4
|
export { compactAttributes, escapeHtml, escapeMarkdown, flattenTree, safeString, stableJson, summarizeTree } from './chunk-CAWPF22J.mjs';
|
|
5
|
-
import { resolveRedactionProfile, applyProfileMetadataCaps, truncateStringForProfile } from './chunk-
|
|
6
|
-
import { Redactor } from './chunk-
|
|
7
|
-
import './chunk-
|
|
5
|
+
import { resolveRedactionProfile, applyProfileMetadataCaps, truncateStringForProfile, stringContainsHighConfidenceCredential } from './chunk-2KJR6X4V.mjs';
|
|
6
|
+
import { Redactor, DEFAULT_REDACT_KEYS, isCredentialSensitiveKey } from './chunk-VLVCLAPB.mjs';
|
|
7
|
+
import './chunk-7DHSWDKB.mjs';
|
|
8
8
|
import './chunk-EE5Z2GQ3.mjs';
|
|
9
9
|
import './chunk-7TGZLWEE.mjs';
|
|
10
10
|
import crypto from 'crypto';
|
|
@@ -12,6 +12,124 @@ import crypto from 'crypto';
|
|
|
12
12
|
// packages/core/src/exporters/types.ts
|
|
13
13
|
var EXPORT_PAYLOAD_VERSION = "0.1.2";
|
|
14
14
|
|
|
15
|
+
// packages/core/src/safety/url-redaction.ts
|
|
16
|
+
var HTTP_URL = /^https?:\/\/[^\s]+$/i;
|
|
17
|
+
var CONNECTION_PROTOCOLS = /* @__PURE__ */ new Set([
|
|
18
|
+
"postgres:",
|
|
19
|
+
"postgresql:",
|
|
20
|
+
"mysql:",
|
|
21
|
+
"mariadb:",
|
|
22
|
+
"mongodb:",
|
|
23
|
+
"mongodb+srv:",
|
|
24
|
+
"redis:",
|
|
25
|
+
"rediss:",
|
|
26
|
+
"amqp:",
|
|
27
|
+
"amqps:"
|
|
28
|
+
]);
|
|
29
|
+
var CONNECTION_URI = /^(?:postgres|postgresql|mysql|mariadb|mongodb(?:\+srv)?|rediss?|amqps?):\/\/[^\s]+$/i;
|
|
30
|
+
var UUID_SEGMENT = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
31
|
+
var HEX_SEGMENT = /^[0-9a-f]{12,}$/i;
|
|
32
|
+
var NUMERIC_SEGMENT = /^\d{5,}$/;
|
|
33
|
+
var OPAQUE_SEGMENT = /^[A-Za-z0-9_-]{20,}$/;
|
|
34
|
+
function looksLikeHttpUrl(value) {
|
|
35
|
+
return HTTP_URL.test(value.trim());
|
|
36
|
+
}
|
|
37
|
+
function looksLikeConnectionUri(value) {
|
|
38
|
+
return CONNECTION_URI.test(value.trim());
|
|
39
|
+
}
|
|
40
|
+
function looksLikeUrlForRedaction(value) {
|
|
41
|
+
return looksLikeHttpUrl(value) || looksLikeConnectionUri(value);
|
|
42
|
+
}
|
|
43
|
+
function parseRedactableUrl(value) {
|
|
44
|
+
try {
|
|
45
|
+
const url = new URL(value.trim());
|
|
46
|
+
if (url.protocol === "http:" || url.protocol === "https:") return url;
|
|
47
|
+
if (CONNECTION_PROTOCOLS.has(url.protocol)) return url;
|
|
48
|
+
return void 0;
|
|
49
|
+
} catch {
|
|
50
|
+
return void 0;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function isHttpProtocol(protocol) {
|
|
54
|
+
return protocol === "http:" || protocol === "https:";
|
|
55
|
+
}
|
|
56
|
+
function isIdentifierSegment(segment) {
|
|
57
|
+
if (UUID_SEGMENT.test(segment)) return true;
|
|
58
|
+
if (HEX_SEGMENT.test(segment)) return true;
|
|
59
|
+
if (NUMERIC_SEGMENT.test(segment)) return true;
|
|
60
|
+
return OPAQUE_SEGMENT.test(segment) && /\d/.test(segment) && /[A-Za-z]/.test(segment);
|
|
61
|
+
}
|
|
62
|
+
function decodeParam(value) {
|
|
63
|
+
try {
|
|
64
|
+
return decodeURIComponent(value.replace(/\+/g, " "));
|
|
65
|
+
} catch {
|
|
66
|
+
return value;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function redactParams(raw, options, replacement) {
|
|
70
|
+
let redacted = false;
|
|
71
|
+
const parts = raw.split("&").map((part) => {
|
|
72
|
+
if (part.length === 0) return part;
|
|
73
|
+
const separator = part.indexOf("=");
|
|
74
|
+
if (separator < 0) return part;
|
|
75
|
+
const rawKey = part.slice(0, separator);
|
|
76
|
+
const rawValue = part.slice(separator + 1);
|
|
77
|
+
const key = decodeParam(rawKey);
|
|
78
|
+
const value = decodeParam(rawValue);
|
|
79
|
+
if (isCredentialSensitiveKey(key, options.sensitiveKeys) || options.isSensitiveValue(value)) {
|
|
80
|
+
redacted = true;
|
|
81
|
+
return `${rawKey}=${replacement}`;
|
|
82
|
+
}
|
|
83
|
+
return part;
|
|
84
|
+
});
|
|
85
|
+
return { value: parts.join("&"), redacted };
|
|
86
|
+
}
|
|
87
|
+
function redactUrlString(value, options) {
|
|
88
|
+
const unchanged = {
|
|
89
|
+
value,
|
|
90
|
+
credentialRedacted: false,
|
|
91
|
+
identifiersMasked: false
|
|
92
|
+
};
|
|
93
|
+
if (!looksLikeUrlForRedaction(value)) return unchanged;
|
|
94
|
+
const url = parseRedactableUrl(value);
|
|
95
|
+
if (!url) return unchanged;
|
|
96
|
+
const replacement = options.replacement ?? "[REDACTED]";
|
|
97
|
+
const idPlaceholder = options.idPlaceholder ?? "[id]";
|
|
98
|
+
const http = isHttpProtocol(url.protocol);
|
|
99
|
+
let credentialRedacted = url.username.length > 0 || url.password.length > 0;
|
|
100
|
+
let identifiersMasked = false;
|
|
101
|
+
let pathname = url.pathname;
|
|
102
|
+
if (http && options.maskPathIds === true) {
|
|
103
|
+
pathname = url.pathname.split("/").map((segment) => {
|
|
104
|
+
if (segment.length === 0 || !isIdentifierSegment(decodeParam(segment))) {
|
|
105
|
+
return segment;
|
|
106
|
+
}
|
|
107
|
+
identifiersMasked = true;
|
|
108
|
+
return idPlaceholder;
|
|
109
|
+
}).join("/");
|
|
110
|
+
}
|
|
111
|
+
let search = "";
|
|
112
|
+
if (url.search.length > 1) {
|
|
113
|
+
const params = redactParams(url.search.slice(1), options, replacement);
|
|
114
|
+
if (params.redacted) credentialRedacted = true;
|
|
115
|
+
search = `?${params.value}`;
|
|
116
|
+
} else if (url.search.length === 1) {
|
|
117
|
+
search = "?";
|
|
118
|
+
}
|
|
119
|
+
let hash = url.hash;
|
|
120
|
+
if (url.hash.includes("=")) {
|
|
121
|
+
const params = redactParams(url.hash.slice(1), options, replacement);
|
|
122
|
+
if (params.redacted) credentialRedacted = true;
|
|
123
|
+
hash = `#${params.value}`;
|
|
124
|
+
}
|
|
125
|
+
if (!credentialRedacted && !identifiersMasked) return unchanged;
|
|
126
|
+
return {
|
|
127
|
+
value: `${url.protocol}//${url.host}${pathname}${search}${hash}`,
|
|
128
|
+
credentialRedacted,
|
|
129
|
+
identifiersMasked
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
15
133
|
// packages/core/src/exporters/redact-export.ts
|
|
16
134
|
function isRecord(value) {
|
|
17
135
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -29,21 +147,34 @@ function deepClone(value) {
|
|
|
29
147
|
}
|
|
30
148
|
return out;
|
|
31
149
|
}
|
|
32
|
-
function boundAttributeValues(record, maxMetadataValueLength, maxPreviewLength, seen, depth) {
|
|
150
|
+
function boundAttributeValues(record, sensitiveKeys, maxMetadataValueLength, maxPreviewLength, seen, depth) {
|
|
33
151
|
if (depth > 32) {
|
|
34
152
|
return { truncated: true, reason: "maxDepth" };
|
|
35
153
|
}
|
|
36
154
|
const out = {};
|
|
37
155
|
for (const [key, value] of Object.entries(record)) {
|
|
38
|
-
out[key] = boundValue(
|
|
156
|
+
out[key] = boundValue(
|
|
157
|
+
value,
|
|
158
|
+
key,
|
|
159
|
+
sensitiveKeys,
|
|
160
|
+
maxMetadataValueLength,
|
|
161
|
+
maxPreviewLength,
|
|
162
|
+
seen,
|
|
163
|
+
depth
|
|
164
|
+
);
|
|
39
165
|
}
|
|
40
166
|
return out;
|
|
41
167
|
}
|
|
42
|
-
function boundValue(value, key, maxMetadataValueLength, maxPreviewLength, seen, depth) {
|
|
168
|
+
function boundValue(value, key, sensitiveKeys, maxMetadataValueLength, maxPreviewLength, seen, depth) {
|
|
43
169
|
if (value === null || typeof value !== "object") {
|
|
44
170
|
if (typeof value === "string") {
|
|
171
|
+
const rewritten = redactUrlString(value, {
|
|
172
|
+
sensitiveKeys,
|
|
173
|
+
isSensitiveValue: stringContainsHighConfidenceCredential,
|
|
174
|
+
maskPathIds: true
|
|
175
|
+
}).value;
|
|
45
176
|
return truncateStringForProfile(
|
|
46
|
-
|
|
177
|
+
stringContainsHighConfidenceCredential(rewritten) ? "[REDACTED]" : rewritten,
|
|
47
178
|
key,
|
|
48
179
|
maxMetadataValueLength,
|
|
49
180
|
maxPreviewLength
|
|
@@ -58,6 +189,7 @@ function boundValue(value, key, maxMetadataValueLength, maxPreviewLength, seen,
|
|
|
58
189
|
(item, index) => boundValue(
|
|
59
190
|
item,
|
|
60
191
|
String(index),
|
|
192
|
+
sensitiveKeys,
|
|
61
193
|
maxMetadataValueLength,
|
|
62
194
|
maxPreviewLength,
|
|
63
195
|
seen,
|
|
@@ -67,6 +199,7 @@ function boundValue(value, key, maxMetadataValueLength, maxPreviewLength, seen,
|
|
|
67
199
|
}
|
|
68
200
|
return boundAttributeValues(
|
|
69
201
|
value,
|
|
202
|
+
sensitiveKeys,
|
|
70
203
|
maxMetadataValueLength,
|
|
71
204
|
maxPreviewLength,
|
|
72
205
|
seen,
|
|
@@ -81,6 +214,7 @@ function redactEventAttributes(attrs, redactor, maxMetadataValueLength, maxPrevi
|
|
|
81
214
|
const seen = /* @__PURE__ */ new WeakSet();
|
|
82
215
|
const bounded = boundAttributeValues(
|
|
83
216
|
redacted,
|
|
217
|
+
[...DEFAULT_REDACT_KEYS, ...redactor.sensitiveKeys],
|
|
84
218
|
maxMetadataValueLength,
|
|
85
219
|
maxPreviewLength,
|
|
86
220
|
seen,
|