@node9/proxy 1.67.5 → 2.0.0

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.mjs CHANGED
@@ -248,8 +248,8 @@ function sanitizeConfig(raw) {
248
248
  }
249
249
  }
250
250
  const lines = result.error.issues.map((issue) => {
251
- const path72 = issue.path.length > 0 ? issue.path.join(".") : "root";
252
- return ` \u2022 ${path72}: ${issue.message}`;
251
+ const path71 = issue.path.length > 0 ? issue.path.join(".") : "root";
252
+ return ` \u2022 ${path71}: ${issue.message}`;
253
253
  });
254
254
  return {
255
255
  sanitized,
@@ -634,9 +634,9 @@ function matchesPattern(text, patterns) {
634
634
  const withoutDotSlash = text.replace(/^\.\//, "");
635
635
  return isMatch(withoutDotSlash) || isMatch(`./${withoutDotSlash}`);
636
636
  }
637
- function getNestedValue(obj, path72) {
637
+ function getNestedValue(obj, path71) {
638
638
  if (!obj || typeof obj !== "object") return null;
639
- const segments = path72.split(".");
639
+ const segments = path71.split(".");
640
640
  for (const seg of segments) {
641
641
  if (FORBIDDEN_PATH_SEGMENTS.has(seg)) return null;
642
642
  }
@@ -5105,11 +5105,6 @@ function getConfig(cwd) {
5105
5105
  ignoredTools: [...DEFAULT_CONFIG.policy.ignoredTools],
5106
5106
  toolInspection: { ...DEFAULT_CONFIG.policy.toolInspection },
5107
5107
  smartRules: [...DEFAULT_CONFIG.policy.smartRules],
5108
- snapshot: {
5109
- tools: [...DEFAULT_CONFIG.policy.snapshot.tools],
5110
- onlyPaths: [...DEFAULT_CONFIG.policy.snapshot.onlyPaths],
5111
- ignorePaths: [...DEFAULT_CONFIG.policy.snapshot.ignorePaths]
5112
- },
5113
5108
  dlp: { ...DEFAULT_CONFIG.policy.dlp },
5114
5109
  egress: {
5115
5110
  ...DEFAULT_CONFIG.policy.egress,
@@ -5177,12 +5172,6 @@ function getConfig(cwd) {
5177
5172
  );
5178
5173
  mergedPolicy.smartRules = [...filteredBlocks, ...localRules, ...filteredNonBlocks];
5179
5174
  }
5180
- if (p.snapshot) {
5181
- const s2 = p.snapshot;
5182
- if (s2.tools) mergedPolicy.snapshot.tools.push(...s2.tools);
5183
- if (s2.onlyPaths) mergedPolicy.snapshot.onlyPaths.push(...s2.onlyPaths);
5184
- if (s2.ignorePaths) mergedPolicy.snapshot.ignorePaths.push(...s2.ignorePaths);
5185
- }
5186
5175
  if (p.dlp) {
5187
5176
  const d = p.dlp;
5188
5177
  if (d.enabled !== void 0) mergedPolicy.dlp.enabled = d.enabled;
@@ -5388,13 +5377,13 @@ function getConfig(cwd) {
5388
5377
  }
5389
5378
  if (Array.isArray(mc.jailPaths)) {
5390
5379
  for (const jp of mc.jailPaths) {
5391
- const path72 = typeof jp?.path === "string" ? jp.path.trim() : "";
5392
- if (!path72) continue;
5380
+ const path71 = typeof jp?.path === "string" ? jp.path.trim() : "";
5381
+ if (!path71) continue;
5393
5382
  const verdict = jp?.verdict === "review" ? "review" : "block";
5394
- for (const r of pathRules(path72, verdict, "org-managed jail")) {
5383
+ for (const r of pathRules(path71, verdict, "org-managed jail")) {
5395
5384
  mergedPolicy.smartRules.push({ ...r, name: `org:${r.name}` });
5396
5385
  }
5397
- mergedPolicy.managedJailPaths.push({ path: path72, verdict });
5386
+ mergedPolicy.managedJailPaths.push({ path: path71, verdict });
5398
5387
  }
5399
5388
  }
5400
5389
  if (Array.isArray(mc.trustedHosts)) {
@@ -5517,10 +5506,6 @@ function getConfig(cwd) {
5517
5506
  mergedPolicy.dangerousWords = [...new Set(mergedPolicy.dangerousWords)];
5518
5507
  mergedPolicy.ignoredTools = [...new Set(mergedPolicy.ignoredTools)];
5519
5508
  mergedPolicy.skillPinning.roots = [...new Set(mergedPolicy.skillPinning.roots)];
5520
- mergedPolicy.snapshot.tools = [...new Set(mergedPolicy.snapshot.tools)];
5521
- mergedPolicy.snapshot.onlyPaths = [...new Set(mergedPolicy.snapshot.onlyPaths)];
5522
- mergedPolicy.snapshot.ignorePaths = [...new Set(mergedPolicy.snapshot.ignorePaths)];
5523
- mergedSettings.enableUndo = false;
5524
5509
  const result = {
5525
5510
  settings: mergedSettings,
5526
5511
  policy: mergedPolicy,
@@ -5603,19 +5588,6 @@ var init_config = __esm({
5603
5588
  settings: {
5604
5589
  mode: "standard",
5605
5590
  autoStartDaemon: true,
5606
- // The undo feature was REMOVED. This default is one of two places that say
5607
- // so; the other is the pin further down, which overwrites whatever a config
5608
- // file, the dashboard or the cloud supplies. Setting `enableUndo` anywhere
5609
- // has no effect — do not restore the advice that used to live here, because
5610
- // a comment recommending a knob that is silently discarded is the same lie
5611
- // on disk the pin exists to prevent.
5612
- //
5613
- // Why it went: the store was a per-project bare git repo with no size
5614
- // ceiling, and eviction dropped the index row without deleting the objects.
5615
- // On one machine it reached 378G (352G of it orphaned tmp_pack_* from an
5616
- // interrupted `git gc`) and filled the disk. A security tool must not be
5617
- // what fills a customer's disk. Leftovers: `node9 undo --purge`.
5618
- enableUndo: false,
5619
5591
  enableHookLogDebug: true,
5620
5592
  approvalTimeoutMs: 12e4,
5621
5593
  // 120-second auto-deny timeout
@@ -5656,25 +5628,6 @@ var init_config = __esm({
5656
5628
  "terminal.execute": "command",
5657
5629
  "postgres:query": "sql"
5658
5630
  },
5659
- snapshot: {
5660
- tools: [
5661
- "str_replace_based_edit_tool",
5662
- "write_file",
5663
- "edit_file",
5664
- "create_file",
5665
- "edit",
5666
- "replace",
5667
- // Claude / canonicalised Hermes — shouldSnapshot lowercases the
5668
- // incoming name before set-membership, so we list the lowercase
5669
- // forms of `Bash`/`Write`/`Edit`/`MultiEdit`. Without these,
5670
- // post-canonicalisation Hermes `patch` / `write_file` (which now
5671
- // arrive as `Edit` / `Write`) silently skipped snapshotting.
5672
- "write",
5673
- "multiedit"
5674
- ],
5675
- onlyPaths: [],
5676
- ignorePaths: ["**/node_modules/**", "dist/**", "build/**", ".next/**", "**/*.log"]
5677
- },
5678
5631
  smartRules: [
5679
5632
  // ── rm safety (critical — always evaluated first) ──────────────────────
5680
5633
  {
@@ -6023,19 +5976,6 @@ var init_provenance = __esm({
6023
5976
  import fs7 from "fs";
6024
5977
  import path7 from "path";
6025
5978
  import os6 from "os";
6026
- import pm2 from "picomatch";
6027
- function shouldSnapshot(toolName, args, config) {
6028
- if (!config.settings.enableUndo) return false;
6029
- const snap = config.policy.snapshot;
6030
- if (!snap.tools.includes(toolName.toLowerCase())) return false;
6031
- const a = args && typeof args === "object" ? args : {};
6032
- const filePath = String(a.file_path ?? a.path ?? a.filename ?? "");
6033
- if (filePath) {
6034
- if (snap.ignorePaths.length && pm2(snap.ignorePaths)(filePath)) return false;
6035
- if (snap.onlyPaths.length && !pm2(snap.onlyPaths)(filePath)) return false;
6036
- }
6037
- return true;
6038
- }
6039
5979
  async function evaluatePolicy2(toolName, args, agent, cwd, opts) {
6040
5980
  const config = getConfig();
6041
5981
  const activeEnvironment = getActiveEnvironment(config) ?? void 0;
@@ -16908,16 +16848,6 @@ function bindActivitySocket() {
16908
16848
  sessionHistory.recordTestFail(data.ts);
16909
16849
  return;
16910
16850
  }
16911
- if (data.status === "snapshot") {
16912
- broadcast("snapshot", {
16913
- hash: data.hash,
16914
- tool: data.tool,
16915
- argsSummary: data.argsSummary,
16916
- fileCount: data.fileCount,
16917
- ts: data.ts
16918
- });
16919
- return;
16920
- }
16921
16851
  if (data.status === "execution-completed") {
16922
16852
  broadcast("execution-result", {
16923
16853
  id: data.id,
@@ -22818,7 +22748,7 @@ var require_util = __commonJS({
22818
22748
  var { kDestroyed, kBodyUsed, kListeners, kBody } = require_symbols();
22819
22749
  var { IncomingMessage } = __require("http");
22820
22750
  var stream = __require("stream");
22821
- var net4 = __require("net");
22751
+ var net3 = __require("net");
22822
22752
  var { stringify } = __require("querystring");
22823
22753
  var { EventEmitter: EE } = __require("events");
22824
22754
  var timers = require_timers();
@@ -22930,14 +22860,14 @@ var require_util = __commonJS({
22930
22860
  }
22931
22861
  const port = url.port != null ? url.port : url.protocol === "https:" ? 443 : 80;
22932
22862
  let origin = url.origin != null ? url.origin : `${url.protocol || ""}//${url.hostname || ""}:${port}`;
22933
- let path72 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
22863
+ let path71 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
22934
22864
  if (origin[origin.length - 1] === "/") {
22935
22865
  origin = origin.slice(0, origin.length - 1);
22936
22866
  }
22937
- if (path72 && path72[0] !== "/") {
22938
- path72 = `/${path72}`;
22867
+ if (path71 && path71[0] !== "/") {
22868
+ path71 = `/${path71}`;
22939
22869
  }
22940
- return new URL(`${origin}${path72}`);
22870
+ return new URL(`${origin}${path71}`);
22941
22871
  }
22942
22872
  if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) {
22943
22873
  throw new InvalidArgumentError("Invalid URL protocol: the URL must start with `http:` or `https:`.");
@@ -22967,7 +22897,7 @@ var require_util = __commonJS({
22967
22897
  }
22968
22898
  assert(typeof host === "string");
22969
22899
  const servername = getHostname(host);
22970
- if (net4.isIP(servername)) {
22900
+ if (net3.isIP(servername)) {
22971
22901
  return "";
22972
22902
  }
22973
22903
  return servername;
@@ -23758,9 +23688,9 @@ var require_diagnostics = __commonJS({
23758
23688
  "undici:client:sendHeaders",
23759
23689
  (evt) => {
23760
23690
  const {
23761
- request: { method, path: path72, origin }
23691
+ request: { method, path: path71, origin }
23762
23692
  } = evt;
23763
- debugLog("sending request to %s %s%s", method, origin, path72);
23693
+ debugLog("sending request to %s %s%s", method, origin, path71);
23764
23694
  }
23765
23695
  );
23766
23696
  }
@@ -23778,14 +23708,14 @@ var require_diagnostics = __commonJS({
23778
23708
  "undici:request:headers",
23779
23709
  (evt) => {
23780
23710
  const {
23781
- request: { method, path: path72, origin },
23711
+ request: { method, path: path71, origin },
23782
23712
  response: { statusCode }
23783
23713
  } = evt;
23784
23714
  debugLog(
23785
23715
  "received response to %s %s%s - HTTP %d",
23786
23716
  method,
23787
23717
  origin,
23788
- path72,
23718
+ path71,
23789
23719
  statusCode
23790
23720
  );
23791
23721
  }
@@ -23794,23 +23724,23 @@ var require_diagnostics = __commonJS({
23794
23724
  "undici:request:trailers",
23795
23725
  (evt) => {
23796
23726
  const {
23797
- request: { method, path: path72, origin }
23727
+ request: { method, path: path71, origin }
23798
23728
  } = evt;
23799
- debugLog("trailers received from %s %s%s", method, origin, path72);
23729
+ debugLog("trailers received from %s %s%s", method, origin, path71);
23800
23730
  }
23801
23731
  );
23802
23732
  diagnosticsChannel.subscribe(
23803
23733
  "undici:request:error",
23804
23734
  (evt) => {
23805
23735
  const {
23806
- request: { method, path: path72, origin },
23736
+ request: { method, path: path71, origin },
23807
23737
  error
23808
23738
  } = evt;
23809
23739
  debugLog(
23810
23740
  "request to %s %s%s errored - %s",
23811
23741
  method,
23812
23742
  origin,
23813
- path72,
23743
+ path71,
23814
23744
  error.message
23815
23745
  );
23816
23746
  }
@@ -23913,7 +23843,7 @@ var require_request = __commonJS({
23913
23843
  var kHandler = /* @__PURE__ */ Symbol("handler");
23914
23844
  var Request = class {
23915
23845
  constructor(origin, {
23916
- path: path72,
23846
+ path: path71,
23917
23847
  method,
23918
23848
  body,
23919
23849
  headers,
@@ -23930,11 +23860,11 @@ var require_request = __commonJS({
23930
23860
  maxRedirections,
23931
23861
  typeOfService
23932
23862
  }, handler) {
23933
- if (typeof path72 !== "string") {
23863
+ if (typeof path71 !== "string") {
23934
23864
  throw new InvalidArgumentError("path must be a string");
23935
- } else if (path72[0] !== "/" && !(path72.startsWith("http://") || path72.startsWith("https://")) && method !== "CONNECT") {
23865
+ } else if (path71[0] !== "/" && !(path71.startsWith("http://") || path71.startsWith("https://")) && method !== "CONNECT") {
23936
23866
  throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
23937
- } else if (invalidPathRegex.test(path72)) {
23867
+ } else if (invalidPathRegex.test(path71)) {
23938
23868
  throw new InvalidArgumentError("invalid request path");
23939
23869
  }
23940
23870
  if (typeof method !== "string") {
@@ -24009,7 +23939,7 @@ var require_request = __commonJS({
24009
23939
  this.completed = false;
24010
23940
  this.aborted = false;
24011
23941
  this.upgrade = upgrade || null;
24012
- this.path = query ? serializePathWithQuery(path72, query) : path72;
23942
+ this.path = query ? serializePathWithQuery(path71, query) : path71;
24013
23943
  this.origin = origin;
24014
23944
  this.protocol = getProtocolFromUrlString(origin);
24015
23945
  this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
@@ -24588,7 +24518,7 @@ var require_dispatcher_base = __commonJS({
24588
24518
  var require_connect = __commonJS({
24589
24519
  "node_modules/undici/lib/core/connect.js"(exports, module) {
24590
24520
  "use strict";
24591
- var net4 = __require("net");
24521
+ var net3 = __require("net");
24592
24522
  var assert = __require("assert");
24593
24523
  var util = require_util();
24594
24524
  var { InvalidArgumentError } = require_errors();
@@ -24657,7 +24587,7 @@ var require_connect = __commonJS({
24657
24587
  } else {
24658
24588
  assert(!httpSocket, "httpSocket can only be sent on TLS update");
24659
24589
  port = port || 80;
24660
- socket = net4.connect({
24590
+ socket = net3.connect({
24661
24591
  highWaterMark: 64 * 1024,
24662
24592
  // Same as nodejs fs streams.
24663
24593
  ...options,
@@ -29048,7 +28978,7 @@ var require_client_h1 = __commonJS({
29048
28978
  return method !== "GET" && method !== "HEAD" && method !== "OPTIONS" && method !== "TRACE" && method !== "CONNECT";
29049
28979
  }
29050
28980
  function writeH1(client, request2) {
29051
- const { method, path: path72, host, upgrade, blocking, reset } = request2;
28981
+ const { method, path: path71, host, upgrade, blocking, reset } = request2;
29052
28982
  let { body, headers, contentLength } = request2;
29053
28983
  const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
29054
28984
  if (util.isFormDataLike(body)) {
@@ -29117,7 +29047,7 @@ var require_client_h1 = __commonJS({
29117
29047
  if (socket.setTypeOfService) {
29118
29048
  socket.setTypeOfService(request2.typeOfService);
29119
29049
  }
29120
- let header = `${method} ${path72} HTTP/1.1\r
29050
+ let header = `${method} ${path71} HTTP/1.1\r
29121
29051
  `;
29122
29052
  if (typeof host === "string") {
29123
29053
  header += `host: ${host}\r
@@ -29770,7 +29700,7 @@ var require_client_h2 = __commonJS({
29770
29700
  function writeH2(client, request2) {
29771
29701
  const requestTimeout = request2.bodyTimeout ?? client[kBodyTimeout];
29772
29702
  const session = client[kHTTP2Session];
29773
- const { method, path: path72, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request2;
29703
+ const { method, path: path71, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request2;
29774
29704
  let { body } = request2;
29775
29705
  if (upgrade != null && upgrade !== "websocket") {
29776
29706
  util.errorRequest(client, request2, new InvalidArgumentError(`Custom upgrade "${upgrade}" not supported over HTTP/2`));
@@ -29838,7 +29768,7 @@ var require_client_h2 = __commonJS({
29838
29768
  }
29839
29769
  headers[HTTP2_HEADER_METHOD] = "CONNECT";
29840
29770
  headers[HTTP2_HEADER_PROTOCOL] = "websocket";
29841
- headers[HTTP2_HEADER_PATH] = path72;
29771
+ headers[HTTP2_HEADER_PATH] = path71;
29842
29772
  if (protocol === "ws:" || protocol === "wss:") {
29843
29773
  headers[HTTP2_HEADER_SCHEME] = protocol === "ws:" ? "http" : "https";
29844
29774
  } else {
@@ -29879,7 +29809,7 @@ var require_client_h2 = __commonJS({
29879
29809
  stream.setTimeout(requestTimeout);
29880
29810
  return true;
29881
29811
  }
29882
- headers[HTTP2_HEADER_PATH] = path72;
29812
+ headers[HTTP2_HEADER_PATH] = path71;
29883
29813
  headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https";
29884
29814
  const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
29885
29815
  if (body && typeof body.read === "function") {
@@ -30195,7 +30125,7 @@ var require_client = __commonJS({
30195
30125
  "node_modules/undici/lib/dispatcher/client.js"(exports, module) {
30196
30126
  "use strict";
30197
30127
  var assert = __require("assert");
30198
- var net4 = __require("net");
30128
+ var net3 = __require("net");
30199
30129
  var http7 = __require("http");
30200
30130
  var util = require_util();
30201
30131
  var { ClientStats } = require_stats();
@@ -30349,7 +30279,7 @@ var require_client = __commonJS({
30349
30279
  if (maxRequestsPerClient != null && (!Number.isInteger(maxRequestsPerClient) || maxRequestsPerClient < 0)) {
30350
30280
  throw new InvalidArgumentError("maxRequestsPerClient must be a positive number");
30351
30281
  }
30352
- if (localAddress != null && (typeof localAddress !== "string" || net4.isIP(localAddress) === 0)) {
30282
+ if (localAddress != null && (typeof localAddress !== "string" || net3.isIP(localAddress) === 0)) {
30353
30283
  throw new InvalidArgumentError("localAddress must be valid string IP address");
30354
30284
  }
30355
30285
  if (maxResponseSize != null && (!Number.isInteger(maxResponseSize) || maxResponseSize < -1)) {
@@ -30521,7 +30451,7 @@ var require_client = __commonJS({
30521
30451
  const idx = hostname.indexOf("]");
30522
30452
  assert(idx !== -1);
30523
30453
  const ip = hostname.substring(1, idx);
30524
- assert(net4.isIPv6(ip));
30454
+ assert(net3.isIPv6(ip));
30525
30455
  hostname = ip;
30526
30456
  }
30527
30457
  client[kConnecting] = true;
@@ -31464,10 +31394,10 @@ var require_socks5_utils = __commonJS({
31464
31394
  "node_modules/undici/lib/core/socks5-utils.js"(exports, module) {
31465
31395
  "use strict";
31466
31396
  var { Buffer: Buffer2 } = __require("buffer");
31467
- var net4 = __require("net");
31397
+ var net3 = __require("net");
31468
31398
  var { InvalidArgumentError } = require_errors();
31469
31399
  function parseAddress(address) {
31470
- if (net4.isIPv4(address)) {
31400
+ if (net3.isIPv4(address)) {
31471
31401
  const parts = address.split(".").map(Number);
31472
31402
  return {
31473
31403
  type: 1,
@@ -31475,7 +31405,7 @@ var require_socks5_utils = __commonJS({
31475
31405
  buffer: Buffer2.from(parts)
31476
31406
  };
31477
31407
  }
31478
- if (net4.isIPv6(address)) {
31408
+ if (net3.isIPv6(address)) {
31479
31409
  return {
31480
31410
  type: 4,
31481
31411
  // IPv6
@@ -31935,7 +31865,7 @@ var require_socks5_client = __commonJS({
31935
31865
  var require_socks5_proxy_agent = __commonJS({
31936
31866
  "node_modules/undici/lib/dispatcher/socks5-proxy-agent.js"(exports, module) {
31937
31867
  "use strict";
31938
- var net4 = __require("net");
31868
+ var net3 = __require("net");
31939
31869
  var { URL: URL5 } = __require("url");
31940
31870
  var tls;
31941
31871
  var DispatcherBase = require_dispatcher_base();
@@ -31997,7 +31927,7 @@ var require_socks5_proxy_agent = __commonJS({
31997
31927
  socket2.removeListener("connect", onConnect);
31998
31928
  reject(err2);
31999
31929
  };
32000
- const socket2 = net4.connect({
31930
+ const socket2 = net3.connect({
32001
31931
  host: proxyHost,
32002
31932
  port: proxyPort
32003
31933
  });
@@ -32181,10 +32111,10 @@ var require_proxy_agent = __commonJS({
32181
32111
  };
32182
32112
  const {
32183
32113
  origin,
32184
- path: path72 = "/",
32114
+ path: path71 = "/",
32185
32115
  headers = {}
32186
32116
  } = opts;
32187
- opts.path = origin + path72;
32117
+ opts.path = origin + path71;
32188
32118
  if (!("host" in headers) && !("Host" in headers)) {
32189
32119
  const { host } = new URL(origin);
32190
32120
  headers.host = host;
@@ -34247,20 +34177,20 @@ var require_mock_utils = __commonJS({
34247
34177
  }
34248
34178
  return normalizedQp;
34249
34179
  }
34250
- function safeUrl(path72) {
34251
- if (typeof path72 !== "string") {
34252
- return path72;
34180
+ function safeUrl(path71) {
34181
+ if (typeof path71 !== "string") {
34182
+ return path71;
34253
34183
  }
34254
- const pathSegments = path72.split("?", 3);
34184
+ const pathSegments = path71.split("?", 3);
34255
34185
  if (pathSegments.length !== 2) {
34256
- return path72;
34186
+ return path71;
34257
34187
  }
34258
34188
  const qp = new URLSearchParams(pathSegments.pop());
34259
34189
  qp.sort();
34260
34190
  return [...pathSegments, qp.toString()].join("?");
34261
34191
  }
34262
- function matchKey(mockDispatch2, { path: path72, method, body, headers }) {
34263
- const pathMatch = matchValue(mockDispatch2.path, path72);
34192
+ function matchKey(mockDispatch2, { path: path71, method, body, headers }) {
34193
+ const pathMatch = matchValue(mockDispatch2.path, path71);
34264
34194
  const methodMatch = matchValue(mockDispatch2.method, method);
34265
34195
  const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
34266
34196
  const headersMatch = matchHeaders(mockDispatch2, headers);
@@ -34285,8 +34215,8 @@ var require_mock_utils = __commonJS({
34285
34215
  const basePath = key.query ? serializePathWithQuery(key.path, key.query) : key.path;
34286
34216
  const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
34287
34217
  const resolvedPathWithoutTrailingSlash = removeTrailingSlash(resolvedPath);
34288
- let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path72, ignoreTrailingSlash }) => {
34289
- return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path72)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path72), resolvedPath);
34218
+ let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path71, ignoreTrailingSlash }) => {
34219
+ return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path71)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path71), resolvedPath);
34290
34220
  });
34291
34221
  if (matchedMockDispatches.length === 0) {
34292
34222
  throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
@@ -34325,19 +34255,19 @@ var require_mock_utils = __commonJS({
34325
34255
  mockDispatches.splice(index, 1);
34326
34256
  }
34327
34257
  }
34328
- function removeTrailingSlash(path72) {
34329
- while (path72.endsWith("/")) {
34330
- path72 = path72.slice(0, -1);
34258
+ function removeTrailingSlash(path71) {
34259
+ while (path71.endsWith("/")) {
34260
+ path71 = path71.slice(0, -1);
34331
34261
  }
34332
- if (path72.length === 0) {
34333
- path72 = "/";
34262
+ if (path71.length === 0) {
34263
+ path71 = "/";
34334
34264
  }
34335
- return path72;
34265
+ return path71;
34336
34266
  }
34337
34267
  function buildKey(opts) {
34338
- const { path: path72, method, body, headers, query } = opts;
34268
+ const { path: path71, method, body, headers, query } = opts;
34339
34269
  return {
34340
- path: path72,
34270
+ path: path71,
34341
34271
  method,
34342
34272
  body,
34343
34273
  headers,
@@ -35027,10 +34957,10 @@ var require_pending_interceptors_formatter = __commonJS({
35027
34957
  }
35028
34958
  format(pendingInterceptors) {
35029
34959
  const withPrettyHeaders = pendingInterceptors.map(
35030
- ({ method, path: path72, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
34960
+ ({ method, path: path71, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
35031
34961
  Method: method,
35032
34962
  Origin: origin,
35033
- Path: path72,
34963
+ Path: path71,
35034
34964
  "Status code": statusCode,
35035
34965
  Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
35036
34966
  Invocations: timesInvoked,
@@ -35112,9 +35042,9 @@ var require_mock_agent = __commonJS({
35112
35042
  const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters];
35113
35043
  const dispatchOpts = { ...opts };
35114
35044
  if (acceptNonStandardSearchParameters && dispatchOpts.path) {
35115
- const [path72, searchParams] = dispatchOpts.path.split("?");
35045
+ const [path71, searchParams] = dispatchOpts.path.split("?");
35116
35046
  const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters);
35117
- dispatchOpts.path = `${path72}?${normalizedSearchParams}`;
35047
+ dispatchOpts.path = `${path71}?${normalizedSearchParams}`;
35118
35048
  }
35119
35049
  return this[kAgent].dispatch(dispatchOpts, handler);
35120
35050
  }
@@ -35242,8 +35172,8 @@ var require_snapshot_utils = __commonJS({
35242
35172
  match: new Set(matchHeaders.map((header) => caseSensitive ? header : header.toLowerCase()))
35243
35173
  };
35244
35174
  }
35245
- var crypto10 = runtimeFeatures.has("crypto") ? __require("crypto") : null;
35246
- var hashId = crypto10?.hash ? (value) => crypto10.hash("sha256", value, "base64url") : (value) => Buffer.from(value).toString("base64url");
35175
+ var crypto9 = runtimeFeatures.has("crypto") ? __require("crypto") : null;
35176
+ var hashId = crypto9?.hash ? (value) => crypto9.hash("sha256", value, "base64url") : (value) => Buffer.from(value).toString("base64url");
35247
35177
  function isUndiciHeaders(headers) {
35248
35178
  return Array.isArray(headers) && (headers.length & 1) === 0;
35249
35179
  }
@@ -35515,12 +35445,12 @@ var require_snapshot_recorder = __commonJS({
35515
35445
  * @return {Promise<void>} - Resolves when snapshots are loaded
35516
35446
  */
35517
35447
  async loadSnapshots(filePath) {
35518
- const path72 = filePath || this.#snapshotPath;
35519
- if (!path72) {
35448
+ const path71 = filePath || this.#snapshotPath;
35449
+ if (!path71) {
35520
35450
  throw new InvalidArgumentError("Snapshot path is required");
35521
35451
  }
35522
35452
  try {
35523
- const data = await readFile(resolve2(path72), "utf8");
35453
+ const data = await readFile(resolve2(path71), "utf8");
35524
35454
  const parsed = JSON.parse(data);
35525
35455
  if (Array.isArray(parsed)) {
35526
35456
  this.#snapshots.clear();
@@ -35534,7 +35464,7 @@ var require_snapshot_recorder = __commonJS({
35534
35464
  if (error.code === "ENOENT") {
35535
35465
  this.#snapshots.clear();
35536
35466
  } else {
35537
- throw new UndiciError(`Failed to load snapshots from ${path72}`, { cause: error });
35467
+ throw new UndiciError(`Failed to load snapshots from ${path71}`, { cause: error });
35538
35468
  }
35539
35469
  }
35540
35470
  }
@@ -35545,11 +35475,11 @@ var require_snapshot_recorder = __commonJS({
35545
35475
  * @returns {Promise<void>} - Resolves when snapshots are saved
35546
35476
  */
35547
35477
  async saveSnapshots(filePath) {
35548
- const path72 = filePath || this.#snapshotPath;
35549
- if (!path72) {
35478
+ const path71 = filePath || this.#snapshotPath;
35479
+ if (!path71) {
35550
35480
  throw new InvalidArgumentError("Snapshot path is required");
35551
35481
  }
35552
- const resolvedPath = resolve2(path72);
35482
+ const resolvedPath = resolve2(path71);
35553
35483
  await mkdir(dirname2(resolvedPath), { recursive: true });
35554
35484
  const data = Array.from(this.#snapshots.entries()).map(([hash, snapshot]) => ({
35555
35485
  hash,
@@ -36174,15 +36104,15 @@ var require_redirect_handler = __commonJS({
36174
36104
  return;
36175
36105
  }
36176
36106
  const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
36177
- const path72 = search ? `${pathname}${search}` : pathname;
36178
- const redirectUrlString = `${origin}${path72}`;
36107
+ const path71 = search ? `${pathname}${search}` : pathname;
36108
+ const redirectUrlString = `${origin}${path71}`;
36179
36109
  for (const historyUrl of this.history) {
36180
36110
  if (historyUrl.toString() === redirectUrlString) {
36181
36111
  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.`);
36182
36112
  }
36183
36113
  }
36184
36114
  this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
36185
- this.opts.path = path72;
36115
+ this.opts.path = path71;
36186
36116
  this.opts.origin = origin;
36187
36117
  this.opts.query = null;
36188
36118
  }
@@ -41301,10 +41231,10 @@ var require_subresource_integrity = __commonJS({
41301
41231
  var assert = __require("assert");
41302
41232
  var { runtimeFeatures } = require_runtime_features();
41303
41233
  var validSRIHashAlgorithmTokenSet = /* @__PURE__ */ new Map([["sha256", 0], ["sha384", 1], ["sha512", 2]]);
41304
- var crypto10;
41234
+ var crypto9;
41305
41235
  if (runtimeFeatures.has("crypto")) {
41306
- crypto10 = __require("crypto");
41307
- const cryptoHashes = crypto10.getHashes();
41236
+ crypto9 = __require("crypto");
41237
+ const cryptoHashes = crypto9.getHashes();
41308
41238
  if (cryptoHashes.length === 0) {
41309
41239
  validSRIHashAlgorithmTokenSet.clear();
41310
41240
  }
@@ -41394,7 +41324,7 @@ var require_subresource_integrity = __commonJS({
41394
41324
  return result;
41395
41325
  }
41396
41326
  var applyAlgorithmToBytes = (algorithm, bytes) => {
41397
- return crypto10.hash(algorithm, bytes, "base64");
41327
+ return crypto9.hash(algorithm, bytes, "base64");
41398
41328
  };
41399
41329
  function caseSensitiveMatch(actualValue, expectedValue) {
41400
41330
  let actualValueLength = actualValue.length;
@@ -42389,11 +42319,11 @@ var require_fetch = __commonJS({
42389
42319
  function dispatch({ body }) {
42390
42320
  const url = requestCurrentURL(request2);
42391
42321
  const agent = fetchParams.controller.dispatcher;
42392
- const path72 = url.pathname + url.search;
42322
+ const path71 = url.pathname + url.search;
42393
42323
  const hasTrailingQuestionMark = url.search.length === 0 && url.href[url.href.length - url.hash.length - 1] === "?";
42394
42324
  return new Promise((resolve2, reject) => agent.dispatch(
42395
42325
  {
42396
- path: hasTrailingQuestionMark ? `${path72}?` : path72,
42326
+ path: hasTrailingQuestionMark ? `${path71}?` : path71,
42397
42327
  origin: url.origin,
42398
42328
  method: request2.method,
42399
42329
  body: agent.isMockActive ? request2.body && (request2.body.source || request2.body.stream) : body,
@@ -43324,9 +43254,9 @@ var require_util4 = __commonJS({
43324
43254
  }
43325
43255
  }
43326
43256
  }
43327
- function validateCookiePath(path72) {
43328
- for (let i = 0; i < path72.length; ++i) {
43329
- const code = path72.charCodeAt(i);
43257
+ function validateCookiePath(path71) {
43258
+ for (let i = 0; i < path71.length; ++i) {
43259
+ const code = path71.charCodeAt(i);
43330
43260
  if (code < 32 || // exclude CTLs (0-31)
43331
43261
  code === 127 || // DEL
43332
43262
  code === 59) {
@@ -44328,7 +44258,7 @@ var require_connection = __commonJS({
44328
44258
  var { WebsocketFrameSend } = require_frame();
44329
44259
  var assert = __require("assert");
44330
44260
  var { runtimeFeatures } = require_runtime_features();
44331
- var crypto10 = runtimeFeatures.has("crypto") ? __require("crypto") : null;
44261
+ var crypto9 = runtimeFeatures.has("crypto") ? __require("crypto") : null;
44332
44262
  var warningEmitted = false;
44333
44263
  function establishWebSocketConnection(url, protocols, client, handler, options) {
44334
44264
  const requestURL = url;
@@ -44348,7 +44278,7 @@ var require_connection = __commonJS({
44348
44278
  const headersList = getHeadersList(new Headers(options.headers));
44349
44279
  request2.headersList = headersList;
44350
44280
  }
44351
- const keyValue = crypto10.randomBytes(16).toString("base64");
44281
+ const keyValue = crypto9.randomBytes(16).toString("base64");
44352
44282
  request2.headersList.append("sec-websocket-key", keyValue, true);
44353
44283
  request2.headersList.append("sec-websocket-version", "13", true);
44354
44284
  for (const protocol of protocols) {
@@ -44388,7 +44318,7 @@ var require_connection = __commonJS({
44388
44318
  return;
44389
44319
  }
44390
44320
  const secWSAccept = response.headersList.get("Sec-WebSocket-Accept");
44391
- const digest = crypto10.hash("sha1", keyValue + uid, "base64");
44321
+ const digest = crypto9.hash("sha1", keyValue + uid, "base64");
44392
44322
  if (secWSAccept !== digest) {
44393
44323
  failWebsocketConnection(handler, 1002, "Incorrect hash received in Sec-WebSocket-Accept header.");
44394
44324
  return;
@@ -46496,11 +46426,11 @@ var require_undici = __commonJS({
46496
46426
  if (typeof opts.path !== "string") {
46497
46427
  throw new InvalidArgumentError("invalid opts.path");
46498
46428
  }
46499
- let path72 = opts.path;
46429
+ let path71 = opts.path;
46500
46430
  if (!opts.path.startsWith("/")) {
46501
- path72 = `/${path72}`;
46431
+ path71 = `/${path71}`;
46502
46432
  }
46503
- url = new URL(util.parseOrigin(url).origin + path72);
46433
+ url = new URL(util.parseOrigin(url).origin + path71);
46504
46434
  } else {
46505
46435
  if (!opts) {
46506
46436
  opts = typeof url === "object" ? url : {};
@@ -46620,11 +46550,11 @@ __export(tail_exports, {
46620
46550
  });
46621
46551
  import http5 from "http";
46622
46552
  import chalk39 from "chalk";
46623
- import fs74 from "fs";
46624
- import os62 from "os";
46625
- import path69 from "path";
46553
+ import fs73 from "fs";
46554
+ import os61 from "os";
46555
+ import path68 from "path";
46626
46556
  import readline5 from "readline";
46627
- import { spawn as spawn8 } from "child_process";
46557
+ import { spawn as spawn7 } from "child_process";
46628
46558
  function eventsUrl(port, canApprove) {
46629
46559
  return `http://127.0.0.1:${port}/events${canApprove ? "?capabilities=input" : ""}`;
46630
46560
  }
@@ -46649,20 +46579,20 @@ function getModelContextLimit(model) {
46649
46579
  return 2e5;
46650
46580
  }
46651
46581
  function readSessionUsage() {
46652
- const projectsDir = path69.join(os62.homedir(), ".claude", "projects");
46653
- if (!fs74.existsSync(projectsDir)) return null;
46582
+ const projectsDir = path68.join(os61.homedir(), ".claude", "projects");
46583
+ if (!fs73.existsSync(projectsDir)) return null;
46654
46584
  let latestFile = null;
46655
46585
  let latestMtime = 0;
46656
46586
  try {
46657
- for (const dir of fs74.readdirSync(projectsDir)) {
46658
- const dirPath = path69.join(projectsDir, dir);
46587
+ for (const dir of fs73.readdirSync(projectsDir)) {
46588
+ const dirPath = path68.join(projectsDir, dir);
46659
46589
  try {
46660
- if (!fs74.statSync(dirPath).isDirectory()) continue;
46661
- for (const file of fs74.readdirSync(dirPath)) {
46590
+ if (!fs73.statSync(dirPath).isDirectory()) continue;
46591
+ for (const file of fs73.readdirSync(dirPath)) {
46662
46592
  if (!file.endsWith(".jsonl") || file.startsWith("agent-")) continue;
46663
- const filePath = path69.join(dirPath, file);
46593
+ const filePath = path68.join(dirPath, file);
46664
46594
  try {
46665
- const mtime = fs74.statSync(filePath).mtimeMs;
46595
+ const mtime = fs73.statSync(filePath).mtimeMs;
46666
46596
  if (mtime > latestMtime) {
46667
46597
  latestMtime = mtime;
46668
46598
  latestFile = filePath;
@@ -46677,7 +46607,7 @@ function readSessionUsage() {
46677
46607
  }
46678
46608
  if (!latestFile) return null;
46679
46609
  try {
46680
- const lines = fs74.readFileSync(latestFile, "utf-8").split("\n");
46610
+ const lines = fs73.readFileSync(latestFile, "utf-8").split("\n");
46681
46611
  let lastModel = "";
46682
46612
  let lastInput = 0;
46683
46613
  let lastOutput = 0;
@@ -46738,7 +46668,7 @@ function formatBase(activity) {
46738
46668
  const time = new Date(activity.ts).toLocaleTimeString([], { hour12: false });
46739
46669
  const icon = getIcon(activity.tool);
46740
46670
  const toolName = activity.tool.slice(0, 16).padEnd(16);
46741
- const argsStr = JSON.stringify(activity.args ?? {}).replace(/\s+/g, " ").replaceAll(os62.homedir(), "~");
46671
+ const argsStr = JSON.stringify(activity.args ?? {}).replace(/\s+/g, " ").replaceAll(os61.homedir(), "~");
46742
46672
  const argsPreview = argsStr.length > 70 ? argsStr.slice(0, 70) + "\u2026" : argsStr;
46743
46673
  return `${chalk39.gray(time)} ${icon} ${agentLabel(activity.agent, activity.mcpServer, activity.sessionId)}${chalk39.white.bold(toolName)} ${chalk39.dim(argsPreview)}`;
46744
46674
  }
@@ -46777,9 +46707,9 @@ function renderPending(activity) {
46777
46707
  }
46778
46708
  async function ensureDaemon() {
46779
46709
  let pidPort = null;
46780
- if (fs74.existsSync(PID_FILE)) {
46710
+ if (fs73.existsSync(PID_FILE)) {
46781
46711
  try {
46782
- const { port } = JSON.parse(fs74.readFileSync(PID_FILE, "utf-8"));
46712
+ const { port } = JSON.parse(fs73.readFileSync(PID_FILE, "utf-8"));
46783
46713
  pidPort = port;
46784
46714
  } catch {
46785
46715
  console.error(chalk39.dim("\u26A0\uFE0F Could not read PID file; falling back to default port."));
@@ -46796,7 +46726,7 @@ async function ensureDaemon() {
46796
46726
  console.log(chalk39.dim("\u{1F6E1}\uFE0F Starting Node9 daemon..."));
46797
46727
  const startupFd = openStartupLogFd();
46798
46728
  recordStartupState("starting");
46799
- const child = spawn8(process.execPath, [process.argv[1], "daemon"], {
46729
+ const child = spawn7(process.execPath, [process.argv[1], "daemon"], {
46800
46730
  detached: true,
46801
46731
  stdio: ["ignore", "ignore", startupFd ?? "ignore"],
46802
46732
  env: { ...process.env, NODE9_AUTO_STARTED: "1" }
@@ -46805,7 +46735,7 @@ async function ensureDaemon() {
46805
46735
  child.unref();
46806
46736
  if (startupFd !== void 0) {
46807
46737
  try {
46808
- fs74.closeSync(startupFd);
46738
+ fs73.closeSync(startupFd);
46809
46739
  } catch {
46810
46740
  }
46811
46741
  }
@@ -46944,9 +46874,9 @@ function buildRecoveryCardLines(req) {
46944
46874
  ];
46945
46875
  }
46946
46876
  function readApproversFromDisk() {
46947
- const configPath = path69.join(os62.homedir(), ".node9", "config.json");
46877
+ const configPath = path68.join(os61.homedir(), ".node9", "config.json");
46948
46878
  try {
46949
- const raw = JSON.parse(fs74.readFileSync(configPath, "utf-8"));
46879
+ const raw = JSON.parse(fs73.readFileSync(configPath, "utf-8"));
46950
46880
  const settings = raw.settings ?? {};
46951
46881
  return settings.approvers ?? {};
46952
46882
  } catch {
@@ -46962,15 +46892,15 @@ function approverStatusLine() {
46962
46892
  return `${fmt("native", "native")} ${fmt("cloud", "cloud")} ${fmt("terminal", "terminal")}`;
46963
46893
  }
46964
46894
  function toggleApprover(channel) {
46965
- const configPath = path69.join(os62.homedir(), ".node9", "config.json");
46895
+ const configPath = path68.join(os61.homedir(), ".node9", "config.json");
46966
46896
  try {
46967
- const raw = JSON.parse(fs74.readFileSync(configPath, "utf-8"));
46897
+ const raw = JSON.parse(fs73.readFileSync(configPath, "utf-8"));
46968
46898
  const settings = raw.settings ?? {};
46969
46899
  const approvers = settings.approvers ?? {};
46970
46900
  approvers[channel] = approvers[channel] === false;
46971
46901
  settings.approvers = approvers;
46972
46902
  raw.settings = settings;
46973
- fs74.writeFileSync(configPath, JSON.stringify(raw, null, 2) + "\n");
46903
+ fs73.writeFileSync(configPath, JSON.stringify(raw, null, 2) + "\n");
46974
46904
  } catch (err2) {
46975
46905
  process.stderr.write(`[node9] toggleApprover failed: ${String(err2)}
46976
46906
  `);
@@ -47142,8 +47072,8 @@ async function startTail(options = {}) {
47142
47072
  }
47143
47073
  postDecisionHttp(req2.id, httpDecision, authToken, port, httpOpts).catch((err2) => {
47144
47074
  try {
47145
- fs74.appendFileSync(
47146
- path69.join(os62.homedir(), ".node9", "hook-debug.log"),
47075
+ fs73.appendFileSync(
47076
+ path68.join(os61.homedir(), ".node9", "hook-debug.log"),
47147
47077
  `[tail] POST /decision failed: ${String(err2)}
47148
47078
  `
47149
47079
  );
@@ -47207,9 +47137,9 @@ async function startTail(options = {}) {
47207
47137
  };
47208
47138
  process.stdin.on("keypress", onKeypress);
47209
47139
  }
47210
- const auditLog = path69.join(os62.homedir(), ".node9", "audit.log");
47140
+ const auditLog = path68.join(os61.homedir(), ".node9", "audit.log");
47211
47141
  try {
47212
- const unackedDlp = fs74.readFileSync(auditLog, "utf-8").split("\n").filter((l) => l.includes('"response-dlp"')).length;
47142
+ const unackedDlp = fs73.readFileSync(auditLog, "utf-8").split("\n").filter((l) => l.includes('"response-dlp"')).length;
47213
47143
  if (unackedDlp > 0) {
47214
47144
  console.log("");
47215
47145
  console.log(
@@ -47249,7 +47179,7 @@ async function startTail(options = {}) {
47249
47179
  if (stallWarned) return;
47250
47180
  if (Date.now() - lastActivityFromDaemon < STALL_THRESHOLD_MS) return;
47251
47181
  try {
47252
- const auditMtime = fs74.statSync(auditLog).mtimeMs;
47182
+ const auditMtime = fs73.statSync(auditLog).mtimeMs;
47253
47183
  if (Date.now() - auditMtime >= STALL_THRESHOLD_MS) return;
47254
47184
  console.log("");
47255
47185
  console.log(
@@ -47393,19 +47323,6 @@ async function startTail(options = {}) {
47393
47323
  activityPending.set(data.id, data);
47394
47324
  renderPending(data);
47395
47325
  }
47396
- if (event === "snapshot") {
47397
- const time = new Date(data.ts).toLocaleTimeString([], { hour12: false });
47398
- const hash = data.hash ?? "";
47399
- const rawSummary = data.argsSummary ?? data.tool;
47400
- const summary = shortenPathSummary(rawSummary);
47401
- const fileCount = data.fileCount ?? 0;
47402
- const files = fileCount > 0 ? chalk39.dim(` \xB7 ${fileCount} file${fileCount === 1 ? "" : "s"}`) : "";
47403
- process.stdout.write(
47404
- `${chalk39.dim(time)} ${chalk39.cyan("\u{1F4F8} snapshot")} ${chalk39.dim(hash)} ${summary}${files}
47405
- `
47406
- );
47407
- return;
47408
- }
47409
47326
  if (event === "activity-result") {
47410
47327
  const original = activityPending.get(data.id);
47411
47328
  if (original) {
@@ -47441,7 +47358,7 @@ var init_tail = __esm({
47441
47358
  init_startup_log();
47442
47359
  init_daemon2();
47443
47360
  init_daemon();
47444
- PID_FILE = path69.join(os62.homedir(), ".node9", "daemon.pid");
47361
+ PID_FILE = path68.join(os61.homedir(), ".node9", "daemon.pid");
47445
47362
  ICONS = {
47446
47363
  bash: "\u{1F4BB}",
47447
47364
  shell: "\u{1F4BB}",
@@ -47489,9 +47406,9 @@ __export(hud_exports, {
47489
47406
  main: () => main,
47490
47407
  renderEnvironmentLine: () => renderEnvironmentLine
47491
47408
  });
47492
- import fs75 from "fs";
47493
- import path70 from "path";
47494
- import os63 from "os";
47409
+ import fs74 from "fs";
47410
+ import path69 from "path";
47411
+ import os62 from "os";
47495
47412
  import http6 from "http";
47496
47413
  async function readStdin() {
47497
47414
  const chunks = [];
@@ -47567,9 +47484,9 @@ function formatTimeLeft(resetsAt) {
47567
47484
  return ` (${m}m left)`;
47568
47485
  }
47569
47486
  function safeReadJson(filePath) {
47570
- if (!fs75.existsSync(filePath)) return null;
47487
+ if (!fs74.existsSync(filePath)) return null;
47571
47488
  try {
47572
- return JSON.parse(fs75.readFileSync(filePath, "utf-8"));
47489
+ return JSON.parse(fs74.readFileSync(filePath, "utf-8"));
47573
47490
  } catch {
47574
47491
  return null;
47575
47492
  }
@@ -47590,12 +47507,12 @@ function countHooksInFile(filePath) {
47590
47507
  return Object.keys(cfg.hooks).length;
47591
47508
  }
47592
47509
  function countRulesInDir(rulesDir) {
47593
- if (!fs75.existsSync(rulesDir)) return 0;
47510
+ if (!fs74.existsSync(rulesDir)) return 0;
47594
47511
  let count = 0;
47595
47512
  try {
47596
- for (const entry of fs75.readdirSync(rulesDir, { withFileTypes: true })) {
47513
+ for (const entry of fs74.readdirSync(rulesDir, { withFileTypes: true })) {
47597
47514
  if (entry.isDirectory()) {
47598
- count += countRulesInDir(path70.join(rulesDir, entry.name));
47515
+ count += countRulesInDir(path69.join(rulesDir, entry.name));
47599
47516
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
47600
47517
  count++;
47601
47518
  }
@@ -47606,46 +47523,46 @@ function countRulesInDir(rulesDir) {
47606
47523
  }
47607
47524
  function isSamePath(a, b) {
47608
47525
  try {
47609
- return path70.resolve(a) === path70.resolve(b);
47526
+ return path69.resolve(a) === path69.resolve(b);
47610
47527
  } catch {
47611
47528
  return false;
47612
47529
  }
47613
47530
  }
47614
47531
  function countConfigs(cwd) {
47615
- const homeDir2 = os63.homedir();
47616
- const claudeDir = path70.join(homeDir2, ".claude");
47532
+ const homeDir2 = os62.homedir();
47533
+ const claudeDir = path69.join(homeDir2, ".claude");
47617
47534
  let claudeMdCount = 0;
47618
47535
  let rulesCount = 0;
47619
47536
  let hooksCount = 0;
47620
47537
  const userMcpServers = /* @__PURE__ */ new Set();
47621
47538
  const projectMcpServers = /* @__PURE__ */ new Set();
47622
- if (fs75.existsSync(path70.join(claudeDir, "CLAUDE.md"))) claudeMdCount++;
47623
- rulesCount += countRulesInDir(path70.join(claudeDir, "rules"));
47624
- const userSettings = path70.join(claudeDir, "settings.json");
47539
+ if (fs74.existsSync(path69.join(claudeDir, "CLAUDE.md"))) claudeMdCount++;
47540
+ rulesCount += countRulesInDir(path69.join(claudeDir, "rules"));
47541
+ const userSettings = path69.join(claudeDir, "settings.json");
47625
47542
  for (const name of getMcpServerNames(userSettings)) userMcpServers.add(name);
47626
47543
  hooksCount += countHooksInFile(userSettings);
47627
- const userClaudeJson = path70.join(homeDir2, ".claude.json");
47544
+ const userClaudeJson = path69.join(homeDir2, ".claude.json");
47628
47545
  for (const name of getMcpServerNames(userClaudeJson)) userMcpServers.add(name);
47629
47546
  for (const name of getDisabledMcpServers(userClaudeJson, "disabledMcpServers")) {
47630
47547
  userMcpServers.delete(name);
47631
47548
  }
47632
47549
  if (cwd) {
47633
- if (fs75.existsSync(path70.join(cwd, "CLAUDE.md"))) claudeMdCount++;
47634
- if (fs75.existsSync(path70.join(cwd, "CLAUDE.local.md"))) claudeMdCount++;
47635
- const projectClaudeDir = path70.join(cwd, ".claude");
47550
+ if (fs74.existsSync(path69.join(cwd, "CLAUDE.md"))) claudeMdCount++;
47551
+ if (fs74.existsSync(path69.join(cwd, "CLAUDE.local.md"))) claudeMdCount++;
47552
+ const projectClaudeDir = path69.join(cwd, ".claude");
47636
47553
  const overlapsUserScope = isSamePath(projectClaudeDir, claudeDir);
47637
47554
  if (!overlapsUserScope) {
47638
- if (fs75.existsSync(path70.join(projectClaudeDir, "CLAUDE.md"))) claudeMdCount++;
47639
- rulesCount += countRulesInDir(path70.join(projectClaudeDir, "rules"));
47640
- const projSettings = path70.join(projectClaudeDir, "settings.json");
47555
+ if (fs74.existsSync(path69.join(projectClaudeDir, "CLAUDE.md"))) claudeMdCount++;
47556
+ rulesCount += countRulesInDir(path69.join(projectClaudeDir, "rules"));
47557
+ const projSettings = path69.join(projectClaudeDir, "settings.json");
47641
47558
  for (const name of getMcpServerNames(projSettings)) projectMcpServers.add(name);
47642
47559
  hooksCount += countHooksInFile(projSettings);
47643
47560
  }
47644
- if (fs75.existsSync(path70.join(projectClaudeDir, "CLAUDE.local.md"))) claudeMdCount++;
47645
- const localSettings = path70.join(projectClaudeDir, "settings.local.json");
47561
+ if (fs74.existsSync(path69.join(projectClaudeDir, "CLAUDE.local.md"))) claudeMdCount++;
47562
+ const localSettings = path69.join(projectClaudeDir, "settings.local.json");
47646
47563
  for (const name of getMcpServerNames(localSettings)) projectMcpServers.add(name);
47647
47564
  hooksCount += countHooksInFile(localSettings);
47648
- const mcpJsonServers = getMcpServerNames(path70.join(cwd, ".mcp.json"));
47565
+ const mcpJsonServers = getMcpServerNames(path69.join(cwd, ".mcp.json"));
47649
47566
  const disabledMcpJson = getDisabledMcpServers(localSettings, "disabledMcpjsonServers");
47650
47567
  for (const name of disabledMcpJson) mcpJsonServers.delete(name);
47651
47568
  for (const name of mcpJsonServers) projectMcpServers.add(name);
@@ -47678,12 +47595,12 @@ function readActiveShieldsHud() {
47678
47595
  return shieldsCache.value;
47679
47596
  }
47680
47597
  try {
47681
- const shieldsPath = path70.join(os63.homedir(), ".node9", "shields.json");
47682
- if (!fs75.existsSync(shieldsPath)) {
47598
+ const shieldsPath = path69.join(os62.homedir(), ".node9", "shields.json");
47599
+ if (!fs74.existsSync(shieldsPath)) {
47683
47600
  shieldsCache = { value: [], ts: now };
47684
47601
  return [];
47685
47602
  }
47686
- const parsed = JSON.parse(fs75.readFileSync(shieldsPath, "utf-8"));
47603
+ const parsed = JSON.parse(fs74.readFileSync(shieldsPath, "utf-8"));
47687
47604
  if (!Array.isArray(parsed.active)) {
47688
47605
  shieldsCache = { value: [], ts: now };
47689
47606
  return [];
@@ -47785,17 +47702,17 @@ function renderContextLine(stdin) {
47785
47702
  async function main() {
47786
47703
  try {
47787
47704
  const [stdin, daemonStatus2] = await Promise.all([readStdin(), queryDaemon()]);
47788
- if (fs75.existsSync(path70.join(os63.homedir(), ".node9", "hud-debug"))) {
47705
+ if (fs74.existsSync(path69.join(os62.homedir(), ".node9", "hud-debug"))) {
47789
47706
  try {
47790
- const logPath = path70.join(os63.homedir(), ".node9", "hud-debug.log");
47707
+ const logPath = path69.join(os62.homedir(), ".node9", "hud-debug.log");
47791
47708
  const MAX_LOG_SIZE = 10 * 1024 * 1024;
47792
47709
  let size = 0;
47793
47710
  try {
47794
- size = fs75.statSync(logPath).size;
47711
+ size = fs74.statSync(logPath).size;
47795
47712
  } catch {
47796
47713
  }
47797
47714
  if (size < MAX_LOG_SIZE) {
47798
- fs75.appendFileSync(
47715
+ fs74.appendFileSync(
47799
47716
  logPath,
47800
47717
  JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), stdin }) + "\n"
47801
47718
  );
@@ -47816,11 +47733,11 @@ async function main() {
47816
47733
  try {
47817
47734
  const cwd = stdin.cwd ?? process.cwd();
47818
47735
  for (const configPath of [
47819
- path70.join(cwd, "node9.config.json"),
47820
- path70.join(os63.homedir(), ".node9", "config.json")
47736
+ path69.join(cwd, "node9.config.json"),
47737
+ path69.join(os62.homedir(), ".node9", "config.json")
47821
47738
  ]) {
47822
- if (!fs75.existsSync(configPath)) continue;
47823
- const cfg = JSON.parse(fs75.readFileSync(configPath, "utf-8"));
47739
+ if (!fs74.existsSync(configPath)) continue;
47740
+ const cfg = JSON.parse(fs74.readFileSync(configPath, "utf-8"));
47824
47741
  const hud = cfg.settings?.hud;
47825
47742
  if (hud && "showEnvironmentCounts" in hud) return hud.showEnvironmentCounts !== false;
47826
47743
  }
@@ -47962,10 +47879,10 @@ function writeCredentialsAndConfig(apiKey, opts = {}) {
47962
47879
  // src/cli.ts
47963
47880
  init_daemon2();
47964
47881
  import chalk40 from "chalk";
47965
- import fs76 from "fs";
47966
- import path71 from "path";
47967
- import os64 from "os";
47968
- import { spawn as spawn9 } from "child_process";
47882
+ import fs75 from "fs";
47883
+ import path70 from "path";
47884
+ import os63 from "os";
47885
+ import { spawn as spawn8 } from "child_process";
47969
47886
  import { confirm as confirm3 } from "@inquirer/prompts";
47970
47887
 
47971
47888
  // src/utils/duration.ts
@@ -48249,286 +48166,24 @@ init_state();
48249
48166
  init_daemon();
48250
48167
  init_startup_log();
48251
48168
  init_config();
48252
- init_policy();
48253
48169
  import chalk9 from "chalk";
48254
- import fs50 from "fs";
48255
- import { spawn as spawn5 } from "child_process";
48256
- import path48 from "path";
48257
- import os45 from "os";
48170
+ import fs49 from "fs";
48171
+ import { spawn as spawn4 } from "child_process";
48172
+ import path47 from "path";
48173
+ import os44 from "os";
48258
48174
 
48259
- // src/undo.ts
48260
- import { spawnSync as spawnSync3, spawn as spawn4 } from "child_process";
48261
- import crypto7 from "crypto";
48175
+ // src/skill-pin.ts
48262
48176
  import fs47 from "fs";
48263
- import net3 from "net";
48264
48177
  import path45 from "path";
48265
48178
  import os42 from "os";
48266
- var ACTIVITY_SOCKET_PATH3 = process.platform === "win32" ? "\\\\.\\pipe\\node9-activity" : path45.join(os42.tmpdir(), "node9-activity.sock");
48267
- function notifySnapshotTaken(hash, tool, argsSummary, fileCount) {
48268
- try {
48269
- const payload = JSON.stringify({
48270
- status: "snapshot",
48271
- hash,
48272
- tool,
48273
- argsSummary,
48274
- fileCount,
48275
- ts: Date.now()
48276
- });
48277
- const sock = net3.createConnection(ACTIVITY_SOCKET_PATH3);
48278
- sock.on("connect", () => {
48279
- sock.end(payload);
48280
- });
48281
- sock.on("error", () => {
48282
- });
48283
- } catch {
48284
- }
48285
- }
48286
- var SNAPSHOT_STACK_PATH = path45.join(os42.homedir(), ".node9", "snapshots.json");
48287
- var UNDO_LATEST_PATH = path45.join(os42.homedir(), ".node9", "undo_latest.txt");
48288
- var MAX_SNAPSHOTS = 10;
48289
- var GIT_TIMEOUT = 15e3;
48290
- function readStack() {
48291
- try {
48292
- if (fs47.existsSync(SNAPSHOT_STACK_PATH))
48293
- return JSON.parse(fs47.readFileSync(SNAPSHOT_STACK_PATH, "utf-8"));
48294
- } catch {
48295
- }
48296
- return [];
48297
- }
48298
- function writeStack(stack) {
48299
- const dir = path45.dirname(SNAPSHOT_STACK_PATH);
48300
- if (!fs47.existsSync(dir)) fs47.mkdirSync(dir, { recursive: true });
48301
- fs47.writeFileSync(SNAPSHOT_STACK_PATH, JSON.stringify(stack, null, 2));
48302
- }
48303
- function extractFilePath(args) {
48304
- if (!args || typeof args !== "object") return null;
48305
- const a = args;
48306
- const fp = a.file_path ?? a.path ?? a.filename;
48307
- return typeof fp === "string" ? fp : null;
48308
- }
48309
- function buildArgsSummary(tool, args) {
48310
- const filePath = extractFilePath(args);
48311
- if (filePath) return filePath;
48312
- if (!args || typeof args !== "object") return "";
48313
- const a = args;
48314
- const cmd = a.command ?? a.cmd;
48315
- if (typeof cmd === "string") return cmd.slice(0, 80);
48316
- const sql = a.sql ?? a.query;
48317
- if (typeof sql === "string") return sql.slice(0, 80);
48318
- return "";
48319
- }
48320
- function findProjectRoot(filePath) {
48321
- let dir = path45.dirname(filePath);
48322
- while (true) {
48323
- if (fs47.existsSync(path45.join(dir, ".git")) || fs47.existsSync(path45.join(dir, "package.json"))) {
48324
- return dir;
48325
- }
48326
- const parent = path45.dirname(dir);
48327
- if (parent === dir) return process.cwd();
48328
- dir = parent;
48329
- }
48330
- }
48331
- function normalizeCwdForHash(cwd) {
48332
- let normalized;
48333
- try {
48334
- normalized = fs47.realpathSync(cwd);
48335
- } catch {
48336
- normalized = cwd;
48337
- }
48338
- normalized = normalized.replace(/\\/g, "/");
48339
- if (process.platform === "win32") normalized = normalized.toLowerCase();
48340
- return normalized;
48341
- }
48342
- function getShadowRepoDir(cwd) {
48343
- const hash = crypto7.createHash("sha256").update(normalizeCwdForHash(cwd)).digest("hex").slice(0, 16);
48344
- return path45.join(os42.homedir(), ".node9", "snapshots", hash);
48345
- }
48346
- function cleanOrphanedIndexFiles(shadowDir) {
48347
- try {
48348
- const cutoff = Date.now() - 6e4;
48349
- for (const f of fs47.readdirSync(shadowDir)) {
48350
- if (f.startsWith("index_")) {
48351
- const fp = path45.join(shadowDir, f);
48352
- try {
48353
- if (fs47.statSync(fp).mtimeMs < cutoff) fs47.unlinkSync(fp);
48354
- } catch {
48355
- }
48356
- }
48357
- }
48358
- } catch {
48359
- }
48360
- }
48361
- function writeShadowExcludes(shadowDir, ignorePaths) {
48362
- const hardcoded = [".git", ".node9"];
48363
- const lines = [...hardcoded, ...ignorePaths].join("\n");
48364
- try {
48365
- fs47.writeFileSync(path45.join(shadowDir, "info", "exclude"), lines + "\n", "utf8");
48366
- } catch {
48367
- }
48368
- }
48369
- function ensureShadowRepo(shadowDir, cwd) {
48370
- cleanOrphanedIndexFiles(shadowDir);
48371
- const normalizedCwd = normalizeCwdForHash(cwd);
48372
- const shadowEnvBase = { ...process.env, GIT_DIR: shadowDir, GIT_WORK_TREE: cwd };
48373
- const check = spawnSync3("git", ["rev-parse", "--git-dir"], {
48374
- env: shadowEnvBase,
48375
- timeout: 3e3
48376
- });
48377
- if (check.status === 0) {
48378
- const ptPath = path45.join(shadowDir, "project-path.txt");
48379
- try {
48380
- const stored = fs47.readFileSync(ptPath, "utf8").trim();
48381
- if (stored === normalizedCwd) return true;
48382
- if (process.env.NODE9_DEBUG === "1")
48383
- console.error(
48384
- `[Node9] Shadow repo path mismatch: stored="${stored}" expected="${normalizedCwd}" \u2014 reinitializing`
48385
- );
48386
- fs47.rmSync(shadowDir, { recursive: true, force: true });
48387
- } catch {
48388
- try {
48389
- fs47.writeFileSync(ptPath, normalizedCwd, "utf8");
48390
- } catch {
48391
- }
48392
- return true;
48393
- }
48394
- }
48395
- try {
48396
- fs47.mkdirSync(shadowDir, { recursive: true });
48397
- } catch {
48398
- }
48399
- const init = spawnSync3("git", ["init", "--bare", shadowDir], { timeout: 5e3 });
48400
- if (init.status !== 0 || init.error) {
48401
- const reason = init.error ? init.error.message : init.stderr?.toString();
48402
- if (process.env.NODE9_DEBUG === "1") console.error("[Node9] git init --bare failed:", reason);
48403
- return false;
48404
- }
48405
- const configFile = path45.join(shadowDir, "config");
48406
- spawnSync3("git", ["config", "--file", configFile, "core.untrackedCache", "true"], {
48407
- timeout: 3e3
48408
- });
48409
- spawnSync3("git", ["config", "--file", configFile, "core.fsmonitor", "true"], {
48410
- timeout: 3e3
48411
- });
48412
- try {
48413
- fs47.writeFileSync(path45.join(shadowDir, "project-path.txt"), normalizedCwd, "utf8");
48414
- } catch {
48415
- }
48416
- return true;
48417
- }
48418
- async function createShadowSnapshot(tool = "unknown", args = {}, ignorePaths = []) {
48419
- let indexFile = null;
48420
- try {
48421
- const rawFilePath = extractFilePath(args);
48422
- const absFilePath = rawFilePath && path45.isAbsolute(rawFilePath) ? rawFilePath : null;
48423
- const cwd = absFilePath ? findProjectRoot(absFilePath) : process.cwd();
48424
- const shadowDir = getShadowRepoDir(cwd);
48425
- if (!ensureShadowRepo(shadowDir, cwd)) return null;
48426
- writeShadowExcludes(shadowDir, ignorePaths);
48427
- indexFile = path45.join(shadowDir, `index_${process.pid}_${Date.now()}`);
48428
- const shadowEnv = {
48429
- ...process.env,
48430
- GIT_DIR: shadowDir,
48431
- GIT_WORK_TREE: cwd,
48432
- GIT_INDEX_FILE: indexFile
48433
- };
48434
- spawnSync3("git", ["add", "-A"], { env: shadowEnv, timeout: GIT_TIMEOUT });
48435
- const treeRes = spawnSync3("git", ["write-tree"], { env: shadowEnv, timeout: GIT_TIMEOUT });
48436
- const treeHash = treeRes.stdout?.toString().trim();
48437
- if (!treeHash || treeRes.status !== 0) return null;
48438
- const commitRes = spawnSync3(
48439
- "git",
48440
- ["commit-tree", treeHash, "-m", `Node9 AI Snapshot: ${(/* @__PURE__ */ new Date()).toISOString()}`],
48441
- { env: shadowEnv, timeout: GIT_TIMEOUT }
48442
- );
48443
- const commitHash = commitRes.stdout?.toString().trim();
48444
- if (!commitHash || commitRes.status !== 0) return null;
48445
- const stack = readStack();
48446
- const prevEntry = [...stack].reverse().find((e) => e.cwd === cwd);
48447
- let capturedFiles = [];
48448
- let capturedDiff = null;
48449
- if (prevEntry) {
48450
- const filesRes = spawnSync3("git", ["diff", "--name-only", prevEntry.hash, commitHash], {
48451
- env: shadowEnv,
48452
- timeout: GIT_TIMEOUT
48453
- });
48454
- if (filesRes.status === 0) {
48455
- capturedFiles = filesRes.stdout?.toString().trim().split("\n").filter(Boolean) ?? [];
48456
- }
48457
- if (capturedFiles.length === 0) {
48458
- return prevEntry.hash;
48459
- }
48460
- const diffRes = spawnSync3("git", ["diff", prevEntry.hash, commitHash], {
48461
- env: shadowEnv,
48462
- timeout: GIT_TIMEOUT
48463
- });
48464
- if (diffRes.status === 0) {
48465
- capturedDiff = diffRes.stdout?.toString() || null;
48466
- }
48467
- } else {
48468
- const filesRes = spawnSync3("git", ["ls-tree", "-r", "--name-only", commitHash], {
48469
- env: shadowEnv,
48470
- timeout: GIT_TIMEOUT
48471
- });
48472
- if (filesRes.status === 0) {
48473
- capturedFiles = filesRes.stdout?.toString().trim().split("\n").filter(Boolean) ?? [];
48474
- }
48475
- capturedDiff = null;
48476
- }
48477
- stack.push({
48478
- hash: commitHash,
48479
- tool,
48480
- argsSummary: buildArgsSummary(tool, args),
48481
- files: capturedFiles,
48482
- diff: capturedDiff,
48483
- cwd,
48484
- timestamp: Date.now()
48485
- });
48486
- const shouldGc = stack.length % 5 === 0;
48487
- let cwdCount = 0;
48488
- let oldestCwdIdx = -1;
48489
- for (let i = 0; i < stack.length; i++) {
48490
- if (stack[i].cwd === cwd) {
48491
- if (oldestCwdIdx === -1) oldestCwdIdx = i;
48492
- cwdCount++;
48493
- }
48494
- }
48495
- if (cwdCount > MAX_SNAPSHOTS) stack.splice(oldestCwdIdx, 1);
48496
- writeStack(stack);
48497
- const entry = stack[stack.length - 1];
48498
- notifySnapshotTaken(commitHash.slice(0, 7), tool, entry.argsSummary, capturedFiles.length);
48499
- fs47.writeFileSync(UNDO_LATEST_PATH, commitHash);
48500
- if (shouldGc) {
48501
- spawn4("git", ["gc", "--auto"], { env: shadowEnv, detached: true, stdio: "ignore" }).unref();
48502
- }
48503
- return commitHash;
48504
- } catch (err2) {
48505
- if (process.env.NODE9_DEBUG === "1") console.error("[Node9 Undo Engine Error]:", err2);
48506
- return null;
48507
- } finally {
48508
- if (indexFile) {
48509
- try {
48510
- fs47.unlinkSync(indexFile);
48511
- } catch {
48512
- }
48513
- }
48514
- }
48515
- }
48516
- function getSnapshotHistory() {
48517
- return readStack();
48518
- }
48519
-
48520
- // src/skill-pin.ts
48521
- import fs48 from "fs";
48522
- import path46 from "path";
48523
- import os43 from "os";
48524
- import crypto8 from "crypto";
48179
+ import crypto7 from "crypto";
48525
48180
  function getPinsFilePath2() {
48526
- return path46.join(os43.homedir(), ".node9", "skill-pins.json");
48181
+ return path45.join(os42.homedir(), ".node9", "skill-pins.json");
48527
48182
  }
48528
48183
  var MAX_FILES = 5e3;
48529
48184
  var MAX_TOTAL_BYTES = 50 * 1024 * 1024;
48530
48185
  function sha256Bytes(buf) {
48531
- return crypto8.createHash("sha256").update(buf).digest("hex");
48186
+ return crypto7.createHash("sha256").update(buf).digest("hex");
48532
48187
  }
48533
48188
  function walkDir(root) {
48534
48189
  const out = [];
@@ -48537,18 +48192,18 @@ function walkDir(root) {
48537
48192
  if (out.length >= MAX_FILES) return;
48538
48193
  let entries;
48539
48194
  try {
48540
- entries = fs48.readdirSync(dir, { withFileTypes: true });
48195
+ entries = fs47.readdirSync(dir, { withFileTypes: true });
48541
48196
  } catch {
48542
48197
  return;
48543
48198
  }
48544
48199
  entries.sort((a, b) => a.name.localeCompare(b.name));
48545
48200
  for (const entry of entries) {
48546
48201
  if (out.length >= MAX_FILES) return;
48547
- const full = path46.join(dir, entry.name);
48548
- const rel = relDir ? path46.posix.join(relDir, entry.name) : entry.name;
48202
+ const full = path45.join(dir, entry.name);
48203
+ const rel = relDir ? path45.posix.join(relDir, entry.name) : entry.name;
48549
48204
  let lst;
48550
48205
  try {
48551
- lst = fs48.lstatSync(full);
48206
+ lst = fs47.lstatSync(full);
48552
48207
  } catch {
48553
48208
  continue;
48554
48209
  }
@@ -48560,7 +48215,7 @@ function walkDir(root) {
48560
48215
  if (!lst.isFile()) continue;
48561
48216
  if (totalBytes + lst.size > MAX_TOTAL_BYTES) continue;
48562
48217
  try {
48563
- const buf = fs48.readFileSync(full);
48218
+ const buf = fs47.readFileSync(full);
48564
48219
  totalBytes += buf.length;
48565
48220
  out.push({ rel, hash: sha256Bytes(buf) });
48566
48221
  } catch {
@@ -48574,32 +48229,32 @@ function walkDir(root) {
48574
48229
  function hashSkillRoot(absPath) {
48575
48230
  let lst;
48576
48231
  try {
48577
- lst = fs48.lstatSync(absPath);
48232
+ lst = fs47.lstatSync(absPath);
48578
48233
  } catch {
48579
48234
  return { exists: false, contentHash: "", fileCount: 0 };
48580
48235
  }
48581
48236
  if (lst.isSymbolicLink()) return { exists: false, contentHash: "", fileCount: 0 };
48582
48237
  if (lst.isFile()) {
48583
48238
  try {
48584
- return { exists: true, contentHash: sha256Bytes(fs48.readFileSync(absPath)), fileCount: 1 };
48239
+ return { exists: true, contentHash: sha256Bytes(fs47.readFileSync(absPath)), fileCount: 1 };
48585
48240
  } catch {
48586
48241
  return { exists: false, contentHash: "", fileCount: 0 };
48587
48242
  }
48588
48243
  }
48589
48244
  if (lst.isDirectory()) {
48590
48245
  const entries = walkDir(absPath);
48591
- const contentHash = crypto8.createHash("sha256").update(entries.join("\n")).digest("hex");
48246
+ const contentHash = crypto7.createHash("sha256").update(entries.join("\n")).digest("hex");
48592
48247
  return { exists: true, contentHash, fileCount: entries.length };
48593
48248
  }
48594
48249
  return { exists: false, contentHash: "", fileCount: 0 };
48595
48250
  }
48596
48251
  function getRootKey(absPath) {
48597
- return crypto8.createHash("sha256").update(absPath).digest("hex").slice(0, 16);
48252
+ return crypto7.createHash("sha256").update(absPath).digest("hex").slice(0, 16);
48598
48253
  }
48599
48254
  function readSkillPinsSafe() {
48600
48255
  const filePath = getPinsFilePath2();
48601
48256
  try {
48602
- const raw = fs48.readFileSync(filePath, "utf-8");
48257
+ const raw = fs47.readFileSync(filePath, "utf-8");
48603
48258
  if (!raw.trim()) return { ok: false, reason: "corrupt", detail: "empty file" };
48604
48259
  const parsed = JSON.parse(raw);
48605
48260
  if (!parsed.roots || typeof parsed.roots !== "object" || Array.isArray(parsed.roots)) {
@@ -48619,10 +48274,10 @@ function readSkillPins() {
48619
48274
  }
48620
48275
  function writeSkillPins(data) {
48621
48276
  const filePath = getPinsFilePath2();
48622
- fs48.mkdirSync(path46.dirname(filePath), { recursive: true });
48623
- const tmp = `${filePath}.${crypto8.randomBytes(6).toString("hex")}.tmp`;
48624
- fs48.writeFileSync(tmp, JSON.stringify(data, null, 2), { mode: 384 });
48625
- fs48.renameSync(tmp, filePath);
48277
+ fs47.mkdirSync(path45.dirname(filePath), { recursive: true });
48278
+ const tmp = `${filePath}.${crypto7.randomBytes(6).toString("hex")}.tmp`;
48279
+ fs47.writeFileSync(tmp, JSON.stringify(data, null, 2), { mode: 384 });
48280
+ fs47.renameSync(tmp, filePath);
48626
48281
  }
48627
48282
  function removePin2(rootKey) {
48628
48283
  const pins = readSkillPins();
@@ -48666,36 +48321,36 @@ function verifyAndPinRoots(roots) {
48666
48321
  return { kind: "verified" };
48667
48322
  }
48668
48323
  function defaultSkillRoots(_cwd) {
48669
- const marketplaces = path46.join(os43.homedir(), ".claude", "plugins", "marketplaces");
48324
+ const marketplaces = path45.join(os42.homedir(), ".claude", "plugins", "marketplaces");
48670
48325
  const roots = [];
48671
48326
  let registries;
48672
48327
  try {
48673
- registries = fs48.readdirSync(marketplaces, { withFileTypes: true });
48328
+ registries = fs47.readdirSync(marketplaces, { withFileTypes: true });
48674
48329
  } catch {
48675
48330
  return [];
48676
48331
  }
48677
48332
  for (const registry of registries) {
48678
48333
  if (!registry.isDirectory()) continue;
48679
- const pluginsDir = path46.join(marketplaces, registry.name, "plugins");
48334
+ const pluginsDir = path45.join(marketplaces, registry.name, "plugins");
48680
48335
  let plugins;
48681
48336
  try {
48682
- plugins = fs48.readdirSync(pluginsDir, { withFileTypes: true });
48337
+ plugins = fs47.readdirSync(pluginsDir, { withFileTypes: true });
48683
48338
  } catch {
48684
48339
  continue;
48685
48340
  }
48686
48341
  for (const plugin of plugins) {
48687
48342
  if (!plugin.isDirectory()) continue;
48688
- roots.push(path46.join(pluginsDir, plugin.name));
48343
+ roots.push(path45.join(pluginsDir, plugin.name));
48689
48344
  }
48690
48345
  }
48691
48346
  return roots;
48692
48347
  }
48693
48348
  function resolveUserSkillRoot(entry, cwd) {
48694
48349
  if (!entry) return null;
48695
- if (entry.startsWith("~/") || entry === "~") return path46.join(os43.homedir(), entry.slice(1));
48696
- if (path46.isAbsolute(entry)) return entry;
48697
- if (!cwd || !path46.isAbsolute(cwd)) return null;
48698
- return path46.join(cwd, entry);
48350
+ if (entry.startsWith("~/") || entry === "~") return path45.join(os42.homedir(), entry.slice(1));
48351
+ if (path45.isAbsolute(entry)) return entry;
48352
+ if (!cwd || !path45.isAbsolute(cwd)) return null;
48353
+ return path45.join(cwd, entry);
48699
48354
  }
48700
48355
 
48701
48356
  // src/cli/commands/check.ts
@@ -48704,11 +48359,11 @@ init_audit();
48704
48359
 
48705
48360
  // src/review-pending.ts
48706
48361
  init_hasher();
48707
- import fs49 from "fs";
48708
- import os44 from "os";
48709
- import path47 from "path";
48362
+ import fs48 from "fs";
48363
+ import os43 from "os";
48364
+ import path46 from "path";
48710
48365
  function storePath() {
48711
- return process.env.NODE9_PENDING_STORE || path47.join(os44.homedir(), ".node9", "pending-reviews.json");
48366
+ return process.env.NODE9_PENDING_STORE || path46.join(os43.homedir(), ".node9", "pending-reviews.json");
48712
48367
  }
48713
48368
  var TTL_TUID_MS = 72 * 60 * 60 * 1e3;
48714
48369
  var TTL_MS2 = 6 * 60 * 60 * 1e3;
@@ -48726,7 +48381,7 @@ function reviewCorrelationKey(payload) {
48726
48381
  }
48727
48382
  function read() {
48728
48383
  try {
48729
- const parsed = JSON.parse(fs49.readFileSync(storePath(), "utf-8"));
48384
+ const parsed = JSON.parse(fs48.readFileSync(storePath(), "utf-8"));
48730
48385
  if (parsed && Array.isArray(parsed.entries)) return parsed;
48731
48386
  } catch {
48732
48387
  }
@@ -48735,11 +48390,11 @@ function read() {
48735
48390
  function write(store) {
48736
48391
  try {
48737
48392
  const p = storePath();
48738
- const dir = path47.dirname(p);
48739
- if (!fs49.existsSync(dir)) fs49.mkdirSync(dir, { recursive: true });
48393
+ const dir = path46.dirname(p);
48394
+ if (!fs48.existsSync(dir)) fs48.mkdirSync(dir, { recursive: true });
48740
48395
  const tmp = `${p}.${process.pid}.tmp`;
48741
- fs49.writeFileSync(tmp, JSON.stringify(store));
48742
- fs49.renameSync(tmp, p);
48396
+ fs48.writeFileSync(tmp, JSON.stringify(store));
48397
+ fs48.renameSync(tmp, p);
48743
48398
  } catch {
48744
48399
  }
48745
48400
  }
@@ -48868,9 +48523,9 @@ function registerCheckCommand(program2) {
48868
48523
  } catch (err2) {
48869
48524
  const tempConfig = getConfig();
48870
48525
  if (process.env.NODE9_DEBUG === "1" || tempConfig.settings.enableHookLogDebug) {
48871
- const logPath = path48.join(os45.homedir(), ".node9", "hook-debug.log");
48526
+ const logPath = path47.join(os44.homedir(), ".node9", "hook-debug.log");
48872
48527
  const errMsg = err2 instanceof Error ? err2.message : String(err2);
48873
- fs50.appendFileSync(
48528
+ fs49.appendFileSync(
48874
48529
  logPath,
48875
48530
  `[${(/* @__PURE__ */ new Date()).toISOString()}] JSON_PARSE_ERROR: ${errMsg}
48876
48531
  RAW: ${raw}
@@ -48883,14 +48538,14 @@ RAW: ${raw}
48883
48538
  const prompt = typeof payload.prompt === "string" ? payload.prompt : "";
48884
48539
  if (process.env.NODE9_DEBUG === "1") {
48885
48540
  try {
48886
- const logPath = path48.join(os45.homedir(), ".node9", "hook-debug.log");
48887
- if (!fs50.existsSync(path48.dirname(logPath)))
48888
- fs50.mkdirSync(path48.dirname(logPath), { recursive: true });
48541
+ const logPath = path47.join(os44.homedir(), ".node9", "hook-debug.log");
48542
+ if (!fs49.existsSync(path47.dirname(logPath)))
48543
+ fs49.mkdirSync(path47.dirname(logPath), { recursive: true });
48889
48544
  const sanitized = JSON.stringify({
48890
48545
  ...payload,
48891
48546
  prompt: `<redacted, ${prompt.length} bytes>`
48892
48547
  });
48893
- fs50.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] STDIN: ${sanitized}
48548
+ fs49.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] STDIN: ${sanitized}
48894
48549
  `);
48895
48550
  } catch {
48896
48551
  }
@@ -48911,8 +48566,8 @@ RAW: ${raw}
48911
48566
  );
48912
48567
  const reason = `\u{1F6A8} Node9 DLP: ${dlpMatch.patternName} detected in prompt (${dlpMatch.redactedSample}). Prompt was not submitted \u2014 remove the credential and try again.`;
48913
48568
  try {
48914
- const ttyFd = fs50.openSync("/dev/tty", "w");
48915
- fs50.writeSync(
48569
+ const ttyFd = fs49.openSync("/dev/tty", "w");
48570
+ fs49.writeSync(
48916
48571
  ttyFd,
48917
48572
  chalk9.bgRed.white.bold(`
48918
48573
  \u{1F6A8} NODE9 DLP \u2014 PROMPT BLOCKED
@@ -48922,7 +48577,7 @@ RAW: ${raw}
48922
48577
 
48923
48578
  `)
48924
48579
  );
48925
- fs50.closeSync(ttyFd);
48580
+ fs49.closeSync(ttyFd);
48926
48581
  } catch {
48927
48582
  }
48928
48583
  const isCodex = agent2 === "Codex";
@@ -48941,17 +48596,17 @@ RAW: ${raw}
48941
48596
  process.exit(2);
48942
48597
  }
48943
48598
  const payloadCwd = typeof payload.cwd === "string" ? payload.cwd : Array.isArray(payload.workspacePaths) && typeof payload.workspacePaths[0] === "string" ? payload.workspacePaths[0] : void 0;
48944
- const safeCwdForConfig = typeof payloadCwd === "string" && path48.isAbsolute(payloadCwd) ? payloadCwd : void 0;
48599
+ const safeCwdForConfig = typeof payloadCwd === "string" && path47.isAbsolute(payloadCwd) ? payloadCwd : void 0;
48945
48600
  const config = getConfig(safeCwdForConfig);
48946
48601
  const daemonDown = !isDaemonRunning();
48947
48602
  if (config.settings.autoStartDaemon && daemonDown && !process.env.NODE9_NO_AUTO_DAEMON) {
48948
48603
  try {
48949
48604
  const scriptPath = process.argv[1];
48950
- if (typeof scriptPath !== "string" || !path48.isAbsolute(scriptPath))
48605
+ if (typeof scriptPath !== "string" || !path47.isAbsolute(scriptPath))
48951
48606
  throw new Error("node9: argv[1] is not an absolute path");
48952
- const resolvedScript = fs50.realpathSync(scriptPath);
48953
- const packageDist = fs50.realpathSync(path48.resolve(__dirname, "../.."));
48954
- if (!resolvedScript.startsWith(packageDist + path48.sep) && resolvedScript !== packageDist)
48607
+ const resolvedScript = fs49.realpathSync(scriptPath);
48608
+ const packageDist = fs49.realpathSync(path47.resolve(__dirname, "../.."));
48609
+ if (!resolvedScript.startsWith(packageDist + path47.sep) && resolvedScript !== packageDist)
48955
48610
  throw new Error(
48956
48611
  `node9: daemon spawn aborted \u2014 argv[1] (${resolvedScript}) is outside package dist (${packageDist})`
48957
48612
  );
@@ -48969,7 +48624,7 @@ RAW: ${raw}
48969
48624
  const startupFd = openStartupLogFd();
48970
48625
  recordStartupState("starting");
48971
48626
  try {
48972
- const d = spawn5(process.execPath, [scriptPath, "daemon"], {
48627
+ const d = spawn4(process.execPath, [scriptPath, "daemon"], {
48973
48628
  detached: true,
48974
48629
  stdio: ["ignore", "ignore", startupFd ?? "ignore"],
48975
48630
  env: { ...safeEnv, NODE9_AUTO_STARTED: "1" }
@@ -48981,17 +48636,17 @@ RAW: ${raw}
48981
48636
  } finally {
48982
48637
  if (startupFd !== void 0) {
48983
48638
  try {
48984
- fs50.closeSync(startupFd);
48639
+ fs49.closeSync(startupFd);
48985
48640
  } catch {
48986
48641
  }
48987
48642
  }
48988
48643
  }
48989
48644
  } catch (spawnErr) {
48990
- const logPath = path48.join(os45.homedir(), ".node9", "hook-debug.log");
48645
+ const logPath = path47.join(os44.homedir(), ".node9", "hook-debug.log");
48991
48646
  const msg = spawnErr instanceof Error ? spawnErr.message : String(spawnErr);
48992
48647
  recordStartupState("failed", "spawn-aborted", msg);
48993
48648
  try {
48994
- fs50.appendFileSync(
48649
+ fs49.appendFileSync(
48995
48650
  logPath,
48996
48651
  `[${(/* @__PURE__ */ new Date()).toISOString()}] daemon-autostart-failed: ${msg}
48997
48652
  `
@@ -49005,10 +48660,10 @@ RAW: ${raw}
49005
48660
  );
49006
48661
  }
49007
48662
  if (process.env.NODE9_DEBUG === "1" || config.settings.enableHookLogDebug) {
49008
- const logPath = path48.join(os45.homedir(), ".node9", "hook-debug.log");
49009
- if (!fs50.existsSync(path48.dirname(logPath)))
49010
- fs50.mkdirSync(path48.dirname(logPath), { recursive: true });
49011
- fs50.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] STDIN: ${raw}
48663
+ const logPath = path47.join(os44.homedir(), ".node9", "hook-debug.log");
48664
+ if (!fs49.existsSync(path47.dirname(logPath)))
48665
+ fs49.mkdirSync(path47.dirname(logPath), { recursive: true });
48666
+ fs49.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] STDIN: ${raw}
49012
48667
  `);
49013
48668
  }
49014
48669
  const rawToolName = sanitize2(extractToolName(payload));
@@ -49022,8 +48677,8 @@ RAW: ${raw}
49022
48677
  const isHumanDecision = blockedByContext.toLowerCase().includes("user") || blockedByContext.toLowerCase().includes("daemon") || blockedByContext.toLowerCase().includes("decision");
49023
48678
  let ttyFd = null;
49024
48679
  try {
49025
- ttyFd = fs50.openSync("/dev/tty", "w");
49026
- const writeTty = (line) => fs50.writeSync(ttyFd, line + "\n");
48680
+ ttyFd = fs49.openSync("/dev/tty", "w");
48681
+ const writeTty = (line) => fs49.writeSync(ttyFd, line + "\n");
49027
48682
  if (blockedByContext.includes("DLP") || blockedByContext.includes("Secret Detected") || blockedByContext.includes("Credential Review")) {
49028
48683
  writeTty(chalk9.bgRed.white.bold(`
49029
48684
  \u{1F6A8} NODE9 DLP ALERT \u2014 CREDENTIAL DETECTED `));
@@ -49042,7 +48697,7 @@ RAW: ${raw}
49042
48697
  } finally {
49043
48698
  if (ttyFd !== null)
49044
48699
  try {
49045
- fs50.closeSync(ttyFd);
48700
+ fs49.closeSync(ttyFd);
49046
48701
  } catch {
49047
48702
  }
49048
48703
  }
@@ -49103,8 +48758,8 @@ RAW: ${raw}
49103
48758
  } catch {
49104
48759
  }
49105
48760
  try {
49106
- const ttyFd = fs50.openSync("/dev/tty", "w");
49107
- fs50.writeSync(
48761
+ const ttyFd = fs49.openSync("/dev/tty", "w");
48762
+ fs49.writeSync(
49108
48763
  ttyFd,
49109
48764
  chalk9.yellow(
49110
48765
  `
@@ -49112,7 +48767,7 @@ RAW: ${raw}
49112
48767
  `
49113
48768
  )
49114
48769
  );
49115
- fs50.closeSync(ttyFd);
48770
+ fs49.closeSync(ttyFd);
49116
48771
  } catch {
49117
48772
  }
49118
48773
  if (agent === "GitHub Copilot") {
@@ -49144,17 +48799,17 @@ RAW: ${raw}
49144
48799
  const safeSessionId = /^[A-Za-z0-9_\-]{1,128}$/.test(rawSessionId) ? rawSessionId : "";
49145
48800
  if (skillPinCfg.enabled && safeSessionId) {
49146
48801
  try {
49147
- const sessionsDir = path48.join(os45.homedir(), ".node9", "skill-sessions");
49148
- const flagPath = path48.join(sessionsDir, `${safeSessionId}.json`);
48802
+ const sessionsDir = path47.join(os44.homedir(), ".node9", "skill-sessions");
48803
+ const flagPath = path47.join(sessionsDir, `${safeSessionId}.json`);
49149
48804
  let flag = null;
49150
48805
  try {
49151
- flag = JSON.parse(fs50.readFileSync(flagPath, "utf-8"));
48806
+ flag = JSON.parse(fs49.readFileSync(flagPath, "utf-8"));
49152
48807
  } catch {
49153
48808
  }
49154
48809
  const writeFlag = (data2) => {
49155
48810
  try {
49156
- fs50.mkdirSync(sessionsDir, { recursive: true });
49157
- fs50.writeFileSync(
48811
+ fs49.mkdirSync(sessionsDir, { recursive: true });
48812
+ fs49.writeFileSync(
49158
48813
  flagPath,
49159
48814
  JSON.stringify({ ...data2, timestamp: (/* @__PURE__ */ new Date()).toISOString() }, null, 2),
49160
48815
  { mode: 384 }
@@ -49165,8 +48820,8 @@ RAW: ${raw}
49165
48820
  const sendSkillWarn = (detail, recoveryCmd) => {
49166
48821
  let ttyFd = null;
49167
48822
  try {
49168
- ttyFd = fs50.openSync("/dev/tty", "w");
49169
- const w = (line) => fs50.writeSync(ttyFd, line + "\n");
48823
+ ttyFd = fs49.openSync("/dev/tty", "w");
48824
+ const w = (line) => fs49.writeSync(ttyFd, line + "\n");
49170
48825
  w(chalk9.yellow(`
49171
48826
  \u26A0\uFE0F Node9: installed skill drift detected`));
49172
48827
  w(chalk9.gray(` ${detail}`));
@@ -49181,7 +48836,7 @@ RAW: ${raw}
49181
48836
  } finally {
49182
48837
  if (ttyFd !== null)
49183
48838
  try {
49184
- fs50.closeSync(ttyFd);
48839
+ fs49.closeSync(ttyFd);
49185
48840
  } catch {
49186
48841
  }
49187
48842
  }
@@ -49197,7 +48852,7 @@ RAW: ${raw}
49197
48852
  return;
49198
48853
  }
49199
48854
  if (!flag || flag.state !== "verified" && flag.state !== "warned") {
49200
- const absoluteCwd = typeof payloadCwd === "string" && path48.isAbsolute(payloadCwd) ? payloadCwd : void 0;
48855
+ const absoluteCwd = typeof payloadCwd === "string" && path47.isAbsolute(payloadCwd) ? payloadCwd : void 0;
49201
48856
  const extraRoots = skillPinCfg.roots;
49202
48857
  const resolvedExtra = extraRoots.map((r) => resolveUserSkillRoot(r, absoluteCwd)).filter((r) => typeof r === "string");
49203
48858
  const roots = [...defaultSkillRoots(absoluteCwd), ...resolvedExtra];
@@ -49238,10 +48893,10 @@ RAW: ${raw}
49238
48893
  }
49239
48894
  try {
49240
48895
  const cutoff = Date.now() - 7 * 24 * 60 * 60 * 1e3;
49241
- for (const name of fs50.readdirSync(sessionsDir)) {
49242
- const p = path48.join(sessionsDir, name);
48896
+ for (const name of fs49.readdirSync(sessionsDir)) {
48897
+ const p = path47.join(sessionsDir, name);
49243
48898
  try {
49244
- if (fs50.statSync(p).mtimeMs < cutoff) fs50.unlinkSync(p);
48899
+ if (fs49.statSync(p).mtimeMs < cutoff) fs49.unlinkSync(p);
49245
48900
  } catch {
49246
48901
  }
49247
48902
  }
@@ -49251,19 +48906,16 @@ RAW: ${raw}
49251
48906
  } catch (err2) {
49252
48907
  if (process.env.NODE9_DEBUG === "1") {
49253
48908
  try {
49254
- const dbg = path48.join(os45.homedir(), ".node9", "hook-debug.log");
48909
+ const dbg = path47.join(os44.homedir(), ".node9", "hook-debug.log");
49255
48910
  const msg = err2 instanceof Error ? err2.message : String(err2);
49256
- fs50.appendFileSync(dbg, `[${(/* @__PURE__ */ new Date()).toISOString()}] SKILL_PIN_ERROR: ${msg}
48911
+ fs49.appendFileSync(dbg, `[${(/* @__PURE__ */ new Date()).toISOString()}] SKILL_PIN_ERROR: ${msg}
49257
48912
  `);
49258
48913
  } catch {
49259
48914
  }
49260
48915
  }
49261
48916
  }
49262
48917
  }
49263
- if (shouldSnapshot(toolName, toolInput, config)) {
49264
- await createShadowSnapshot(toolName, toolInput, config.policy.snapshot.ignorePaths);
49265
- }
49266
- const safeCwdForAuth = typeof payloadCwd === "string" && path48.isAbsolute(payloadCwd) ? payloadCwd : void 0;
48918
+ const safeCwdForAuth = typeof payloadCwd === "string" && path47.isAbsolute(payloadCwd) ? payloadCwd : void 0;
49267
48919
  const askMode = resolveAskMode(agent, opts, config);
49268
48920
  const result = await authorizeHeadless(toolName, toolInput, meta, {
49269
48921
  cwd: safeCwdForAuth,
@@ -49288,12 +48940,12 @@ RAW: ${raw}
49288
48940
  }
49289
48941
  if (result.noApprovalMechanism && !isDaemonRunning() && !process.env.NODE9_NO_AUTO_DAEMON && !process.stdout.isTTY && config.settings.autoStartDaemon) {
49290
48942
  try {
49291
- const tty = fs50.openSync("/dev/tty", "w");
49292
- fs50.writeSync(
48943
+ const tty = fs49.openSync("/dev/tty", "w");
48944
+ fs49.writeSync(
49293
48945
  tty,
49294
48946
  chalk9.cyan("\n\u{1F6E1}\uFE0F Node9: Starting approval daemon automatically...\n")
49295
48947
  );
49296
- fs50.closeSync(tty);
48948
+ fs49.closeSync(tty);
49297
48949
  } catch {
49298
48950
  }
49299
48951
  const daemonReady = await autoStartDaemonAndWait();
@@ -49320,9 +48972,9 @@ RAW: ${raw}
49320
48972
  });
49321
48973
  } catch (err2) {
49322
48974
  if (process.env.NODE9_DEBUG === "1") {
49323
- const logPath = path48.join(os45.homedir(), ".node9", "hook-debug.log");
48975
+ const logPath = path47.join(os44.homedir(), ".node9", "hook-debug.log");
49324
48976
  const errMsg = err2 instanceof Error ? err2.message : String(err2);
49325
- fs50.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] ERROR: ${errMsg}
48977
+ fs49.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] ERROR: ${errMsg}
49326
48978
  `);
49327
48979
  }
49328
48980
  process.exit(0);
@@ -49358,9 +49010,9 @@ RAW: ${raw}
49358
49010
  // src/cli/commands/log.ts
49359
49011
  init_audit();
49360
49012
  init_config();
49361
- import fs51 from "fs";
49362
- import path49 from "path";
49363
- import os46 from "os";
49013
+ import fs50 from "fs";
49014
+ import path48 from "path";
49015
+ import os45 from "os";
49364
49016
  init_daemon();
49365
49017
  init_dlp();
49366
49018
  init_hasher();
@@ -49494,10 +49146,10 @@ function registerLogCommand(program2) {
49494
49146
  if (rawToolName !== tool) entry.agentToolName = rawToolName;
49495
49147
  const payloadSessionId = payload.session_id ?? payload.conversationId;
49496
49148
  if (payloadSessionId) entry.sessionId = payloadSessionId;
49497
- const logPath = path49.join(os46.homedir(), ".node9", "audit.log");
49498
- if (!fs51.existsSync(path49.dirname(logPath)))
49499
- fs51.mkdirSync(path49.dirname(logPath), { recursive: true });
49500
- fs51.appendFileSync(logPath, JSON.stringify(entry) + "\n");
49149
+ const logPath = path48.join(os45.homedir(), ".node9", "audit.log");
49150
+ if (!fs50.existsSync(path48.dirname(logPath)))
49151
+ fs50.mkdirSync(path48.dirname(logPath), { recursive: true });
49152
+ fs50.appendFileSync(logPath, JSON.stringify(entry) + "\n");
49501
49153
  if ((tool === "Bash" || tool === "bash") && isDaemonRunning()) {
49502
49154
  const command = typeof rawInput === "object" && rawInput !== null && "command" in rawInput && typeof rawInput.command === "string" ? rawInput.command : null;
49503
49155
  if (command) {
@@ -49531,7 +49183,7 @@ function registerLogCommand(program2) {
49531
49183
  }
49532
49184
  }
49533
49185
  const payloadCwd = typeof payload.cwd === "string" ? payload.cwd : Array.isArray(payload.workspacePaths) && typeof payload.workspacePaths[0] === "string" ? payload.workspacePaths[0] : void 0;
49534
- const safeCwd = typeof payloadCwd === "string" && path49.isAbsolute(payloadCwd) ? payloadCwd : void 0;
49186
+ const safeCwd = typeof payloadCwd === "string" && path48.isAbsolute(payloadCwd) ? payloadCwd : void 0;
49535
49187
  const config = getConfig(safeCwd);
49536
49188
  if (resolvedReview) {
49537
49189
  try {
@@ -49616,28 +49268,13 @@ function registerLogCommand(program2) {
49616
49268
  }
49617
49269
  }
49618
49270
  }
49619
- if ((tool === "Bash" || tool === "bash") && config.settings.enableUndo === true) {
49620
- const bashCommand = typeof rawInput === "object" && rawInput !== null && "command" in rawInput && typeof rawInput.command === "string" ? rawInput.command : null;
49621
- if (bashCommand) {
49622
- const effectiveCwd = safeCwd ?? process.cwd();
49623
- const history = getSnapshotHistory();
49624
- const hasPrior = history.some((e) => e.cwd === effectiveCwd);
49625
- if (hasPrior) {
49626
- await createShadowSnapshot(
49627
- "Bash",
49628
- { command: bashCommand },
49629
- config.policy.snapshot.ignorePaths
49630
- );
49631
- }
49632
- }
49633
- }
49634
49271
  } catch (err2) {
49635
49272
  const msg = err2 instanceof Error ? err2.message : String(err2);
49636
49273
  process.stderr.write(`[Node9] audit log error: ${msg}
49637
49274
  `);
49638
- const debugPath = path49.join(os46.homedir(), ".node9", "hook-debug.log");
49275
+ const debugPath = path48.join(os45.homedir(), ".node9", "hook-debug.log");
49639
49276
  try {
49640
- fs51.appendFileSync(debugPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] LOG_ERROR: ${msg}
49277
+ fs50.appendFileSync(debugPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] LOG_ERROR: ${msg}
49641
49278
  `);
49642
49279
  } catch {
49643
49280
  }
@@ -49664,16 +49301,16 @@ function registerLogCommand(program2) {
49664
49301
  init_shields();
49665
49302
  init_build();
49666
49303
  import chalk10 from "chalk";
49667
- import fs53 from "fs";
49668
- import path51 from "path";
49669
- import os47 from "os";
49304
+ import fs52 from "fs";
49305
+ import path50 from "path";
49306
+ import os46 from "os";
49670
49307
 
49671
49308
  // src/shields/create.ts
49672
49309
  init_dist();
49673
49310
  init_shields();
49674
49311
  init_audit();
49675
- import fs52 from "fs";
49676
- import path50 from "path";
49312
+ import fs51 from "fs";
49313
+ import path49 from "path";
49677
49314
  function builtinNames() {
49678
49315
  const names = /* @__PURE__ */ new Set();
49679
49316
  for (const def of Object.values(BUILTIN_SHIELDS)) {
@@ -49690,8 +49327,8 @@ function createShield(def, opts = {}) {
49690
49327
  error: `"${name}" is a built-in shield \u2014 choose a different name (a user shield with this name would shadow the built-in).`
49691
49328
  };
49692
49329
  }
49693
- const filePath = path50.join(USER_SHIELDS_DIR_PATH, `${name}.json`);
49694
- if (!opts.overwrite && fs52.existsSync(filePath)) {
49330
+ const filePath = path49.join(USER_SHIELDS_DIR_PATH, `${name}.json`);
49331
+ if (!opts.overwrite && fs51.existsSync(filePath)) {
49695
49332
  return {
49696
49333
  ok: false,
49697
49334
  error: `Shield "${name}" already exists at ${filePath}. Pass --overwrite to replace it.`
@@ -49756,8 +49393,8 @@ var COMMUNITY_INDEX_URL = "https://raw.githubusercontent.com/node9ai/node9-proxy
49756
49393
  function readCloudShields() {
49757
49394
  const out = /* @__PURE__ */ new Set();
49758
49395
  try {
49759
- const file = path51.join(os47.homedir(), ".node9", "rules-cache.json");
49760
- const raw = JSON.parse(fs53.readFileSync(file, "utf-8"));
49396
+ const file = path50.join(os46.homedir(), ".node9", "rules-cache.json");
49397
+ const raw = JSON.parse(fs52.readFileSync(file, "utf-8"));
49761
49398
  for (const r of raw.rules ?? []) {
49762
49399
  const rule = r;
49763
49400
  const fromSource = rule.source?.startsWith("SHIELD:") ? rule.source.slice("SHIELD:".length).toLowerCase() : void 0;
@@ -50074,7 +49711,7 @@ function registerShieldCommand(program2) {
50074
49711
  if (opts.fromFile) {
50075
49712
  let raw;
50076
49713
  try {
50077
- raw = JSON.parse(fs53.readFileSync(opts.fromFile, "utf-8"));
49714
+ raw = JSON.parse(fs52.readFileSync(opts.fromFile, "utf-8"));
50078
49715
  } catch (err2) {
50079
49716
  console.error(
50080
49717
  chalk10.red(`
@@ -50200,9 +49837,9 @@ init_agent_wiring();
50200
49837
  init_sync();
50201
49838
  init_service();
50202
49839
  import chalk11 from "chalk";
50203
- import fs55 from "fs";
50204
- import path53 from "path";
50205
- import os49 from "os";
49840
+ import fs54 from "fs";
49841
+ import path52 from "path";
49842
+ import os48 from "os";
50206
49843
  import { execSync } from "child_process";
50207
49844
 
50208
49845
  // src/lib/relative-time.ts
@@ -50222,22 +49859,22 @@ function agoLabel(iso, now = Date.now()) {
50222
49859
  init_startup_log();
50223
49860
 
50224
49861
  // src/utils/undo-leftovers.ts
50225
- import fs54 from "fs";
50226
- import os48 from "os";
50227
- import path52 from "path";
49862
+ import fs53 from "fs";
49863
+ import os47 from "os";
49864
+ import path51 from "path";
50228
49865
  function candidates(homeDir2) {
50229
- const node9Dir = path52.join(homeDir2, ".node9");
49866
+ const node9Dir = path51.join(homeDir2, ".node9");
50230
49867
  return [
50231
- path52.join(node9Dir, "snapshots"),
50232
- path52.join(node9Dir, "snapshots.json"),
50233
- path52.join(node9Dir, "undo_latest.txt")
49868
+ path51.join(node9Dir, "snapshots"),
49869
+ path51.join(node9Dir, "snapshots.json"),
49870
+ path51.join(node9Dir, "undo_latest.txt")
50234
49871
  ];
50235
49872
  }
50236
- function undoLeftoverPaths(homeDir2 = os48.homedir()) {
49873
+ function undoLeftoverPaths(homeDir2 = os47.homedir()) {
50237
49874
  const found = [];
50238
49875
  for (const p of candidates(homeDir2)) {
50239
49876
  try {
50240
- fs54.lstatSync(p);
49877
+ fs53.lstatSync(p);
50241
49878
  found.push(p);
50242
49879
  } catch (err2) {
50243
49880
  if (err2.code !== "ENOENT") found.push(p);
@@ -50245,11 +49882,11 @@ function undoLeftoverPaths(homeDir2 = os48.homedir()) {
50245
49882
  }
50246
49883
  return found;
50247
49884
  }
50248
- function purgeUndoLeftovers(homeDir2 = os48.homedir()) {
49885
+ function purgeUndoLeftovers(homeDir2 = os47.homedir()) {
50249
49886
  const out = { deleted: [], skipped: [], failed: [] };
50250
49887
  for (const p of undoLeftoverPaths(homeDir2)) {
50251
49888
  try {
50252
- if (fs54.lstatSync(p).isSymbolicLink()) {
49889
+ if (fs53.lstatSync(p).isSymbolicLink()) {
50253
49890
  out.skipped.push({
50254
49891
  path: p,
50255
49892
  reason: "is a symlink \u2014 remove it yourself so nothing else is followed"
@@ -50262,11 +49899,11 @@ function purgeUndoLeftovers(homeDir2 = os48.homedir()) {
50262
49899
  }
50263
49900
  let reason = null;
50264
49901
  try {
50265
- fs54.rmSync(p, { recursive: true, force: true });
49902
+ fs53.rmSync(p, { recursive: true, force: true });
50266
49903
  } catch (err2) {
50267
49904
  reason = err2.message;
50268
49905
  }
50269
- if (fs54.existsSync(p)) {
49906
+ if (fs53.existsSync(p)) {
50270
49907
  out.failed.push({ path: p, reason: reason ?? "still present after removal" });
50271
49908
  } else {
50272
49909
  out.deleted.push(p);
@@ -50278,7 +49915,7 @@ function purgeUndoLeftovers(homeDir2 = os48.homedir()) {
50278
49915
  // src/cli/commands/doctor.ts
50279
49916
  function registerDoctorCommand(program2, version2) {
50280
49917
  program2.command("doctor").description("Check that Node9 is installed and configured correctly").action(async () => {
50281
- const homeDir2 = os49.homedir();
49918
+ const homeDir2 = os48.homedir();
50282
49919
  let failures = 0;
50283
49920
  function pass(msg) {
50284
49921
  console.log(chalk11.green(" \u2705 ") + msg);
@@ -50321,10 +49958,10 @@ function registerDoctorCommand(program2, version2) {
50321
49958
  warn("git not found", "Install git \u2014 node9 reads repo state for scans and reports");
50322
49959
  }
50323
49960
  section("Configuration");
50324
- const globalConfigPath = path53.join(homeDir2, ".node9", "config.json");
50325
- if (fs55.existsSync(globalConfigPath)) {
49961
+ const globalConfigPath = path52.join(homeDir2, ".node9", "config.json");
49962
+ if (fs54.existsSync(globalConfigPath)) {
50326
49963
  try {
50327
- JSON.parse(fs55.readFileSync(globalConfigPath, "utf-8"));
49964
+ JSON.parse(fs54.readFileSync(globalConfigPath, "utf-8"));
50328
49965
  pass("~/.node9/config.json found and valid");
50329
49966
  } catch {
50330
49967
  fail("~/.node9/config.json is invalid JSON", "Run: node9 init --force");
@@ -50339,10 +49976,10 @@ function registerDoctorCommand(program2, version2) {
50339
49976
  "Remove them when ready: node9 undo --purge"
50340
49977
  );
50341
49978
  }
50342
- const projectConfigPath = path53.join(process.cwd(), "node9.config.json");
50343
- if (fs55.existsSync(projectConfigPath)) {
49979
+ const projectConfigPath = path52.join(process.cwd(), "node9.config.json");
49980
+ if (fs54.existsSync(projectConfigPath)) {
50344
49981
  try {
50345
- JSON.parse(fs55.readFileSync(projectConfigPath, "utf-8"));
49982
+ JSON.parse(fs54.readFileSync(projectConfigPath, "utf-8"));
50346
49983
  pass("node9.config.json found and valid (project)");
50347
49984
  } catch {
50348
49985
  fail(
@@ -50351,8 +49988,8 @@ function registerDoctorCommand(program2, version2) {
50351
49988
  );
50352
49989
  }
50353
49990
  }
50354
- const credsPath = path53.join(homeDir2, ".node9", "credentials.json");
50355
- if (fs55.existsSync(credsPath)) {
49991
+ const credsPath = path52.join(homeDir2, ".node9", "credentials.json");
49992
+ if (fs54.existsSync(credsPath)) {
50356
49993
  pass("Cloud credentials found (~/.node9/credentials.json)");
50357
49994
  } else {
50358
49995
  warn(
@@ -50418,7 +50055,7 @@ function registerDoctorCommand(program2, version2) {
50418
50055
  cloudEnabled: !!getConfig().settings.approvers?.cloud
50419
50056
  });
50420
50057
  if (autostart) warn(autostart.message, autostart.hint);
50421
- if (fs55.existsSync(path53.join(os49.homedir(), ".node9", "credentials.json")) && getConfig().settings.approvers?.cloud) {
50058
+ if (fs54.existsSync(path52.join(os48.homedir(), ".node9", "credentials.json")) && getConfig().settings.approvers?.cloud) {
50422
50059
  section("Policy sync");
50423
50060
  const health = readSyncHealth();
50424
50061
  if (isPolicyStale(Date.now(), health)) {
@@ -50436,7 +50073,7 @@ function registerDoctorCommand(program2, version2) {
50436
50073
  try {
50437
50074
  const { shipLagBytes: shipLagBytes2, readWatermark: readWatermark2, AUDIT_SHIP_WATERMARK: AUDIT_SHIP_WATERMARK2 } = await Promise.resolve().then(() => (init_audit_shipper(), audit_shipper_exports));
50438
50075
  const cfg = getConfig();
50439
- const creds = fs55.existsSync(path53.join(os49.homedir(), ".node9", "credentials.json"));
50076
+ const creds = fs54.existsSync(path52.join(os48.homedir(), ".node9", "credentials.json"));
50440
50077
  if (!creds) {
50441
50078
  warn("Not logged in \u2014 audit rows stay local", "Run: node9 login <api-key>");
50442
50079
  } else if (!cfg.settings.approvers.cloud) {
@@ -50487,9 +50124,9 @@ function registerDoctorCommand(program2, version2) {
50487
50124
  // src/cli/commands/audit.ts
50488
50125
  init_decision();
50489
50126
  import chalk12 from "chalk";
50490
- import fs56 from "fs";
50491
- import path54 from "path";
50492
- import os50 from "os";
50127
+ import fs55 from "fs";
50128
+ import path53 from "path";
50129
+ import os49 from "os";
50493
50130
  function formatRelativeTime(timestamp) {
50494
50131
  const diff = Date.now() - new Date(timestamp).getTime();
50495
50132
  const sec = Math.floor(diff / 1e3);
@@ -50502,14 +50139,14 @@ function formatRelativeTime(timestamp) {
50502
50139
  }
50503
50140
  function registerAuditCommand(program2) {
50504
50141
  program2.command("audit").description("View local execution audit log").option("--tail <n>", "Number of entries to show", "20").option("--tool <pattern>", "Filter by tool name (substring match)").option("--deny", "Show only denied actions").option("--json", "Output raw JSON").action((options) => {
50505
- const logPath = path54.join(os50.homedir(), ".node9", "audit.log");
50506
- if (!fs56.existsSync(logPath)) {
50142
+ const logPath = path53.join(os49.homedir(), ".node9", "audit.log");
50143
+ if (!fs55.existsSync(logPath)) {
50507
50144
  console.log(
50508
50145
  chalk12.yellow("No audit logs found. Run node9 with an agent to generate entries.")
50509
50146
  );
50510
50147
  return;
50511
50148
  }
50512
- const raw = fs56.readFileSync(logPath, "utf-8");
50149
+ const raw = fs55.readFileSync(logPath, "utf-8");
50513
50150
  const lines = raw.split("\n").filter((l) => l.trim() !== "");
50514
50151
  let entries = lines.flatMap((line) => {
50515
50152
  try {
@@ -50575,9 +50212,9 @@ init_costSync();
50575
50212
  init_litellm();
50576
50213
  init_cost_codex();
50577
50214
  init_decision();
50578
- import fs57 from "fs";
50579
- import os51 from "os";
50580
- import path55 from "path";
50215
+ import fs56 from "fs";
50216
+ import os50 from "os";
50217
+ import path54 from "path";
50581
50218
  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;
50582
50219
  function buildTestTimestamps(allEntries) {
50583
50220
  const testTs = /* @__PURE__ */ new Set();
@@ -50657,8 +50294,8 @@ function getDateRange(period, now) {
50657
50294
  }
50658
50295
  }
50659
50296
  function parseAuditLog(logPath) {
50660
- if (!fs57.existsSync(logPath)) return [];
50661
- const raw = fs57.readFileSync(logPath, "utf-8");
50297
+ if (!fs56.existsSync(logPath)) return [];
50298
+ const raw = fs56.readFileSync(logPath, "utf-8");
50662
50299
  return raw.split("\n").flatMap((line) => {
50663
50300
  if (!line.trim()) return [];
50664
50301
  try {
@@ -50712,25 +50349,25 @@ function freezeClaudeCost(acc) {
50712
50349
  };
50713
50350
  }
50714
50351
  function processClaudeCostProject(proj, projectsDir, start, end, acc) {
50715
- const projPath = path55.join(projectsDir, proj);
50352
+ const projPath = path54.join(projectsDir, proj);
50716
50353
  let files;
50717
50354
  try {
50718
- const stat = fs57.statSync(projPath);
50355
+ const stat = fs56.statSync(projPath);
50719
50356
  if (!stat.isDirectory()) return;
50720
- files = fs57.readdirSync(projPath).filter((f) => f.endsWith(".jsonl") && !f.startsWith("agent-"));
50357
+ files = fs56.readdirSync(projPath).filter((f) => f.endsWith(".jsonl") && !f.startsWith("agent-"));
50721
50358
  } catch {
50722
50359
  return;
50723
50360
  }
50724
50361
  const startMs = start.getTime();
50725
50362
  for (const file of files) {
50726
- const filePath = path55.join(projPath, file);
50363
+ const filePath = path54.join(projPath, file);
50727
50364
  try {
50728
- if (fs57.statSync(filePath).mtimeMs < startMs) continue;
50365
+ if (fs56.statSync(filePath).mtimeMs < startMs) continue;
50729
50366
  } catch {
50730
50367
  continue;
50731
50368
  }
50732
50369
  try {
50733
- const raw = fs57.readFileSync(filePath, "utf-8");
50370
+ const raw = fs56.readFileSync(filePath, "utf-8");
50734
50371
  for (const line of raw.split("\n")) {
50735
50372
  if (!line.trim()) continue;
50736
50373
  let entry;
@@ -50780,10 +50417,10 @@ function processClaudeCostProject(proj, projectsDir, start, end, acc) {
50780
50417
  }
50781
50418
  function loadClaudeCost(start, end, projectsDir) {
50782
50419
  const acc = emptyClaudeCostAccumulator();
50783
- if (!fs57.existsSync(projectsDir)) return freezeClaudeCost(acc);
50420
+ if (!fs56.existsSync(projectsDir)) return freezeClaudeCost(acc);
50784
50421
  let dirs;
50785
50422
  try {
50786
- dirs = fs57.readdirSync(projectsDir);
50423
+ dirs = fs56.readdirSync(projectsDir);
50787
50424
  } catch {
50788
50425
  return freezeClaudeCost(acc);
50789
50426
  }
@@ -50795,7 +50432,7 @@ function loadClaudeCost(start, end, projectsDir) {
50795
50432
  function processCodexCostFile(filePath, start, end, acc) {
50796
50433
  let lines;
50797
50434
  try {
50798
- lines = fs57.readFileSync(filePath, "utf-8").split("\n");
50435
+ lines = fs56.readFileSync(filePath, "utf-8").split("\n");
50799
50436
  } catch {
50800
50437
  return;
50801
50438
  }
@@ -50850,31 +50487,31 @@ function processCodexCostFile(filePath, start, end, acc) {
50850
50487
  }
50851
50488
  function listCodexSessionFiles2(sessionsBase) {
50852
50489
  const jsonlFiles = [];
50853
- if (!fs57.existsSync(sessionsBase)) return jsonlFiles;
50490
+ if (!fs56.existsSync(sessionsBase)) return jsonlFiles;
50854
50491
  try {
50855
- for (const year of fs57.readdirSync(sessionsBase)) {
50856
- const yearPath = path55.join(sessionsBase, year);
50492
+ for (const year of fs56.readdirSync(sessionsBase)) {
50493
+ const yearPath = path54.join(sessionsBase, year);
50857
50494
  try {
50858
- if (!fs57.statSync(yearPath).isDirectory()) continue;
50495
+ if (!fs56.statSync(yearPath).isDirectory()) continue;
50859
50496
  } catch {
50860
50497
  continue;
50861
50498
  }
50862
- for (const month of fs57.readdirSync(yearPath)) {
50863
- const monthPath = path55.join(yearPath, month);
50499
+ for (const month of fs56.readdirSync(yearPath)) {
50500
+ const monthPath = path54.join(yearPath, month);
50864
50501
  try {
50865
- if (!fs57.statSync(monthPath).isDirectory()) continue;
50502
+ if (!fs56.statSync(monthPath).isDirectory()) continue;
50866
50503
  } catch {
50867
50504
  continue;
50868
50505
  }
50869
- for (const day of fs57.readdirSync(monthPath)) {
50870
- const dayPath = path55.join(monthPath, day);
50506
+ for (const day of fs56.readdirSync(monthPath)) {
50507
+ const dayPath = path54.join(monthPath, day);
50871
50508
  try {
50872
- if (!fs57.statSync(dayPath).isDirectory()) continue;
50509
+ if (!fs56.statSync(dayPath).isDirectory()) continue;
50873
50510
  } catch {
50874
50511
  continue;
50875
50512
  }
50876
- for (const file of fs57.readdirSync(dayPath)) {
50877
- if (file.endsWith(".jsonl")) jsonlFiles.push(path55.join(dayPath, file));
50513
+ for (const file of fs56.readdirSync(dayPath)) {
50514
+ if (file.endsWith(".jsonl")) jsonlFiles.push(path54.join(dayPath, file));
50878
50515
  }
50879
50516
  }
50880
50517
  }
@@ -50939,13 +50576,13 @@ function freezeGeminiCost(acc) {
50939
50576
  function processGeminiCostFile(filePath, projectKey, start, end, acc) {
50940
50577
  const startMs = start.getTime();
50941
50578
  try {
50942
- if (fs57.statSync(filePath).mtimeMs < startMs) return;
50579
+ if (fs56.statSync(filePath).mtimeMs < startMs) return;
50943
50580
  } catch {
50944
50581
  return;
50945
50582
  }
50946
50583
  let raw;
50947
50584
  try {
50948
- raw = fs57.readFileSync(filePath, "utf-8");
50585
+ raw = fs56.readFileSync(filePath, "utf-8");
50949
50586
  } catch {
50950
50587
  return;
50951
50588
  }
@@ -50994,30 +50631,30 @@ function listGeminiSessionFiles2(geminiTmpDir2) {
50994
50631
  const out = [];
50995
50632
  let dirs;
50996
50633
  try {
50997
- if (!fs57.statSync(geminiTmpDir2).isDirectory()) return out;
50998
- dirs = fs57.readdirSync(geminiTmpDir2);
50634
+ if (!fs56.statSync(geminiTmpDir2).isDirectory()) return out;
50635
+ dirs = fs56.readdirSync(geminiTmpDir2);
50999
50636
  } catch {
51000
50637
  return out;
51001
50638
  }
51002
50639
  for (const proj of dirs) {
51003
- const chatsDir = path55.join(geminiTmpDir2, proj, "chats");
50640
+ const chatsDir = path54.join(geminiTmpDir2, proj, "chats");
51004
50641
  let files;
51005
50642
  try {
51006
- if (!fs57.statSync(chatsDir).isDirectory()) continue;
51007
- files = fs57.readdirSync(chatsDir);
50643
+ if (!fs56.statSync(chatsDir).isDirectory()) continue;
50644
+ files = fs56.readdirSync(chatsDir);
51008
50645
  } catch {
51009
50646
  continue;
51010
50647
  }
51011
50648
  for (const f of files) {
51012
50649
  if (!f.endsWith(".jsonl")) continue;
51013
- out.push({ projectKey: proj, file: path55.join(chatsDir, f) });
50650
+ out.push({ projectKey: proj, file: path54.join(chatsDir, f) });
51014
50651
  }
51015
50652
  }
51016
50653
  return out;
51017
50654
  }
51018
50655
  function loadGeminiCost(start, end, geminiTmpDir2) {
51019
50656
  const acc = emptyGeminiAccumulator();
51020
- if (!fs57.existsSync(geminiTmpDir2)) return freezeGeminiCost(acc);
50657
+ if (!fs56.existsSync(geminiTmpDir2)) return freezeGeminiCost(acc);
51021
50658
  for (const { projectKey, file } of listGeminiSessionFiles2(geminiTmpDir2)) {
51022
50659
  processGeminiCostFile(file, projectKey, start, end, acc);
51023
50660
  }
@@ -51035,11 +50672,11 @@ function dimensionOfBlock(checkedBy, ruleName) {
51035
50672
  }
51036
50673
  function aggregateReportFromAudit(period, opts = {}) {
51037
50674
  const now = opts.now ?? /* @__PURE__ */ new Date();
51038
- const auditLogPath = opts.auditLogPath ?? path55.join(os51.homedir(), ".node9", "audit.log");
51039
- const claudeProjectsDir = opts.claudeProjectsDir ?? path55.join(os51.homedir(), ".claude", "projects");
51040
- const codexSessionsDir2 = opts.codexSessionsDir ?? path55.join(os51.homedir(), ".codex", "sessions");
51041
- const geminiTmpDir2 = opts.geminiTmpDir ?? path55.join(os51.homedir(), ".gemini", "tmp");
51042
- const hasAuditFile = fs57.existsSync(auditLogPath);
50675
+ const auditLogPath = opts.auditLogPath ?? path54.join(os50.homedir(), ".node9", "audit.log");
50676
+ const claudeProjectsDir = opts.claudeProjectsDir ?? path54.join(os50.homedir(), ".claude", "projects");
50677
+ const codexSessionsDir2 = opts.codexSessionsDir ?? path54.join(os50.homedir(), ".codex", "sessions");
50678
+ const geminiTmpDir2 = opts.geminiTmpDir ?? path54.join(os50.homedir(), ".gemini", "tmp");
50679
+ const hasAuditFile = fs56.existsSync(auditLogPath);
51043
50680
  const allEntries = opts.preloadedAuditEntries ?? parseAuditLog(auditLogPath);
51044
50681
  const unackedDlp = allEntries.filter((e) => e.source === "response-dlp");
51045
50682
  const { start, end } = getDateRange(period, now);
@@ -51748,8 +51385,8 @@ init_daemon();
51748
51385
  init_startup_log();
51749
51386
  init_daemon2();
51750
51387
  import chalk14 from "chalk";
51751
- import { spawn as spawn6 } from "child_process";
51752
- import fs58 from "fs";
51388
+ import { spawn as spawn5 } from "child_process";
51389
+ import fs57 from "fs";
51753
51390
  var VALID_ACTIONS = "start | stop | restart | status | install | uninstall";
51754
51391
  function registerDaemonCommand(program2) {
51755
51392
  program2.command("daemon").description("Manage the local approval daemon").argument("[action]", `${VALID_ACTIONS} (default: start)`).option("-b, --background", "Start the daemon in the background (detached)").option(
@@ -51792,7 +51429,7 @@ function registerDaemonCommand(program2) {
51792
51429
  }
51793
51430
  const restartFd = openStartupLogFd();
51794
51431
  recordStartupState("starting");
51795
- const child = spawn6(process.execPath, [process.argv[1], "daemon"], {
51432
+ const child = spawn5(process.execPath, [process.argv[1], "daemon"], {
51796
51433
  detached: true,
51797
51434
  stdio: ["ignore", "ignore", restartFd ?? "ignore"],
51798
51435
  env: { ...process.env, NODE9_AUTO_STARTED: "1" }
@@ -51804,7 +51441,7 @@ function registerDaemonCommand(program2) {
51804
51441
  child.unref();
51805
51442
  if (restartFd !== void 0) {
51806
51443
  try {
51807
- fs58.closeSync(restartFd);
51444
+ fs57.closeSync(restartFd);
51808
51445
  } catch {
51809
51446
  }
51810
51447
  }
@@ -51836,7 +51473,7 @@ function registerDaemonCommand(program2) {
51836
51473
  const startupFd = openStartupLogFd();
51837
51474
  try {
51838
51475
  recordStartupState("starting");
51839
- const child = spawn6(process.execPath, [process.argv[1], "daemon"], {
51476
+ const child = spawn5(process.execPath, [process.argv[1], "daemon"], {
51840
51477
  detached: true,
51841
51478
  // Capture the child's stderr: a module-load crash prints its stack there
51842
51479
  // and dies before it can record anything itself.
@@ -51855,7 +51492,7 @@ function registerDaemonCommand(program2) {
51855
51492
  } finally {
51856
51493
  if (startupFd !== void 0) {
51857
51494
  try {
51858
- fs58.closeSync(startupFd);
51495
+ fs57.closeSync(startupFd);
51859
51496
  } catch {
51860
51497
  }
51861
51498
  }
@@ -51875,9 +51512,9 @@ init_agent_wiring();
51875
51512
  init_sync();
51876
51513
  init_service();
51877
51514
  import chalk15 from "chalk";
51878
- import fs59 from "fs";
51879
- import path56 from "path";
51880
- import os52 from "os";
51515
+ import fs58 from "fs";
51516
+ import path55 from "path";
51517
+ import os51 from "os";
51881
51518
  function printAgentSection(label2, hookPairs, wrapped) {
51882
51519
  console.log(chalk15.bold(` ${label2}`));
51883
51520
  for (const { name, present } of hookPairs) {
@@ -51958,20 +51595,20 @@ function registerStatusCommand(program2) {
51958
51595
  console.log("");
51959
51596
  const modeLabel = settings.mode === "audit" ? chalk15.blue("audit") : settings.mode === "strict" ? chalk15.red("strict") : chalk15.white("standard");
51960
51597
  console.log(` Mode: ${modeLabel}`);
51961
- const projectConfig = path56.join(process.cwd(), "node9.config.json");
51962
- const globalConfig = path56.join(os52.homedir(), ".node9", "config.json");
51598
+ const projectConfig = path55.join(process.cwd(), "node9.config.json");
51599
+ const globalConfig = path55.join(os51.homedir(), ".node9", "config.json");
51963
51600
  console.log(
51964
- ` Local: ${fs59.existsSync(projectConfig) ? chalk15.green("Active (node9.config.json)") : chalk15.gray("Not present")}`
51601
+ ` Local: ${fs58.existsSync(projectConfig) ? chalk15.green("Active (node9.config.json)") : chalk15.gray("Not present")}`
51965
51602
  );
51966
51603
  console.log(
51967
- ` Global: ${fs59.existsSync(globalConfig) ? chalk15.green("Active (~/.node9/config.json)") : chalk15.gray("Not present")}`
51604
+ ` Global: ${fs58.existsSync(globalConfig) ? chalk15.green("Active (~/.node9/config.json)") : chalk15.gray("Not present")}`
51968
51605
  );
51969
51606
  if (mergedConfig.policy.sandboxPaths.length > 0) {
51970
51607
  console.log(
51971
51608
  ` Sandbox: ${chalk15.green(`${mergedConfig.policy.sandboxPaths.length} safe zones active`)}`
51972
51609
  );
51973
51610
  }
51974
- const wiring = getAgentWiring(os52.homedir()).filter((a) => a.present);
51611
+ const wiring = getAgentWiring(os51.homedir()).filter((a) => a.present);
51975
51612
  if (wiring.length > 0) {
51976
51613
  console.log("");
51977
51614
  console.log(chalk15.bold(" Agent Wiring:"));
@@ -52011,9 +51648,9 @@ init_shields();
52011
51648
  init_service();
52012
51649
  init_core();
52013
51650
  import chalk16 from "chalk";
52014
- import fs60 from "fs";
52015
- import path57 from "path";
52016
- import os53 from "os";
51651
+ import fs59 from "fs";
51652
+ import path56 from "path";
51653
+ import os52 from "os";
52017
51654
  import https6 from "https";
52018
51655
  var DEFAULT_SHIELDS = ["bash-safe", "filesystem", "project-jail"];
52019
51656
  function buildTelemetryPayload(agents, firstInstall) {
@@ -52099,16 +51736,16 @@ function registerInitCommand(program2) {
52099
51736
  }
52100
51737
  console.log("");
52101
51738
  }
52102
- const configPath = path57.join(os53.homedir(), ".node9", "config.json");
52103
- const isFirstInstall = !fs60.existsSync(configPath);
52104
- if (fs60.existsSync(configPath) && !options.force) {
51739
+ const configPath = path56.join(os52.homedir(), ".node9", "config.json");
51740
+ const isFirstInstall = !fs59.existsSync(configPath);
51741
+ if (fs59.existsSync(configPath) && !options.force) {
52105
51742
  try {
52106
- const existing = JSON.parse(fs60.readFileSync(configPath, "utf-8"));
51743
+ const existing = JSON.parse(fs59.readFileSync(configPath, "utf-8"));
52107
51744
  const settings = existing.settings ?? {};
52108
51745
  if (settings.mode !== chosenMode) {
52109
51746
  settings.mode = chosenMode;
52110
51747
  existing.settings = settings;
52111
- fs60.writeFileSync(configPath, JSON.stringify(existing, null, 2) + "\n");
51748
+ fs59.writeFileSync(configPath, JSON.stringify(existing, null, 2) + "\n");
52112
51749
  console.log(chalk16.green(`\u2705 Mode updated: ${chosenMode}`));
52113
51750
  } else {
52114
51751
  console.log(chalk16.blue(`\u2139\uFE0F Config already exists: ${configPath}`));
@@ -52121,9 +51758,9 @@ function registerInitCommand(program2) {
52121
51758
  ...DEFAULT_CONFIG,
52122
51759
  settings: { ...DEFAULT_CONFIG.settings, mode: chosenMode }
52123
51760
  };
52124
- const dir = path57.dirname(configPath);
52125
- if (!fs60.existsSync(dir)) fs60.mkdirSync(dir, { recursive: true });
52126
- fs60.writeFileSync(configPath, JSON.stringify(configToSave, null, 2) + "\n");
51761
+ const dir = path56.dirname(configPath);
51762
+ if (!fs59.existsSync(dir)) fs59.mkdirSync(dir, { recursive: true });
51763
+ fs59.writeFileSync(configPath, JSON.stringify(configToSave, null, 2) + "\n");
52127
51764
  console.log(chalk16.green(`\u2705 Config created: ${configPath}`));
52128
51765
  console.log(chalk16.gray(` Mode: ${chosenMode}`));
52129
51766
  }
@@ -52226,11 +51863,11 @@ init_agent_wiring();
52226
51863
  init_setup();
52227
51864
  init_hook_baseline();
52228
51865
  import chalk17 from "chalk";
52229
- import fs61 from "fs";
51866
+ import fs60 from "fs";
52230
51867
  var hasHookSurface = (a) => a.hooks.length > 0;
52231
51868
  function backupForHeal(file) {
52232
51869
  try {
52233
- if (file && fs61.existsSync(file)) fs61.copyFileSync(file, `${file}.node9-heal-bak`);
51870
+ if (file && fs60.existsSync(file)) fs60.copyFileSync(file, `${file}.node9-heal-bak`);
52234
51871
  } catch {
52235
51872
  }
52236
51873
  }
@@ -52465,7 +52102,7 @@ init_cloud();
52465
52102
  init_config();
52466
52103
  import readline3 from "readline";
52467
52104
  import chalk20 from "chalk";
52468
- import { spawn as spawn7 } from "child_process";
52105
+ import { spawn as spawn6 } from "child_process";
52469
52106
  import { execa as execa2 } from "execa";
52470
52107
  init_provenance();
52471
52108
  init_mcp_pin();
@@ -52594,7 +52231,7 @@ async function runMcpGateway(upstreamCommand, configName) {
52594
52231
  const safeEnv = Object.fromEntries(
52595
52232
  Object.entries(process.env).filter(([k]) => !UPSTREAM_INJECTOR_VARS.has(k))
52596
52233
  );
52597
- const child = spawn7(executable, cmdArgs, {
52234
+ const child = spawn6(executable, cmdArgs, {
52598
52235
  stdio: ["pipe", "pipe", "inherit"],
52599
52236
  // control stdin/stdout; inherit stderr
52600
52237
  shell: false,
@@ -52971,15 +52608,15 @@ init_core();
52971
52608
  init_daemon();
52972
52609
  init_shields();
52973
52610
  import readline4 from "readline";
52974
- import fs63 from "fs";
52975
- import os55 from "os";
52976
- import path59 from "path";
52977
- import { spawnSync as spawnSync4 } from "child_process";
52978
-
52979
- // src/auth/egress-config.ts
52980
52611
  import fs62 from "fs";
52981
52612
  import os54 from "os";
52982
52613
  import path58 from "path";
52614
+ import { spawnSync as spawnSync3 } from "child_process";
52615
+
52616
+ // src/auth/egress-config.ts
52617
+ import fs61 from "fs";
52618
+ import os53 from "os";
52619
+ import path57 from "path";
52983
52620
  var DEFAULT_EGRESS = {
52984
52621
  enabled: false,
52985
52622
  mode: "review",
@@ -52988,12 +52625,12 @@ var DEFAULT_EGRESS = {
52988
52625
  allowPrivate: true
52989
52626
  };
52990
52627
  function egressConfigPath() {
52991
- return path58.join(os54.homedir(), ".node9", "config.json");
52628
+ return path57.join(os53.homedir(), ".node9", "config.json");
52992
52629
  }
52993
52630
  function readEgressRawConfig() {
52994
52631
  let text;
52995
52632
  try {
52996
- text = fs62.readFileSync(egressConfigPath(), "utf8");
52633
+ text = fs61.readFileSync(egressConfigPath(), "utf8");
52997
52634
  } catch (err2) {
52998
52635
  if (err2.code === "ENOENT") return {};
52999
52636
  throw err2;
@@ -53008,8 +52645,8 @@ function readEgressRawConfig() {
53008
52645
  }
53009
52646
  function writeEgressRawConfig(config) {
53010
52647
  const p = egressConfigPath();
53011
- fs62.mkdirSync(path58.dirname(p), { recursive: true });
53012
- fs62.writeFileSync(p, JSON.stringify(config, null, 2) + "\n", { mode: 384 });
52648
+ fs61.mkdirSync(path57.dirname(p), { recursive: true });
52649
+ fs61.writeFileSync(p, JSON.stringify(config, null, 2) + "\n", { mode: 384 });
53013
52650
  }
53014
52651
  function applyEgress(config, change) {
53015
52652
  const policy = config.policy = config.policy ?? {};
@@ -53343,13 +52980,13 @@ function handleStatus() {
53343
52980
  lines.push(`Active shields: ${activeShields.length > 0 ? activeShields.join(", ") : "none"}`);
53344
52981
  lines.push(`Smart rules: ${config.policy.smartRules.length} loaded`);
53345
52982
  lines.push(`DLP: ${config.policy.dlp?.enabled !== false ? "enabled" : "disabled"}`);
53346
- const projectConfig = path59.join(process.cwd(), "node9.config.json");
53347
- const globalConfig = path59.join(os55.homedir(), ".node9", "config.json");
52983
+ const projectConfig = path58.join(process.cwd(), "node9.config.json");
52984
+ const globalConfig = path58.join(os54.homedir(), ".node9", "config.json");
53348
52985
  lines.push(
53349
- `Project config (node9.config.json): ${fs63.existsSync(projectConfig) ? "present" : "not found"}`
52986
+ `Project config (node9.config.json): ${fs62.existsSync(projectConfig) ? "present" : "not found"}`
53350
52987
  );
53351
52988
  lines.push(
53352
- `Global config (~/.node9/config.json): ${fs63.existsSync(globalConfig) ? "present" : "not found"}`
52989
+ `Global config (~/.node9/config.json): ${fs62.existsSync(globalConfig) ? "present" : "not found"}`
53353
52990
  );
53354
52991
  return lines.join("\n");
53355
52992
  }
@@ -53454,21 +53091,21 @@ function handleEgressDeny(args) {
53454
53091
  addEgressHost("deny", host);
53455
53092
  return `Denied egress to ${host} (deny always wins over allow).`;
53456
53093
  }
53457
- var GLOBAL_CONFIG_PATH = path59.join(os55.homedir(), ".node9", "config.json");
53094
+ var GLOBAL_CONFIG_PATH = path58.join(os54.homedir(), ".node9", "config.json");
53458
53095
  var APPROVER_CHANNELS = ["native", "browser", "cloud", "terminal"];
53459
53096
  function readGlobalConfigRaw() {
53460
53097
  try {
53461
- if (fs63.existsSync(GLOBAL_CONFIG_PATH)) {
53462
- return JSON.parse(fs63.readFileSync(GLOBAL_CONFIG_PATH, "utf-8"));
53098
+ if (fs62.existsSync(GLOBAL_CONFIG_PATH)) {
53099
+ return JSON.parse(fs62.readFileSync(GLOBAL_CONFIG_PATH, "utf-8"));
53463
53100
  }
53464
53101
  } catch {
53465
53102
  }
53466
53103
  return {};
53467
53104
  }
53468
53105
  function writeGlobalConfigRaw(data) {
53469
- const dir = path59.dirname(GLOBAL_CONFIG_PATH);
53470
- if (!fs63.existsSync(dir)) fs63.mkdirSync(dir, { recursive: true });
53471
- fs63.writeFileSync(GLOBAL_CONFIG_PATH, JSON.stringify(data, null, 2) + "\n");
53106
+ const dir = path58.dirname(GLOBAL_CONFIG_PATH);
53107
+ if (!fs62.existsSync(dir)) fs62.mkdirSync(dir, { recursive: true });
53108
+ fs62.writeFileSync(GLOBAL_CONFIG_PATH, JSON.stringify(data, null, 2) + "\n");
53472
53109
  }
53473
53110
  function handleApproverList() {
53474
53111
  const config = getConfig();
@@ -53512,9 +53149,9 @@ function handleApproverSet(args) {
53512
53149
  function handleAuditGet(args) {
53513
53150
  const limit = Math.min(typeof args.limit === "number" ? args.limit : 20, 100);
53514
53151
  const filter = typeof args.filter === "string" && args.filter !== "all" ? args.filter : null;
53515
- const auditPath = path59.join(os55.homedir(), ".node9", "audit.log");
53516
- if (!fs63.existsSync(auditPath)) return "No audit log found.";
53517
- const rawLines = fs63.readFileSync(auditPath, "utf-8").trim().split("\n").filter(Boolean);
53152
+ const auditPath = path58.join(os54.homedir(), ".node9", "audit.log");
53153
+ if (!fs62.existsSync(auditPath)) return "No audit log found.";
53154
+ const rawLines = fs62.readFileSync(auditPath, "utf-8").trim().split("\n").filter(Boolean);
53518
53155
  const wanted = filter === "block" ? "deny" : filter;
53519
53156
  const parsed = [];
53520
53157
  for (const line of rawLines) {
@@ -53600,7 +53237,7 @@ function handleRuleAdd(args) {
53600
53237
  return `Rule "${name}" added to ~/.node9/config.json \u2014 verdict: ${verdict} when ${field} matches "${pattern}"`;
53601
53238
  }
53602
53239
  function runCliCommand(subArgs) {
53603
- const result = spawnSync4(process.execPath, [process.argv[1], ...subArgs], {
53240
+ const result = spawnSync3(process.execPath, [process.argv[1], ...subArgs], {
53604
53241
  encoding: "utf-8",
53605
53242
  timeout: 6e4,
53606
53243
  // Disable colors — stdout is piped (not a TTY), chalk auto-detects, but be explicit
@@ -53816,7 +53453,7 @@ function registerTrustCommand(program2) {
53816
53453
  // src/cli/commands/mcp-pin.ts
53817
53454
  init_mcp_pin();
53818
53455
  import chalk23 from "chalk";
53819
- import fs64 from "fs";
53456
+ import fs63 from "fs";
53820
53457
 
53821
53458
  // src/cli/commands/mcp-gateway-cmd.ts
53822
53459
  init_mcp_wrap();
@@ -54024,7 +53661,7 @@ function registerMcpPinCommand(program2) {
54024
53661
  let repoCorrupt = false;
54025
53662
  if (found.source === "repo") {
54026
53663
  try {
54027
- const raw = fs64.readFileSync(found.path, "utf-8");
53664
+ const raw = fs63.readFileSync(found.path, "utf-8");
54028
53665
  const parsed = JSON.parse(raw);
54029
53666
  repoEntries = parsed.servers ?? {};
54030
53667
  } catch {
@@ -54618,8 +54255,8 @@ import chalk29 from "chalk";
54618
54255
 
54619
54256
  // src/ci-check/fetch.ts
54620
54257
  var import_undici = __toESM(require_undici());
54621
- import fs65 from "fs";
54622
- import path60 from "path";
54258
+ import fs64 from "fs";
54259
+ import path59 from "path";
54623
54260
  import { execFileSync as execFileSync2 } from "child_process";
54624
54261
  var cachedGhToken;
54625
54262
  function resolveGitHubToken() {
@@ -54702,7 +54339,7 @@ function parseRepoUrl(input) {
54702
54339
  function isLocalPath(input) {
54703
54340
  if (input.startsWith(".") || input.startsWith("/") || input.startsWith("~")) return true;
54704
54341
  try {
54705
- return fs65.existsSync(input) && fs65.statSync(input).isDirectory();
54342
+ return fs64.existsSync(input) && fs64.statSync(input).isDirectory();
54706
54343
  } catch {
54707
54344
  return false;
54708
54345
  }
@@ -54817,10 +54454,10 @@ function readLocalTree(dir) {
54817
54454
  const files = [];
54818
54455
  const notes = [];
54819
54456
  const add = (rel) => {
54820
- const abs = path60.join(root, rel);
54457
+ const abs = path59.join(root, rel);
54821
54458
  try {
54822
- if (fs65.existsSync(abs) && fs65.statSync(abs).isFile()) {
54823
- files.push({ path: rel, content: fs65.readFileSync(abs, "utf8") });
54459
+ if (fs64.existsSync(abs) && fs64.statSync(abs).isFile()) {
54460
+ files.push({ path: rel, content: fs64.readFileSync(abs, "utf8") });
54824
54461
  }
54825
54462
  } catch {
54826
54463
  }
@@ -54840,7 +54477,7 @@ function readLocalTree(dir) {
54840
54477
  dirsVisited++;
54841
54478
  let entries;
54842
54479
  try {
54843
- entries = fs65.readdirSync(path60.join(root, relDir), { withFileTypes: true });
54480
+ entries = fs64.readdirSync(path59.join(root, relDir), { withFileTypes: true });
54844
54481
  } catch {
54845
54482
  return;
54846
54483
  }
@@ -54861,11 +54498,11 @@ function readLocalTree(dir) {
54861
54498
  `repo is large \u2014 some agent-surface files may be INCOMPLETE (capped at ${MAX_SURFACE_FILES} files / ${MAX_DIRS} dirs).`
54862
54499
  );
54863
54500
  for (const rel of matches) collect(rel);
54864
- const wfDir = path60.join(root, WORKFLOW_DIR);
54501
+ const wfDir = path59.join(root, WORKFLOW_DIR);
54865
54502
  try {
54866
- if (fs65.existsSync(wfDir)) {
54867
- for (const name of fs65.readdirSync(wfDir)) {
54868
- if (/\.ya?ml$/.test(name)) add(path60.join(WORKFLOW_DIR, name));
54503
+ if (fs64.existsSync(wfDir)) {
54504
+ for (const name of fs64.readdirSync(wfDir)) {
54505
+ if (/\.ya?ml$/.test(name)) add(path59.join(WORKFLOW_DIR, name));
54869
54506
  }
54870
54507
  }
54871
54508
  } catch {
@@ -55170,7 +54807,7 @@ function severityFromScore(score) {
55170
54807
  if (score >= 1) return "advisory";
55171
54808
  return null;
55172
54809
  }
55173
- function analyzeWorkflow(path72, content) {
54810
+ function analyzeWorkflow(path71, content) {
55174
54811
  let raw;
55175
54812
  try {
55176
54813
  raw = parseYaml(content) ?? {};
@@ -55296,7 +54933,7 @@ function analyzeWorkflow(path72, content) {
55296
54933
  dimension: "workflows",
55297
54934
  severity,
55298
54935
  title,
55299
- file: path72,
54936
+ file: path71,
55300
54937
  signals,
55301
54938
  mitigations: mitigations.length ? mitigations : void 0,
55302
54939
  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."
@@ -55372,7 +55009,7 @@ function evalAgentJob(job, wf, raw, untrustedTrigger, reusable) {
55372
55009
  if (reusable && !loadedGun && SEVERITY_RANK2[severity] > SEVERITY_RANK2.medium) severity = "medium";
55373
55010
  return { severity, secrets, injectable, canReadEnv };
55374
55011
  }
55375
- function analyzeWorkflowSecrets(path72, content) {
55012
+ function analyzeWorkflowSecrets(path71, content) {
55376
55013
  let raw;
55377
55014
  try {
55378
55015
  raw = parseYaml(content) ?? {};
@@ -55392,7 +55029,7 @@ function analyzeWorkflowSecrets(path72, content) {
55392
55029
  dimension: "data",
55393
55030
  severity: worst.severity,
55394
55031
  title: worst.severity === "advisory" ? "Secrets reachable by the agent \u2014 hardening" : "Exfiltratable secrets reachable by an injectable agent",
55395
- file: path72,
55032
+ file: path71,
55396
55033
  signals: [
55397
55034
  `agent can reach: ${worst.secrets.map((s) => s.name).join(", ")}`,
55398
55035
  worst.injectable ? "the agent is externally triggerable (untrusted trigger, no gate)" : "gated / not externally triggerable \u2014 latent risk only",
@@ -55419,7 +55056,7 @@ function hookCommands(hooks) {
55419
55056
  }
55420
55057
  return out;
55421
55058
  }
55422
- function analyzeAgentConfig(path72, content) {
55059
+ function analyzeAgentConfig(path71, content) {
55423
55060
  let cfg;
55424
55061
  try {
55425
55062
  cfg = JSON.parse(content);
@@ -55438,7 +55075,7 @@ function analyzeAgentConfig(path72, content) {
55438
55075
  dimension: "toolRules",
55439
55076
  severity: high ? "high" : "medium",
55440
55077
  title: high ? "Agent hook runs UNPINNED/remote third-party code on every action" : "Agent hook runs third-party code in the agent hot path",
55441
- file: path72,
55078
+ file: path71,
55442
55079
  signals: [
55443
55080
  `hook command: \`${cmd.slice(0, 120)}\``,
55444
55081
  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"
@@ -55458,7 +55095,7 @@ function analyzeAgentConfig(path72, content) {
55458
55095
  dimension: "toolRules",
55459
55096
  severity: hasBackstop ? "medium" : "high",
55460
55097
  title: hasBackstop ? "Committed agent config pre-authorizes broad tools" : "Committed agent config pre-authorizes broad tools with no deny backstop",
55461
- file: path72,
55098
+ file: path71,
55462
55099
  signals: [
55463
55100
  `broad allow(s): ${broad.slice(0, 5).join(", ")}`,
55464
55101
  hasBackstop ? "a `deny` list backstops the broad allow" : "no `deny` entry covers Bash/Write/Edit \u2014 every contributor is pre-authorized for catastrophic tools"
@@ -55471,16 +55108,16 @@ function analyzeAgentConfig(path72, content) {
55471
55108
 
55472
55109
  // src/ci-check/mcp.ts
55473
55110
  init_dist();
55474
- function analyzeMcp(path72, content) {
55111
+ function analyzeMcp(path71, content) {
55475
55112
  let cfg;
55476
55113
  try {
55477
55114
  cfg = JSON.parse(content);
55478
55115
  } catch {
55479
55116
  return [];
55480
55117
  }
55481
- return analyzeMcpServers(cfg.mcpServers ?? {}, path72);
55118
+ return analyzeMcpServers(cfg.mcpServers ?? {}, path71);
55482
55119
  }
55483
- function analyzeMcpServers(servers, path72) {
55120
+ function analyzeMcpServers(servers, path71) {
55484
55121
  const findings = [];
55485
55122
  for (const [name, srv] of Object.entries(servers ?? {})) {
55486
55123
  if (!srv || srv.disabled) continue;
@@ -55491,7 +55128,7 @@ function analyzeMcpServers(servers, path72) {
55491
55128
  dimension: "mcp",
55492
55129
  severity: "medium",
55493
55130
  title: `MCP server "${name}" runs an unpinned executable`,
55494
- file: path72,
55131
+ file: path71,
55495
55132
  signals: [`\`${argv.slice(0, 120)}\` \u2014 unversioned/@latest npx`],
55496
55133
  fix: "Pin the MCP server package to an exact version so a PR (or a registry compromise) can\u2019t swap the toolchain."
55497
55134
  });
@@ -55505,7 +55142,7 @@ function analyzeMcpServers(servers, path72) {
55505
55142
  dimension: "mcp",
55506
55143
  severity: "high",
55507
55144
  title: `MCP server "${name}" has an inline credential`,
55508
- file: path72,
55145
+ file: path71,
55509
55146
  signals: [
55510
55147
  `env.${k} matches ${hit.patternName} \u2014 agent-reachable secret committed to the repo`
55511
55148
  ],
@@ -55519,7 +55156,7 @@ function analyzeMcpServers(servers, path72) {
55519
55156
 
55520
55157
  // src/ci-check/codex.ts
55521
55158
  import { parse as parseToml5 } from "smol-toml";
55522
- function analyzeCodexConfig(path72, content) {
55159
+ function analyzeCodexConfig(path71, content) {
55523
55160
  let cfg;
55524
55161
  try {
55525
55162
  cfg = parseToml5(content);
@@ -55527,7 +55164,7 @@ function analyzeCodexConfig(path72, content) {
55527
55164
  return [];
55528
55165
  }
55529
55166
  const findings = [];
55530
- findings.push(...analyzeMcpServers(cfg.mcp_servers ?? {}, path72));
55167
+ findings.push(...analyzeMcpServers(cfg.mcp_servers ?? {}, path71));
55531
55168
  const sandbox = typeof cfg.sandbox_mode === "string" ? cfg.sandbox_mode : "";
55532
55169
  const approval = typeof cfg.approval_policy === "string" ? cfg.approval_policy : "";
55533
55170
  const fullAccess = /danger-full-access/i.test(sandbox);
@@ -55542,7 +55179,7 @@ function analyzeCodexConfig(path72, content) {
55542
55179
  dimension: "toolRules",
55543
55180
  severity: fullAccess ? "high" : "medium",
55544
55181
  title: fullAccess ? "Codex config grants a full-access sandbox" : "Codex config never requires approval",
55545
- file: path72,
55182
+ file: path71,
55546
55183
  signals,
55547
55184
  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.'
55548
55185
  });
@@ -55598,10 +55235,10 @@ function decodeSuspiciousBase64(text) {
55598
55235
  }
55599
55236
  return out;
55600
55237
  }
55601
- function mk(severity, title, signals, fix, path72) {
55602
- return { check: "CI-6", dimension: "instructions", severity, title, file: path72, signals, fix };
55238
+ function mk(severity, title, signals, fix, path71) {
55239
+ return { check: "CI-6", dimension: "instructions", severity, title, file: path71, signals, fix };
55603
55240
  }
55604
- function analyzeInstructionFile(path72, content) {
55241
+ function analyzeInstructionFile(path71, content) {
55605
55242
  const findings = [];
55606
55243
  const decoded = decodeSuspiciousBase64(content);
55607
55244
  if (TAG_CHARS.test(content))
@@ -55613,7 +55250,7 @@ function analyzeInstructionFile(path72, content) {
55613
55250
  "contains Unicode tag characters (U+E0000\u2013E007F) \u2014 an invisible instruction-smuggling channel with no legitimate use in text"
55614
55251
  ],
55615
55252
  "Remove the tag characters. Instruction files must be plain, reviewable text.",
55616
- path72
55253
+ path71
55617
55254
  )
55618
55255
  );
55619
55256
  if (BIDI_OVERRIDE.test(content))
@@ -55625,7 +55262,7 @@ function analyzeInstructionFile(path72, content) {
55625
55262
  "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"
55626
55263
  ],
55627
55264
  "Remove the bidi override characters.",
55628
- path72
55265
+ path71
55629
55266
  )
55630
55267
  );
55631
55268
  else if (BIDI_EMBED_ISOLATE.test(content))
@@ -55637,7 +55274,7 @@ function analyzeInstructionFile(path72, content) {
55637
55274
  "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"
55638
55275
  ],
55639
55276
  "Confirm the bidi marks are legitimate RTL formatting; remove otherwise.",
55640
- path72
55277
+ path71
55641
55278
  )
55642
55279
  );
55643
55280
  const zw = suspiciousZeroWidth(content);
@@ -55651,7 +55288,7 @@ function analyzeInstructionFile(path72, content) {
55651
55288
  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)"
55652
55289
  ],
55653
55290
  "Remove the zero-width characters. Instruction files must be plain, reviewable text.",
55654
- path72
55291
+ path71
55655
55292
  )
55656
55293
  );
55657
55294
  }
@@ -55667,7 +55304,7 @@ function analyzeInstructionFile(path72, content) {
55667
55304
  `contains a prompt-override / role-impersonation directive (\`${m[0].slice(0, 60).trim()}\`)${ovEnc ? " \u2014 concealed in a base64 blob" : ""}`
55668
55305
  ],
55669
55306
  "Remove the override text. An instruction file should not tell the agent to ignore its own rules.",
55670
- path72
55307
+ path71
55671
55308
  )
55672
55309
  );
55673
55310
  }
@@ -55679,7 +55316,7 @@ function analyzeInstructionFile(path72, content) {
55679
55316
  "Instruction directs the agent to fetch and run remote code",
55680
55317
  [`\`${fo[0].slice(0, 70).trim()}\` \u2014 fetch-and-obey, outside an install/setup section`],
55681
55318
  "Do not instruct the agent to pipe remote content into a shell; pin and vendor scripts instead.",
55682
- path72
55319
+ path71
55683
55320
  )
55684
55321
  );
55685
55322
  }
@@ -55691,7 +55328,7 @@ function analyzeInstructionFile(path72, content) {
55691
55328
  "Instruction points the agent at credential material",
55692
55329
  [`references \`${sp[0].slice(0, 50).trim()}\` \u2014 directs the agent toward secrets`],
55693
55330
  "Do not reference credential files or paths in agent instructions.",
55694
- path72
55331
+ path71
55695
55332
  )
55696
55333
  );
55697
55334
  }
@@ -55703,7 +55340,7 @@ function analyzeInstructionFile(path72, content) {
55703
55340
  "Instruction directs the agent to send data to an external endpoint",
55704
55341
  [`\`${ex[0].slice(0, 70).trim()}\` \u2014 possible exfiltration directive`],
55705
55342
  "Remove external post/upload directives from agent instructions.",
55706
- path72
55343
+ path71
55707
55344
  )
55708
55345
  );
55709
55346
  }
@@ -56100,13 +55737,13 @@ function registerJailCommand(program2) {
56100
55737
  // src/cli/commands/sandbox.ts
56101
55738
  init_config();
56102
55739
  import chalk32 from "chalk";
56103
- import fs68 from "fs";
56104
- import path63 from "path";
56105
- import { spawnSync as spawnSync6 } from "child_process";
55740
+ import fs67 from "fs";
55741
+ import path62 from "path";
55742
+ import { spawnSync as spawnSync5 } from "child_process";
56106
55743
 
56107
55744
  // src/sandbox/config.ts
56108
- import fs66 from "fs";
56109
- import path61 from "path";
55745
+ import fs65 from "fs";
55746
+ import path60 from "path";
56110
55747
  import { parse as parseYaml2, stringify as stringifyYaml } from "yaml";
56111
55748
  var SANDBOX_CONFIG_FILE = "node9.sandbox.yaml";
56112
55749
  var FORBIDDEN_ENV = /* @__PURE__ */ new Set(["NODE9_API_KEY", "NODE9_API_URL"]);
@@ -56179,16 +55816,16 @@ function scaffoldSandboxYaml(agent) {
56179
55816
  return header + stringifyYaml(defaultSandboxConfig(agent));
56180
55817
  }
56181
55818
  function sandboxConfigPath(cwd = process.cwd()) {
56182
- return path61.join(cwd, SANDBOX_CONFIG_FILE);
55819
+ return path60.join(cwd, SANDBOX_CONFIG_FILE);
56183
55820
  }
56184
55821
  function loadSandboxConfig(cwd = process.cwd(), fallbackAgent = "claude") {
56185
55822
  const p = sandboxConfigPath(cwd);
56186
- if (!fs66.existsSync(p)) {
55823
+ if (!fs65.existsSync(p)) {
56187
55824
  throw new Error(`sandbox: ${SANDBOX_CONFIG_FILE} not found \u2014 run \`node9 sandbox new\` first.`);
56188
55825
  }
56189
55826
  let raw;
56190
55827
  try {
56191
- raw = parseYaml2(fs66.readFileSync(p, "utf-8"));
55828
+ raw = parseYaml2(fs65.readFileSync(p, "utf-8"));
56192
55829
  } catch (err2) {
56193
55830
  throw new Error(
56194
55831
  `sandbox: ${SANDBOX_CONFIG_FILE} is not valid YAML \u2014 ${err2.message}`
@@ -56247,16 +55884,16 @@ init_templates();
56247
55884
 
56248
55885
  // src/sandbox/runtime.ts
56249
55886
  init_templates();
56250
- import fs67 from "fs";
56251
- import os56 from "os";
56252
- import path62 from "path";
56253
- import crypto9 from "crypto";
56254
- import { spawnSync as spawnSync5 } from "child_process";
55887
+ import fs66 from "fs";
55888
+ import os55 from "os";
55889
+ import path61 from "path";
55890
+ import crypto8 from "crypto";
55891
+ import { spawnSync as spawnSync4 } from "child_process";
56255
55892
  function sandboxDataDir(cwd = process.cwd()) {
56256
- return path62.join(cwd, ".node9", "sandbox", "data");
55893
+ return path61.join(cwd, ".node9", "sandbox", "data");
56257
55894
  }
56258
55895
  function detectEngine(engine) {
56259
- const r = spawnSync5(engine, ["--version"], { encoding: "utf-8" });
55896
+ const r = spawnSync4(engine, ["--version"], { encoding: "utf-8" });
56260
55897
  if (r.status === 0 && typeof r.stdout === "string") {
56261
55898
  return { available: true, version: r.stdout.trim() };
56262
55899
  }
@@ -56264,7 +55901,7 @@ function detectEngine(engine) {
56264
55901
  }
56265
55902
  function agentCredentialsMount(agent) {
56266
55903
  const rel = agent === "codex" ? ".codex/auth.json" : ".claude/.credentials.json";
56267
- return { hostPath: path62.join(os56.homedir(), rel), target: `/home/${RUN_AS_USER}/${rel}` };
55904
+ return { hostPath: path61.join(os55.homedir(), rel), target: `/home/${RUN_AS_USER}/${rel}` };
56268
55905
  }
56269
55906
  function buildRunArgs(opts) {
56270
55907
  const { config, workspaceHostPath, dataHostPath, allowlistHostPath, agentArgs } = opts;
@@ -56274,7 +55911,7 @@ function buildRunArgs(opts) {
56274
55911
  args.push("-v", `${allowlistHostPath}:${ALLOWED_DOMAINS_PATH}:ro`);
56275
55912
  if (config.node9.mountAgentCredentials) {
56276
55913
  const creds = agentCredentialsMount(config.agent);
56277
- if (fs67.existsSync(creds.hostPath)) {
55914
+ if (fs66.existsSync(creds.hostPath)) {
56278
55915
  args.push("-v", `${creds.hostPath}:${creds.target}`);
56279
55916
  }
56280
55917
  }
@@ -56289,33 +55926,33 @@ function buildRunArgs(opts) {
56289
55926
  return args;
56290
55927
  }
56291
55928
  function imageContentHash(dockerfile, entrypoint) {
56292
- return crypto9.createHash("sha256").update(dockerfile).update("\0").update(entrypoint).digest("hex").slice(0, 16);
55929
+ return crypto8.createHash("sha256").update(dockerfile).update("\0").update(entrypoint).digest("hex").slice(0, 16);
56293
55930
  }
56294
55931
  function sandboxBuildDir(cwd = process.cwd()) {
56295
- return path62.join(cwd, ".node9", "sandbox", "build");
55932
+ return path61.join(cwd, ".node9", "sandbox", "build");
56296
55933
  }
56297
55934
  function writeBuildContext(cwd, dockerfile, entrypoint) {
56298
55935
  const dir = sandboxBuildDir(cwd);
56299
- fs67.mkdirSync(dir, { recursive: true });
56300
- fs67.writeFileSync(path62.join(dir, "Dockerfile"), dockerfile);
56301
- fs67.writeFileSync(path62.join(dir, "entrypoint.sh"), entrypoint);
55936
+ fs66.mkdirSync(dir, { recursive: true });
55937
+ fs66.writeFileSync(path61.join(dir, "Dockerfile"), dockerfile);
55938
+ fs66.writeFileSync(path61.join(dir, "entrypoint.sh"), entrypoint);
56302
55939
  return dir;
56303
55940
  }
56304
55941
  function writeAllowlist(cwd, hosts) {
56305
- const dir = path62.join(cwd, ".node9", "sandbox");
56306
- fs67.mkdirSync(dir, { recursive: true });
56307
- const p = path62.join(dir, "allowed-domains.txt");
56308
- fs67.writeFileSync(p, hosts.join("\n") + "\n");
55942
+ const dir = path61.join(cwd, ".node9", "sandbox");
55943
+ fs66.mkdirSync(dir, { recursive: true });
55944
+ const p = path61.join(dir, "allowed-domains.txt");
55945
+ fs66.writeFileSync(p, hosts.join("\n") + "\n");
56309
55946
  return p;
56310
55947
  }
56311
55948
  function resolveHomePath(p) {
56312
- return p.startsWith("~") ? path62.join(os56.homedir(), p.slice(1)) : path62.resolve(p);
55949
+ return p.startsWith("~") ? path61.join(os55.homedir(), p.slice(1)) : path61.resolve(p);
56313
55950
  }
56314
55951
 
56315
55952
  // src/cli/commands/sandbox.ts
56316
55953
  function seedDataDirConfig(dataDir, sandbox) {
56317
- fs68.mkdirSync(dataDir, { recursive: true });
56318
- const configPath = path63.join(dataDir, "config.json");
55954
+ fs67.mkdirSync(dataDir, { recursive: true });
55955
+ const configPath = path62.join(dataDir, "config.json");
56319
55956
  const seed = {
56320
55957
  settings: {
56321
55958
  approvers: {
@@ -56326,7 +55963,7 @@ function seedDataDirConfig(dataDir, sandbox) {
56326
55963
  }
56327
55964
  }
56328
55965
  };
56329
- fs68.writeFileSync(configPath, JSON.stringify(seed, null, 2), { mode: 384 });
55966
+ fs67.writeFileSync(configPath, JSON.stringify(seed, null, 2), { mode: 384 });
56330
55967
  }
56331
55968
  function registerSandboxCommand(program2, version2) {
56332
55969
  const node9Version2 = pinnedNode9Version(version2);
@@ -56334,13 +55971,13 @@ function registerSandboxCommand(program2, version2) {
56334
55971
  cmd.command("new").description(`Scaffold ${SANDBOX_CONFIG_FILE} in this project`).option("--agent <agent>", "claude (default) or codex", "claude").action((opts) => {
56335
55972
  const agent = opts.agent === "codex" ? "codex" : "claude";
56336
55973
  const p = sandboxConfigPath();
56337
- if (fs68.existsSync(p)) {
55974
+ if (fs67.existsSync(p)) {
56338
55975
  console.log(
56339
55976
  chalk32.yellow(` ${SANDBOX_CONFIG_FILE} already exists \u2014 leaving it untouched.`)
56340
55977
  );
56341
55978
  return;
56342
55979
  }
56343
- fs68.writeFileSync(p, scaffoldSandboxYaml(agent));
55980
+ fs67.writeFileSync(p, scaffoldSandboxYaml(agent));
56344
55981
  console.log(
56345
55982
  chalk32.green(` \u2713 wrote ${SANDBOX_CONFIG_FILE}`) + chalk32.dim(` (agent: ${agent})`)
56346
55983
  );
@@ -56380,20 +56017,20 @@ function registerSandboxCommand(program2, version2) {
56380
56017
  const buildDir = writeBuildContext(cwd, dockerfile, entrypoint);
56381
56018
  const hash = imageContentHash(dockerfile, entrypoint);
56382
56019
  const image = sandbox.runtime.image;
56383
- const hashFile = path63.join(sandboxBuildDir(cwd), ".image-hash");
56384
- const lastHash = fs68.existsSync(hashFile) ? fs68.readFileSync(hashFile, "utf-8").trim() : "";
56385
- const imageExists = spawnSync6(sandbox.runtime.engine, ["image", "inspect", image], { stdio: "ignore" }).status === 0;
56020
+ const hashFile = path62.join(sandboxBuildDir(cwd), ".image-hash");
56021
+ const lastHash = fs67.existsSync(hashFile) ? fs67.readFileSync(hashFile, "utf-8").trim() : "";
56022
+ const imageExists = spawnSync5(sandbox.runtime.engine, ["image", "inspect", image], { stdio: "ignore" }).status === 0;
56386
56023
  const needBuild = sandbox.runtime.rebuild === "always" || !imageExists || sandbox.runtime.rebuild !== "never" && lastHash !== hash;
56387
56024
  if (needBuild) {
56388
56025
  console.log(chalk32.dim(` building ${image} \u2026`));
56389
- const b = spawnSync6(sandbox.runtime.engine, ["build", "-t", image, buildDir], {
56026
+ const b = spawnSync5(sandbox.runtime.engine, ["build", "-t", image, buildDir], {
56390
56027
  stdio: "inherit"
56391
56028
  });
56392
56029
  if (b.status !== 0) {
56393
56030
  console.error(chalk32.red(" build failed."));
56394
56031
  process.exit(b.status ?? 1);
56395
56032
  }
56396
- fs68.writeFileSync(hashFile, hash);
56033
+ fs67.writeFileSync(hashFile, hash);
56397
56034
  }
56398
56035
  const dataDir = sandboxDataDir(cwd);
56399
56036
  seedDataDirConfig(dataDir, sandbox);
@@ -56407,7 +56044,7 @@ function registerSandboxCommand(program2, version2) {
56407
56044
  });
56408
56045
  if (sandbox.node9.mountAgentCredentials) {
56409
56046
  const creds = agentCredentialsMount(sandbox.agent);
56410
- if (fs68.existsSync(creds.hostPath)) {
56047
+ if (fs67.existsSync(creds.hostPath)) {
56411
56048
  console.log(chalk32.dim(` mounting ${creds.hostPath} (agent credentials, rw)`));
56412
56049
  } else {
56413
56050
  console.log(
@@ -56419,24 +56056,24 @@ function registerSandboxCommand(program2, version2) {
56419
56056
  chalk32.green(` \u{1F6E1}\uFE0F ${sandbox.agent} jailed \u2014 ${compiled.allow.length} hosts allowed
56420
56057
  `)
56421
56058
  );
56422
- const r = spawnSync6(sandbox.runtime.engine, runArgs, { stdio: "inherit" });
56059
+ const r = spawnSync5(sandbox.runtime.engine, runArgs, { stdio: "inherit" });
56423
56060
  process.exit(r.status ?? 0);
56424
56061
  });
56425
56062
  cmd.command("tail").description("Stream the sandbox's audit log (host-side)").action(() => {
56426
- const auditPath = path63.join(sandboxDataDir(), "audit.log");
56427
- if (!fs68.existsSync(auditPath)) {
56063
+ const auditPath = path62.join(sandboxDataDir(), "audit.log");
56064
+ if (!fs67.existsSync(auditPath)) {
56428
56065
  console.log(chalk32.dim(" no sandbox audit yet."));
56429
56066
  return;
56430
56067
  }
56431
- spawnSync6("tail", ["-f", auditPath], { stdio: "inherit" });
56068
+ spawnSync5("tail", ["-f", auditPath], { stdio: "inherit" });
56432
56069
  });
56433
56070
  cmd.command("logs").description("Dump the sandbox's audit log").action(() => {
56434
- const auditPath = path63.join(sandboxDataDir(), "audit.log");
56435
- if (!fs68.existsSync(auditPath)) {
56071
+ const auditPath = path62.join(sandboxDataDir(), "audit.log");
56072
+ if (!fs67.existsSync(auditPath)) {
56436
56073
  console.log(chalk32.dim(" no sandbox audit yet."));
56437
56074
  return;
56438
56075
  }
56439
- process.stdout.write(fs68.readFileSync(auditPath, "utf-8"));
56076
+ process.stdout.write(fs67.readFileSync(auditPath, "utf-8"));
56440
56077
  });
56441
56078
  cmd.command("clean").description("Remove the sandbox image, build context, and data").action(() => {
56442
56079
  const cwd = process.cwd();
@@ -56446,11 +56083,11 @@ function registerSandboxCommand(program2, version2) {
56446
56083
  } catch {
56447
56084
  }
56448
56085
  if (sandbox) {
56449
- spawnSync6(sandbox.runtime.engine, ["image", "rm", "-f", sandbox.runtime.image], {
56086
+ spawnSync5(sandbox.runtime.engine, ["image", "rm", "-f", sandbox.runtime.image], {
56450
56087
  stdio: "ignore"
56451
56088
  });
56452
56089
  }
56453
- fs68.rmSync(path63.join(cwd, ".node9", "sandbox"), { recursive: true, force: true });
56090
+ fs67.rmSync(path62.join(cwd, ".node9", "sandbox"), { recursive: true, force: true });
56454
56091
  console.log(chalk32.green(" \u2713 sandbox image + build + data removed."));
56455
56092
  });
56456
56093
  }
@@ -56462,9 +56099,9 @@ init_litellm();
56462
56099
  init_cost_gemini();
56463
56100
  init_cost_codex();
56464
56101
  import chalk33 from "chalk";
56465
- import fs69 from "fs";
56466
- import path64 from "path";
56467
- import os57 from "os";
56102
+ import fs68 from "fs";
56103
+ import path63 from "path";
56104
+ import os56 from "os";
56468
56105
  function modelPrice(model) {
56469
56106
  const t = pricingFor(model);
56470
56107
  if (!t) return null;
@@ -56481,10 +56118,10 @@ function encodeProjectPath(projectPath) {
56481
56118
  }
56482
56119
  function sessionJsonlPath(projectPath, sessionId) {
56483
56120
  const encoded = encodeProjectPath(projectPath);
56484
- return path64.join(os57.homedir(), ".claude", "projects", encoded, `${sessionId}.jsonl`);
56121
+ return path63.join(os56.homedir(), ".claude", "projects", encoded, `${sessionId}.jsonl`);
56485
56122
  }
56486
56123
  function projectLabel(projectPath) {
56487
- return projectPath.replace(os57.homedir(), "~");
56124
+ return projectPath.replace(os56.homedir(), "~");
56488
56125
  }
56489
56126
  function parseHistoryLines(lines) {
56490
56127
  const entries = [];
@@ -56553,10 +56190,10 @@ function parseSessionLines(lines) {
56553
56190
  return { toolCalls, costUSD, hasSnapshot, modifiedFiles };
56554
56191
  }
56555
56192
  function loadAuditEntries(auditPath) {
56556
- const aPath = auditPath ?? path64.join(os57.homedir(), ".node9", "audit.log");
56193
+ const aPath = auditPath ?? path63.join(os56.homedir(), ".node9", "audit.log");
56557
56194
  let raw;
56558
56195
  try {
56559
- raw = fs69.readFileSync(aPath, "utf-8");
56196
+ raw = fs68.readFileSync(aPath, "utf-8");
56560
56197
  } catch {
56561
56198
  return [];
56562
56199
  }
@@ -56592,8 +56229,8 @@ function auditEntriesInWindow(entries, windowStart, windowEnd) {
56592
56229
  return result;
56593
56230
  }
56594
56231
  function buildGeminiSessions(days, allAuditEntries) {
56595
- const tmpDir = path64.join(os57.homedir(), ".gemini", "tmp");
56596
- if (!fs69.existsSync(tmpDir)) return [];
56232
+ const tmpDir = path63.join(os56.homedir(), ".gemini", "tmp");
56233
+ if (!fs68.existsSync(tmpDir)) return [];
56597
56234
  const cutoff = days !== null ? (() => {
56598
56235
  const d = /* @__PURE__ */ new Date();
56599
56236
  d.setDate(d.getDate() - days);
@@ -56602,35 +56239,35 @@ function buildGeminiSessions(days, allAuditEntries) {
56602
56239
  })() : null;
56603
56240
  let slugDirs;
56604
56241
  try {
56605
- slugDirs = fs69.readdirSync(tmpDir);
56242
+ slugDirs = fs68.readdirSync(tmpDir);
56606
56243
  } catch {
56607
56244
  return [];
56608
56245
  }
56609
56246
  const summaries = [];
56610
56247
  for (const slug2 of slugDirs) {
56611
- const slugPath = path64.join(tmpDir, slug2);
56248
+ const slugPath = path63.join(tmpDir, slug2);
56612
56249
  try {
56613
- if (!fs69.statSync(slugPath).isDirectory()) continue;
56250
+ if (!fs68.statSync(slugPath).isDirectory()) continue;
56614
56251
  } catch {
56615
56252
  continue;
56616
56253
  }
56617
- let projectRoot = path64.join(os57.homedir(), slug2);
56254
+ let projectRoot = path63.join(os56.homedir(), slug2);
56618
56255
  try {
56619
- projectRoot = fs69.readFileSync(path64.join(slugPath, ".project_root"), "utf-8").trim();
56256
+ projectRoot = fs68.readFileSync(path63.join(slugPath, ".project_root"), "utf-8").trim();
56620
56257
  } catch {
56621
56258
  }
56622
- const chatsDir = path64.join(slugPath, "chats");
56623
- if (!fs69.existsSync(chatsDir)) continue;
56259
+ const chatsDir = path63.join(slugPath, "chats");
56260
+ if (!fs68.existsSync(chatsDir)) continue;
56624
56261
  let chatFiles;
56625
56262
  try {
56626
- chatFiles = fs69.readdirSync(chatsDir).filter((f) => f.endsWith(".json"));
56263
+ chatFiles = fs68.readdirSync(chatsDir).filter((f) => f.endsWith(".json"));
56627
56264
  } catch {
56628
56265
  continue;
56629
56266
  }
56630
56267
  for (const chatFile of chatFiles) {
56631
56268
  let raw;
56632
56269
  try {
56633
- raw = fs69.readFileSync(path64.join(chatsDir, chatFile), "utf-8");
56270
+ raw = fs68.readFileSync(path63.join(chatsDir, chatFile), "utf-8");
56634
56271
  } catch {
56635
56272
  continue;
56636
56273
  }
@@ -56710,8 +56347,8 @@ function buildGeminiSessions(days, allAuditEntries) {
56710
56347
  return summaries;
56711
56348
  }
56712
56349
  function buildCodexSessions(days, allAuditEntries) {
56713
- const sessionsBase = path64.join(os57.homedir(), ".codex", "sessions");
56714
- if (!fs69.existsSync(sessionsBase)) return [];
56350
+ const sessionsBase = path63.join(os56.homedir(), ".codex", "sessions");
56351
+ if (!fs68.existsSync(sessionsBase)) return [];
56715
56352
  const cutoff = days !== null ? (() => {
56716
56353
  const d = /* @__PURE__ */ new Date();
56717
56354
  d.setDate(d.getDate() - days);
@@ -56720,29 +56357,29 @@ function buildCodexSessions(days, allAuditEntries) {
56720
56357
  })() : null;
56721
56358
  const jsonlFiles = [];
56722
56359
  try {
56723
- for (const year of fs69.readdirSync(sessionsBase)) {
56724
- const yearPath = path64.join(sessionsBase, year);
56360
+ for (const year of fs68.readdirSync(sessionsBase)) {
56361
+ const yearPath = path63.join(sessionsBase, year);
56725
56362
  try {
56726
- if (!fs69.statSync(yearPath).isDirectory()) continue;
56363
+ if (!fs68.statSync(yearPath).isDirectory()) continue;
56727
56364
  } catch {
56728
56365
  continue;
56729
56366
  }
56730
- for (const month of fs69.readdirSync(yearPath)) {
56731
- const monthPath = path64.join(yearPath, month);
56367
+ for (const month of fs68.readdirSync(yearPath)) {
56368
+ const monthPath = path63.join(yearPath, month);
56732
56369
  try {
56733
- if (!fs69.statSync(monthPath).isDirectory()) continue;
56370
+ if (!fs68.statSync(monthPath).isDirectory()) continue;
56734
56371
  } catch {
56735
56372
  continue;
56736
56373
  }
56737
- for (const day of fs69.readdirSync(monthPath)) {
56738
- const dayPath = path64.join(monthPath, day);
56374
+ for (const day of fs68.readdirSync(monthPath)) {
56375
+ const dayPath = path63.join(monthPath, day);
56739
56376
  try {
56740
- if (!fs69.statSync(dayPath).isDirectory()) continue;
56377
+ if (!fs68.statSync(dayPath).isDirectory()) continue;
56741
56378
  } catch {
56742
56379
  continue;
56743
56380
  }
56744
- for (const file of fs69.readdirSync(dayPath)) {
56745
- if (file.endsWith(".jsonl")) jsonlFiles.push(path64.join(dayPath, file));
56381
+ for (const file of fs68.readdirSync(dayPath)) {
56382
+ if (file.endsWith(".jsonl")) jsonlFiles.push(path63.join(dayPath, file));
56746
56383
  }
56747
56384
  }
56748
56385
  }
@@ -56754,7 +56391,7 @@ function buildCodexSessions(days, allAuditEntries) {
56754
56391
  for (const filePath of jsonlFiles) {
56755
56392
  let lines;
56756
56393
  try {
56757
- lines = fs69.readFileSync(filePath, "utf-8").split("\n");
56394
+ lines = fs68.readFileSync(filePath, "utf-8").split("\n");
56758
56395
  } catch {
56759
56396
  continue;
56760
56397
  }
@@ -56840,10 +56477,10 @@ function buildCodexSessions(days, allAuditEntries) {
56840
56477
  return summaries;
56841
56478
  }
56842
56479
  function buildSessions(days, historyPath) {
56843
- const hPath = historyPath ?? path64.join(os57.homedir(), ".claude", "history.jsonl");
56480
+ const hPath = historyPath ?? path63.join(os56.homedir(), ".claude", "history.jsonl");
56844
56481
  let historyRaw = "";
56845
56482
  try {
56846
- historyRaw = fs69.readFileSync(hPath, "utf-8");
56483
+ historyRaw = fs68.readFileSync(hPath, "utf-8");
56847
56484
  } catch {
56848
56485
  }
56849
56486
  const cutoff = days !== null ? (() => {
@@ -56867,7 +56504,7 @@ function buildSessions(days, historyPath) {
56867
56504
  const jsonlFile = sessionJsonlPath(entry.project, entry.sessionId);
56868
56505
  let sessionLines = [];
56869
56506
  try {
56870
- sessionLines = fs69.readFileSync(jsonlFile, "utf-8").split("\n");
56507
+ sessionLines = fs68.readFileSync(jsonlFile, "utf-8").split("\n");
56871
56508
  } catch {
56872
56509
  }
56873
56510
  const { toolCalls, costUSD, hasSnapshot, modifiedFiles } = parseSessionLines(sessionLines);
@@ -57261,12 +56898,12 @@ function registerSessionTaintCommand(program2) {
57261
56898
 
57262
56899
  // src/cli/commands/skill-pin.ts
57263
56900
  import chalk35 from "chalk";
57264
- import fs70 from "fs";
57265
- import os58 from "os";
57266
- import path65 from "path";
56901
+ import fs69 from "fs";
56902
+ import os57 from "os";
56903
+ import path64 from "path";
57267
56904
  function wipeSkillSessions() {
57268
56905
  try {
57269
- fs70.rmSync(path65.join(os58.homedir(), ".node9", "skill-sessions"), {
56906
+ fs69.rmSync(path64.join(os57.homedir(), ".node9", "skill-sessions"), {
57270
56907
  recursive: true,
57271
56908
  force: true
57272
56909
  });
@@ -57348,15 +56985,15 @@ function registerSkillPinCommand(program2) {
57348
56985
  }
57349
56986
 
57350
56987
  // src/cli/commands/decisions.ts
57351
- import fs71 from "fs";
57352
- import os59 from "os";
57353
- import path66 from "path";
56988
+ import fs70 from "fs";
56989
+ import os58 from "os";
56990
+ import path65 from "path";
57354
56991
  import chalk36 from "chalk";
57355
- var DECISIONS_FILE2 = path66.join(os59.homedir(), ".node9", "decisions.json");
56992
+ var DECISIONS_FILE2 = path65.join(os58.homedir(), ".node9", "decisions.json");
57356
56993
  function readDecisions() {
57357
56994
  try {
57358
- if (!fs71.existsSync(DECISIONS_FILE2)) return {};
57359
- const raw = fs71.readFileSync(DECISIONS_FILE2, "utf-8");
56995
+ if (!fs70.existsSync(DECISIONS_FILE2)) return {};
56996
+ const raw = fs70.readFileSync(DECISIONS_FILE2, "utf-8");
57360
56997
  const parsed = JSON.parse(raw);
57361
56998
  const out = {};
57362
56999
  for (const [k, v] of Object.entries(parsed)) {
@@ -57368,11 +57005,11 @@ function readDecisions() {
57368
57005
  }
57369
57006
  }
57370
57007
  function writeDecisions(d) {
57371
- const dir = path66.dirname(DECISIONS_FILE2);
57372
- if (!fs71.existsSync(dir)) fs71.mkdirSync(dir, { recursive: true });
57008
+ const dir = path65.dirname(DECISIONS_FILE2);
57009
+ if (!fs70.existsSync(dir)) fs70.mkdirSync(dir, { recursive: true });
57373
57010
  const tmp = `${DECISIONS_FILE2}.${process.pid}.tmp`;
57374
- fs71.writeFileSync(tmp, JSON.stringify(d, null, 2));
57375
- fs71.renameSync(tmp, DECISIONS_FILE2);
57011
+ fs70.writeFileSync(tmp, JSON.stringify(d, null, 2));
57012
+ fs70.renameSync(tmp, DECISIONS_FILE2);
57376
57013
  }
57377
57014
  function registerDecisionsCommand(program2) {
57378
57015
  const cmd = program2.command("decisions").description('Manage persistent "Always Allow" / "Always Deny" tool decisions');
@@ -57429,18 +57066,18 @@ Persistent decisions (${entries.length})
57429
57066
 
57430
57067
  // src/cli/commands/dlp.ts
57431
57068
  import chalk37 from "chalk";
57432
- import fs72 from "fs";
57433
- import path67 from "path";
57434
- import os60 from "os";
57435
- var AUDIT_LOG = path67.join(os60.homedir(), ".node9", "audit.log");
57436
- var RESOLVED_FILE = path67.join(os60.homedir(), ".node9", "dlp-resolved.json");
57069
+ import fs71 from "fs";
57070
+ import path66 from "path";
57071
+ import os59 from "os";
57072
+ var AUDIT_LOG = path66.join(os59.homedir(), ".node9", "audit.log");
57073
+ var RESOLVED_FILE = path66.join(os59.homedir(), ".node9", "dlp-resolved.json");
57437
57074
  var ANSI_RE = /\x1b(?:\[[0-9;?]*[a-zA-Z]|\][^\x07\x1b]*(?:\x07|\x1b\\)|[@-_])/g;
57438
57075
  function stripAnsi(s) {
57439
57076
  return s.replace(ANSI_RE, "");
57440
57077
  }
57441
57078
  function loadResolved() {
57442
57079
  try {
57443
- const raw = JSON.parse(fs72.readFileSync(RESOLVED_FILE, "utf-8"));
57080
+ const raw = JSON.parse(fs71.readFileSync(RESOLVED_FILE, "utf-8"));
57444
57081
  return new Set(raw);
57445
57082
  } catch {
57446
57083
  return /* @__PURE__ */ new Set();
@@ -57448,13 +57085,13 @@ function loadResolved() {
57448
57085
  }
57449
57086
  function saveResolved(resolved) {
57450
57087
  try {
57451
- fs72.writeFileSync(RESOLVED_FILE, JSON.stringify([...resolved], null, 2), { mode: 384 });
57088
+ fs71.writeFileSync(RESOLVED_FILE, JSON.stringify([...resolved], null, 2), { mode: 384 });
57452
57089
  } catch {
57453
57090
  }
57454
57091
  }
57455
57092
  function loadDlpFindings() {
57456
- if (!fs72.existsSync(AUDIT_LOG)) return [];
57457
- return fs72.readFileSync(AUDIT_LOG, "utf-8").split("\n").flatMap((line) => {
57093
+ if (!fs71.existsSync(AUDIT_LOG)) return [];
57094
+ return fs71.readFileSync(AUDIT_LOG, "utf-8").split("\n").flatMap((line) => {
57458
57095
  if (!line.trim()) return [];
57459
57096
  try {
57460
57097
  const e = JSON.parse(line);
@@ -57553,14 +57190,14 @@ function registerDlpCommand(program2) {
57553
57190
  // src/cli/commands/mask.ts
57554
57191
  init_dlp();
57555
57192
  import chalk38 from "chalk";
57556
- import fs73 from "fs";
57557
- import path68 from "path";
57558
- import os61 from "os";
57193
+ import fs72 from "fs";
57194
+ import path67 from "path";
57195
+ import os60 from "os";
57559
57196
  function findJsonlFiles(dir) {
57560
57197
  const results = [];
57561
- if (!fs73.existsSync(dir)) return results;
57562
- for (const entry of fs73.readdirSync(dir, { withFileTypes: true })) {
57563
- const full = path68.join(dir, entry.name);
57198
+ if (!fs72.existsSync(dir)) return results;
57199
+ for (const entry of fs72.readdirSync(dir, { withFileTypes: true })) {
57200
+ const full = path67.join(dir, entry.name);
57564
57201
  if (entry.isDirectory()) results.push(...findJsonlFiles(full));
57565
57202
  else if (entry.isFile() && entry.name.endsWith(".jsonl")) results.push(full);
57566
57203
  }
@@ -57603,7 +57240,7 @@ function redactJson(obj) {
57603
57240
  function processFile(filePath, dryRun) {
57604
57241
  let raw;
57605
57242
  try {
57606
- raw = fs73.readFileSync(filePath, "utf-8");
57243
+ raw = fs72.readFileSync(filePath, "utf-8");
57607
57244
  } catch {
57608
57245
  return { redactedLines: 0, patterns: [] };
57609
57246
  }
@@ -57635,14 +57272,14 @@ function processFile(filePath, dryRun) {
57635
57272
  }
57636
57273
  }
57637
57274
  if (!dryRun && redactedLines > 0) {
57638
- fs73.writeFileSync(filePath, newLines.join("\n"), "utf-8");
57275
+ fs72.writeFileSync(filePath, newLines.join("\n"), "utf-8");
57639
57276
  }
57640
57277
  return { redactedLines, patterns };
57641
57278
  }
57642
57279
  function processJsonFile(filePath, dryRun) {
57643
57280
  let raw;
57644
57281
  try {
57645
- raw = fs73.readFileSync(filePath, "utf-8");
57282
+ raw = fs72.readFileSync(filePath, "utf-8");
57646
57283
  } catch {
57647
57284
  return { redactedLines: 0, patterns: [] };
57648
57285
  }
@@ -57655,15 +57292,15 @@ function processJsonFile(filePath, dryRun) {
57655
57292
  const { value, modified, found } = redactJson(parsed);
57656
57293
  if (!modified) return { redactedLines: 0, patterns: [] };
57657
57294
  if (!dryRun) {
57658
- fs73.writeFileSync(filePath, JSON.stringify(value, null, 2), "utf-8");
57295
+ fs72.writeFileSync(filePath, JSON.stringify(value, null, 2), "utf-8");
57659
57296
  }
57660
57297
  return { redactedLines: 1, patterns: found };
57661
57298
  }
57662
57299
  function findJsonFiles(dir) {
57663
57300
  const results = [];
57664
- if (!fs73.existsSync(dir)) return results;
57665
- for (const entry of fs73.readdirSync(dir, { withFileTypes: true })) {
57666
- const full = path68.join(dir, entry.name);
57301
+ if (!fs72.existsSync(dir)) return results;
57302
+ for (const entry of fs72.readdirSync(dir, { withFileTypes: true })) {
57303
+ const full = path67.join(dir, entry.name);
57667
57304
  if (entry.isDirectory()) results.push(...findJsonFiles(full));
57668
57305
  else if (entry.isFile() && entry.name.endsWith(".json")) results.push(full);
57669
57306
  }
@@ -57672,9 +57309,9 @@ function findJsonFiles(dir) {
57672
57309
  function registerMaskCommand(program2) {
57673
57310
  program2.command("mask").description("Redact plaintext secrets from local AI session history files").option("--dry-run", "show what would be redacted without making changes").option("--all", "scan all history (default: last 30 days)").action(async (options) => {
57674
57311
  const dryRun = !!options.dryRun;
57675
- const home = os61.homedir();
57676
- const claudeDir = path68.join(home, ".claude", "projects");
57677
- const geminiDir = path68.join(home, ".gemini", "tmp");
57312
+ const home = os60.homedir();
57313
+ const claudeDir = path67.join(home, ".claude", "projects");
57314
+ const geminiDir = path67.join(home, ".gemini", "tmp");
57678
57315
  const allFiles = [
57679
57316
  ...findJsonlFiles(claudeDir).map((p) => ({ path: p, type: "jsonl" })),
57680
57317
  ...findJsonFiles(geminiDir).map((p) => ({ path: p, type: "json" }))
@@ -57682,7 +57319,7 @@ function registerMaskCommand(program2) {
57682
57319
  const cutoff = options.all ? null : new Date(Date.now() - 30 * 24 * 60 * 60 * 1e3);
57683
57320
  const filtered = cutoff ? allFiles.filter((f) => {
57684
57321
  try {
57685
- return fs73.statSync(f.path).mtime >= cutoff;
57322
+ return fs72.statSync(f.path).mtime >= cutoff;
57686
57323
  } catch {
57687
57324
  return false;
57688
57325
  }
@@ -57738,7 +57375,7 @@ function registerMaskCommand(program2) {
57738
57375
  // src/cli.ts
57739
57376
  init_blast();
57740
57377
  var { version } = JSON.parse(
57741
- fs76.readFileSync(path71.join(__dirname, "../package.json"), "utf-8")
57378
+ fs75.readFileSync(path70.join(__dirname, "../package.json"), "utf-8")
57742
57379
  );
57743
57380
  var program = new Command();
57744
57381
  program.name("node9").description("The Sudo Command for AI Agents").version(version);
@@ -57778,7 +57415,7 @@ program.command("signup").description("Create your node9 account / open the dash
57778
57415
  console.log(" " + chalk40.dim("Opening ") + chalk40.cyan.underline(url));
57779
57416
  const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
57780
57417
  try {
57781
- const child = spawn9(opener, [url], {
57418
+ const child = spawn8(opener, [url], {
57782
57419
  stdio: "ignore",
57783
57420
  detached: true,
57784
57421
  shell: process.platform === "win32"
@@ -57921,16 +57558,16 @@ program.command("uninstall").description("Remove all Node9 hooks and optionally
57921
57558
  } catch {
57922
57559
  }
57923
57560
  if (options.purge) {
57924
- const node9Dir = path71.join(os64.homedir(), ".node9");
57925
- if (fs76.existsSync(node9Dir)) {
57561
+ const node9Dir = path70.join(os63.homedir(), ".node9");
57562
+ if (fs75.existsSync(node9Dir)) {
57926
57563
  const alsoSnapshots = undoLeftoverPaths().length > 0 ? ", old undo snapshots" : "";
57927
57564
  const confirmed = await confirm3({
57928
57565
  message: `Permanently delete ${node9Dir} (config, audit log, credentials${alsoSnapshots})?`,
57929
57566
  default: false
57930
57567
  });
57931
57568
  if (confirmed) {
57932
- fs76.rmSync(node9Dir, { recursive: true });
57933
- if (fs76.existsSync(node9Dir)) {
57569
+ fs75.rmSync(node9Dir, { recursive: true });
57570
+ if (fs75.existsSync(node9Dir)) {
57934
57571
  console.error(
57935
57572
  chalk40.red("\n \u26A0\uFE0F ~/.node9/ could not be fully deleted \u2014 remove it manually.")
57936
57573
  );
@@ -58066,7 +57703,7 @@ program.command("tail").description("Stream live agent activity to the terminal"
58066
57703
  });
58067
57704
  program.command("monitor").description("Live interactive dashboard \u2014 activity feed, approvals, security signals").action(async () => {
58068
57705
  try {
58069
- const dashboardPath = path71.join(__dirname, "dashboard.mjs");
57706
+ const dashboardPath = path70.join(__dirname, "dashboard.mjs");
58070
57707
  const dynamicImport = new Function("id", "return import(id)");
58071
57708
  const mod = await dynamicImport(`file://${dashboardPath}`);
58072
57709
  await mod.startMonitor();
@@ -58104,14 +57741,14 @@ Claude Code spawns this command every ~300ms and writes a JSON payload to stdin.
58104
57741
  Run "node9 addto claude" to register it as the statusLine.`
58105
57742
  ).argument("[subcommand]", 'Optional: "debug on" / "debug off" to toggle stdin logging').argument("[state]", 'on|off \u2014 used with "debug" subcommand').action(async (subcommand, state) => {
58106
57743
  if (subcommand === "debug") {
58107
- const flagFile = path71.join(os64.homedir(), ".node9", "hud-debug");
57744
+ const flagFile = path70.join(os63.homedir(), ".node9", "hud-debug");
58108
57745
  if (state === "on") {
58109
- fs76.mkdirSync(path71.dirname(flagFile), { recursive: true });
58110
- fs76.writeFileSync(flagFile, "");
57746
+ fs75.mkdirSync(path70.dirname(flagFile), { recursive: true });
57747
+ fs75.writeFileSync(flagFile, "");
58111
57748
  console.log("HUD debug logging enabled \u2192 ~/.node9/hud-debug.log");
58112
57749
  console.log("Tail it with: tail -f ~/.node9/hud-debug.log");
58113
57750
  } else if (state === "off") {
58114
- if (fs76.existsSync(flagFile)) fs76.unlinkSync(flagFile);
57751
+ if (fs75.existsSync(flagFile)) fs75.unlinkSync(flagFile);
58115
57752
  console.log("HUD debug logging disabled.");
58116
57753
  } else {
58117
57754
  console.error("Usage: node9 hud debug on|off");
@@ -58234,9 +57871,9 @@ if (process.argv[2] !== "daemon") {
58234
57871
  const isCheckHook = process.argv[2] === "check";
58235
57872
  if (isCheckHook) {
58236
57873
  if (process.env.NODE9_DEBUG === "1" || getConfig().settings.enableHookLogDebug) {
58237
- const logPath = path71.join(os64.homedir(), ".node9", "hook-debug.log");
57874
+ const logPath = path70.join(os63.homedir(), ".node9", "hook-debug.log");
58238
57875
  const msg = reason instanceof Error ? reason.message : String(reason);
58239
- fs76.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] UNHANDLED: ${msg}
57876
+ fs75.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] UNHANDLED: ${msg}
58240
57877
  `);
58241
57878
  }
58242
57879
  process.exit(0);