@node9/proxy 2.7.0 → 2.7.1

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 CHANGED
@@ -243,8 +243,8 @@ function sanitizeConfig(raw) {
243
243
  }
244
244
  }
245
245
  const lines = result.error.issues.map((issue) => {
246
- const path73 = issue.path.length > 0 ? issue.path.join(".") : "root";
247
- return ` \u2022 ${path73}: ${issue.message}`;
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, path73) {
627
+ function getNestedValue(obj, path74) {
628
628
  if (!obj || typeof obj !== "object") return null;
629
- const segments = path73.split(".");
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 path73 = typeof jp?.path === "string" ? jp.path.trim() : "";
5427
- if (!path73) continue;
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(path73, verdict, "org-managed jail")) {
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: path73, verdict });
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 < 0 || ageMs > TTL_MS) return null;
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 = import_fs23.default.readdirSync(dirPath).filter((f) => f.endsWith(".jsonl"));
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 += import_fs26.default.readdirSync(dp).filter((f) => f.endsWith(".jsonl")).length;
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.replace(/\.jsonl$/, "");
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 = import_fs26.default.readdirSync(projPath).filter((f) => f.endsWith(".jsonl") && !f.startsWith("agent-"));
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 = path37.join(homeDir2, ".node9", "machine-id");
18934
+ const file = path38.join(homeDir2, ".node9", "machine-id");
18900
18935
  try {
18901
- const existing = fs38.readFileSync(file, "utf-8").trim();
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
- fs38.mkdirSync(path37.dirname(file), { recursive: true });
18908
- fs38.writeFileSync(file, id + "\n", { mode: 384 });
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, fs38, os34, path37, UUID_RE;
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
- fs38 = __toESM(require("fs"));
18953
+ fs39 = __toESM(require("fs"));
18919
18954
  os34 = __toESM(require("os"));
18920
- path37 = __toESM(require("path"));
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 path73 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
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 (path73 && path73[0] !== "/") {
23166
- path73 = `/${path73}`;
23200
+ if (path74 && path74[0] !== "/") {
23201
+ path74 = `/${path74}`;
23167
23202
  }
23168
- return new URL(`${origin}${path73}`);
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: path73, origin }
24024
+ request: { method, path: path74, origin }
23990
24025
  } = evt;
23991
- debugLog("sending request to %s %s%s", method, origin, path73);
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: path73, origin },
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
- path73,
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: path73, origin }
24060
+ request: { method, path: path74, origin }
24026
24061
  } = evt;
24027
- debugLog("trailers received from %s %s%s", method, origin, path73);
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: path73, origin },
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
- path73,
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: path73,
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 path73 !== "string") {
24196
+ if (typeof path74 !== "string") {
24162
24197
  throw new InvalidArgumentError("path must be a string");
24163
- } else if (path73[0] !== "/" && !(path73.startsWith("http://") || path73.startsWith("https://")) && method !== "CONNECT") {
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(path73)) {
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(path73, query) : path73;
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: path73, host, upgrade, blocking, reset } = request2;
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} ${path73} HTTP/1.1\r
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: path73, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request2;
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] = path73;
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] = path73;
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: path73 = "/",
32447
+ path: path74 = "/",
32413
32448
  headers = {}
32414
32449
  } = opts;
32415
- opts.path = origin + path73;
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(path73) {
34479
- if (typeof path73 !== "string") {
34480
- return path73;
34513
+ function safeUrl(path74) {
34514
+ if (typeof path74 !== "string") {
34515
+ return path74;
34481
34516
  }
34482
- const pathSegments = path73.split("?", 3);
34517
+ const pathSegments = path74.split("?", 3);
34483
34518
  if (pathSegments.length !== 2) {
34484
- return path73;
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: path73, method, body, headers }) {
34491
- const pathMatch = matchValue(mockDispatch2.path, path73);
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: path73, ignoreTrailingSlash }) => {
34517
- return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path73)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path73), resolvedPath);
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(path73) {
34557
- while (path73.endsWith("/")) {
34558
- path73 = path73.slice(0, -1);
34591
+ function removeTrailingSlash(path74) {
34592
+ while (path74.endsWith("/")) {
34593
+ path74 = path74.slice(0, -1);
34559
34594
  }
34560
- if (path73.length === 0) {
34561
- path73 = "/";
34595
+ if (path74.length === 0) {
34596
+ path74 = "/";
34562
34597
  }
34563
- return path73;
34598
+ return path74;
34564
34599
  }
34565
34600
  function buildKey(opts) {
34566
- const { path: path73, method, body, headers, query } = opts;
34601
+ const { path: path74, method, body, headers, query } = opts;
34567
34602
  return {
34568
- path: path73,
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: path73, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
35293
+ ({ method, path: path74, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
35259
35294
  Method: method,
35260
35295
  Origin: origin,
35261
- Path: path73,
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 [path73, searchParams] = dispatchOpts.path.split("?");
35378
+ const [path74, searchParams] = dispatchOpts.path.split("?");
35344
35379
  const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters);
35345
- dispatchOpts.path = `${path73}?${normalizedSearchParams}`;
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 path73 = filePath || this.#snapshotPath;
35747
- if (!path73) {
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(path73), "utf8");
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 ${path73}`, { cause: error });
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 path73 = filePath || this.#snapshotPath;
35777
- if (!path73) {
35811
+ const path74 = filePath || this.#snapshotPath;
35812
+ if (!path74) {
35778
35813
  throw new InvalidArgumentError("Snapshot path is required");
35779
35814
  }
35780
- const resolvedPath = resolve2(path73);
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 path73 = search ? `${pathname}${search}` : pathname;
36406
- const redirectUrlString = `${origin}${path73}`;
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 = path73;
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 path73 = url.pathname + url.search;
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 ? `${path73}?` : path73,
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(path73) {
43556
- for (let i = 0; i < path73.length; ++i) {
43557
- const code = path73.charCodeAt(i);
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 path73 = opts.path;
46762
+ let path74 = opts.path;
46728
46763
  if (!opts.path.startsWith("/")) {
46729
- path73 = `/${path73}`;
46764
+ path74 = `/${path74}`;
46730
46765
  }
46731
- url = new URL(util.parseOrigin(url).origin + path73);
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 fs48 = __toESM(require("fs"));
48754
+ var fs49 = __toESM(require("fs"));
48720
48755
  var os44 = __toESM(require("os"));
48721
- var path46 = __toESM(require("path"));
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 = path46.join(os44.homedir(), ".node9", "credentials.json");
48774
+ const credPath = path47.join(os44.homedir(), ".node9", "credentials.json");
48740
48775
  let all = {};
48741
48776
  try {
48742
- all = JSON.parse(fs48.readFileSync(credPath, "utf-8"));
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
- fs48.unlinkSync(credPath);
48807
+ fs49.unlinkSync(credPath);
48773
48808
  } catch {
48774
48809
  }
48775
48810
  } else {
48776
- fs48.writeFileSync(credPath, JSON.stringify(all, null, 2), { mode: 384 });
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 = import_fs55.default.readdirSync(projPath).filter((f) => f.endsWith(".jsonl") && !f.startsWith("agent-"));
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(path73, content) {
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: path73,
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(path73, content) {
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: path73,
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(path73, content) {
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: path73,
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: path73,
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(path73, content) {
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 ?? {}, path73);
55866
+ return analyzeMcpServers(cfg.mcpServers ?? {}, path74);
55831
55867
  }
55832
- function analyzeMcpServers(servers, path73) {
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: path73,
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: path73,
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(path73, content) {
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 ?? {}, path73));
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: path73,
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, path73) {
55951
- return { check: "CI-6", dimension: "instructions", severity, title, file: path73, signals, fix };
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(path73, content) {
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
- path73
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
- path73
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
- path73
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
- path73
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
- path73
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
- path73
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
- path73
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
- path73
56091
+ path74
56056
56092
  )
56057
56093
  );
56058
56094
  }