@node9/proxy 2.7.0 → 2.7.2
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/dist/cli.js +155 -119
- package/dist/cli.mjs +943 -908
- package/dist/dashboard.mjs +149 -116
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -243,8 +243,8 @@ function sanitizeConfig(raw) {
|
|
|
243
243
|
}
|
|
244
244
|
}
|
|
245
245
|
const lines = result.error.issues.map((issue) => {
|
|
246
|
-
const
|
|
247
|
-
return ` \u2022 ${
|
|
246
|
+
const path74 = issue.path.length > 0 ? issue.path.join(".") : "root";
|
|
247
|
+
return ` \u2022 ${path74}: ${issue.message}`;
|
|
248
248
|
});
|
|
249
249
|
return {
|
|
250
250
|
sanitized,
|
|
@@ -624,9 +624,9 @@ function matchesPattern(text, patterns) {
|
|
|
624
624
|
const withoutDotSlash = text.replace(/^\.\//, "");
|
|
625
625
|
return isMatch(withoutDotSlash) || isMatch(`./${withoutDotSlash}`);
|
|
626
626
|
}
|
|
627
|
-
function getNestedValue(obj,
|
|
627
|
+
function getNestedValue(obj, path74) {
|
|
628
628
|
if (!obj || typeof obj !== "object") return null;
|
|
629
|
-
const segments =
|
|
629
|
+
const segments = path74.split(".");
|
|
630
630
|
for (const seg of segments) {
|
|
631
631
|
if (FORBIDDEN_PATH_SEGMENTS.has(seg)) return null;
|
|
632
632
|
}
|
|
@@ -5423,13 +5423,13 @@ function getConfig(cwd) {
|
|
|
5423
5423
|
}
|
|
5424
5424
|
if (Array.isArray(mc.jailPaths)) {
|
|
5425
5425
|
for (const jp of mc.jailPaths) {
|
|
5426
|
-
const
|
|
5427
|
-
if (!
|
|
5426
|
+
const path74 = typeof jp?.path === "string" ? jp.path.trim() : "";
|
|
5427
|
+
if (!path74) continue;
|
|
5428
5428
|
const verdict = jp?.verdict === "review" ? "review" : "block";
|
|
5429
|
-
for (const r of pathRules(
|
|
5429
|
+
for (const r of pathRules(path74, verdict, "org-managed jail")) {
|
|
5430
5430
|
mergedPolicy.smartRules.push({ ...r, name: `org:${r.name}` });
|
|
5431
5431
|
}
|
|
5432
|
-
mergedPolicy.managedJailPaths.push({ path:
|
|
5432
|
+
mergedPolicy.managedJailPaths.push({ path: path74, verdict });
|
|
5433
5433
|
}
|
|
5434
5434
|
}
|
|
5435
5435
|
if (Array.isArray(mc.trustedHosts)) {
|
|
@@ -11401,14 +11401,15 @@ var init_keyed_guard = __esm({
|
|
|
11401
11401
|
function normalizeModel(raw) {
|
|
11402
11402
|
return raw.replace(/-\d{8}$/, "").toLowerCase();
|
|
11403
11403
|
}
|
|
11404
|
-
function readCache() {
|
|
11404
|
+
function readCache(opts) {
|
|
11405
11405
|
try {
|
|
11406
11406
|
const raw = JSON.parse(import_fs17.default.readFileSync(CACHE_FILE(), "utf-8"));
|
|
11407
11407
|
if (typeof raw.fetchedAt !== "string" || typeof raw.prices !== "object" || raw.prices === null) {
|
|
11408
11408
|
return null;
|
|
11409
11409
|
}
|
|
11410
11410
|
const ageMs = Date.now() - new Date(raw.fetchedAt).getTime();
|
|
11411
|
-
if (ageMs
|
|
11411
|
+
if (!Number.isFinite(ageMs) || ageMs < 0) return null;
|
|
11412
|
+
if (opts.requireFresh && ageMs > TTL_MS) return null;
|
|
11412
11413
|
return raw.prices;
|
|
11413
11414
|
} catch {
|
|
11414
11415
|
return null;
|
|
@@ -11474,7 +11475,7 @@ async function fetchLiteLLMPricing() {
|
|
|
11474
11475
|
}
|
|
11475
11476
|
async function ensurePricingLoaded() {
|
|
11476
11477
|
if (memCache !== null && Date.now() - memCacheAt < TTL_MS) return;
|
|
11477
|
-
const fromDisk = readCache();
|
|
11478
|
+
const fromDisk = readCache({ requireFresh: true });
|
|
11478
11479
|
if (fromDisk && Object.keys(fromDisk).length > 0) {
|
|
11479
11480
|
memCache = fromDisk;
|
|
11480
11481
|
memCacheAt = Date.now();
|
|
@@ -11499,7 +11500,7 @@ function pricingFor(model) {
|
|
|
11499
11500
|
if (cached !== void 0) return cached;
|
|
11500
11501
|
if (memCache === null && !diskChecked) {
|
|
11501
11502
|
diskChecked = true;
|
|
11502
|
-
const disk = readCache();
|
|
11503
|
+
const disk = readCache({ requireFresh: false });
|
|
11503
11504
|
if (disk && Object.keys(disk).length > 0) {
|
|
11504
11505
|
memCache = disk;
|
|
11505
11506
|
memCacheAt = Date.now();
|
|
@@ -12506,6 +12507,38 @@ var init_scan_json = __esm({
|
|
|
12506
12507
|
}
|
|
12507
12508
|
});
|
|
12508
12509
|
|
|
12510
|
+
// src/session-files.ts
|
|
12511
|
+
function listSessionFiles(dir, maxDepth = 6) {
|
|
12512
|
+
const out = [];
|
|
12513
|
+
const walk = (d, rel, depth) => {
|
|
12514
|
+
if (depth > maxDepth) return;
|
|
12515
|
+
let entries;
|
|
12516
|
+
try {
|
|
12517
|
+
entries = fs22.readdirSync(d, { withFileTypes: true });
|
|
12518
|
+
} catch {
|
|
12519
|
+
return;
|
|
12520
|
+
}
|
|
12521
|
+
for (const e of entries) {
|
|
12522
|
+
const childRel = rel ? path24.join(rel, e.name) : e.name;
|
|
12523
|
+
if (e.isDirectory()) walk(path24.join(d, e.name), childRel, depth + 1);
|
|
12524
|
+
else if (e.name.endsWith(".jsonl")) out.push(childRel);
|
|
12525
|
+
}
|
|
12526
|
+
};
|
|
12527
|
+
walk(dir, "", 0);
|
|
12528
|
+
return out;
|
|
12529
|
+
}
|
|
12530
|
+
function sessionIdOf(relPath) {
|
|
12531
|
+
return path24.basename(relPath).replace(/\.jsonl$/, "");
|
|
12532
|
+
}
|
|
12533
|
+
var fs22, path24;
|
|
12534
|
+
var init_session_files = __esm({
|
|
12535
|
+
"src/session-files.ts"() {
|
|
12536
|
+
"use strict";
|
|
12537
|
+
fs22 = __toESM(require("fs"));
|
|
12538
|
+
path24 = __toESM(require("path"));
|
|
12539
|
+
}
|
|
12540
|
+
});
|
|
12541
|
+
|
|
12509
12542
|
// src/cli/render/scan-history.ts
|
|
12510
12543
|
function defaultHistoryPath() {
|
|
12511
12544
|
return import_path23.default.join(import_os20.default.homedir(), ".node9", "scan-history.json");
|
|
@@ -12869,6 +12902,7 @@ var init_costSync = __esm({
|
|
|
12869
12902
|
init_cost_codex();
|
|
12870
12903
|
init_cost_gemini();
|
|
12871
12904
|
init_cost_copilot();
|
|
12905
|
+
init_session_files();
|
|
12872
12906
|
SYNC_INTERVAL_MS = 10 * 60 * 1e3;
|
|
12873
12907
|
claudeSource = {
|
|
12874
12908
|
id: "claude",
|
|
@@ -12894,7 +12928,7 @@ var init_costSync = __esm({
|
|
|
12894
12928
|
}
|
|
12895
12929
|
let files;
|
|
12896
12930
|
try {
|
|
12897
|
-
files =
|
|
12931
|
+
files = listSessionFiles(dirPath);
|
|
12898
12932
|
} catch {
|
|
12899
12933
|
continue;
|
|
12900
12934
|
}
|
|
@@ -13948,7 +13982,7 @@ function countScanFiles() {
|
|
|
13948
13982
|
const dp = import_path28.default.join(mp, day);
|
|
13949
13983
|
try {
|
|
13950
13984
|
if (!import_fs26.default.statSync(dp).isDirectory()) continue;
|
|
13951
|
-
total +=
|
|
13985
|
+
total += listSessionFiles(dp).length;
|
|
13952
13986
|
} catch {
|
|
13953
13987
|
continue;
|
|
13954
13988
|
}
|
|
@@ -13981,7 +14015,7 @@ function processClaudeFile(file, projPath, projLabel, ruleSources, startDate, re
|
|
|
13981
14015
|
result.filesScanned++;
|
|
13982
14016
|
result.sessions++;
|
|
13983
14017
|
onProgress?.(result.filesScanned);
|
|
13984
|
-
const sessionId = file
|
|
14018
|
+
const sessionId = sessionIdOf(file);
|
|
13985
14019
|
const session = { sessionId, costUSD: 0, toolCalls: 0 };
|
|
13986
14020
|
let raw;
|
|
13987
14021
|
try {
|
|
@@ -14207,7 +14241,7 @@ function processClaudeProject(proj, projectsDir, ruleSources, startDate, result,
|
|
|
14207
14241
|
);
|
|
14208
14242
|
let files;
|
|
14209
14243
|
try {
|
|
14210
|
-
files =
|
|
14244
|
+
files = listSessionFiles(projPath);
|
|
14211
14245
|
} catch {
|
|
14212
14246
|
return;
|
|
14213
14247
|
}
|
|
@@ -16228,6 +16262,7 @@ var init_scan = __esm({
|
|
|
16228
16262
|
init_protection();
|
|
16229
16263
|
import_string_width2 = __toESM(require("string-width"));
|
|
16230
16264
|
init_scan_json();
|
|
16265
|
+
init_session_files();
|
|
16231
16266
|
init_scan_history();
|
|
16232
16267
|
toolInspectionMap = DEFAULT_CONFIG.policy.toolInspection;
|
|
16233
16268
|
CODE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
@@ -18896,28 +18931,28 @@ var init_ship2 = __esm({
|
|
|
18896
18931
|
|
|
18897
18932
|
// src/machine-id.ts
|
|
18898
18933
|
function getMachineId(homeDir2 = os34.homedir()) {
|
|
18899
|
-
const file =
|
|
18934
|
+
const file = path38.join(homeDir2, ".node9", "machine-id");
|
|
18900
18935
|
try {
|
|
18901
|
-
const existing =
|
|
18936
|
+
const existing = fs39.readFileSync(file, "utf-8").trim();
|
|
18902
18937
|
if (UUID_RE.test(existing)) return existing;
|
|
18903
18938
|
} catch {
|
|
18904
18939
|
}
|
|
18905
18940
|
const id = crypto5.randomUUID();
|
|
18906
18941
|
try {
|
|
18907
|
-
|
|
18908
|
-
|
|
18942
|
+
fs39.mkdirSync(path38.dirname(file), { recursive: true });
|
|
18943
|
+
fs39.writeFileSync(file, id + "\n", { mode: 384 });
|
|
18909
18944
|
} catch {
|
|
18910
18945
|
}
|
|
18911
18946
|
return id;
|
|
18912
18947
|
}
|
|
18913
|
-
var crypto5,
|
|
18948
|
+
var crypto5, fs39, os34, path38, UUID_RE;
|
|
18914
18949
|
var init_machine_id = __esm({
|
|
18915
18950
|
"src/machine-id.ts"() {
|
|
18916
18951
|
"use strict";
|
|
18917
18952
|
crypto5 = __toESM(require("crypto"));
|
|
18918
|
-
|
|
18953
|
+
fs39 = __toESM(require("fs"));
|
|
18919
18954
|
os34 = __toESM(require("os"));
|
|
18920
|
-
|
|
18955
|
+
path38 = __toESM(require("path"));
|
|
18921
18956
|
UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
18922
18957
|
}
|
|
18923
18958
|
});
|
|
@@ -23158,14 +23193,14 @@ var require_util = __commonJS({
|
|
|
23158
23193
|
}
|
|
23159
23194
|
const port = url.port != null ? url.port : url.protocol === "https:" ? 443 : 80;
|
|
23160
23195
|
let origin = url.origin != null ? url.origin : `${url.protocol || ""}//${url.hostname || ""}:${port}`;
|
|
23161
|
-
let
|
|
23196
|
+
let path74 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
|
|
23162
23197
|
if (origin[origin.length - 1] === "/") {
|
|
23163
23198
|
origin = origin.slice(0, origin.length - 1);
|
|
23164
23199
|
}
|
|
23165
|
-
if (
|
|
23166
|
-
|
|
23200
|
+
if (path74 && path74[0] !== "/") {
|
|
23201
|
+
path74 = `/${path74}`;
|
|
23167
23202
|
}
|
|
23168
|
-
return new URL(`${origin}${
|
|
23203
|
+
return new URL(`${origin}${path74}`);
|
|
23169
23204
|
}
|
|
23170
23205
|
if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) {
|
|
23171
23206
|
throw new InvalidArgumentError("Invalid URL protocol: the URL must start with `http:` or `https:`.");
|
|
@@ -23986,9 +24021,9 @@ var require_diagnostics = __commonJS({
|
|
|
23986
24021
|
"undici:client:sendHeaders",
|
|
23987
24022
|
(evt) => {
|
|
23988
24023
|
const {
|
|
23989
|
-
request: { method, path:
|
|
24024
|
+
request: { method, path: path74, origin }
|
|
23990
24025
|
} = evt;
|
|
23991
|
-
debugLog("sending request to %s %s%s", method, origin,
|
|
24026
|
+
debugLog("sending request to %s %s%s", method, origin, path74);
|
|
23992
24027
|
}
|
|
23993
24028
|
);
|
|
23994
24029
|
}
|
|
@@ -24006,14 +24041,14 @@ var require_diagnostics = __commonJS({
|
|
|
24006
24041
|
"undici:request:headers",
|
|
24007
24042
|
(evt) => {
|
|
24008
24043
|
const {
|
|
24009
|
-
request: { method, path:
|
|
24044
|
+
request: { method, path: path74, origin },
|
|
24010
24045
|
response: { statusCode }
|
|
24011
24046
|
} = evt;
|
|
24012
24047
|
debugLog(
|
|
24013
24048
|
"received response to %s %s%s - HTTP %d",
|
|
24014
24049
|
method,
|
|
24015
24050
|
origin,
|
|
24016
|
-
|
|
24051
|
+
path74,
|
|
24017
24052
|
statusCode
|
|
24018
24053
|
);
|
|
24019
24054
|
}
|
|
@@ -24022,23 +24057,23 @@ var require_diagnostics = __commonJS({
|
|
|
24022
24057
|
"undici:request:trailers",
|
|
24023
24058
|
(evt) => {
|
|
24024
24059
|
const {
|
|
24025
|
-
request: { method, path:
|
|
24060
|
+
request: { method, path: path74, origin }
|
|
24026
24061
|
} = evt;
|
|
24027
|
-
debugLog("trailers received from %s %s%s", method, origin,
|
|
24062
|
+
debugLog("trailers received from %s %s%s", method, origin, path74);
|
|
24028
24063
|
}
|
|
24029
24064
|
);
|
|
24030
24065
|
diagnosticsChannel.subscribe(
|
|
24031
24066
|
"undici:request:error",
|
|
24032
24067
|
(evt) => {
|
|
24033
24068
|
const {
|
|
24034
|
-
request: { method, path:
|
|
24069
|
+
request: { method, path: path74, origin },
|
|
24035
24070
|
error
|
|
24036
24071
|
} = evt;
|
|
24037
24072
|
debugLog(
|
|
24038
24073
|
"request to %s %s%s errored - %s",
|
|
24039
24074
|
method,
|
|
24040
24075
|
origin,
|
|
24041
|
-
|
|
24076
|
+
path74,
|
|
24042
24077
|
error.message
|
|
24043
24078
|
);
|
|
24044
24079
|
}
|
|
@@ -24141,7 +24176,7 @@ var require_request = __commonJS({
|
|
|
24141
24176
|
var kHandler = /* @__PURE__ */ Symbol("handler");
|
|
24142
24177
|
var Request = class {
|
|
24143
24178
|
constructor(origin, {
|
|
24144
|
-
path:
|
|
24179
|
+
path: path74,
|
|
24145
24180
|
method,
|
|
24146
24181
|
body,
|
|
24147
24182
|
headers,
|
|
@@ -24158,11 +24193,11 @@ var require_request = __commonJS({
|
|
|
24158
24193
|
maxRedirections,
|
|
24159
24194
|
typeOfService
|
|
24160
24195
|
}, handler) {
|
|
24161
|
-
if (typeof
|
|
24196
|
+
if (typeof path74 !== "string") {
|
|
24162
24197
|
throw new InvalidArgumentError("path must be a string");
|
|
24163
|
-
} else if (
|
|
24198
|
+
} else if (path74[0] !== "/" && !(path74.startsWith("http://") || path74.startsWith("https://")) && method !== "CONNECT") {
|
|
24164
24199
|
throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
|
|
24165
|
-
} else if (invalidPathRegex.test(
|
|
24200
|
+
} else if (invalidPathRegex.test(path74)) {
|
|
24166
24201
|
throw new InvalidArgumentError("invalid request path");
|
|
24167
24202
|
}
|
|
24168
24203
|
if (typeof method !== "string") {
|
|
@@ -24237,7 +24272,7 @@ var require_request = __commonJS({
|
|
|
24237
24272
|
this.completed = false;
|
|
24238
24273
|
this.aborted = false;
|
|
24239
24274
|
this.upgrade = upgrade || null;
|
|
24240
|
-
this.path = query ? serializePathWithQuery(
|
|
24275
|
+
this.path = query ? serializePathWithQuery(path74, query) : path74;
|
|
24241
24276
|
this.origin = origin;
|
|
24242
24277
|
this.protocol = getProtocolFromUrlString(origin);
|
|
24243
24278
|
this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
|
|
@@ -29276,7 +29311,7 @@ var require_client_h1 = __commonJS({
|
|
|
29276
29311
|
return method !== "GET" && method !== "HEAD" && method !== "OPTIONS" && method !== "TRACE" && method !== "CONNECT";
|
|
29277
29312
|
}
|
|
29278
29313
|
function writeH1(client, request2) {
|
|
29279
|
-
const { method, path:
|
|
29314
|
+
const { method, path: path74, host, upgrade, blocking, reset } = request2;
|
|
29280
29315
|
let { body, headers, contentLength } = request2;
|
|
29281
29316
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
|
|
29282
29317
|
if (util.isFormDataLike(body)) {
|
|
@@ -29345,7 +29380,7 @@ var require_client_h1 = __commonJS({
|
|
|
29345
29380
|
if (socket.setTypeOfService) {
|
|
29346
29381
|
socket.setTypeOfService(request2.typeOfService);
|
|
29347
29382
|
}
|
|
29348
|
-
let header = `${method} ${
|
|
29383
|
+
let header = `${method} ${path74} HTTP/1.1\r
|
|
29349
29384
|
`;
|
|
29350
29385
|
if (typeof host === "string") {
|
|
29351
29386
|
header += `host: ${host}\r
|
|
@@ -29998,7 +30033,7 @@ var require_client_h2 = __commonJS({
|
|
|
29998
30033
|
function writeH2(client, request2) {
|
|
29999
30034
|
const requestTimeout = request2.bodyTimeout ?? client[kBodyTimeout];
|
|
30000
30035
|
const session = client[kHTTP2Session];
|
|
30001
|
-
const { method, path:
|
|
30036
|
+
const { method, path: path74, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request2;
|
|
30002
30037
|
let { body } = request2;
|
|
30003
30038
|
if (upgrade != null && upgrade !== "websocket") {
|
|
30004
30039
|
util.errorRequest(client, request2, new InvalidArgumentError(`Custom upgrade "${upgrade}" not supported over HTTP/2`));
|
|
@@ -30066,7 +30101,7 @@ var require_client_h2 = __commonJS({
|
|
|
30066
30101
|
}
|
|
30067
30102
|
headers[HTTP2_HEADER_METHOD] = "CONNECT";
|
|
30068
30103
|
headers[HTTP2_HEADER_PROTOCOL] = "websocket";
|
|
30069
|
-
headers[HTTP2_HEADER_PATH] =
|
|
30104
|
+
headers[HTTP2_HEADER_PATH] = path74;
|
|
30070
30105
|
if (protocol === "ws:" || protocol === "wss:") {
|
|
30071
30106
|
headers[HTTP2_HEADER_SCHEME] = protocol === "ws:" ? "http" : "https";
|
|
30072
30107
|
} else {
|
|
@@ -30107,7 +30142,7 @@ var require_client_h2 = __commonJS({
|
|
|
30107
30142
|
stream.setTimeout(requestTimeout);
|
|
30108
30143
|
return true;
|
|
30109
30144
|
}
|
|
30110
|
-
headers[HTTP2_HEADER_PATH] =
|
|
30145
|
+
headers[HTTP2_HEADER_PATH] = path74;
|
|
30111
30146
|
headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https";
|
|
30112
30147
|
const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
|
|
30113
30148
|
if (body && typeof body.read === "function") {
|
|
@@ -32409,10 +32444,10 @@ var require_proxy_agent = __commonJS({
|
|
|
32409
32444
|
};
|
|
32410
32445
|
const {
|
|
32411
32446
|
origin,
|
|
32412
|
-
path:
|
|
32447
|
+
path: path74 = "/",
|
|
32413
32448
|
headers = {}
|
|
32414
32449
|
} = opts;
|
|
32415
|
-
opts.path = origin +
|
|
32450
|
+
opts.path = origin + path74;
|
|
32416
32451
|
if (!("host" in headers) && !("Host" in headers)) {
|
|
32417
32452
|
const { host } = new URL(origin);
|
|
32418
32453
|
headers.host = host;
|
|
@@ -34475,20 +34510,20 @@ var require_mock_utils = __commonJS({
|
|
|
34475
34510
|
}
|
|
34476
34511
|
return normalizedQp;
|
|
34477
34512
|
}
|
|
34478
|
-
function safeUrl(
|
|
34479
|
-
if (typeof
|
|
34480
|
-
return
|
|
34513
|
+
function safeUrl(path74) {
|
|
34514
|
+
if (typeof path74 !== "string") {
|
|
34515
|
+
return path74;
|
|
34481
34516
|
}
|
|
34482
|
-
const pathSegments =
|
|
34517
|
+
const pathSegments = path74.split("?", 3);
|
|
34483
34518
|
if (pathSegments.length !== 2) {
|
|
34484
|
-
return
|
|
34519
|
+
return path74;
|
|
34485
34520
|
}
|
|
34486
34521
|
const qp = new URLSearchParams(pathSegments.pop());
|
|
34487
34522
|
qp.sort();
|
|
34488
34523
|
return [...pathSegments, qp.toString()].join("?");
|
|
34489
34524
|
}
|
|
34490
|
-
function matchKey(mockDispatch2, { path:
|
|
34491
|
-
const pathMatch = matchValue(mockDispatch2.path,
|
|
34525
|
+
function matchKey(mockDispatch2, { path: path74, method, body, headers }) {
|
|
34526
|
+
const pathMatch = matchValue(mockDispatch2.path, path74);
|
|
34492
34527
|
const methodMatch = matchValue(mockDispatch2.method, method);
|
|
34493
34528
|
const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
|
|
34494
34529
|
const headersMatch = matchHeaders(mockDispatch2, headers);
|
|
@@ -34513,8 +34548,8 @@ var require_mock_utils = __commonJS({
|
|
|
34513
34548
|
const basePath = key.query ? serializePathWithQuery(key.path, key.query) : key.path;
|
|
34514
34549
|
const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
|
|
34515
34550
|
const resolvedPathWithoutTrailingSlash = removeTrailingSlash(resolvedPath);
|
|
34516
|
-
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path:
|
|
34517
|
-
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(
|
|
34551
|
+
let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path74, ignoreTrailingSlash }) => {
|
|
34552
|
+
return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path74)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path74), resolvedPath);
|
|
34518
34553
|
});
|
|
34519
34554
|
if (matchedMockDispatches.length === 0) {
|
|
34520
34555
|
throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
|
|
@@ -34553,19 +34588,19 @@ var require_mock_utils = __commonJS({
|
|
|
34553
34588
|
mockDispatches.splice(index, 1);
|
|
34554
34589
|
}
|
|
34555
34590
|
}
|
|
34556
|
-
function removeTrailingSlash(
|
|
34557
|
-
while (
|
|
34558
|
-
|
|
34591
|
+
function removeTrailingSlash(path74) {
|
|
34592
|
+
while (path74.endsWith("/")) {
|
|
34593
|
+
path74 = path74.slice(0, -1);
|
|
34559
34594
|
}
|
|
34560
|
-
if (
|
|
34561
|
-
|
|
34595
|
+
if (path74.length === 0) {
|
|
34596
|
+
path74 = "/";
|
|
34562
34597
|
}
|
|
34563
|
-
return
|
|
34598
|
+
return path74;
|
|
34564
34599
|
}
|
|
34565
34600
|
function buildKey(opts) {
|
|
34566
|
-
const { path:
|
|
34601
|
+
const { path: path74, method, body, headers, query } = opts;
|
|
34567
34602
|
return {
|
|
34568
|
-
path:
|
|
34603
|
+
path: path74,
|
|
34569
34604
|
method,
|
|
34570
34605
|
body,
|
|
34571
34606
|
headers,
|
|
@@ -35255,10 +35290,10 @@ var require_pending_interceptors_formatter = __commonJS({
|
|
|
35255
35290
|
}
|
|
35256
35291
|
format(pendingInterceptors) {
|
|
35257
35292
|
const withPrettyHeaders = pendingInterceptors.map(
|
|
35258
|
-
({ method, path:
|
|
35293
|
+
({ method, path: path74, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
|
|
35259
35294
|
Method: method,
|
|
35260
35295
|
Origin: origin,
|
|
35261
|
-
Path:
|
|
35296
|
+
Path: path74,
|
|
35262
35297
|
"Status code": statusCode,
|
|
35263
35298
|
Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
|
|
35264
35299
|
Invocations: timesInvoked,
|
|
@@ -35340,9 +35375,9 @@ var require_mock_agent = __commonJS({
|
|
|
35340
35375
|
const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters];
|
|
35341
35376
|
const dispatchOpts = { ...opts };
|
|
35342
35377
|
if (acceptNonStandardSearchParameters && dispatchOpts.path) {
|
|
35343
|
-
const [
|
|
35378
|
+
const [path74, searchParams] = dispatchOpts.path.split("?");
|
|
35344
35379
|
const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters);
|
|
35345
|
-
dispatchOpts.path = `${
|
|
35380
|
+
dispatchOpts.path = `${path74}?${normalizedSearchParams}`;
|
|
35346
35381
|
}
|
|
35347
35382
|
return this[kAgent].dispatch(dispatchOpts, handler);
|
|
35348
35383
|
}
|
|
@@ -35743,12 +35778,12 @@ var require_snapshot_recorder = __commonJS({
|
|
|
35743
35778
|
* @return {Promise<void>} - Resolves when snapshots are loaded
|
|
35744
35779
|
*/
|
|
35745
35780
|
async loadSnapshots(filePath) {
|
|
35746
|
-
const
|
|
35747
|
-
if (!
|
|
35781
|
+
const path74 = filePath || this.#snapshotPath;
|
|
35782
|
+
if (!path74) {
|
|
35748
35783
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
35749
35784
|
}
|
|
35750
35785
|
try {
|
|
35751
|
-
const data = await readFile(resolve2(
|
|
35786
|
+
const data = await readFile(resolve2(path74), "utf8");
|
|
35752
35787
|
const parsed = JSON.parse(data);
|
|
35753
35788
|
if (Array.isArray(parsed)) {
|
|
35754
35789
|
this.#snapshots.clear();
|
|
@@ -35762,7 +35797,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
35762
35797
|
if (error.code === "ENOENT") {
|
|
35763
35798
|
this.#snapshots.clear();
|
|
35764
35799
|
} else {
|
|
35765
|
-
throw new UndiciError(`Failed to load snapshots from ${
|
|
35800
|
+
throw new UndiciError(`Failed to load snapshots from ${path74}`, { cause: error });
|
|
35766
35801
|
}
|
|
35767
35802
|
}
|
|
35768
35803
|
}
|
|
@@ -35773,11 +35808,11 @@ var require_snapshot_recorder = __commonJS({
|
|
|
35773
35808
|
* @returns {Promise<void>} - Resolves when snapshots are saved
|
|
35774
35809
|
*/
|
|
35775
35810
|
async saveSnapshots(filePath) {
|
|
35776
|
-
const
|
|
35777
|
-
if (!
|
|
35811
|
+
const path74 = filePath || this.#snapshotPath;
|
|
35812
|
+
if (!path74) {
|
|
35778
35813
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
35779
35814
|
}
|
|
35780
|
-
const resolvedPath = resolve2(
|
|
35815
|
+
const resolvedPath = resolve2(path74);
|
|
35781
35816
|
await mkdir(dirname3(resolvedPath), { recursive: true });
|
|
35782
35817
|
const data = Array.from(this.#snapshots.entries()).map(([hash, snapshot]) => ({
|
|
35783
35818
|
hash,
|
|
@@ -36402,15 +36437,15 @@ var require_redirect_handler = __commonJS({
|
|
|
36402
36437
|
return;
|
|
36403
36438
|
}
|
|
36404
36439
|
const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
|
|
36405
|
-
const
|
|
36406
|
-
const redirectUrlString = `${origin}${
|
|
36440
|
+
const path74 = search ? `${pathname}${search}` : pathname;
|
|
36441
|
+
const redirectUrlString = `${origin}${path74}`;
|
|
36407
36442
|
for (const historyUrl of this.history) {
|
|
36408
36443
|
if (historyUrl.toString() === redirectUrlString) {
|
|
36409
36444
|
throw new InvalidArgumentError(`Redirect loop detected. Cannot redirect to ${origin}. This typically happens when using a Client or Pool with cross-origin redirects. Use an Agent for cross-origin redirects.`);
|
|
36410
36445
|
}
|
|
36411
36446
|
}
|
|
36412
36447
|
this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
|
|
36413
|
-
this.opts.path =
|
|
36448
|
+
this.opts.path = path74;
|
|
36414
36449
|
this.opts.origin = origin;
|
|
36415
36450
|
this.opts.query = null;
|
|
36416
36451
|
}
|
|
@@ -42617,11 +42652,11 @@ var require_fetch = __commonJS({
|
|
|
42617
42652
|
function dispatch({ body }) {
|
|
42618
42653
|
const url = requestCurrentURL(request2);
|
|
42619
42654
|
const agent = fetchParams.controller.dispatcher;
|
|
42620
|
-
const
|
|
42655
|
+
const path74 = url.pathname + url.search;
|
|
42621
42656
|
const hasTrailingQuestionMark = url.search.length === 0 && url.href[url.href.length - url.hash.length - 1] === "?";
|
|
42622
42657
|
return new Promise((resolve2, reject) => agent.dispatch(
|
|
42623
42658
|
{
|
|
42624
|
-
path: hasTrailingQuestionMark ? `${
|
|
42659
|
+
path: hasTrailingQuestionMark ? `${path74}?` : path74,
|
|
42625
42660
|
origin: url.origin,
|
|
42626
42661
|
method: request2.method,
|
|
42627
42662
|
body: agent.isMockActive ? request2.body && (request2.body.source || request2.body.stream) : body,
|
|
@@ -43552,9 +43587,9 @@ var require_util4 = __commonJS({
|
|
|
43552
43587
|
}
|
|
43553
43588
|
}
|
|
43554
43589
|
}
|
|
43555
|
-
function validateCookiePath(
|
|
43556
|
-
for (let i = 0; i <
|
|
43557
|
-
const code =
|
|
43590
|
+
function validateCookiePath(path74) {
|
|
43591
|
+
for (let i = 0; i < path74.length; ++i) {
|
|
43592
|
+
const code = path74.charCodeAt(i);
|
|
43558
43593
|
if (code < 32 || // exclude CTLs (0-31)
|
|
43559
43594
|
code === 127 || // DEL
|
|
43560
43595
|
code === 59) {
|
|
@@ -46724,11 +46759,11 @@ var require_undici = __commonJS({
|
|
|
46724
46759
|
if (typeof opts.path !== "string") {
|
|
46725
46760
|
throw new InvalidArgumentError("invalid opts.path");
|
|
46726
46761
|
}
|
|
46727
|
-
let
|
|
46762
|
+
let path74 = opts.path;
|
|
46728
46763
|
if (!opts.path.startsWith("/")) {
|
|
46729
|
-
|
|
46764
|
+
path74 = `/${path74}`;
|
|
46730
46765
|
}
|
|
46731
|
-
url = new URL(util.parseOrigin(url).origin +
|
|
46766
|
+
url = new URL(util.parseOrigin(url).origin + path74);
|
|
46732
46767
|
} else {
|
|
46733
46768
|
if (!opts) {
|
|
46734
46769
|
opts = typeof url === "object" ? url : {};
|
|
@@ -48716,9 +48751,9 @@ async function runDeviceLogin(opts = {}) {
|
|
|
48716
48751
|
}
|
|
48717
48752
|
|
|
48718
48753
|
// src/cli/commands/logout.ts
|
|
48719
|
-
var
|
|
48754
|
+
var fs49 = __toESM(require("fs"));
|
|
48720
48755
|
var os44 = __toESM(require("os"));
|
|
48721
|
-
var
|
|
48756
|
+
var path47 = __toESM(require("path"));
|
|
48722
48757
|
var import_chalk12 = __toESM(require("chalk"));
|
|
48723
48758
|
async function revokeSelf(creds) {
|
|
48724
48759
|
const url = creds.apiUrl.replace(/\/$/, "") + "/machines/self/disconnect";
|
|
@@ -48736,10 +48771,10 @@ function registerLogoutCommand(program2) {
|
|
|
48736
48771
|
"Disconnect this machine from the cloud (revokes its key; local enforcement keeps running)"
|
|
48737
48772
|
).action(async () => {
|
|
48738
48773
|
const profile = process.env.NODE9_PROFILE || "default";
|
|
48739
|
-
const credPath =
|
|
48774
|
+
const credPath = path47.join(os44.homedir(), ".node9", "credentials.json");
|
|
48740
48775
|
let all = {};
|
|
48741
48776
|
try {
|
|
48742
|
-
all = JSON.parse(
|
|
48777
|
+
all = JSON.parse(fs49.readFileSync(credPath, "utf-8"));
|
|
48743
48778
|
} catch {
|
|
48744
48779
|
}
|
|
48745
48780
|
const entry = all[profile];
|
|
@@ -48769,11 +48804,11 @@ function registerLogoutCommand(program2) {
|
|
|
48769
48804
|
delete all[profile];
|
|
48770
48805
|
if (Object.keys(all).length === 0) {
|
|
48771
48806
|
try {
|
|
48772
|
-
|
|
48807
|
+
fs49.unlinkSync(credPath);
|
|
48773
48808
|
} catch {
|
|
48774
48809
|
}
|
|
48775
48810
|
} else {
|
|
48776
|
-
|
|
48811
|
+
fs49.writeFileSync(credPath, JSON.stringify(all, null, 2), { mode: 384 });
|
|
48777
48812
|
}
|
|
48778
48813
|
console.log(import_chalk12.default.green("\u2713 Local: credentials removed."));
|
|
48779
48814
|
console.log(
|
|
@@ -50911,6 +50946,7 @@ init_costSync();
|
|
|
50911
50946
|
init_litellm();
|
|
50912
50947
|
init_cost_codex();
|
|
50913
50948
|
init_decision();
|
|
50949
|
+
init_session_files();
|
|
50914
50950
|
var TEST_COMMAND_RE3 = /(?:^|\s)(npm\s+(?:run\s+)?test|npx\s+(?:vitest|jest|mocha)|yarn\s+(?:run\s+)?test|pnpm\s+(?:run\s+)?test|vitest|jest|mocha|pytest|py\.test|cargo\s+test|go\s+test|bundle\s+exec\s+rspec|rspec|phpunit|dotnet\s+test)\b/i;
|
|
50915
50951
|
function buildTestTimestamps(allEntries) {
|
|
50916
50952
|
const testTs = /* @__PURE__ */ new Set();
|
|
@@ -51050,7 +51086,7 @@ function processClaudeCostProject(proj, projectsDir, start, end, acc) {
|
|
|
51050
51086
|
try {
|
|
51051
51087
|
const stat = import_fs55.default.statSync(projPath);
|
|
51052
51088
|
if (!stat.isDirectory()) return;
|
|
51053
|
-
files =
|
|
51089
|
+
files = listSessionFiles(projPath);
|
|
51054
51090
|
} catch {
|
|
51055
51091
|
return;
|
|
51056
51092
|
}
|
|
@@ -55519,7 +55555,7 @@ function severityFromScore(score) {
|
|
|
55519
55555
|
if (score >= 1) return "advisory";
|
|
55520
55556
|
return null;
|
|
55521
55557
|
}
|
|
55522
|
-
function analyzeWorkflow(
|
|
55558
|
+
function analyzeWorkflow(path74, content) {
|
|
55523
55559
|
let raw;
|
|
55524
55560
|
try {
|
|
55525
55561
|
raw = (0, import_yaml.parse)(content) ?? {};
|
|
@@ -55645,7 +55681,7 @@ function analyzeWorkflow(path73, content) {
|
|
|
55645
55681
|
dimension: "workflows",
|
|
55646
55682
|
severity,
|
|
55647
55683
|
title,
|
|
55648
|
-
file:
|
|
55684
|
+
file: path74,
|
|
55649
55685
|
signals,
|
|
55650
55686
|
mitigations: mitigations.length ? mitigations : void 0,
|
|
55651
55687
|
fix: head === "root" && privileged ? "Do not check out the untrusted PR head into the workspace root under a privileged trigger (pull_request_target/workflow_run) \u2014 check out the base ref, or isolate the head in a subdir (--add-dir). Add an actor gate and scope the agent tools." : head === "root" ? "This runs under `pull_request` (fork PRs get a read-only token), so the head checkout is low-risk today \u2014 keep it on `pull_request` (not `pull_request_target`) and keep the actor gate + scoped tools." : "Add/verify an actor gate, scope the agent tools to read-only, and env-deny secrets. See Anthropic\u2019s claude-code-action security doc."
|
|
@@ -55721,7 +55757,7 @@ function evalAgentJob(job, wf, raw, untrustedTrigger, reusable) {
|
|
|
55721
55757
|
if (reusable && !loadedGun && SEVERITY_RANK2[severity] > SEVERITY_RANK2.medium) severity = "medium";
|
|
55722
55758
|
return { severity, secrets, injectable, canReadEnv };
|
|
55723
55759
|
}
|
|
55724
|
-
function analyzeWorkflowSecrets(
|
|
55760
|
+
function analyzeWorkflowSecrets(path74, content) {
|
|
55725
55761
|
let raw;
|
|
55726
55762
|
try {
|
|
55727
55763
|
raw = (0, import_yaml.parse)(content) ?? {};
|
|
@@ -55741,7 +55777,7 @@ function analyzeWorkflowSecrets(path73, content) {
|
|
|
55741
55777
|
dimension: "data",
|
|
55742
55778
|
severity: worst.severity,
|
|
55743
55779
|
title: worst.severity === "advisory" ? "Secrets reachable by the agent \u2014 hardening" : "Exfiltratable secrets reachable by an injectable agent",
|
|
55744
|
-
file:
|
|
55780
|
+
file: path74,
|
|
55745
55781
|
signals: [
|
|
55746
55782
|
`agent can reach: ${worst.secrets.map((s) => s.name).join(", ")}`,
|
|
55747
55783
|
worst.injectable ? "the agent is externally triggerable (untrusted trigger, no gate)" : "gated / not externally triggerable \u2014 latent risk only",
|
|
@@ -55768,7 +55804,7 @@ function hookCommands(hooks) {
|
|
|
55768
55804
|
}
|
|
55769
55805
|
return out;
|
|
55770
55806
|
}
|
|
55771
|
-
function analyzeAgentConfig(
|
|
55807
|
+
function analyzeAgentConfig(path74, content) {
|
|
55772
55808
|
let cfg;
|
|
55773
55809
|
try {
|
|
55774
55810
|
cfg = JSON.parse(content);
|
|
@@ -55787,7 +55823,7 @@ function analyzeAgentConfig(path73, content) {
|
|
|
55787
55823
|
dimension: "toolRules",
|
|
55788
55824
|
severity: high ? "high" : "medium",
|
|
55789
55825
|
title: high ? "Agent hook runs UNPINNED/remote third-party code on every action" : "Agent hook runs third-party code in the agent hot path",
|
|
55790
|
-
file:
|
|
55826
|
+
file: path74,
|
|
55791
55827
|
signals: [
|
|
55792
55828
|
`hook command: \`${cmd.slice(0, 120)}\``,
|
|
55793
55829
|
remoteExec ? "fetch-and-run (curl|wget / pipe-to-shell) \u2014 unpinnable remote code execution on every contributor" : unpinned ? "unpinned \u2014 a compromised/yanked package = code execution on every contributor" : "pinned, but still a standing supply-chain dependency in the agent hot path"
|
|
@@ -55807,7 +55843,7 @@ function analyzeAgentConfig(path73, content) {
|
|
|
55807
55843
|
dimension: "toolRules",
|
|
55808
55844
|
severity: hasBackstop ? "medium" : "high",
|
|
55809
55845
|
title: hasBackstop ? "Committed agent config pre-authorizes broad tools" : "Committed agent config pre-authorizes broad tools with no deny backstop",
|
|
55810
|
-
file:
|
|
55846
|
+
file: path74,
|
|
55811
55847
|
signals: [
|
|
55812
55848
|
`broad allow(s): ${broad.slice(0, 5).join(", ")}`,
|
|
55813
55849
|
hasBackstop ? "a `deny` list backstops the broad allow" : "no `deny` entry covers Bash/Write/Edit \u2014 every contributor is pre-authorized for catastrophic tools"
|
|
@@ -55820,16 +55856,16 @@ function analyzeAgentConfig(path73, content) {
|
|
|
55820
55856
|
|
|
55821
55857
|
// src/ci-check/mcp.ts
|
|
55822
55858
|
init_dist();
|
|
55823
|
-
function analyzeMcp(
|
|
55859
|
+
function analyzeMcp(path74, content) {
|
|
55824
55860
|
let cfg;
|
|
55825
55861
|
try {
|
|
55826
55862
|
cfg = JSON.parse(content);
|
|
55827
55863
|
} catch {
|
|
55828
55864
|
return [];
|
|
55829
55865
|
}
|
|
55830
|
-
return analyzeMcpServers(cfg.mcpServers ?? {},
|
|
55866
|
+
return analyzeMcpServers(cfg.mcpServers ?? {}, path74);
|
|
55831
55867
|
}
|
|
55832
|
-
function analyzeMcpServers(servers,
|
|
55868
|
+
function analyzeMcpServers(servers, path74) {
|
|
55833
55869
|
const findings = [];
|
|
55834
55870
|
for (const [name, srv] of Object.entries(servers ?? {})) {
|
|
55835
55871
|
if (!srv || srv.disabled) continue;
|
|
@@ -55840,7 +55876,7 @@ function analyzeMcpServers(servers, path73) {
|
|
|
55840
55876
|
dimension: "mcp",
|
|
55841
55877
|
severity: "medium",
|
|
55842
55878
|
title: `MCP server "${name}" runs an unpinned executable`,
|
|
55843
|
-
file:
|
|
55879
|
+
file: path74,
|
|
55844
55880
|
signals: [`\`${argv.slice(0, 120)}\` \u2014 unversioned/@latest npx`],
|
|
55845
55881
|
fix: "Pin the MCP server package to an exact version so a PR (or a registry compromise) can\u2019t swap the toolchain."
|
|
55846
55882
|
});
|
|
@@ -55854,7 +55890,7 @@ function analyzeMcpServers(servers, path73) {
|
|
|
55854
55890
|
dimension: "mcp",
|
|
55855
55891
|
severity: "high",
|
|
55856
55892
|
title: `MCP server "${name}" has an inline credential`,
|
|
55857
|
-
file:
|
|
55893
|
+
file: path74,
|
|
55858
55894
|
signals: [
|
|
55859
55895
|
`env.${k} matches ${hit.patternName} \u2014 agent-reachable secret committed to the repo`
|
|
55860
55896
|
],
|
|
@@ -55868,7 +55904,7 @@ function analyzeMcpServers(servers, path73) {
|
|
|
55868
55904
|
|
|
55869
55905
|
// src/ci-check/codex.ts
|
|
55870
55906
|
var import_smol_toml5 = require("smol-toml");
|
|
55871
|
-
function analyzeCodexConfig(
|
|
55907
|
+
function analyzeCodexConfig(path74, content) {
|
|
55872
55908
|
let cfg;
|
|
55873
55909
|
try {
|
|
55874
55910
|
cfg = (0, import_smol_toml5.parse)(content);
|
|
@@ -55876,7 +55912,7 @@ function analyzeCodexConfig(path73, content) {
|
|
|
55876
55912
|
return [];
|
|
55877
55913
|
}
|
|
55878
55914
|
const findings = [];
|
|
55879
|
-
findings.push(...analyzeMcpServers(cfg.mcp_servers ?? {},
|
|
55915
|
+
findings.push(...analyzeMcpServers(cfg.mcp_servers ?? {}, path74));
|
|
55880
55916
|
const sandbox = typeof cfg.sandbox_mode === "string" ? cfg.sandbox_mode : "";
|
|
55881
55917
|
const approval = typeof cfg.approval_policy === "string" ? cfg.approval_policy : "";
|
|
55882
55918
|
const fullAccess = /danger-full-access/i.test(sandbox);
|
|
@@ -55891,7 +55927,7 @@ function analyzeCodexConfig(path73, content) {
|
|
|
55891
55927
|
dimension: "toolRules",
|
|
55892
55928
|
severity: fullAccess ? "high" : "medium",
|
|
55893
55929
|
title: fullAccess ? "Codex config grants a full-access sandbox" : "Codex config never requires approval",
|
|
55894
|
-
file:
|
|
55930
|
+
file: path74,
|
|
55895
55931
|
signals,
|
|
55896
55932
|
fix: 'Commit a least-privilege Codex config: prefer `sandbox_mode = "read-only"` (or `"workspace-write"`) and `approval_policy = "on-request"`/`"on-failure"`. A repo-committed config applies to every contributor who runs Codex here.'
|
|
55897
55933
|
});
|
|
@@ -55947,10 +55983,10 @@ function decodeSuspiciousBase64(text) {
|
|
|
55947
55983
|
}
|
|
55948
55984
|
return out;
|
|
55949
55985
|
}
|
|
55950
|
-
function mk(severity, title, signals, fix,
|
|
55951
|
-
return { check: "CI-6", dimension: "instructions", severity, title, file:
|
|
55986
|
+
function mk(severity, title, signals, fix, path74) {
|
|
55987
|
+
return { check: "CI-6", dimension: "instructions", severity, title, file: path74, signals, fix };
|
|
55952
55988
|
}
|
|
55953
|
-
function analyzeInstructionFile(
|
|
55989
|
+
function analyzeInstructionFile(path74, content) {
|
|
55954
55990
|
const findings = [];
|
|
55955
55991
|
const decoded = decodeSuspiciousBase64(content);
|
|
55956
55992
|
if (TAG_CHARS.test(content))
|
|
@@ -55962,7 +55998,7 @@ function analyzeInstructionFile(path73, content) {
|
|
|
55962
55998
|
"contains Unicode tag characters (U+E0000\u2013E007F) \u2014 an invisible instruction-smuggling channel with no legitimate use in text"
|
|
55963
55999
|
],
|
|
55964
56000
|
"Remove the tag characters. Instruction files must be plain, reviewable text.",
|
|
55965
|
-
|
|
56001
|
+
path74
|
|
55966
56002
|
)
|
|
55967
56003
|
);
|
|
55968
56004
|
if (BIDI_OVERRIDE.test(content))
|
|
@@ -55974,7 +56010,7 @@ function analyzeInstructionFile(path73, content) {
|
|
|
55974
56010
|
"contains a bidi override (U+202D/U+202E) \u2014 a Trojan-Source technique that visually reorders text so a human reads something different from what the agent parses"
|
|
55975
56011
|
],
|
|
55976
56012
|
"Remove the bidi override characters.",
|
|
55977
|
-
|
|
56013
|
+
path74
|
|
55978
56014
|
)
|
|
55979
56015
|
);
|
|
55980
56016
|
else if (BIDI_EMBED_ISOLATE.test(content))
|
|
@@ -55986,7 +56022,7 @@ function analyzeInstructionFile(path73, content) {
|
|
|
55986
56022
|
"contains bidi embed/isolate characters (U+202A\u2013202C / U+2066\u20132069) \u2014 legitimate in right-to-left text, but confirm they are not being used to hide or reorder instructions"
|
|
55987
56023
|
],
|
|
55988
56024
|
"Confirm the bidi marks are legitimate RTL formatting; remove otherwise.",
|
|
55989
|
-
|
|
56025
|
+
path74
|
|
55990
56026
|
)
|
|
55991
56027
|
);
|
|
55992
56028
|
const zw = suspiciousZeroWidth(content);
|
|
@@ -56000,7 +56036,7 @@ function analyzeInstructionFile(path73, content) {
|
|
|
56000
56036
|
revealed ? "a zero-width character conceals a prompt-override directive that only appears once the hidden characters are stripped" : "a zero-width character splits a visible Latin word \u2014 a concealment technique (hides text from human review while the agent reads it as contiguous)"
|
|
56001
56037
|
],
|
|
56002
56038
|
"Remove the zero-width characters. Instruction files must be plain, reviewable text.",
|
|
56003
|
-
|
|
56039
|
+
path74
|
|
56004
56040
|
)
|
|
56005
56041
|
);
|
|
56006
56042
|
}
|
|
@@ -56016,7 +56052,7 @@ function analyzeInstructionFile(path73, content) {
|
|
|
56016
56052
|
`contains a prompt-override / role-impersonation directive (\`${m[0].slice(0, 60).trim()}\`)${ovEnc ? " \u2014 concealed in a base64 blob" : ""}`
|
|
56017
56053
|
],
|
|
56018
56054
|
"Remove the override text. An instruction file should not tell the agent to ignore its own rules.",
|
|
56019
|
-
|
|
56055
|
+
path74
|
|
56020
56056
|
)
|
|
56021
56057
|
);
|
|
56022
56058
|
}
|
|
@@ -56028,7 +56064,7 @@ function analyzeInstructionFile(path73, content) {
|
|
|
56028
56064
|
"Instruction directs the agent to fetch and run remote code",
|
|
56029
56065
|
[`\`${fo[0].slice(0, 70).trim()}\` \u2014 fetch-and-obey, outside an install/setup section`],
|
|
56030
56066
|
"Do not instruct the agent to pipe remote content into a shell; pin and vendor scripts instead.",
|
|
56031
|
-
|
|
56067
|
+
path74
|
|
56032
56068
|
)
|
|
56033
56069
|
);
|
|
56034
56070
|
}
|
|
@@ -56040,7 +56076,7 @@ function analyzeInstructionFile(path73, content) {
|
|
|
56040
56076
|
"Instruction points the agent at credential material",
|
|
56041
56077
|
[`references \`${sp[0].slice(0, 50).trim()}\` \u2014 directs the agent toward secrets`],
|
|
56042
56078
|
"Do not reference credential files or paths in agent instructions.",
|
|
56043
|
-
|
|
56079
|
+
path74
|
|
56044
56080
|
)
|
|
56045
56081
|
);
|
|
56046
56082
|
}
|
|
@@ -56052,7 +56088,7 @@ function analyzeInstructionFile(path73, content) {
|
|
|
56052
56088
|
"Instruction directs the agent to send data to an external endpoint",
|
|
56053
56089
|
[`\`${ex[0].slice(0, 70).trim()}\` \u2014 possible exfiltration directive`],
|
|
56054
56090
|
"Remove external post/upload directives from agent instructions.",
|
|
56055
|
-
|
|
56091
|
+
path74
|
|
56056
56092
|
)
|
|
56057
56093
|
);
|
|
56058
56094
|
}
|