@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.js CHANGED
@@ -243,8 +243,8 @@ function sanitizeConfig(raw) {
243
243
  }
244
244
  }
245
245
  const lines = result.error.issues.map((issue) => {
246
- const path72 = issue.path.length > 0 ? issue.path.join(".") : "root";
247
- return ` \u2022 ${path72}: ${issue.message}`;
246
+ const path71 = issue.path.length > 0 ? issue.path.join(".") : "root";
247
+ return ` \u2022 ${path71}: ${issue.message}`;
248
248
  });
249
249
  return {
250
250
  sanitized,
@@ -624,9 +624,9 @@ function matchesPattern(text, patterns) {
624
624
  const withoutDotSlash = text.replace(/^\.\//, "");
625
625
  return isMatch(withoutDotSlash) || isMatch(`./${withoutDotSlash}`);
626
626
  }
627
- function getNestedValue(obj, path72) {
627
+ function getNestedValue(obj, path71) {
628
628
  if (!obj || typeof obj !== "object") return null;
629
- const segments = path72.split(".");
629
+ const segments = path71.split(".");
630
630
  for (const seg of segments) {
631
631
  if (FORBIDDEN_PATH_SEGMENTS.has(seg)) return null;
632
632
  }
@@ -5098,11 +5098,6 @@ function getConfig(cwd) {
5098
5098
  ignoredTools: [...DEFAULT_CONFIG.policy.ignoredTools],
5099
5099
  toolInspection: { ...DEFAULT_CONFIG.policy.toolInspection },
5100
5100
  smartRules: [...DEFAULT_CONFIG.policy.smartRules],
5101
- snapshot: {
5102
- tools: [...DEFAULT_CONFIG.policy.snapshot.tools],
5103
- onlyPaths: [...DEFAULT_CONFIG.policy.snapshot.onlyPaths],
5104
- ignorePaths: [...DEFAULT_CONFIG.policy.snapshot.ignorePaths]
5105
- },
5106
5101
  dlp: { ...DEFAULT_CONFIG.policy.dlp },
5107
5102
  egress: {
5108
5103
  ...DEFAULT_CONFIG.policy.egress,
@@ -5170,12 +5165,6 @@ function getConfig(cwd) {
5170
5165
  );
5171
5166
  mergedPolicy.smartRules = [...filteredBlocks, ...localRules, ...filteredNonBlocks];
5172
5167
  }
5173
- if (p.snapshot) {
5174
- const s2 = p.snapshot;
5175
- if (s2.tools) mergedPolicy.snapshot.tools.push(...s2.tools);
5176
- if (s2.onlyPaths) mergedPolicy.snapshot.onlyPaths.push(...s2.onlyPaths);
5177
- if (s2.ignorePaths) mergedPolicy.snapshot.ignorePaths.push(...s2.ignorePaths);
5178
- }
5179
5168
  if (p.dlp) {
5180
5169
  const d = p.dlp;
5181
5170
  if (d.enabled !== void 0) mergedPolicy.dlp.enabled = d.enabled;
@@ -5381,13 +5370,13 @@ function getConfig(cwd) {
5381
5370
  }
5382
5371
  if (Array.isArray(mc.jailPaths)) {
5383
5372
  for (const jp of mc.jailPaths) {
5384
- const path72 = typeof jp?.path === "string" ? jp.path.trim() : "";
5385
- if (!path72) continue;
5373
+ const path71 = typeof jp?.path === "string" ? jp.path.trim() : "";
5374
+ if (!path71) continue;
5386
5375
  const verdict = jp?.verdict === "review" ? "review" : "block";
5387
- for (const r of pathRules(path72, verdict, "org-managed jail")) {
5376
+ for (const r of pathRules(path71, verdict, "org-managed jail")) {
5388
5377
  mergedPolicy.smartRules.push({ ...r, name: `org:${r.name}` });
5389
5378
  }
5390
- mergedPolicy.managedJailPaths.push({ path: path72, verdict });
5379
+ mergedPolicy.managedJailPaths.push({ path: path71, verdict });
5391
5380
  }
5392
5381
  }
5393
5382
  if (Array.isArray(mc.trustedHosts)) {
@@ -5510,10 +5499,6 @@ function getConfig(cwd) {
5510
5499
  mergedPolicy.dangerousWords = [...new Set(mergedPolicy.dangerousWords)];
5511
5500
  mergedPolicy.ignoredTools = [...new Set(mergedPolicy.ignoredTools)];
5512
5501
  mergedPolicy.skillPinning.roots = [...new Set(mergedPolicy.skillPinning.roots)];
5513
- mergedPolicy.snapshot.tools = [...new Set(mergedPolicy.snapshot.tools)];
5514
- mergedPolicy.snapshot.onlyPaths = [...new Set(mergedPolicy.snapshot.onlyPaths)];
5515
- mergedPolicy.snapshot.ignorePaths = [...new Set(mergedPolicy.snapshot.ignorePaths)];
5516
- mergedSettings.enableUndo = false;
5517
5502
  const result = {
5518
5503
  settings: mergedSettings,
5519
5504
  policy: mergedPolicy,
@@ -5599,19 +5584,6 @@ var init_config = __esm({
5599
5584
  settings: {
5600
5585
  mode: "standard",
5601
5586
  autoStartDaemon: true,
5602
- // The undo feature was REMOVED. This default is one of two places that say
5603
- // so; the other is the pin further down, which overwrites whatever a config
5604
- // file, the dashboard or the cloud supplies. Setting `enableUndo` anywhere
5605
- // has no effect — do not restore the advice that used to live here, because
5606
- // a comment recommending a knob that is silently discarded is the same lie
5607
- // on disk the pin exists to prevent.
5608
- //
5609
- // Why it went: the store was a per-project bare git repo with no size
5610
- // ceiling, and eviction dropped the index row without deleting the objects.
5611
- // On one machine it reached 378G (352G of it orphaned tmp_pack_* from an
5612
- // interrupted `git gc`) and filled the disk. A security tool must not be
5613
- // what fills a customer's disk. Leftovers: `node9 undo --purge`.
5614
- enableUndo: false,
5615
5587
  enableHookLogDebug: true,
5616
5588
  approvalTimeoutMs: 12e4,
5617
5589
  // 120-second auto-deny timeout
@@ -5652,25 +5624,6 @@ var init_config = __esm({
5652
5624
  "terminal.execute": "command",
5653
5625
  "postgres:query": "sql"
5654
5626
  },
5655
- snapshot: {
5656
- tools: [
5657
- "str_replace_based_edit_tool",
5658
- "write_file",
5659
- "edit_file",
5660
- "create_file",
5661
- "edit",
5662
- "replace",
5663
- // Claude / canonicalised Hermes — shouldSnapshot lowercases the
5664
- // incoming name before set-membership, so we list the lowercase
5665
- // forms of `Bash`/`Write`/`Edit`/`MultiEdit`. Without these,
5666
- // post-canonicalisation Hermes `patch` / `write_file` (which now
5667
- // arrive as `Edit` / `Write`) silently skipped snapshotting.
5668
- "write",
5669
- "multiedit"
5670
- ],
5671
- onlyPaths: [],
5672
- ignorePaths: ["**/node_modules/**", "dist/**", "build/**", ".next/**", "**/*.log"]
5673
- },
5674
5627
  smartRules: [
5675
5628
  // ── rm safety (critical — always evaluated first) ──────────────────────
5676
5629
  {
@@ -6017,18 +5970,6 @@ var init_provenance = __esm({
6017
5970
  });
6018
5971
 
6019
5972
  // src/policy/index.ts
6020
- function shouldSnapshot(toolName, args, config) {
6021
- if (!config.settings.enableUndo) return false;
6022
- const snap = config.policy.snapshot;
6023
- if (!snap.tools.includes(toolName.toLowerCase())) return false;
6024
- const a = args && typeof args === "object" ? args : {};
6025
- const filePath = String(a.file_path ?? a.path ?? a.filename ?? "");
6026
- if (filePath) {
6027
- if (snap.ignorePaths.length && (0, import_picomatch2.default)(snap.ignorePaths)(filePath)) return false;
6028
- if (snap.onlyPaths.length && !(0, import_picomatch2.default)(snap.onlyPaths)(filePath)) return false;
6029
- }
6030
- return true;
6031
- }
6032
5973
  async function evaluatePolicy2(toolName, args, agent, cwd, opts) {
6033
5974
  const config = getConfig();
6034
5975
  const activeEnvironment = getActiveEnvironment(config) ?? void 0;
@@ -6377,14 +6318,13 @@ async function deriveExplainTrace(toolName, args) {
6377
6318
  });
6378
6319
  return { tool: toolName, args, waterfall, steps, decision: "allow" };
6379
6320
  }
6380
- var import_fs7, import_path7, import_os6, import_picomatch2, SQL_DML_KEYWORDS2, EXPLAIN_AGENT;
6321
+ var import_fs7, import_path7, import_os6, SQL_DML_KEYWORDS2, EXPLAIN_AGENT;
6381
6322
  var init_policy = __esm({
6382
6323
  "src/policy/index.ts"() {
6383
6324
  "use strict";
6384
6325
  import_fs7 = __toESM(require("fs"));
6385
6326
  import_path7 = __toESM(require("path"));
6386
6327
  import_os6 = __toESM(require("os"));
6387
- import_picomatch2 = __toESM(require("picomatch"));
6388
6328
  init_dlp();
6389
6329
  init_config();
6390
6330
  init_provenance();
@@ -16903,16 +16843,6 @@ function bindActivitySocket() {
16903
16843
  sessionHistory.recordTestFail(data.ts);
16904
16844
  return;
16905
16845
  }
16906
- if (data.status === "snapshot") {
16907
- broadcast("snapshot", {
16908
- hash: data.hash,
16909
- tool: data.tool,
16910
- argsSummary: data.argsSummary,
16911
- fileCount: data.fileCount,
16912
- ts: data.ts
16913
- });
16914
- return;
16915
- }
16916
16846
  if (data.status === "execution-completed") {
16917
16847
  broadcast("execution-result", {
16918
16848
  id: data.id,
@@ -22825,7 +22755,7 @@ var require_util = __commonJS({
22825
22755
  var { kDestroyed, kBodyUsed, kListeners, kBody } = require_symbols();
22826
22756
  var { IncomingMessage } = require("http");
22827
22757
  var stream = require("stream");
22828
- var net4 = require("net");
22758
+ var net3 = require("net");
22829
22759
  var { stringify } = require("querystring");
22830
22760
  var { EventEmitter: EE } = require("events");
22831
22761
  var timers = require_timers();
@@ -22937,14 +22867,14 @@ var require_util = __commonJS({
22937
22867
  }
22938
22868
  const port = url.port != null ? url.port : url.protocol === "https:" ? 443 : 80;
22939
22869
  let origin = url.origin != null ? url.origin : `${url.protocol || ""}//${url.hostname || ""}:${port}`;
22940
- let path72 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
22870
+ let path71 = url.path != null ? url.path : `${url.pathname || ""}${url.search || ""}`;
22941
22871
  if (origin[origin.length - 1] === "/") {
22942
22872
  origin = origin.slice(0, origin.length - 1);
22943
22873
  }
22944
- if (path72 && path72[0] !== "/") {
22945
- path72 = `/${path72}`;
22874
+ if (path71 && path71[0] !== "/") {
22875
+ path71 = `/${path71}`;
22946
22876
  }
22947
- return new URL(`${origin}${path72}`);
22877
+ return new URL(`${origin}${path71}`);
22948
22878
  }
22949
22879
  if (!isHttpOrHttpsPrefixed(url.origin || url.protocol)) {
22950
22880
  throw new InvalidArgumentError("Invalid URL protocol: the URL must start with `http:` or `https:`.");
@@ -22974,7 +22904,7 @@ var require_util = __commonJS({
22974
22904
  }
22975
22905
  assert(typeof host === "string");
22976
22906
  const servername = getHostname(host);
22977
- if (net4.isIP(servername)) {
22907
+ if (net3.isIP(servername)) {
22978
22908
  return "";
22979
22909
  }
22980
22910
  return servername;
@@ -23765,9 +23695,9 @@ var require_diagnostics = __commonJS({
23765
23695
  "undici:client:sendHeaders",
23766
23696
  (evt) => {
23767
23697
  const {
23768
- request: { method, path: path72, origin }
23698
+ request: { method, path: path71, origin }
23769
23699
  } = evt;
23770
- debugLog("sending request to %s %s%s", method, origin, path72);
23700
+ debugLog("sending request to %s %s%s", method, origin, path71);
23771
23701
  }
23772
23702
  );
23773
23703
  }
@@ -23785,14 +23715,14 @@ var require_diagnostics = __commonJS({
23785
23715
  "undici:request:headers",
23786
23716
  (evt) => {
23787
23717
  const {
23788
- request: { method, path: path72, origin },
23718
+ request: { method, path: path71, origin },
23789
23719
  response: { statusCode }
23790
23720
  } = evt;
23791
23721
  debugLog(
23792
23722
  "received response to %s %s%s - HTTP %d",
23793
23723
  method,
23794
23724
  origin,
23795
- path72,
23725
+ path71,
23796
23726
  statusCode
23797
23727
  );
23798
23728
  }
@@ -23801,23 +23731,23 @@ var require_diagnostics = __commonJS({
23801
23731
  "undici:request:trailers",
23802
23732
  (evt) => {
23803
23733
  const {
23804
- request: { method, path: path72, origin }
23734
+ request: { method, path: path71, origin }
23805
23735
  } = evt;
23806
- debugLog("trailers received from %s %s%s", method, origin, path72);
23736
+ debugLog("trailers received from %s %s%s", method, origin, path71);
23807
23737
  }
23808
23738
  );
23809
23739
  diagnosticsChannel.subscribe(
23810
23740
  "undici:request:error",
23811
23741
  (evt) => {
23812
23742
  const {
23813
- request: { method, path: path72, origin },
23743
+ request: { method, path: path71, origin },
23814
23744
  error
23815
23745
  } = evt;
23816
23746
  debugLog(
23817
23747
  "request to %s %s%s errored - %s",
23818
23748
  method,
23819
23749
  origin,
23820
- path72,
23750
+ path71,
23821
23751
  error.message
23822
23752
  );
23823
23753
  }
@@ -23920,7 +23850,7 @@ var require_request = __commonJS({
23920
23850
  var kHandler = /* @__PURE__ */ Symbol("handler");
23921
23851
  var Request = class {
23922
23852
  constructor(origin, {
23923
- path: path72,
23853
+ path: path71,
23924
23854
  method,
23925
23855
  body,
23926
23856
  headers,
@@ -23937,11 +23867,11 @@ var require_request = __commonJS({
23937
23867
  maxRedirections,
23938
23868
  typeOfService
23939
23869
  }, handler) {
23940
- if (typeof path72 !== "string") {
23870
+ if (typeof path71 !== "string") {
23941
23871
  throw new InvalidArgumentError("path must be a string");
23942
- } else if (path72[0] !== "/" && !(path72.startsWith("http://") || path72.startsWith("https://")) && method !== "CONNECT") {
23872
+ } else if (path71[0] !== "/" && !(path71.startsWith("http://") || path71.startsWith("https://")) && method !== "CONNECT") {
23943
23873
  throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
23944
- } else if (invalidPathRegex.test(path72)) {
23874
+ } else if (invalidPathRegex.test(path71)) {
23945
23875
  throw new InvalidArgumentError("invalid request path");
23946
23876
  }
23947
23877
  if (typeof method !== "string") {
@@ -24016,7 +23946,7 @@ var require_request = __commonJS({
24016
23946
  this.completed = false;
24017
23947
  this.aborted = false;
24018
23948
  this.upgrade = upgrade || null;
24019
- this.path = query ? serializePathWithQuery(path72, query) : path72;
23949
+ this.path = query ? serializePathWithQuery(path71, query) : path71;
24020
23950
  this.origin = origin;
24021
23951
  this.protocol = getProtocolFromUrlString(origin);
24022
23952
  this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
@@ -24595,7 +24525,7 @@ var require_dispatcher_base = __commonJS({
24595
24525
  var require_connect = __commonJS({
24596
24526
  "node_modules/undici/lib/core/connect.js"(exports2, module2) {
24597
24527
  "use strict";
24598
- var net4 = require("net");
24528
+ var net3 = require("net");
24599
24529
  var assert = require("assert");
24600
24530
  var util = require_util();
24601
24531
  var { InvalidArgumentError } = require_errors();
@@ -24664,7 +24594,7 @@ var require_connect = __commonJS({
24664
24594
  } else {
24665
24595
  assert(!httpSocket, "httpSocket can only be sent on TLS update");
24666
24596
  port = port || 80;
24667
- socket = net4.connect({
24597
+ socket = net3.connect({
24668
24598
  highWaterMark: 64 * 1024,
24669
24599
  // Same as nodejs fs streams.
24670
24600
  ...options,
@@ -29055,7 +28985,7 @@ var require_client_h1 = __commonJS({
29055
28985
  return method !== "GET" && method !== "HEAD" && method !== "OPTIONS" && method !== "TRACE" && method !== "CONNECT";
29056
28986
  }
29057
28987
  function writeH1(client, request2) {
29058
- const { method, path: path72, host, upgrade, blocking, reset } = request2;
28988
+ const { method, path: path71, host, upgrade, blocking, reset } = request2;
29059
28989
  let { body, headers, contentLength } = request2;
29060
28990
  const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
29061
28991
  if (util.isFormDataLike(body)) {
@@ -29124,7 +29054,7 @@ var require_client_h1 = __commonJS({
29124
29054
  if (socket.setTypeOfService) {
29125
29055
  socket.setTypeOfService(request2.typeOfService);
29126
29056
  }
29127
- let header = `${method} ${path72} HTTP/1.1\r
29057
+ let header = `${method} ${path71} HTTP/1.1\r
29128
29058
  `;
29129
29059
  if (typeof host === "string") {
29130
29060
  header += `host: ${host}\r
@@ -29777,7 +29707,7 @@ var require_client_h2 = __commonJS({
29777
29707
  function writeH2(client, request2) {
29778
29708
  const requestTimeout = request2.bodyTimeout ?? client[kBodyTimeout];
29779
29709
  const session = client[kHTTP2Session];
29780
- const { method, path: path72, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request2;
29710
+ const { method, path: path71, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request2;
29781
29711
  let { body } = request2;
29782
29712
  if (upgrade != null && upgrade !== "websocket") {
29783
29713
  util.errorRequest(client, request2, new InvalidArgumentError(`Custom upgrade "${upgrade}" not supported over HTTP/2`));
@@ -29845,7 +29775,7 @@ var require_client_h2 = __commonJS({
29845
29775
  }
29846
29776
  headers[HTTP2_HEADER_METHOD] = "CONNECT";
29847
29777
  headers[HTTP2_HEADER_PROTOCOL] = "websocket";
29848
- headers[HTTP2_HEADER_PATH] = path72;
29778
+ headers[HTTP2_HEADER_PATH] = path71;
29849
29779
  if (protocol === "ws:" || protocol === "wss:") {
29850
29780
  headers[HTTP2_HEADER_SCHEME] = protocol === "ws:" ? "http" : "https";
29851
29781
  } else {
@@ -29886,7 +29816,7 @@ var require_client_h2 = __commonJS({
29886
29816
  stream.setTimeout(requestTimeout);
29887
29817
  return true;
29888
29818
  }
29889
- headers[HTTP2_HEADER_PATH] = path72;
29819
+ headers[HTTP2_HEADER_PATH] = path71;
29890
29820
  headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https";
29891
29821
  const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
29892
29822
  if (body && typeof body.read === "function") {
@@ -30202,7 +30132,7 @@ var require_client = __commonJS({
30202
30132
  "node_modules/undici/lib/dispatcher/client.js"(exports2, module2) {
30203
30133
  "use strict";
30204
30134
  var assert = require("assert");
30205
- var net4 = require("net");
30135
+ var net3 = require("net");
30206
30136
  var http7 = require("http");
30207
30137
  var util = require_util();
30208
30138
  var { ClientStats } = require_stats();
@@ -30356,7 +30286,7 @@ var require_client = __commonJS({
30356
30286
  if (maxRequestsPerClient != null && (!Number.isInteger(maxRequestsPerClient) || maxRequestsPerClient < 0)) {
30357
30287
  throw new InvalidArgumentError("maxRequestsPerClient must be a positive number");
30358
30288
  }
30359
- if (localAddress != null && (typeof localAddress !== "string" || net4.isIP(localAddress) === 0)) {
30289
+ if (localAddress != null && (typeof localAddress !== "string" || net3.isIP(localAddress) === 0)) {
30360
30290
  throw new InvalidArgumentError("localAddress must be valid string IP address");
30361
30291
  }
30362
30292
  if (maxResponseSize != null && (!Number.isInteger(maxResponseSize) || maxResponseSize < -1)) {
@@ -30528,7 +30458,7 @@ var require_client = __commonJS({
30528
30458
  const idx = hostname.indexOf("]");
30529
30459
  assert(idx !== -1);
30530
30460
  const ip = hostname.substring(1, idx);
30531
- assert(net4.isIPv6(ip));
30461
+ assert(net3.isIPv6(ip));
30532
30462
  hostname = ip;
30533
30463
  }
30534
30464
  client[kConnecting] = true;
@@ -31471,10 +31401,10 @@ var require_socks5_utils = __commonJS({
31471
31401
  "node_modules/undici/lib/core/socks5-utils.js"(exports2, module2) {
31472
31402
  "use strict";
31473
31403
  var { Buffer: Buffer2 } = require("buffer");
31474
- var net4 = require("net");
31404
+ var net3 = require("net");
31475
31405
  var { InvalidArgumentError } = require_errors();
31476
31406
  function parseAddress(address) {
31477
- if (net4.isIPv4(address)) {
31407
+ if (net3.isIPv4(address)) {
31478
31408
  const parts = address.split(".").map(Number);
31479
31409
  return {
31480
31410
  type: 1,
@@ -31482,7 +31412,7 @@ var require_socks5_utils = __commonJS({
31482
31412
  buffer: Buffer2.from(parts)
31483
31413
  };
31484
31414
  }
31485
- if (net4.isIPv6(address)) {
31415
+ if (net3.isIPv6(address)) {
31486
31416
  return {
31487
31417
  type: 4,
31488
31418
  // IPv6
@@ -31942,7 +31872,7 @@ var require_socks5_client = __commonJS({
31942
31872
  var require_socks5_proxy_agent = __commonJS({
31943
31873
  "node_modules/undici/lib/dispatcher/socks5-proxy-agent.js"(exports2, module2) {
31944
31874
  "use strict";
31945
- var net4 = require("net");
31875
+ var net3 = require("net");
31946
31876
  var { URL: URL5 } = require("url");
31947
31877
  var tls;
31948
31878
  var DispatcherBase = require_dispatcher_base();
@@ -32004,7 +31934,7 @@ var require_socks5_proxy_agent = __commonJS({
32004
31934
  socket2.removeListener("connect", onConnect);
32005
31935
  reject(err2);
32006
31936
  };
32007
- const socket2 = net4.connect({
31937
+ const socket2 = net3.connect({
32008
31938
  host: proxyHost,
32009
31939
  port: proxyPort
32010
31940
  });
@@ -32188,10 +32118,10 @@ var require_proxy_agent = __commonJS({
32188
32118
  };
32189
32119
  const {
32190
32120
  origin,
32191
- path: path72 = "/",
32121
+ path: path71 = "/",
32192
32122
  headers = {}
32193
32123
  } = opts;
32194
- opts.path = origin + path72;
32124
+ opts.path = origin + path71;
32195
32125
  if (!("host" in headers) && !("Host" in headers)) {
32196
32126
  const { host } = new URL(origin);
32197
32127
  headers.host = host;
@@ -34254,20 +34184,20 @@ var require_mock_utils = __commonJS({
34254
34184
  }
34255
34185
  return normalizedQp;
34256
34186
  }
34257
- function safeUrl(path72) {
34258
- if (typeof path72 !== "string") {
34259
- return path72;
34187
+ function safeUrl(path71) {
34188
+ if (typeof path71 !== "string") {
34189
+ return path71;
34260
34190
  }
34261
- const pathSegments = path72.split("?", 3);
34191
+ const pathSegments = path71.split("?", 3);
34262
34192
  if (pathSegments.length !== 2) {
34263
- return path72;
34193
+ return path71;
34264
34194
  }
34265
34195
  const qp = new URLSearchParams(pathSegments.pop());
34266
34196
  qp.sort();
34267
34197
  return [...pathSegments, qp.toString()].join("?");
34268
34198
  }
34269
- function matchKey(mockDispatch2, { path: path72, method, body, headers }) {
34270
- const pathMatch = matchValue(mockDispatch2.path, path72);
34199
+ function matchKey(mockDispatch2, { path: path71, method, body, headers }) {
34200
+ const pathMatch = matchValue(mockDispatch2.path, path71);
34271
34201
  const methodMatch = matchValue(mockDispatch2.method, method);
34272
34202
  const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
34273
34203
  const headersMatch = matchHeaders(mockDispatch2, headers);
@@ -34292,8 +34222,8 @@ var require_mock_utils = __commonJS({
34292
34222
  const basePath = key.query ? serializePathWithQuery(key.path, key.query) : key.path;
34293
34223
  const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
34294
34224
  const resolvedPathWithoutTrailingSlash = removeTrailingSlash(resolvedPath);
34295
- let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path72, ignoreTrailingSlash }) => {
34296
- return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path72)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path72), resolvedPath);
34225
+ let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path71, ignoreTrailingSlash }) => {
34226
+ return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path71)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path71), resolvedPath);
34297
34227
  });
34298
34228
  if (matchedMockDispatches.length === 0) {
34299
34229
  throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
@@ -34332,19 +34262,19 @@ var require_mock_utils = __commonJS({
34332
34262
  mockDispatches.splice(index, 1);
34333
34263
  }
34334
34264
  }
34335
- function removeTrailingSlash(path72) {
34336
- while (path72.endsWith("/")) {
34337
- path72 = path72.slice(0, -1);
34265
+ function removeTrailingSlash(path71) {
34266
+ while (path71.endsWith("/")) {
34267
+ path71 = path71.slice(0, -1);
34338
34268
  }
34339
- if (path72.length === 0) {
34340
- path72 = "/";
34269
+ if (path71.length === 0) {
34270
+ path71 = "/";
34341
34271
  }
34342
- return path72;
34272
+ return path71;
34343
34273
  }
34344
34274
  function buildKey(opts) {
34345
- const { path: path72, method, body, headers, query } = opts;
34275
+ const { path: path71, method, body, headers, query } = opts;
34346
34276
  return {
34347
- path: path72,
34277
+ path: path71,
34348
34278
  method,
34349
34279
  body,
34350
34280
  headers,
@@ -35034,10 +34964,10 @@ var require_pending_interceptors_formatter = __commonJS({
35034
34964
  }
35035
34965
  format(pendingInterceptors) {
35036
34966
  const withPrettyHeaders = pendingInterceptors.map(
35037
- ({ method, path: path72, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
34967
+ ({ method, path: path71, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
35038
34968
  Method: method,
35039
34969
  Origin: origin,
35040
- Path: path72,
34970
+ Path: path71,
35041
34971
  "Status code": statusCode,
35042
34972
  Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
35043
34973
  Invocations: timesInvoked,
@@ -35119,9 +35049,9 @@ var require_mock_agent = __commonJS({
35119
35049
  const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters];
35120
35050
  const dispatchOpts = { ...opts };
35121
35051
  if (acceptNonStandardSearchParameters && dispatchOpts.path) {
35122
- const [path72, searchParams] = dispatchOpts.path.split("?");
35052
+ const [path71, searchParams] = dispatchOpts.path.split("?");
35123
35053
  const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters);
35124
- dispatchOpts.path = `${path72}?${normalizedSearchParams}`;
35054
+ dispatchOpts.path = `${path71}?${normalizedSearchParams}`;
35125
35055
  }
35126
35056
  return this[kAgent].dispatch(dispatchOpts, handler);
35127
35057
  }
@@ -35249,8 +35179,8 @@ var require_snapshot_utils = __commonJS({
35249
35179
  match: new Set(matchHeaders.map((header) => caseSensitive ? header : header.toLowerCase()))
35250
35180
  };
35251
35181
  }
35252
- var crypto10 = runtimeFeatures.has("crypto") ? require("crypto") : null;
35253
- var hashId = crypto10?.hash ? (value) => crypto10.hash("sha256", value, "base64url") : (value) => Buffer.from(value).toString("base64url");
35182
+ var crypto9 = runtimeFeatures.has("crypto") ? require("crypto") : null;
35183
+ var hashId = crypto9?.hash ? (value) => crypto9.hash("sha256", value, "base64url") : (value) => Buffer.from(value).toString("base64url");
35254
35184
  function isUndiciHeaders(headers) {
35255
35185
  return Array.isArray(headers) && (headers.length & 1) === 0;
35256
35186
  }
@@ -35522,12 +35452,12 @@ var require_snapshot_recorder = __commonJS({
35522
35452
  * @return {Promise<void>} - Resolves when snapshots are loaded
35523
35453
  */
35524
35454
  async loadSnapshots(filePath) {
35525
- const path72 = filePath || this.#snapshotPath;
35526
- if (!path72) {
35455
+ const path71 = filePath || this.#snapshotPath;
35456
+ if (!path71) {
35527
35457
  throw new InvalidArgumentError("Snapshot path is required");
35528
35458
  }
35529
35459
  try {
35530
- const data = await readFile(resolve2(path72), "utf8");
35460
+ const data = await readFile(resolve2(path71), "utf8");
35531
35461
  const parsed = JSON.parse(data);
35532
35462
  if (Array.isArray(parsed)) {
35533
35463
  this.#snapshots.clear();
@@ -35541,7 +35471,7 @@ var require_snapshot_recorder = __commonJS({
35541
35471
  if (error.code === "ENOENT") {
35542
35472
  this.#snapshots.clear();
35543
35473
  } else {
35544
- throw new UndiciError(`Failed to load snapshots from ${path72}`, { cause: error });
35474
+ throw new UndiciError(`Failed to load snapshots from ${path71}`, { cause: error });
35545
35475
  }
35546
35476
  }
35547
35477
  }
@@ -35552,11 +35482,11 @@ var require_snapshot_recorder = __commonJS({
35552
35482
  * @returns {Promise<void>} - Resolves when snapshots are saved
35553
35483
  */
35554
35484
  async saveSnapshots(filePath) {
35555
- const path72 = filePath || this.#snapshotPath;
35556
- if (!path72) {
35485
+ const path71 = filePath || this.#snapshotPath;
35486
+ if (!path71) {
35557
35487
  throw new InvalidArgumentError("Snapshot path is required");
35558
35488
  }
35559
- const resolvedPath = resolve2(path72);
35489
+ const resolvedPath = resolve2(path71);
35560
35490
  await mkdir(dirname2(resolvedPath), { recursive: true });
35561
35491
  const data = Array.from(this.#snapshots.entries()).map(([hash, snapshot]) => ({
35562
35492
  hash,
@@ -36181,15 +36111,15 @@ var require_redirect_handler = __commonJS({
36181
36111
  return;
36182
36112
  }
36183
36113
  const { origin, pathname, search } = util.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
36184
- const path72 = search ? `${pathname}${search}` : pathname;
36185
- const redirectUrlString = `${origin}${path72}`;
36114
+ const path71 = search ? `${pathname}${search}` : pathname;
36115
+ const redirectUrlString = `${origin}${path71}`;
36186
36116
  for (const historyUrl of this.history) {
36187
36117
  if (historyUrl.toString() === redirectUrlString) {
36188
36118
  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.`);
36189
36119
  }
36190
36120
  }
36191
36121
  this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
36192
- this.opts.path = path72;
36122
+ this.opts.path = path71;
36193
36123
  this.opts.origin = origin;
36194
36124
  this.opts.query = null;
36195
36125
  }
@@ -41308,10 +41238,10 @@ var require_subresource_integrity = __commonJS({
41308
41238
  var assert = require("assert");
41309
41239
  var { runtimeFeatures } = require_runtime_features();
41310
41240
  var validSRIHashAlgorithmTokenSet = /* @__PURE__ */ new Map([["sha256", 0], ["sha384", 1], ["sha512", 2]]);
41311
- var crypto10;
41241
+ var crypto9;
41312
41242
  if (runtimeFeatures.has("crypto")) {
41313
- crypto10 = require("crypto");
41314
- const cryptoHashes = crypto10.getHashes();
41243
+ crypto9 = require("crypto");
41244
+ const cryptoHashes = crypto9.getHashes();
41315
41245
  if (cryptoHashes.length === 0) {
41316
41246
  validSRIHashAlgorithmTokenSet.clear();
41317
41247
  }
@@ -41401,7 +41331,7 @@ var require_subresource_integrity = __commonJS({
41401
41331
  return result;
41402
41332
  }
41403
41333
  var applyAlgorithmToBytes = (algorithm, bytes) => {
41404
- return crypto10.hash(algorithm, bytes, "base64");
41334
+ return crypto9.hash(algorithm, bytes, "base64");
41405
41335
  };
41406
41336
  function caseSensitiveMatch(actualValue, expectedValue) {
41407
41337
  let actualValueLength = actualValue.length;
@@ -42396,11 +42326,11 @@ var require_fetch = __commonJS({
42396
42326
  function dispatch({ body }) {
42397
42327
  const url = requestCurrentURL(request2);
42398
42328
  const agent = fetchParams.controller.dispatcher;
42399
- const path72 = url.pathname + url.search;
42329
+ const path71 = url.pathname + url.search;
42400
42330
  const hasTrailingQuestionMark = url.search.length === 0 && url.href[url.href.length - url.hash.length - 1] === "?";
42401
42331
  return new Promise((resolve2, reject) => agent.dispatch(
42402
42332
  {
42403
- path: hasTrailingQuestionMark ? `${path72}?` : path72,
42333
+ path: hasTrailingQuestionMark ? `${path71}?` : path71,
42404
42334
  origin: url.origin,
42405
42335
  method: request2.method,
42406
42336
  body: agent.isMockActive ? request2.body && (request2.body.source || request2.body.stream) : body,
@@ -43331,9 +43261,9 @@ var require_util4 = __commonJS({
43331
43261
  }
43332
43262
  }
43333
43263
  }
43334
- function validateCookiePath(path72) {
43335
- for (let i = 0; i < path72.length; ++i) {
43336
- const code = path72.charCodeAt(i);
43264
+ function validateCookiePath(path71) {
43265
+ for (let i = 0; i < path71.length; ++i) {
43266
+ const code = path71.charCodeAt(i);
43337
43267
  if (code < 32 || // exclude CTLs (0-31)
43338
43268
  code === 127 || // DEL
43339
43269
  code === 59) {
@@ -44335,7 +44265,7 @@ var require_connection = __commonJS({
44335
44265
  var { WebsocketFrameSend } = require_frame();
44336
44266
  var assert = require("assert");
44337
44267
  var { runtimeFeatures } = require_runtime_features();
44338
- var crypto10 = runtimeFeatures.has("crypto") ? require("crypto") : null;
44268
+ var crypto9 = runtimeFeatures.has("crypto") ? require("crypto") : null;
44339
44269
  var warningEmitted = false;
44340
44270
  function establishWebSocketConnection(url, protocols, client, handler, options) {
44341
44271
  const requestURL = url;
@@ -44355,7 +44285,7 @@ var require_connection = __commonJS({
44355
44285
  const headersList = getHeadersList(new Headers(options.headers));
44356
44286
  request2.headersList = headersList;
44357
44287
  }
44358
- const keyValue = crypto10.randomBytes(16).toString("base64");
44288
+ const keyValue = crypto9.randomBytes(16).toString("base64");
44359
44289
  request2.headersList.append("sec-websocket-key", keyValue, true);
44360
44290
  request2.headersList.append("sec-websocket-version", "13", true);
44361
44291
  for (const protocol of protocols) {
@@ -44395,7 +44325,7 @@ var require_connection = __commonJS({
44395
44325
  return;
44396
44326
  }
44397
44327
  const secWSAccept = response.headersList.get("Sec-WebSocket-Accept");
44398
- const digest = crypto10.hash("sha1", keyValue + uid, "base64");
44328
+ const digest = crypto9.hash("sha1", keyValue + uid, "base64");
44399
44329
  if (secWSAccept !== digest) {
44400
44330
  failWebsocketConnection(handler, 1002, "Incorrect hash received in Sec-WebSocket-Accept header.");
44401
44331
  return;
@@ -46503,11 +46433,11 @@ var require_undici = __commonJS({
46503
46433
  if (typeof opts.path !== "string") {
46504
46434
  throw new InvalidArgumentError("invalid opts.path");
46505
46435
  }
46506
- let path72 = opts.path;
46436
+ let path71 = opts.path;
46507
46437
  if (!opts.path.startsWith("/")) {
46508
- path72 = `/${path72}`;
46438
+ path71 = `/${path71}`;
46509
46439
  }
46510
- url = new URL(util.parseOrigin(url).origin + path72);
46440
+ url = new URL(util.parseOrigin(url).origin + path71);
46511
46441
  } else {
46512
46442
  if (!opts) {
46513
46443
  opts = typeof url === "object" ? url : {};
@@ -46649,20 +46579,20 @@ function getModelContextLimit(model) {
46649
46579
  return 2e5;
46650
46580
  }
46651
46581
  function readSessionUsage() {
46652
- const projectsDir = import_path68.default.join(import_os61.default.homedir(), ".claude", "projects");
46653
- if (!import_fs73.default.existsSync(projectsDir)) return null;
46582
+ const projectsDir = import_path67.default.join(import_os60.default.homedir(), ".claude", "projects");
46583
+ if (!import_fs72.default.existsSync(projectsDir)) return null;
46654
46584
  let latestFile = null;
46655
46585
  let latestMtime = 0;
46656
46586
  try {
46657
- for (const dir of import_fs73.default.readdirSync(projectsDir)) {
46658
- const dirPath = import_path68.default.join(projectsDir, dir);
46587
+ for (const dir of import_fs72.default.readdirSync(projectsDir)) {
46588
+ const dirPath = import_path67.default.join(projectsDir, dir);
46659
46589
  try {
46660
- if (!import_fs73.default.statSync(dirPath).isDirectory()) continue;
46661
- for (const file of import_fs73.default.readdirSync(dirPath)) {
46590
+ if (!import_fs72.default.statSync(dirPath).isDirectory()) continue;
46591
+ for (const file of import_fs72.default.readdirSync(dirPath)) {
46662
46592
  if (!file.endsWith(".jsonl") || file.startsWith("agent-")) continue;
46663
- const filePath = import_path68.default.join(dirPath, file);
46593
+ const filePath = import_path67.default.join(dirPath, file);
46664
46594
  try {
46665
- const mtime = import_fs73.default.statSync(filePath).mtimeMs;
46595
+ const mtime = import_fs72.default.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 = import_fs73.default.readFileSync(latestFile, "utf-8").split("\n");
46610
+ const lines = import_fs72.default.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(import_os61.default.homedir(), "~");
46671
+ const argsStr = JSON.stringify(activity.args ?? {}).replace(/\s+/g, " ").replaceAll(import_os60.default.homedir(), "~");
46742
46672
  const argsPreview = argsStr.length > 70 ? argsStr.slice(0, 70) + "\u2026" : argsStr;
46743
46673
  return `${import_chalk39.default.gray(time)} ${icon} ${agentLabel(activity.agent, activity.mcpServer, activity.sessionId)}${import_chalk39.default.white.bold(toolName)} ${import_chalk39.default.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 (import_fs73.default.existsSync(PID_FILE)) {
46710
+ if (import_fs72.default.existsSync(PID_FILE)) {
46781
46711
  try {
46782
- const { port } = JSON.parse(import_fs73.default.readFileSync(PID_FILE, "utf-8"));
46712
+ const { port } = JSON.parse(import_fs72.default.readFileSync(PID_FILE, "utf-8"));
46783
46713
  pidPort = port;
46784
46714
  } catch {
46785
46715
  console.error(import_chalk39.default.dim("\u26A0\uFE0F Could not read PID file; falling back to default port."));
@@ -46796,7 +46726,7 @@ async function ensureDaemon() {
46796
46726
  console.log(import_chalk39.default.dim("\u{1F6E1}\uFE0F Starting Node9 daemon..."));
46797
46727
  const startupFd = openStartupLogFd();
46798
46728
  recordStartupState("starting");
46799
- const child = (0, import_child_process14.spawn)(process.execPath, [process.argv[1], "daemon"], {
46729
+ const child = (0, import_child_process13.spawn)(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
- import_fs73.default.closeSync(startupFd);
46738
+ import_fs72.default.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 = import_path68.default.join(import_os61.default.homedir(), ".node9", "config.json");
46877
+ const configPath = import_path67.default.join(import_os60.default.homedir(), ".node9", "config.json");
46948
46878
  try {
46949
- const raw = JSON.parse(import_fs73.default.readFileSync(configPath, "utf-8"));
46879
+ const raw = JSON.parse(import_fs72.default.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 = import_path68.default.join(import_os61.default.homedir(), ".node9", "config.json");
46895
+ const configPath = import_path67.default.join(import_os60.default.homedir(), ".node9", "config.json");
46966
46896
  try {
46967
- const raw = JSON.parse(import_fs73.default.readFileSync(configPath, "utf-8"));
46897
+ const raw = JSON.parse(import_fs72.default.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
- import_fs73.default.writeFileSync(configPath, JSON.stringify(raw, null, 2) + "\n");
46903
+ import_fs72.default.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
- import_fs73.default.appendFileSync(
47146
- import_path68.default.join(import_os61.default.homedir(), ".node9", "hook-debug.log"),
47075
+ import_fs72.default.appendFileSync(
47076
+ import_path67.default.join(import_os60.default.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 = import_path68.default.join(import_os61.default.homedir(), ".node9", "audit.log");
47140
+ const auditLog = import_path67.default.join(import_os60.default.homedir(), ".node9", "audit.log");
47211
47141
  try {
47212
- const unackedDlp = import_fs73.default.readFileSync(auditLog, "utf-8").split("\n").filter((l) => l.includes('"response-dlp"')).length;
47142
+ const unackedDlp = import_fs72.default.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 = import_fs73.default.statSync(auditLog).mtimeMs;
47182
+ const auditMtime = import_fs72.default.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 ? import_chalk39.default.dim(` \xB7 ${fileCount} file${fileCount === 1 ? "" : "s"}`) : "";
47403
- process.stdout.write(
47404
- `${import_chalk39.default.dim(time)} ${import_chalk39.default.cyan("\u{1F4F8} snapshot")} ${import_chalk39.default.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) {
@@ -47434,21 +47351,21 @@ async function startTail(options = {}) {
47434
47351
  process.exit(1);
47435
47352
  });
47436
47353
  }
47437
- var import_http5, import_chalk39, import_fs73, import_os61, import_path68, import_readline5, import_child_process14, PID_FILE, ICONS, MODEL_CONTEXT_LIMITS, RESET, BOLD, RED, YELLOW, CYAN, GRAY, GREEN, HIDE_CURSOR, SHOW_CURSOR, ERASE_DOWN, pendingShownForId, pendingWrappedLines, DIVIDER;
47354
+ var import_http5, import_chalk39, import_fs72, import_os60, import_path67, import_readline5, import_child_process13, PID_FILE, ICONS, MODEL_CONTEXT_LIMITS, RESET, BOLD, RED, YELLOW, CYAN, GRAY, GREEN, HIDE_CURSOR, SHOW_CURSOR, ERASE_DOWN, pendingShownForId, pendingWrappedLines, DIVIDER;
47438
47355
  var init_tail = __esm({
47439
47356
  "src/tui/tail.ts"() {
47440
47357
  "use strict";
47441
47358
  import_http5 = __toESM(require("http"));
47442
47359
  import_chalk39 = __toESM(require("chalk"));
47443
- import_fs73 = __toESM(require("fs"));
47444
- import_os61 = __toESM(require("os"));
47445
- import_path68 = __toESM(require("path"));
47360
+ import_fs72 = __toESM(require("fs"));
47361
+ import_os60 = __toESM(require("os"));
47362
+ import_path67 = __toESM(require("path"));
47446
47363
  import_readline5 = __toESM(require("readline"));
47447
- import_child_process14 = require("child_process");
47364
+ import_child_process13 = require("child_process");
47448
47365
  init_startup_log();
47449
47366
  init_daemon2();
47450
47367
  init_daemon();
47451
- PID_FILE = import_path68.default.join(import_os61.default.homedir(), ".node9", "daemon.pid");
47368
+ PID_FILE = import_path67.default.join(import_os60.default.homedir(), ".node9", "daemon.pid");
47452
47369
  ICONS = {
47453
47370
  bash: "\u{1F4BB}",
47454
47371
  shell: "\u{1F4BB}",
@@ -47570,9 +47487,9 @@ function formatTimeLeft(resetsAt) {
47570
47487
  return ` (${m}m left)`;
47571
47488
  }
47572
47489
  function safeReadJson(filePath) {
47573
- if (!import_fs74.default.existsSync(filePath)) return null;
47490
+ if (!import_fs73.default.existsSync(filePath)) return null;
47574
47491
  try {
47575
- return JSON.parse(import_fs74.default.readFileSync(filePath, "utf-8"));
47492
+ return JSON.parse(import_fs73.default.readFileSync(filePath, "utf-8"));
47576
47493
  } catch {
47577
47494
  return null;
47578
47495
  }
@@ -47593,12 +47510,12 @@ function countHooksInFile(filePath) {
47593
47510
  return Object.keys(cfg.hooks).length;
47594
47511
  }
47595
47512
  function countRulesInDir(rulesDir) {
47596
- if (!import_fs74.default.existsSync(rulesDir)) return 0;
47513
+ if (!import_fs73.default.existsSync(rulesDir)) return 0;
47597
47514
  let count = 0;
47598
47515
  try {
47599
- for (const entry of import_fs74.default.readdirSync(rulesDir, { withFileTypes: true })) {
47516
+ for (const entry of import_fs73.default.readdirSync(rulesDir, { withFileTypes: true })) {
47600
47517
  if (entry.isDirectory()) {
47601
- count += countRulesInDir(import_path69.default.join(rulesDir, entry.name));
47518
+ count += countRulesInDir(import_path68.default.join(rulesDir, entry.name));
47602
47519
  } else if (entry.isFile() && entry.name.endsWith(".md")) {
47603
47520
  count++;
47604
47521
  }
@@ -47609,46 +47526,46 @@ function countRulesInDir(rulesDir) {
47609
47526
  }
47610
47527
  function isSamePath(a, b) {
47611
47528
  try {
47612
- return import_path69.default.resolve(a) === import_path69.default.resolve(b);
47529
+ return import_path68.default.resolve(a) === import_path68.default.resolve(b);
47613
47530
  } catch {
47614
47531
  return false;
47615
47532
  }
47616
47533
  }
47617
47534
  function countConfigs(cwd) {
47618
- const homeDir2 = import_os62.default.homedir();
47619
- const claudeDir = import_path69.default.join(homeDir2, ".claude");
47535
+ const homeDir2 = import_os61.default.homedir();
47536
+ const claudeDir = import_path68.default.join(homeDir2, ".claude");
47620
47537
  let claudeMdCount = 0;
47621
47538
  let rulesCount = 0;
47622
47539
  let hooksCount = 0;
47623
47540
  const userMcpServers = /* @__PURE__ */ new Set();
47624
47541
  const projectMcpServers = /* @__PURE__ */ new Set();
47625
- if (import_fs74.default.existsSync(import_path69.default.join(claudeDir, "CLAUDE.md"))) claudeMdCount++;
47626
- rulesCount += countRulesInDir(import_path69.default.join(claudeDir, "rules"));
47627
- const userSettings = import_path69.default.join(claudeDir, "settings.json");
47542
+ if (import_fs73.default.existsSync(import_path68.default.join(claudeDir, "CLAUDE.md"))) claudeMdCount++;
47543
+ rulesCount += countRulesInDir(import_path68.default.join(claudeDir, "rules"));
47544
+ const userSettings = import_path68.default.join(claudeDir, "settings.json");
47628
47545
  for (const name of getMcpServerNames(userSettings)) userMcpServers.add(name);
47629
47546
  hooksCount += countHooksInFile(userSettings);
47630
- const userClaudeJson = import_path69.default.join(homeDir2, ".claude.json");
47547
+ const userClaudeJson = import_path68.default.join(homeDir2, ".claude.json");
47631
47548
  for (const name of getMcpServerNames(userClaudeJson)) userMcpServers.add(name);
47632
47549
  for (const name of getDisabledMcpServers(userClaudeJson, "disabledMcpServers")) {
47633
47550
  userMcpServers.delete(name);
47634
47551
  }
47635
47552
  if (cwd) {
47636
- if (import_fs74.default.existsSync(import_path69.default.join(cwd, "CLAUDE.md"))) claudeMdCount++;
47637
- if (import_fs74.default.existsSync(import_path69.default.join(cwd, "CLAUDE.local.md"))) claudeMdCount++;
47638
- const projectClaudeDir = import_path69.default.join(cwd, ".claude");
47553
+ if (import_fs73.default.existsSync(import_path68.default.join(cwd, "CLAUDE.md"))) claudeMdCount++;
47554
+ if (import_fs73.default.existsSync(import_path68.default.join(cwd, "CLAUDE.local.md"))) claudeMdCount++;
47555
+ const projectClaudeDir = import_path68.default.join(cwd, ".claude");
47639
47556
  const overlapsUserScope = isSamePath(projectClaudeDir, claudeDir);
47640
47557
  if (!overlapsUserScope) {
47641
- if (import_fs74.default.existsSync(import_path69.default.join(projectClaudeDir, "CLAUDE.md"))) claudeMdCount++;
47642
- rulesCount += countRulesInDir(import_path69.default.join(projectClaudeDir, "rules"));
47643
- const projSettings = import_path69.default.join(projectClaudeDir, "settings.json");
47558
+ if (import_fs73.default.existsSync(import_path68.default.join(projectClaudeDir, "CLAUDE.md"))) claudeMdCount++;
47559
+ rulesCount += countRulesInDir(import_path68.default.join(projectClaudeDir, "rules"));
47560
+ const projSettings = import_path68.default.join(projectClaudeDir, "settings.json");
47644
47561
  for (const name of getMcpServerNames(projSettings)) projectMcpServers.add(name);
47645
47562
  hooksCount += countHooksInFile(projSettings);
47646
47563
  }
47647
- if (import_fs74.default.existsSync(import_path69.default.join(projectClaudeDir, "CLAUDE.local.md"))) claudeMdCount++;
47648
- const localSettings = import_path69.default.join(projectClaudeDir, "settings.local.json");
47564
+ if (import_fs73.default.existsSync(import_path68.default.join(projectClaudeDir, "CLAUDE.local.md"))) claudeMdCount++;
47565
+ const localSettings = import_path68.default.join(projectClaudeDir, "settings.local.json");
47649
47566
  for (const name of getMcpServerNames(localSettings)) projectMcpServers.add(name);
47650
47567
  hooksCount += countHooksInFile(localSettings);
47651
- const mcpJsonServers = getMcpServerNames(import_path69.default.join(cwd, ".mcp.json"));
47568
+ const mcpJsonServers = getMcpServerNames(import_path68.default.join(cwd, ".mcp.json"));
47652
47569
  const disabledMcpJson = getDisabledMcpServers(localSettings, "disabledMcpjsonServers");
47653
47570
  for (const name of disabledMcpJson) mcpJsonServers.delete(name);
47654
47571
  for (const name of mcpJsonServers) projectMcpServers.add(name);
@@ -47681,12 +47598,12 @@ function readActiveShieldsHud() {
47681
47598
  return shieldsCache.value;
47682
47599
  }
47683
47600
  try {
47684
- const shieldsPath = import_path69.default.join(import_os62.default.homedir(), ".node9", "shields.json");
47685
- if (!import_fs74.default.existsSync(shieldsPath)) {
47601
+ const shieldsPath = import_path68.default.join(import_os61.default.homedir(), ".node9", "shields.json");
47602
+ if (!import_fs73.default.existsSync(shieldsPath)) {
47686
47603
  shieldsCache = { value: [], ts: now };
47687
47604
  return [];
47688
47605
  }
47689
- const parsed = JSON.parse(import_fs74.default.readFileSync(shieldsPath, "utf-8"));
47606
+ const parsed = JSON.parse(import_fs73.default.readFileSync(shieldsPath, "utf-8"));
47690
47607
  if (!Array.isArray(parsed.active)) {
47691
47608
  shieldsCache = { value: [], ts: now };
47692
47609
  return [];
@@ -47788,17 +47705,17 @@ function renderContextLine(stdin) {
47788
47705
  async function main() {
47789
47706
  try {
47790
47707
  const [stdin, daemonStatus2] = await Promise.all([readStdin(), queryDaemon()]);
47791
- if (import_fs74.default.existsSync(import_path69.default.join(import_os62.default.homedir(), ".node9", "hud-debug"))) {
47708
+ if (import_fs73.default.existsSync(import_path68.default.join(import_os61.default.homedir(), ".node9", "hud-debug"))) {
47792
47709
  try {
47793
- const logPath = import_path69.default.join(import_os62.default.homedir(), ".node9", "hud-debug.log");
47710
+ const logPath = import_path68.default.join(import_os61.default.homedir(), ".node9", "hud-debug.log");
47794
47711
  const MAX_LOG_SIZE = 10 * 1024 * 1024;
47795
47712
  let size = 0;
47796
47713
  try {
47797
- size = import_fs74.default.statSync(logPath).size;
47714
+ size = import_fs73.default.statSync(logPath).size;
47798
47715
  } catch {
47799
47716
  }
47800
47717
  if (size < MAX_LOG_SIZE) {
47801
- import_fs74.default.appendFileSync(
47718
+ import_fs73.default.appendFileSync(
47802
47719
  logPath,
47803
47720
  JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), stdin }) + "\n"
47804
47721
  );
@@ -47819,11 +47736,11 @@ async function main() {
47819
47736
  try {
47820
47737
  const cwd = stdin.cwd ?? process.cwd();
47821
47738
  for (const configPath of [
47822
- import_path69.default.join(cwd, "node9.config.json"),
47823
- import_path69.default.join(import_os62.default.homedir(), ".node9", "config.json")
47739
+ import_path68.default.join(cwd, "node9.config.json"),
47740
+ import_path68.default.join(import_os61.default.homedir(), ".node9", "config.json")
47824
47741
  ]) {
47825
- if (!import_fs74.default.existsSync(configPath)) continue;
47826
- const cfg = JSON.parse(import_fs74.default.readFileSync(configPath, "utf-8"));
47742
+ if (!import_fs73.default.existsSync(configPath)) continue;
47743
+ const cfg = JSON.parse(import_fs73.default.readFileSync(configPath, "utf-8"));
47827
47744
  const hud = cfg.settings?.hud;
47828
47745
  if (hud && "showEnvironmentCounts" in hud) return hud.showEnvironmentCounts !== false;
47829
47746
  }
@@ -47841,13 +47758,13 @@ async function main() {
47841
47758
  renderOffline();
47842
47759
  }
47843
47760
  }
47844
- var import_fs74, import_path69, import_os62, import_http6, RESET2, BOLD2, DIM, RED2, GREEN2, YELLOW2, BLUE, MAGENTA, CYAN2, WHITE, BAR_FILLED, BAR_EMPTY, BAR_WIDTH, shieldsCache, SHIELDS_CACHE_TTL_MS;
47761
+ var import_fs73, import_path68, import_os61, import_http6, RESET2, BOLD2, DIM, RED2, GREEN2, YELLOW2, BLUE, MAGENTA, CYAN2, WHITE, BAR_FILLED, BAR_EMPTY, BAR_WIDTH, shieldsCache, SHIELDS_CACHE_TTL_MS;
47845
47762
  var init_hud = __esm({
47846
47763
  "src/cli/hud.ts"() {
47847
47764
  "use strict";
47848
- import_fs74 = __toESM(require("fs"));
47849
- import_path69 = __toESM(require("path"));
47850
- import_os62 = __toESM(require("os"));
47765
+ import_fs73 = __toESM(require("fs"));
47766
+ import_path68 = __toESM(require("path"));
47767
+ import_os61 = __toESM(require("os"));
47851
47768
  import_http6 = __toESM(require("http"));
47852
47769
  init_daemon();
47853
47770
  RESET2 = "\x1B[0m";
@@ -47969,10 +47886,10 @@ function writeCredentialsAndConfig(apiKey, opts = {}) {
47969
47886
  // src/cli.ts
47970
47887
  init_daemon2();
47971
47888
  var import_chalk40 = __toESM(require("chalk"));
47972
- var import_fs75 = __toESM(require("fs"));
47973
- var import_path70 = __toESM(require("path"));
47974
- var import_os63 = __toESM(require("os"));
47975
- var import_child_process15 = require("child_process");
47889
+ var import_fs74 = __toESM(require("fs"));
47890
+ var import_path69 = __toESM(require("path"));
47891
+ var import_os62 = __toESM(require("os"));
47892
+ var import_child_process14 = require("child_process");
47976
47893
  var import_prompts3 = require("@inquirer/prompts");
47977
47894
 
47978
47895
  // src/utils/duration.ts
@@ -48252,290 +48169,28 @@ init_service();
48252
48169
 
48253
48170
  // src/cli/commands/check.ts
48254
48171
  var import_chalk9 = __toESM(require("chalk"));
48255
- var import_fs49 = __toESM(require("fs"));
48256
- var import_child_process7 = require("child_process");
48257
- var import_path47 = __toESM(require("path"));
48258
- var import_os44 = __toESM(require("os"));
48172
+ var import_fs48 = __toESM(require("fs"));
48173
+ var import_child_process6 = require("child_process");
48174
+ var import_path46 = __toESM(require("path"));
48175
+ var import_os43 = __toESM(require("os"));
48259
48176
  init_orchestrator();
48260
48177
  init_state();
48261
48178
  init_daemon();
48262
48179
  init_startup_log();
48263
48180
  init_config();
48264
- init_policy();
48265
48181
 
48266
- // src/undo.ts
48267
- var import_child_process6 = require("child_process");
48268
- var import_crypto12 = __toESM(require("crypto"));
48182
+ // src/skill-pin.ts
48269
48183
  var import_fs46 = __toESM(require("fs"));
48270
- var import_net3 = __toESM(require("net"));
48271
48184
  var import_path44 = __toESM(require("path"));
48272
48185
  var import_os41 = __toESM(require("os"));
48273
- var ACTIVITY_SOCKET_PATH3 = process.platform === "win32" ? "\\\\.\\pipe\\node9-activity" : import_path44.default.join(import_os41.default.tmpdir(), "node9-activity.sock");
48274
- function notifySnapshotTaken(hash, tool, argsSummary, fileCount) {
48275
- try {
48276
- const payload = JSON.stringify({
48277
- status: "snapshot",
48278
- hash,
48279
- tool,
48280
- argsSummary,
48281
- fileCount,
48282
- ts: Date.now()
48283
- });
48284
- const sock = import_net3.default.createConnection(ACTIVITY_SOCKET_PATH3);
48285
- sock.on("connect", () => {
48286
- sock.end(payload);
48287
- });
48288
- sock.on("error", () => {
48289
- });
48290
- } catch {
48291
- }
48292
- }
48293
- var SNAPSHOT_STACK_PATH = import_path44.default.join(import_os41.default.homedir(), ".node9", "snapshots.json");
48294
- var UNDO_LATEST_PATH = import_path44.default.join(import_os41.default.homedir(), ".node9", "undo_latest.txt");
48295
- var MAX_SNAPSHOTS = 10;
48296
- var GIT_TIMEOUT = 15e3;
48297
- function readStack() {
48298
- try {
48299
- if (import_fs46.default.existsSync(SNAPSHOT_STACK_PATH))
48300
- return JSON.parse(import_fs46.default.readFileSync(SNAPSHOT_STACK_PATH, "utf-8"));
48301
- } catch {
48302
- }
48303
- return [];
48304
- }
48305
- function writeStack(stack) {
48306
- const dir = import_path44.default.dirname(SNAPSHOT_STACK_PATH);
48307
- if (!import_fs46.default.existsSync(dir)) import_fs46.default.mkdirSync(dir, { recursive: true });
48308
- import_fs46.default.writeFileSync(SNAPSHOT_STACK_PATH, JSON.stringify(stack, null, 2));
48309
- }
48310
- function extractFilePath(args) {
48311
- if (!args || typeof args !== "object") return null;
48312
- const a = args;
48313
- const fp = a.file_path ?? a.path ?? a.filename;
48314
- return typeof fp === "string" ? fp : null;
48315
- }
48316
- function buildArgsSummary(tool, args) {
48317
- const filePath = extractFilePath(args);
48318
- if (filePath) return filePath;
48319
- if (!args || typeof args !== "object") return "";
48320
- const a = args;
48321
- const cmd = a.command ?? a.cmd;
48322
- if (typeof cmd === "string") return cmd.slice(0, 80);
48323
- const sql = a.sql ?? a.query;
48324
- if (typeof sql === "string") return sql.slice(0, 80);
48325
- return "";
48326
- }
48327
- function findProjectRoot(filePath) {
48328
- let dir = import_path44.default.dirname(filePath);
48329
- while (true) {
48330
- if (import_fs46.default.existsSync(import_path44.default.join(dir, ".git")) || import_fs46.default.existsSync(import_path44.default.join(dir, "package.json"))) {
48331
- return dir;
48332
- }
48333
- const parent = import_path44.default.dirname(dir);
48334
- if (parent === dir) return process.cwd();
48335
- dir = parent;
48336
- }
48337
- }
48338
- function normalizeCwdForHash(cwd) {
48339
- let normalized;
48340
- try {
48341
- normalized = import_fs46.default.realpathSync(cwd);
48342
- } catch {
48343
- normalized = cwd;
48344
- }
48345
- normalized = normalized.replace(/\\/g, "/");
48346
- if (process.platform === "win32") normalized = normalized.toLowerCase();
48347
- return normalized;
48348
- }
48349
- function getShadowRepoDir(cwd) {
48350
- const hash = import_crypto12.default.createHash("sha256").update(normalizeCwdForHash(cwd)).digest("hex").slice(0, 16);
48351
- return import_path44.default.join(import_os41.default.homedir(), ".node9", "snapshots", hash);
48352
- }
48353
- function cleanOrphanedIndexFiles(shadowDir) {
48354
- try {
48355
- const cutoff = Date.now() - 6e4;
48356
- for (const f of import_fs46.default.readdirSync(shadowDir)) {
48357
- if (f.startsWith("index_")) {
48358
- const fp = import_path44.default.join(shadowDir, f);
48359
- try {
48360
- if (import_fs46.default.statSync(fp).mtimeMs < cutoff) import_fs46.default.unlinkSync(fp);
48361
- } catch {
48362
- }
48363
- }
48364
- }
48365
- } catch {
48366
- }
48367
- }
48368
- function writeShadowExcludes(shadowDir, ignorePaths) {
48369
- const hardcoded = [".git", ".node9"];
48370
- const lines = [...hardcoded, ...ignorePaths].join("\n");
48371
- try {
48372
- import_fs46.default.writeFileSync(import_path44.default.join(shadowDir, "info", "exclude"), lines + "\n", "utf8");
48373
- } catch {
48374
- }
48375
- }
48376
- function ensureShadowRepo(shadowDir, cwd) {
48377
- cleanOrphanedIndexFiles(shadowDir);
48378
- const normalizedCwd = normalizeCwdForHash(cwd);
48379
- const shadowEnvBase = { ...process.env, GIT_DIR: shadowDir, GIT_WORK_TREE: cwd };
48380
- const check = (0, import_child_process6.spawnSync)("git", ["rev-parse", "--git-dir"], {
48381
- env: shadowEnvBase,
48382
- timeout: 3e3
48383
- });
48384
- if (check.status === 0) {
48385
- const ptPath = import_path44.default.join(shadowDir, "project-path.txt");
48386
- try {
48387
- const stored = import_fs46.default.readFileSync(ptPath, "utf8").trim();
48388
- if (stored === normalizedCwd) return true;
48389
- if (process.env.NODE9_DEBUG === "1")
48390
- console.error(
48391
- `[Node9] Shadow repo path mismatch: stored="${stored}" expected="${normalizedCwd}" \u2014 reinitializing`
48392
- );
48393
- import_fs46.default.rmSync(shadowDir, { recursive: true, force: true });
48394
- } catch {
48395
- try {
48396
- import_fs46.default.writeFileSync(ptPath, normalizedCwd, "utf8");
48397
- } catch {
48398
- }
48399
- return true;
48400
- }
48401
- }
48402
- try {
48403
- import_fs46.default.mkdirSync(shadowDir, { recursive: true });
48404
- } catch {
48405
- }
48406
- const init = (0, import_child_process6.spawnSync)("git", ["init", "--bare", shadowDir], { timeout: 5e3 });
48407
- if (init.status !== 0 || init.error) {
48408
- const reason = init.error ? init.error.message : init.stderr?.toString();
48409
- if (process.env.NODE9_DEBUG === "1") console.error("[Node9] git init --bare failed:", reason);
48410
- return false;
48411
- }
48412
- const configFile = import_path44.default.join(shadowDir, "config");
48413
- (0, import_child_process6.spawnSync)("git", ["config", "--file", configFile, "core.untrackedCache", "true"], {
48414
- timeout: 3e3
48415
- });
48416
- (0, import_child_process6.spawnSync)("git", ["config", "--file", configFile, "core.fsmonitor", "true"], {
48417
- timeout: 3e3
48418
- });
48419
- try {
48420
- import_fs46.default.writeFileSync(import_path44.default.join(shadowDir, "project-path.txt"), normalizedCwd, "utf8");
48421
- } catch {
48422
- }
48423
- return true;
48424
- }
48425
- async function createShadowSnapshot(tool = "unknown", args = {}, ignorePaths = []) {
48426
- let indexFile = null;
48427
- try {
48428
- const rawFilePath = extractFilePath(args);
48429
- const absFilePath = rawFilePath && import_path44.default.isAbsolute(rawFilePath) ? rawFilePath : null;
48430
- const cwd = absFilePath ? findProjectRoot(absFilePath) : process.cwd();
48431
- const shadowDir = getShadowRepoDir(cwd);
48432
- if (!ensureShadowRepo(shadowDir, cwd)) return null;
48433
- writeShadowExcludes(shadowDir, ignorePaths);
48434
- indexFile = import_path44.default.join(shadowDir, `index_${process.pid}_${Date.now()}`);
48435
- const shadowEnv = {
48436
- ...process.env,
48437
- GIT_DIR: shadowDir,
48438
- GIT_WORK_TREE: cwd,
48439
- GIT_INDEX_FILE: indexFile
48440
- };
48441
- (0, import_child_process6.spawnSync)("git", ["add", "-A"], { env: shadowEnv, timeout: GIT_TIMEOUT });
48442
- const treeRes = (0, import_child_process6.spawnSync)("git", ["write-tree"], { env: shadowEnv, timeout: GIT_TIMEOUT });
48443
- const treeHash = treeRes.stdout?.toString().trim();
48444
- if (!treeHash || treeRes.status !== 0) return null;
48445
- const commitRes = (0, import_child_process6.spawnSync)(
48446
- "git",
48447
- ["commit-tree", treeHash, "-m", `Node9 AI Snapshot: ${(/* @__PURE__ */ new Date()).toISOString()}`],
48448
- { env: shadowEnv, timeout: GIT_TIMEOUT }
48449
- );
48450
- const commitHash = commitRes.stdout?.toString().trim();
48451
- if (!commitHash || commitRes.status !== 0) return null;
48452
- const stack = readStack();
48453
- const prevEntry = [...stack].reverse().find((e) => e.cwd === cwd);
48454
- let capturedFiles = [];
48455
- let capturedDiff = null;
48456
- if (prevEntry) {
48457
- const filesRes = (0, import_child_process6.spawnSync)("git", ["diff", "--name-only", prevEntry.hash, commitHash], {
48458
- env: shadowEnv,
48459
- timeout: GIT_TIMEOUT
48460
- });
48461
- if (filesRes.status === 0) {
48462
- capturedFiles = filesRes.stdout?.toString().trim().split("\n").filter(Boolean) ?? [];
48463
- }
48464
- if (capturedFiles.length === 0) {
48465
- return prevEntry.hash;
48466
- }
48467
- const diffRes = (0, import_child_process6.spawnSync)("git", ["diff", prevEntry.hash, commitHash], {
48468
- env: shadowEnv,
48469
- timeout: GIT_TIMEOUT
48470
- });
48471
- if (diffRes.status === 0) {
48472
- capturedDiff = diffRes.stdout?.toString() || null;
48473
- }
48474
- } else {
48475
- const filesRes = (0, import_child_process6.spawnSync)("git", ["ls-tree", "-r", "--name-only", commitHash], {
48476
- env: shadowEnv,
48477
- timeout: GIT_TIMEOUT
48478
- });
48479
- if (filesRes.status === 0) {
48480
- capturedFiles = filesRes.stdout?.toString().trim().split("\n").filter(Boolean) ?? [];
48481
- }
48482
- capturedDiff = null;
48483
- }
48484
- stack.push({
48485
- hash: commitHash,
48486
- tool,
48487
- argsSummary: buildArgsSummary(tool, args),
48488
- files: capturedFiles,
48489
- diff: capturedDiff,
48490
- cwd,
48491
- timestamp: Date.now()
48492
- });
48493
- const shouldGc = stack.length % 5 === 0;
48494
- let cwdCount = 0;
48495
- let oldestCwdIdx = -1;
48496
- for (let i = 0; i < stack.length; i++) {
48497
- if (stack[i].cwd === cwd) {
48498
- if (oldestCwdIdx === -1) oldestCwdIdx = i;
48499
- cwdCount++;
48500
- }
48501
- }
48502
- if (cwdCount > MAX_SNAPSHOTS) stack.splice(oldestCwdIdx, 1);
48503
- writeStack(stack);
48504
- const entry = stack[stack.length - 1];
48505
- notifySnapshotTaken(commitHash.slice(0, 7), tool, entry.argsSummary, capturedFiles.length);
48506
- import_fs46.default.writeFileSync(UNDO_LATEST_PATH, commitHash);
48507
- if (shouldGc) {
48508
- (0, import_child_process6.spawn)("git", ["gc", "--auto"], { env: shadowEnv, detached: true, stdio: "ignore" }).unref();
48509
- }
48510
- return commitHash;
48511
- } catch (err2) {
48512
- if (process.env.NODE9_DEBUG === "1") console.error("[Node9 Undo Engine Error]:", err2);
48513
- return null;
48514
- } finally {
48515
- if (indexFile) {
48516
- try {
48517
- import_fs46.default.unlinkSync(indexFile);
48518
- } catch {
48519
- }
48520
- }
48521
- }
48522
- }
48523
- function getSnapshotHistory() {
48524
- return readStack();
48525
- }
48526
-
48527
- // src/skill-pin.ts
48528
- var import_fs47 = __toESM(require("fs"));
48529
- var import_path45 = __toESM(require("path"));
48530
- var import_os42 = __toESM(require("os"));
48531
- var import_crypto13 = __toESM(require("crypto"));
48186
+ var import_crypto12 = __toESM(require("crypto"));
48532
48187
  function getPinsFilePath2() {
48533
- return import_path45.default.join(import_os42.default.homedir(), ".node9", "skill-pins.json");
48188
+ return import_path44.default.join(import_os41.default.homedir(), ".node9", "skill-pins.json");
48534
48189
  }
48535
48190
  var MAX_FILES = 5e3;
48536
48191
  var MAX_TOTAL_BYTES = 50 * 1024 * 1024;
48537
48192
  function sha256Bytes(buf) {
48538
- return import_crypto13.default.createHash("sha256").update(buf).digest("hex");
48193
+ return import_crypto12.default.createHash("sha256").update(buf).digest("hex");
48539
48194
  }
48540
48195
  function walkDir(root) {
48541
48196
  const out = [];
@@ -48544,18 +48199,18 @@ function walkDir(root) {
48544
48199
  if (out.length >= MAX_FILES) return;
48545
48200
  let entries;
48546
48201
  try {
48547
- entries = import_fs47.default.readdirSync(dir, { withFileTypes: true });
48202
+ entries = import_fs46.default.readdirSync(dir, { withFileTypes: true });
48548
48203
  } catch {
48549
48204
  return;
48550
48205
  }
48551
48206
  entries.sort((a, b) => a.name.localeCompare(b.name));
48552
48207
  for (const entry of entries) {
48553
48208
  if (out.length >= MAX_FILES) return;
48554
- const full = import_path45.default.join(dir, entry.name);
48555
- const rel = relDir ? import_path45.default.posix.join(relDir, entry.name) : entry.name;
48209
+ const full = import_path44.default.join(dir, entry.name);
48210
+ const rel = relDir ? import_path44.default.posix.join(relDir, entry.name) : entry.name;
48556
48211
  let lst;
48557
48212
  try {
48558
- lst = import_fs47.default.lstatSync(full);
48213
+ lst = import_fs46.default.lstatSync(full);
48559
48214
  } catch {
48560
48215
  continue;
48561
48216
  }
@@ -48567,7 +48222,7 @@ function walkDir(root) {
48567
48222
  if (!lst.isFile()) continue;
48568
48223
  if (totalBytes + lst.size > MAX_TOTAL_BYTES) continue;
48569
48224
  try {
48570
- const buf = import_fs47.default.readFileSync(full);
48225
+ const buf = import_fs46.default.readFileSync(full);
48571
48226
  totalBytes += buf.length;
48572
48227
  out.push({ rel, hash: sha256Bytes(buf) });
48573
48228
  } catch {
@@ -48581,32 +48236,32 @@ function walkDir(root) {
48581
48236
  function hashSkillRoot(absPath) {
48582
48237
  let lst;
48583
48238
  try {
48584
- lst = import_fs47.default.lstatSync(absPath);
48239
+ lst = import_fs46.default.lstatSync(absPath);
48585
48240
  } catch {
48586
48241
  return { exists: false, contentHash: "", fileCount: 0 };
48587
48242
  }
48588
48243
  if (lst.isSymbolicLink()) return { exists: false, contentHash: "", fileCount: 0 };
48589
48244
  if (lst.isFile()) {
48590
48245
  try {
48591
- return { exists: true, contentHash: sha256Bytes(import_fs47.default.readFileSync(absPath)), fileCount: 1 };
48246
+ return { exists: true, contentHash: sha256Bytes(import_fs46.default.readFileSync(absPath)), fileCount: 1 };
48592
48247
  } catch {
48593
48248
  return { exists: false, contentHash: "", fileCount: 0 };
48594
48249
  }
48595
48250
  }
48596
48251
  if (lst.isDirectory()) {
48597
48252
  const entries = walkDir(absPath);
48598
- const contentHash = import_crypto13.default.createHash("sha256").update(entries.join("\n")).digest("hex");
48253
+ const contentHash = import_crypto12.default.createHash("sha256").update(entries.join("\n")).digest("hex");
48599
48254
  return { exists: true, contentHash, fileCount: entries.length };
48600
48255
  }
48601
48256
  return { exists: false, contentHash: "", fileCount: 0 };
48602
48257
  }
48603
48258
  function getRootKey(absPath) {
48604
- return import_crypto13.default.createHash("sha256").update(absPath).digest("hex").slice(0, 16);
48259
+ return import_crypto12.default.createHash("sha256").update(absPath).digest("hex").slice(0, 16);
48605
48260
  }
48606
48261
  function readSkillPinsSafe() {
48607
48262
  const filePath = getPinsFilePath2();
48608
48263
  try {
48609
- const raw = import_fs47.default.readFileSync(filePath, "utf-8");
48264
+ const raw = import_fs46.default.readFileSync(filePath, "utf-8");
48610
48265
  if (!raw.trim()) return { ok: false, reason: "corrupt", detail: "empty file" };
48611
48266
  const parsed = JSON.parse(raw);
48612
48267
  if (!parsed.roots || typeof parsed.roots !== "object" || Array.isArray(parsed.roots)) {
@@ -48626,10 +48281,10 @@ function readSkillPins() {
48626
48281
  }
48627
48282
  function writeSkillPins(data) {
48628
48283
  const filePath = getPinsFilePath2();
48629
- import_fs47.default.mkdirSync(import_path45.default.dirname(filePath), { recursive: true });
48630
- const tmp = `${filePath}.${import_crypto13.default.randomBytes(6).toString("hex")}.tmp`;
48631
- import_fs47.default.writeFileSync(tmp, JSON.stringify(data, null, 2), { mode: 384 });
48632
- import_fs47.default.renameSync(tmp, filePath);
48284
+ import_fs46.default.mkdirSync(import_path44.default.dirname(filePath), { recursive: true });
48285
+ const tmp = `${filePath}.${import_crypto12.default.randomBytes(6).toString("hex")}.tmp`;
48286
+ import_fs46.default.writeFileSync(tmp, JSON.stringify(data, null, 2), { mode: 384 });
48287
+ import_fs46.default.renameSync(tmp, filePath);
48633
48288
  }
48634
48289
  function removePin2(rootKey) {
48635
48290
  const pins = readSkillPins();
@@ -48673,36 +48328,36 @@ function verifyAndPinRoots(roots) {
48673
48328
  return { kind: "verified" };
48674
48329
  }
48675
48330
  function defaultSkillRoots(_cwd) {
48676
- const marketplaces = import_path45.default.join(import_os42.default.homedir(), ".claude", "plugins", "marketplaces");
48331
+ const marketplaces = import_path44.default.join(import_os41.default.homedir(), ".claude", "plugins", "marketplaces");
48677
48332
  const roots = [];
48678
48333
  let registries;
48679
48334
  try {
48680
- registries = import_fs47.default.readdirSync(marketplaces, { withFileTypes: true });
48335
+ registries = import_fs46.default.readdirSync(marketplaces, { withFileTypes: true });
48681
48336
  } catch {
48682
48337
  return [];
48683
48338
  }
48684
48339
  for (const registry of registries) {
48685
48340
  if (!registry.isDirectory()) continue;
48686
- const pluginsDir = import_path45.default.join(marketplaces, registry.name, "plugins");
48341
+ const pluginsDir = import_path44.default.join(marketplaces, registry.name, "plugins");
48687
48342
  let plugins;
48688
48343
  try {
48689
- plugins = import_fs47.default.readdirSync(pluginsDir, { withFileTypes: true });
48344
+ plugins = import_fs46.default.readdirSync(pluginsDir, { withFileTypes: true });
48690
48345
  } catch {
48691
48346
  continue;
48692
48347
  }
48693
48348
  for (const plugin of plugins) {
48694
48349
  if (!plugin.isDirectory()) continue;
48695
- roots.push(import_path45.default.join(pluginsDir, plugin.name));
48350
+ roots.push(import_path44.default.join(pluginsDir, plugin.name));
48696
48351
  }
48697
48352
  }
48698
48353
  return roots;
48699
48354
  }
48700
48355
  function resolveUserSkillRoot(entry, cwd) {
48701
48356
  if (!entry) return null;
48702
- if (entry.startsWith("~/") || entry === "~") return import_path45.default.join(import_os42.default.homedir(), entry.slice(1));
48703
- if (import_path45.default.isAbsolute(entry)) return entry;
48704
- if (!cwd || !import_path45.default.isAbsolute(cwd)) return null;
48705
- return import_path45.default.join(cwd, entry);
48357
+ if (entry.startsWith("~/") || entry === "~") return import_path44.default.join(import_os41.default.homedir(), entry.slice(1));
48358
+ if (import_path44.default.isAbsolute(entry)) return entry;
48359
+ if (!cwd || !import_path44.default.isAbsolute(cwd)) return null;
48360
+ return import_path44.default.join(cwd, entry);
48706
48361
  }
48707
48362
 
48708
48363
  // src/cli/commands/check.ts
@@ -48710,12 +48365,12 @@ init_dlp();
48710
48365
  init_audit();
48711
48366
 
48712
48367
  // src/review-pending.ts
48713
- var import_fs48 = __toESM(require("fs"));
48714
- var import_os43 = __toESM(require("os"));
48715
- var import_path46 = __toESM(require("path"));
48368
+ var import_fs47 = __toESM(require("fs"));
48369
+ var import_os42 = __toESM(require("os"));
48370
+ var import_path45 = __toESM(require("path"));
48716
48371
  init_hasher();
48717
48372
  function storePath() {
48718
- return process.env.NODE9_PENDING_STORE || import_path46.default.join(import_os43.default.homedir(), ".node9", "pending-reviews.json");
48373
+ return process.env.NODE9_PENDING_STORE || import_path45.default.join(import_os42.default.homedir(), ".node9", "pending-reviews.json");
48719
48374
  }
48720
48375
  var TTL_TUID_MS = 72 * 60 * 60 * 1e3;
48721
48376
  var TTL_MS2 = 6 * 60 * 60 * 1e3;
@@ -48733,7 +48388,7 @@ function reviewCorrelationKey(payload) {
48733
48388
  }
48734
48389
  function read() {
48735
48390
  try {
48736
- const parsed = JSON.parse(import_fs48.default.readFileSync(storePath(), "utf-8"));
48391
+ const parsed = JSON.parse(import_fs47.default.readFileSync(storePath(), "utf-8"));
48737
48392
  if (parsed && Array.isArray(parsed.entries)) return parsed;
48738
48393
  } catch {
48739
48394
  }
@@ -48742,11 +48397,11 @@ function read() {
48742
48397
  function write(store) {
48743
48398
  try {
48744
48399
  const p = storePath();
48745
- const dir = import_path46.default.dirname(p);
48746
- if (!import_fs48.default.existsSync(dir)) import_fs48.default.mkdirSync(dir, { recursive: true });
48400
+ const dir = import_path45.default.dirname(p);
48401
+ if (!import_fs47.default.existsSync(dir)) import_fs47.default.mkdirSync(dir, { recursive: true });
48747
48402
  const tmp = `${p}.${process.pid}.tmp`;
48748
- import_fs48.default.writeFileSync(tmp, JSON.stringify(store));
48749
- import_fs48.default.renameSync(tmp, p);
48403
+ import_fs47.default.writeFileSync(tmp, JSON.stringify(store));
48404
+ import_fs47.default.renameSync(tmp, p);
48750
48405
  } catch {
48751
48406
  }
48752
48407
  }
@@ -48875,9 +48530,9 @@ function registerCheckCommand(program2) {
48875
48530
  } catch (err2) {
48876
48531
  const tempConfig = getConfig();
48877
48532
  if (process.env.NODE9_DEBUG === "1" || tempConfig.settings.enableHookLogDebug) {
48878
- const logPath = import_path47.default.join(import_os44.default.homedir(), ".node9", "hook-debug.log");
48533
+ const logPath = import_path46.default.join(import_os43.default.homedir(), ".node9", "hook-debug.log");
48879
48534
  const errMsg = err2 instanceof Error ? err2.message : String(err2);
48880
- import_fs49.default.appendFileSync(
48535
+ import_fs48.default.appendFileSync(
48881
48536
  logPath,
48882
48537
  `[${(/* @__PURE__ */ new Date()).toISOString()}] JSON_PARSE_ERROR: ${errMsg}
48883
48538
  RAW: ${raw}
@@ -48890,14 +48545,14 @@ RAW: ${raw}
48890
48545
  const prompt = typeof payload.prompt === "string" ? payload.prompt : "";
48891
48546
  if (process.env.NODE9_DEBUG === "1") {
48892
48547
  try {
48893
- const logPath = import_path47.default.join(import_os44.default.homedir(), ".node9", "hook-debug.log");
48894
- if (!import_fs49.default.existsSync(import_path47.default.dirname(logPath)))
48895
- import_fs49.default.mkdirSync(import_path47.default.dirname(logPath), { recursive: true });
48548
+ const logPath = import_path46.default.join(import_os43.default.homedir(), ".node9", "hook-debug.log");
48549
+ if (!import_fs48.default.existsSync(import_path46.default.dirname(logPath)))
48550
+ import_fs48.default.mkdirSync(import_path46.default.dirname(logPath), { recursive: true });
48896
48551
  const sanitized = JSON.stringify({
48897
48552
  ...payload,
48898
48553
  prompt: `<redacted, ${prompt.length} bytes>`
48899
48554
  });
48900
- import_fs49.default.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] STDIN: ${sanitized}
48555
+ import_fs48.default.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] STDIN: ${sanitized}
48901
48556
  `);
48902
48557
  } catch {
48903
48558
  }
@@ -48918,8 +48573,8 @@ RAW: ${raw}
48918
48573
  );
48919
48574
  const reason = `\u{1F6A8} Node9 DLP: ${dlpMatch.patternName} detected in prompt (${dlpMatch.redactedSample}). Prompt was not submitted \u2014 remove the credential and try again.`;
48920
48575
  try {
48921
- const ttyFd = import_fs49.default.openSync("/dev/tty", "w");
48922
- import_fs49.default.writeSync(
48576
+ const ttyFd = import_fs48.default.openSync("/dev/tty", "w");
48577
+ import_fs48.default.writeSync(
48923
48578
  ttyFd,
48924
48579
  import_chalk9.default.bgRed.white.bold(`
48925
48580
  \u{1F6A8} NODE9 DLP \u2014 PROMPT BLOCKED
@@ -48929,7 +48584,7 @@ RAW: ${raw}
48929
48584
 
48930
48585
  `)
48931
48586
  );
48932
- import_fs49.default.closeSync(ttyFd);
48587
+ import_fs48.default.closeSync(ttyFd);
48933
48588
  } catch {
48934
48589
  }
48935
48590
  const isCodex = agent2 === "Codex";
@@ -48948,17 +48603,17 @@ RAW: ${raw}
48948
48603
  process.exit(2);
48949
48604
  }
48950
48605
  const payloadCwd = typeof payload.cwd === "string" ? payload.cwd : Array.isArray(payload.workspacePaths) && typeof payload.workspacePaths[0] === "string" ? payload.workspacePaths[0] : void 0;
48951
- const safeCwdForConfig = typeof payloadCwd === "string" && import_path47.default.isAbsolute(payloadCwd) ? payloadCwd : void 0;
48606
+ const safeCwdForConfig = typeof payloadCwd === "string" && import_path46.default.isAbsolute(payloadCwd) ? payloadCwd : void 0;
48952
48607
  const config = getConfig(safeCwdForConfig);
48953
48608
  const daemonDown = !isDaemonRunning();
48954
48609
  if (config.settings.autoStartDaemon && daemonDown && !process.env.NODE9_NO_AUTO_DAEMON) {
48955
48610
  try {
48956
48611
  const scriptPath = process.argv[1];
48957
- if (typeof scriptPath !== "string" || !import_path47.default.isAbsolute(scriptPath))
48612
+ if (typeof scriptPath !== "string" || !import_path46.default.isAbsolute(scriptPath))
48958
48613
  throw new Error("node9: argv[1] is not an absolute path");
48959
- const resolvedScript = import_fs49.default.realpathSync(scriptPath);
48960
- const packageDist = import_fs49.default.realpathSync(import_path47.default.resolve(__dirname, "../.."));
48961
- if (!resolvedScript.startsWith(packageDist + import_path47.default.sep) && resolvedScript !== packageDist)
48614
+ const resolvedScript = import_fs48.default.realpathSync(scriptPath);
48615
+ const packageDist = import_fs48.default.realpathSync(import_path46.default.resolve(__dirname, "../.."));
48616
+ if (!resolvedScript.startsWith(packageDist + import_path46.default.sep) && resolvedScript !== packageDist)
48962
48617
  throw new Error(
48963
48618
  `node9: daemon spawn aborted \u2014 argv[1] (${resolvedScript}) is outside package dist (${packageDist})`
48964
48619
  );
@@ -48976,7 +48631,7 @@ RAW: ${raw}
48976
48631
  const startupFd = openStartupLogFd();
48977
48632
  recordStartupState("starting");
48978
48633
  try {
48979
- const d = (0, import_child_process7.spawn)(process.execPath, [scriptPath, "daemon"], {
48634
+ const d = (0, import_child_process6.spawn)(process.execPath, [scriptPath, "daemon"], {
48980
48635
  detached: true,
48981
48636
  stdio: ["ignore", "ignore", startupFd ?? "ignore"],
48982
48637
  env: { ...safeEnv, NODE9_AUTO_STARTED: "1" }
@@ -48988,17 +48643,17 @@ RAW: ${raw}
48988
48643
  } finally {
48989
48644
  if (startupFd !== void 0) {
48990
48645
  try {
48991
- import_fs49.default.closeSync(startupFd);
48646
+ import_fs48.default.closeSync(startupFd);
48992
48647
  } catch {
48993
48648
  }
48994
48649
  }
48995
48650
  }
48996
48651
  } catch (spawnErr) {
48997
- const logPath = import_path47.default.join(import_os44.default.homedir(), ".node9", "hook-debug.log");
48652
+ const logPath = import_path46.default.join(import_os43.default.homedir(), ".node9", "hook-debug.log");
48998
48653
  const msg = spawnErr instanceof Error ? spawnErr.message : String(spawnErr);
48999
48654
  recordStartupState("failed", "spawn-aborted", msg);
49000
48655
  try {
49001
- import_fs49.default.appendFileSync(
48656
+ import_fs48.default.appendFileSync(
49002
48657
  logPath,
49003
48658
  `[${(/* @__PURE__ */ new Date()).toISOString()}] daemon-autostart-failed: ${msg}
49004
48659
  `
@@ -49012,10 +48667,10 @@ RAW: ${raw}
49012
48667
  );
49013
48668
  }
49014
48669
  if (process.env.NODE9_DEBUG === "1" || config.settings.enableHookLogDebug) {
49015
- const logPath = import_path47.default.join(import_os44.default.homedir(), ".node9", "hook-debug.log");
49016
- if (!import_fs49.default.existsSync(import_path47.default.dirname(logPath)))
49017
- import_fs49.default.mkdirSync(import_path47.default.dirname(logPath), { recursive: true });
49018
- import_fs49.default.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] STDIN: ${raw}
48670
+ const logPath = import_path46.default.join(import_os43.default.homedir(), ".node9", "hook-debug.log");
48671
+ if (!import_fs48.default.existsSync(import_path46.default.dirname(logPath)))
48672
+ import_fs48.default.mkdirSync(import_path46.default.dirname(logPath), { recursive: true });
48673
+ import_fs48.default.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] STDIN: ${raw}
49019
48674
  `);
49020
48675
  }
49021
48676
  const rawToolName = sanitize2(extractToolName(payload));
@@ -49029,8 +48684,8 @@ RAW: ${raw}
49029
48684
  const isHumanDecision = blockedByContext.toLowerCase().includes("user") || blockedByContext.toLowerCase().includes("daemon") || blockedByContext.toLowerCase().includes("decision");
49030
48685
  let ttyFd = null;
49031
48686
  try {
49032
- ttyFd = import_fs49.default.openSync("/dev/tty", "w");
49033
- const writeTty = (line) => import_fs49.default.writeSync(ttyFd, line + "\n");
48687
+ ttyFd = import_fs48.default.openSync("/dev/tty", "w");
48688
+ const writeTty = (line) => import_fs48.default.writeSync(ttyFd, line + "\n");
49034
48689
  if (blockedByContext.includes("DLP") || blockedByContext.includes("Secret Detected") || blockedByContext.includes("Credential Review")) {
49035
48690
  writeTty(import_chalk9.default.bgRed.white.bold(`
49036
48691
  \u{1F6A8} NODE9 DLP ALERT \u2014 CREDENTIAL DETECTED `));
@@ -49049,7 +48704,7 @@ RAW: ${raw}
49049
48704
  } finally {
49050
48705
  if (ttyFd !== null)
49051
48706
  try {
49052
- import_fs49.default.closeSync(ttyFd);
48707
+ import_fs48.default.closeSync(ttyFd);
49053
48708
  } catch {
49054
48709
  }
49055
48710
  }
@@ -49110,8 +48765,8 @@ RAW: ${raw}
49110
48765
  } catch {
49111
48766
  }
49112
48767
  try {
49113
- const ttyFd = import_fs49.default.openSync("/dev/tty", "w");
49114
- import_fs49.default.writeSync(
48768
+ const ttyFd = import_fs48.default.openSync("/dev/tty", "w");
48769
+ import_fs48.default.writeSync(
49115
48770
  ttyFd,
49116
48771
  import_chalk9.default.yellow(
49117
48772
  `
@@ -49119,7 +48774,7 @@ RAW: ${raw}
49119
48774
  `
49120
48775
  )
49121
48776
  );
49122
- import_fs49.default.closeSync(ttyFd);
48777
+ import_fs48.default.closeSync(ttyFd);
49123
48778
  } catch {
49124
48779
  }
49125
48780
  if (agent === "GitHub Copilot") {
@@ -49151,17 +48806,17 @@ RAW: ${raw}
49151
48806
  const safeSessionId = /^[A-Za-z0-9_\-]{1,128}$/.test(rawSessionId) ? rawSessionId : "";
49152
48807
  if (skillPinCfg.enabled && safeSessionId) {
49153
48808
  try {
49154
- const sessionsDir = import_path47.default.join(import_os44.default.homedir(), ".node9", "skill-sessions");
49155
- const flagPath = import_path47.default.join(sessionsDir, `${safeSessionId}.json`);
48809
+ const sessionsDir = import_path46.default.join(import_os43.default.homedir(), ".node9", "skill-sessions");
48810
+ const flagPath = import_path46.default.join(sessionsDir, `${safeSessionId}.json`);
49156
48811
  let flag = null;
49157
48812
  try {
49158
- flag = JSON.parse(import_fs49.default.readFileSync(flagPath, "utf-8"));
48813
+ flag = JSON.parse(import_fs48.default.readFileSync(flagPath, "utf-8"));
49159
48814
  } catch {
49160
48815
  }
49161
48816
  const writeFlag = (data2) => {
49162
48817
  try {
49163
- import_fs49.default.mkdirSync(sessionsDir, { recursive: true });
49164
- import_fs49.default.writeFileSync(
48818
+ import_fs48.default.mkdirSync(sessionsDir, { recursive: true });
48819
+ import_fs48.default.writeFileSync(
49165
48820
  flagPath,
49166
48821
  JSON.stringify({ ...data2, timestamp: (/* @__PURE__ */ new Date()).toISOString() }, null, 2),
49167
48822
  { mode: 384 }
@@ -49172,8 +48827,8 @@ RAW: ${raw}
49172
48827
  const sendSkillWarn = (detail, recoveryCmd) => {
49173
48828
  let ttyFd = null;
49174
48829
  try {
49175
- ttyFd = import_fs49.default.openSync("/dev/tty", "w");
49176
- const w = (line) => import_fs49.default.writeSync(ttyFd, line + "\n");
48830
+ ttyFd = import_fs48.default.openSync("/dev/tty", "w");
48831
+ const w = (line) => import_fs48.default.writeSync(ttyFd, line + "\n");
49177
48832
  w(import_chalk9.default.yellow(`
49178
48833
  \u26A0\uFE0F Node9: installed skill drift detected`));
49179
48834
  w(import_chalk9.default.gray(` ${detail}`));
@@ -49188,7 +48843,7 @@ RAW: ${raw}
49188
48843
  } finally {
49189
48844
  if (ttyFd !== null)
49190
48845
  try {
49191
- import_fs49.default.closeSync(ttyFd);
48846
+ import_fs48.default.closeSync(ttyFd);
49192
48847
  } catch {
49193
48848
  }
49194
48849
  }
@@ -49204,7 +48859,7 @@ RAW: ${raw}
49204
48859
  return;
49205
48860
  }
49206
48861
  if (!flag || flag.state !== "verified" && flag.state !== "warned") {
49207
- const absoluteCwd = typeof payloadCwd === "string" && import_path47.default.isAbsolute(payloadCwd) ? payloadCwd : void 0;
48862
+ const absoluteCwd = typeof payloadCwd === "string" && import_path46.default.isAbsolute(payloadCwd) ? payloadCwd : void 0;
49208
48863
  const extraRoots = skillPinCfg.roots;
49209
48864
  const resolvedExtra = extraRoots.map((r) => resolveUserSkillRoot(r, absoluteCwd)).filter((r) => typeof r === "string");
49210
48865
  const roots = [...defaultSkillRoots(absoluteCwd), ...resolvedExtra];
@@ -49245,10 +48900,10 @@ RAW: ${raw}
49245
48900
  }
49246
48901
  try {
49247
48902
  const cutoff = Date.now() - 7 * 24 * 60 * 60 * 1e3;
49248
- for (const name of import_fs49.default.readdirSync(sessionsDir)) {
49249
- const p = import_path47.default.join(sessionsDir, name);
48903
+ for (const name of import_fs48.default.readdirSync(sessionsDir)) {
48904
+ const p = import_path46.default.join(sessionsDir, name);
49250
48905
  try {
49251
- if (import_fs49.default.statSync(p).mtimeMs < cutoff) import_fs49.default.unlinkSync(p);
48906
+ if (import_fs48.default.statSync(p).mtimeMs < cutoff) import_fs48.default.unlinkSync(p);
49252
48907
  } catch {
49253
48908
  }
49254
48909
  }
@@ -49258,19 +48913,16 @@ RAW: ${raw}
49258
48913
  } catch (err2) {
49259
48914
  if (process.env.NODE9_DEBUG === "1") {
49260
48915
  try {
49261
- const dbg = import_path47.default.join(import_os44.default.homedir(), ".node9", "hook-debug.log");
48916
+ const dbg = import_path46.default.join(import_os43.default.homedir(), ".node9", "hook-debug.log");
49262
48917
  const msg = err2 instanceof Error ? err2.message : String(err2);
49263
- import_fs49.default.appendFileSync(dbg, `[${(/* @__PURE__ */ new Date()).toISOString()}] SKILL_PIN_ERROR: ${msg}
48918
+ import_fs48.default.appendFileSync(dbg, `[${(/* @__PURE__ */ new Date()).toISOString()}] SKILL_PIN_ERROR: ${msg}
49264
48919
  `);
49265
48920
  } catch {
49266
48921
  }
49267
48922
  }
49268
48923
  }
49269
48924
  }
49270
- if (shouldSnapshot(toolName, toolInput, config)) {
49271
- await createShadowSnapshot(toolName, toolInput, config.policy.snapshot.ignorePaths);
49272
- }
49273
- const safeCwdForAuth = typeof payloadCwd === "string" && import_path47.default.isAbsolute(payloadCwd) ? payloadCwd : void 0;
48925
+ const safeCwdForAuth = typeof payloadCwd === "string" && import_path46.default.isAbsolute(payloadCwd) ? payloadCwd : void 0;
49274
48926
  const askMode = resolveAskMode(agent, opts, config);
49275
48927
  const result = await authorizeHeadless(toolName, toolInput, meta, {
49276
48928
  cwd: safeCwdForAuth,
@@ -49295,12 +48947,12 @@ RAW: ${raw}
49295
48947
  }
49296
48948
  if (result.noApprovalMechanism && !isDaemonRunning() && !process.env.NODE9_NO_AUTO_DAEMON && !process.stdout.isTTY && config.settings.autoStartDaemon) {
49297
48949
  try {
49298
- const tty = import_fs49.default.openSync("/dev/tty", "w");
49299
- import_fs49.default.writeSync(
48950
+ const tty = import_fs48.default.openSync("/dev/tty", "w");
48951
+ import_fs48.default.writeSync(
49300
48952
  tty,
49301
48953
  import_chalk9.default.cyan("\n\u{1F6E1}\uFE0F Node9: Starting approval daemon automatically...\n")
49302
48954
  );
49303
- import_fs49.default.closeSync(tty);
48955
+ import_fs48.default.closeSync(tty);
49304
48956
  } catch {
49305
48957
  }
49306
48958
  const daemonReady = await autoStartDaemonAndWait();
@@ -49327,9 +48979,9 @@ RAW: ${raw}
49327
48979
  });
49328
48980
  } catch (err2) {
49329
48981
  if (process.env.NODE9_DEBUG === "1") {
49330
- const logPath = import_path47.default.join(import_os44.default.homedir(), ".node9", "hook-debug.log");
48982
+ const logPath = import_path46.default.join(import_os43.default.homedir(), ".node9", "hook-debug.log");
49331
48983
  const errMsg = err2 instanceof Error ? err2.message : String(err2);
49332
- import_fs49.default.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] ERROR: ${errMsg}
48984
+ import_fs48.default.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] ERROR: ${errMsg}
49333
48985
  `);
49334
48986
  }
49335
48987
  process.exit(0);
@@ -49363,9 +49015,9 @@ RAW: ${raw}
49363
49015
  }
49364
49016
 
49365
49017
  // src/cli/commands/log.ts
49366
- var import_fs50 = __toESM(require("fs"));
49367
- var import_path48 = __toESM(require("path"));
49368
- var import_os45 = __toESM(require("os"));
49018
+ var import_fs49 = __toESM(require("fs"));
49019
+ var import_path47 = __toESM(require("path"));
49020
+ var import_os44 = __toESM(require("os"));
49369
49021
  init_audit();
49370
49022
  init_config();
49371
49023
  init_daemon();
@@ -49501,10 +49153,10 @@ function registerLogCommand(program2) {
49501
49153
  if (rawToolName !== tool) entry.agentToolName = rawToolName;
49502
49154
  const payloadSessionId = payload.session_id ?? payload.conversationId;
49503
49155
  if (payloadSessionId) entry.sessionId = payloadSessionId;
49504
- const logPath = import_path48.default.join(import_os45.default.homedir(), ".node9", "audit.log");
49505
- if (!import_fs50.default.existsSync(import_path48.default.dirname(logPath)))
49506
- import_fs50.default.mkdirSync(import_path48.default.dirname(logPath), { recursive: true });
49507
- import_fs50.default.appendFileSync(logPath, JSON.stringify(entry) + "\n");
49156
+ const logPath = import_path47.default.join(import_os44.default.homedir(), ".node9", "audit.log");
49157
+ if (!import_fs49.default.existsSync(import_path47.default.dirname(logPath)))
49158
+ import_fs49.default.mkdirSync(import_path47.default.dirname(logPath), { recursive: true });
49159
+ import_fs49.default.appendFileSync(logPath, JSON.stringify(entry) + "\n");
49508
49160
  if ((tool === "Bash" || tool === "bash") && isDaemonRunning()) {
49509
49161
  const command = typeof rawInput === "object" && rawInput !== null && "command" in rawInput && typeof rawInput.command === "string" ? rawInput.command : null;
49510
49162
  if (command) {
@@ -49538,7 +49190,7 @@ function registerLogCommand(program2) {
49538
49190
  }
49539
49191
  }
49540
49192
  const payloadCwd = typeof payload.cwd === "string" ? payload.cwd : Array.isArray(payload.workspacePaths) && typeof payload.workspacePaths[0] === "string" ? payload.workspacePaths[0] : void 0;
49541
- const safeCwd = typeof payloadCwd === "string" && import_path48.default.isAbsolute(payloadCwd) ? payloadCwd : void 0;
49193
+ const safeCwd = typeof payloadCwd === "string" && import_path47.default.isAbsolute(payloadCwd) ? payloadCwd : void 0;
49542
49194
  const config = getConfig(safeCwd);
49543
49195
  if (resolvedReview) {
49544
49196
  try {
@@ -49623,28 +49275,13 @@ function registerLogCommand(program2) {
49623
49275
  }
49624
49276
  }
49625
49277
  }
49626
- if ((tool === "Bash" || tool === "bash") && config.settings.enableUndo === true) {
49627
- const bashCommand = typeof rawInput === "object" && rawInput !== null && "command" in rawInput && typeof rawInput.command === "string" ? rawInput.command : null;
49628
- if (bashCommand) {
49629
- const effectiveCwd = safeCwd ?? process.cwd();
49630
- const history = getSnapshotHistory();
49631
- const hasPrior = history.some((e) => e.cwd === effectiveCwd);
49632
- if (hasPrior) {
49633
- await createShadowSnapshot(
49634
- "Bash",
49635
- { command: bashCommand },
49636
- config.policy.snapshot.ignorePaths
49637
- );
49638
- }
49639
- }
49640
- }
49641
49278
  } catch (err2) {
49642
49279
  const msg = err2 instanceof Error ? err2.message : String(err2);
49643
49280
  process.stderr.write(`[Node9] audit log error: ${msg}
49644
49281
  `);
49645
- const debugPath = import_path48.default.join(import_os45.default.homedir(), ".node9", "hook-debug.log");
49282
+ const debugPath = import_path47.default.join(import_os44.default.homedir(), ".node9", "hook-debug.log");
49646
49283
  try {
49647
- import_fs50.default.appendFileSync(debugPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] LOG_ERROR: ${msg}
49284
+ import_fs49.default.appendFileSync(debugPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] LOG_ERROR: ${msg}
49648
49285
  `);
49649
49286
  } catch {
49650
49287
  }
@@ -49669,15 +49306,15 @@ function registerLogCommand(program2) {
49669
49306
 
49670
49307
  // src/cli/commands/shield.ts
49671
49308
  var import_chalk10 = __toESM(require("chalk"));
49672
- var import_fs52 = __toESM(require("fs"));
49673
- var import_path50 = __toESM(require("path"));
49674
- var import_os46 = __toESM(require("os"));
49309
+ var import_fs51 = __toESM(require("fs"));
49310
+ var import_path49 = __toESM(require("path"));
49311
+ var import_os45 = __toESM(require("os"));
49675
49312
  init_shields();
49676
49313
  init_build();
49677
49314
 
49678
49315
  // src/shields/create.ts
49679
- var import_fs51 = __toESM(require("fs"));
49680
- var import_path49 = __toESM(require("path"));
49316
+ var import_fs50 = __toESM(require("fs"));
49317
+ var import_path48 = __toESM(require("path"));
49681
49318
  init_dist();
49682
49319
  init_shields();
49683
49320
  init_audit();
@@ -49697,8 +49334,8 @@ function createShield(def, opts = {}) {
49697
49334
  error: `"${name}" is a built-in shield \u2014 choose a different name (a user shield with this name would shadow the built-in).`
49698
49335
  };
49699
49336
  }
49700
- const filePath = import_path49.default.join(USER_SHIELDS_DIR_PATH, `${name}.json`);
49701
- if (!opts.overwrite && import_fs51.default.existsSync(filePath)) {
49337
+ const filePath = import_path48.default.join(USER_SHIELDS_DIR_PATH, `${name}.json`);
49338
+ if (!opts.overwrite && import_fs50.default.existsSync(filePath)) {
49702
49339
  return {
49703
49340
  ok: false,
49704
49341
  error: `Shield "${name}" already exists at ${filePath}. Pass --overwrite to replace it.`
@@ -49763,8 +49400,8 @@ var COMMUNITY_INDEX_URL = "https://raw.githubusercontent.com/node9ai/node9-proxy
49763
49400
  function readCloudShields() {
49764
49401
  const out = /* @__PURE__ */ new Set();
49765
49402
  try {
49766
- const file = import_path50.default.join(import_os46.default.homedir(), ".node9", "rules-cache.json");
49767
- const raw = JSON.parse(import_fs52.default.readFileSync(file, "utf-8"));
49403
+ const file = import_path49.default.join(import_os45.default.homedir(), ".node9", "rules-cache.json");
49404
+ const raw = JSON.parse(import_fs51.default.readFileSync(file, "utf-8"));
49768
49405
  for (const r of raw.rules ?? []) {
49769
49406
  const rule = r;
49770
49407
  const fromSource = rule.source?.startsWith("SHIELD:") ? rule.source.slice("SHIELD:".length).toLowerCase() : void 0;
@@ -50081,7 +49718,7 @@ function registerShieldCommand(program2) {
50081
49718
  if (opts.fromFile) {
50082
49719
  let raw;
50083
49720
  try {
50084
- raw = JSON.parse(import_fs52.default.readFileSync(opts.fromFile, "utf-8"));
49721
+ raw = JSON.parse(import_fs51.default.readFileSync(opts.fromFile, "utf-8"));
50085
49722
  } catch (err2) {
50086
49723
  console.error(
50087
49724
  import_chalk10.default.red(`
@@ -50201,10 +49838,10 @@ function registerConfigShowCommand(program2) {
50201
49838
 
50202
49839
  // src/cli/commands/doctor.ts
50203
49840
  var import_chalk11 = __toESM(require("chalk"));
50204
- var import_fs54 = __toESM(require("fs"));
50205
- var import_path52 = __toESM(require("path"));
50206
- var import_os48 = __toESM(require("os"));
50207
- var import_child_process8 = require("child_process");
49841
+ var import_fs53 = __toESM(require("fs"));
49842
+ var import_path51 = __toESM(require("path"));
49843
+ var import_os47 = __toESM(require("os"));
49844
+ var import_child_process7 = require("child_process");
50208
49845
  init_daemon();
50209
49846
  init_build_id();
50210
49847
  init_config();
@@ -50229,22 +49866,22 @@ function agoLabel(iso, now = Date.now()) {
50229
49866
  init_startup_log();
50230
49867
 
50231
49868
  // src/utils/undo-leftovers.ts
50232
- var import_fs53 = __toESM(require("fs"));
50233
- var import_os47 = __toESM(require("os"));
50234
- var import_path51 = __toESM(require("path"));
49869
+ var import_fs52 = __toESM(require("fs"));
49870
+ var import_os46 = __toESM(require("os"));
49871
+ var import_path50 = __toESM(require("path"));
50235
49872
  function candidates(homeDir2) {
50236
- const node9Dir = import_path51.default.join(homeDir2, ".node9");
49873
+ const node9Dir = import_path50.default.join(homeDir2, ".node9");
50237
49874
  return [
50238
- import_path51.default.join(node9Dir, "snapshots"),
50239
- import_path51.default.join(node9Dir, "snapshots.json"),
50240
- import_path51.default.join(node9Dir, "undo_latest.txt")
49875
+ import_path50.default.join(node9Dir, "snapshots"),
49876
+ import_path50.default.join(node9Dir, "snapshots.json"),
49877
+ import_path50.default.join(node9Dir, "undo_latest.txt")
50241
49878
  ];
50242
49879
  }
50243
- function undoLeftoverPaths(homeDir2 = import_os47.default.homedir()) {
49880
+ function undoLeftoverPaths(homeDir2 = import_os46.default.homedir()) {
50244
49881
  const found = [];
50245
49882
  for (const p of candidates(homeDir2)) {
50246
49883
  try {
50247
- import_fs53.default.lstatSync(p);
49884
+ import_fs52.default.lstatSync(p);
50248
49885
  found.push(p);
50249
49886
  } catch (err2) {
50250
49887
  if (err2.code !== "ENOENT") found.push(p);
@@ -50252,11 +49889,11 @@ function undoLeftoverPaths(homeDir2 = import_os47.default.homedir()) {
50252
49889
  }
50253
49890
  return found;
50254
49891
  }
50255
- function purgeUndoLeftovers(homeDir2 = import_os47.default.homedir()) {
49892
+ function purgeUndoLeftovers(homeDir2 = import_os46.default.homedir()) {
50256
49893
  const out = { deleted: [], skipped: [], failed: [] };
50257
49894
  for (const p of undoLeftoverPaths(homeDir2)) {
50258
49895
  try {
50259
- if (import_fs53.default.lstatSync(p).isSymbolicLink()) {
49896
+ if (import_fs52.default.lstatSync(p).isSymbolicLink()) {
50260
49897
  out.skipped.push({
50261
49898
  path: p,
50262
49899
  reason: "is a symlink \u2014 remove it yourself so nothing else is followed"
@@ -50269,11 +49906,11 @@ function purgeUndoLeftovers(homeDir2 = import_os47.default.homedir()) {
50269
49906
  }
50270
49907
  let reason = null;
50271
49908
  try {
50272
- import_fs53.default.rmSync(p, { recursive: true, force: true });
49909
+ import_fs52.default.rmSync(p, { recursive: true, force: true });
50273
49910
  } catch (err2) {
50274
49911
  reason = err2.message;
50275
49912
  }
50276
- if (import_fs53.default.existsSync(p)) {
49913
+ if (import_fs52.default.existsSync(p)) {
50277
49914
  out.failed.push({ path: p, reason: reason ?? "still present after removal" });
50278
49915
  } else {
50279
49916
  out.deleted.push(p);
@@ -50285,7 +49922,7 @@ function purgeUndoLeftovers(homeDir2 = import_os47.default.homedir()) {
50285
49922
  // src/cli/commands/doctor.ts
50286
49923
  function registerDoctorCommand(program2, version2) {
50287
49924
  program2.command("doctor").description("Check that Node9 is installed and configured correctly").action(async () => {
50288
- const homeDir2 = import_os48.default.homedir();
49925
+ const homeDir2 = import_os47.default.homedir();
50289
49926
  let failures = 0;
50290
49927
  function pass(msg) {
50291
49928
  console.log(import_chalk11.default.green(" \u2705 ") + msg);
@@ -50307,7 +49944,7 @@ function registerDoctorCommand(program2, version2) {
50307
49944
  `));
50308
49945
  section("Binary");
50309
49946
  try {
50310
- const which = (0, import_child_process8.execSync)("which node9", { encoding: "utf-8", timeout: 3e3 }).trim();
49947
+ const which = (0, import_child_process7.execSync)("which node9", { encoding: "utf-8", timeout: 3e3 }).trim();
50311
49948
  pass(`node9 found at ${which}`);
50312
49949
  } catch {
50313
49950
  warn("node9 not found in $PATH \u2014 hooks may not find it", "Run: npm install -g node9-ai");
@@ -50322,16 +49959,16 @@ function registerDoctorCommand(program2, version2) {
50322
49959
  );
50323
49960
  }
50324
49961
  try {
50325
- const gitVersion = (0, import_child_process8.execSync)("git --version", { encoding: "utf-8", timeout: 3e3 }).trim();
49962
+ const gitVersion = (0, import_child_process7.execSync)("git --version", { encoding: "utf-8", timeout: 3e3 }).trim();
50326
49963
  pass(gitVersion);
50327
49964
  } catch {
50328
49965
  warn("git not found", "Install git \u2014 node9 reads repo state for scans and reports");
50329
49966
  }
50330
49967
  section("Configuration");
50331
- const globalConfigPath = import_path52.default.join(homeDir2, ".node9", "config.json");
50332
- if (import_fs54.default.existsSync(globalConfigPath)) {
49968
+ const globalConfigPath = import_path51.default.join(homeDir2, ".node9", "config.json");
49969
+ if (import_fs53.default.existsSync(globalConfigPath)) {
50333
49970
  try {
50334
- JSON.parse(import_fs54.default.readFileSync(globalConfigPath, "utf-8"));
49971
+ JSON.parse(import_fs53.default.readFileSync(globalConfigPath, "utf-8"));
50335
49972
  pass("~/.node9/config.json found and valid");
50336
49973
  } catch {
50337
49974
  fail("~/.node9/config.json is invalid JSON", "Run: node9 init --force");
@@ -50346,10 +49983,10 @@ function registerDoctorCommand(program2, version2) {
50346
49983
  "Remove them when ready: node9 undo --purge"
50347
49984
  );
50348
49985
  }
50349
- const projectConfigPath = import_path52.default.join(process.cwd(), "node9.config.json");
50350
- if (import_fs54.default.existsSync(projectConfigPath)) {
49986
+ const projectConfigPath = import_path51.default.join(process.cwd(), "node9.config.json");
49987
+ if (import_fs53.default.existsSync(projectConfigPath)) {
50351
49988
  try {
50352
- JSON.parse(import_fs54.default.readFileSync(projectConfigPath, "utf-8"));
49989
+ JSON.parse(import_fs53.default.readFileSync(projectConfigPath, "utf-8"));
50353
49990
  pass("node9.config.json found and valid (project)");
50354
49991
  } catch {
50355
49992
  fail(
@@ -50358,8 +49995,8 @@ function registerDoctorCommand(program2, version2) {
50358
49995
  );
50359
49996
  }
50360
49997
  }
50361
- const credsPath = import_path52.default.join(homeDir2, ".node9", "credentials.json");
50362
- if (import_fs54.default.existsSync(credsPath)) {
49998
+ const credsPath = import_path51.default.join(homeDir2, ".node9", "credentials.json");
49999
+ if (import_fs53.default.existsSync(credsPath)) {
50363
50000
  pass("Cloud credentials found (~/.node9/credentials.json)");
50364
50001
  } else {
50365
50002
  warn(
@@ -50425,7 +50062,7 @@ function registerDoctorCommand(program2, version2) {
50425
50062
  cloudEnabled: !!getConfig().settings.approvers?.cloud
50426
50063
  });
50427
50064
  if (autostart) warn(autostart.message, autostart.hint);
50428
- if (import_fs54.default.existsSync(import_path52.default.join(import_os48.default.homedir(), ".node9", "credentials.json")) && getConfig().settings.approvers?.cloud) {
50065
+ if (import_fs53.default.existsSync(import_path51.default.join(import_os47.default.homedir(), ".node9", "credentials.json")) && getConfig().settings.approvers?.cloud) {
50429
50066
  section("Policy sync");
50430
50067
  const health = readSyncHealth();
50431
50068
  if (isPolicyStale(Date.now(), health)) {
@@ -50443,7 +50080,7 @@ function registerDoctorCommand(program2, version2) {
50443
50080
  try {
50444
50081
  const { shipLagBytes: shipLagBytes2, readWatermark: readWatermark2, AUDIT_SHIP_WATERMARK: AUDIT_SHIP_WATERMARK2 } = await Promise.resolve().then(() => (init_audit_shipper(), audit_shipper_exports));
50445
50082
  const cfg = getConfig();
50446
- const creds = import_fs54.default.existsSync(import_path52.default.join(import_os48.default.homedir(), ".node9", "credentials.json"));
50083
+ const creds = import_fs53.default.existsSync(import_path51.default.join(import_os47.default.homedir(), ".node9", "credentials.json"));
50447
50084
  if (!creds) {
50448
50085
  warn("Not logged in \u2014 audit rows stay local", "Run: node9 login <api-key>");
50449
50086
  } else if (!cfg.settings.approvers.cloud) {
@@ -50493,10 +50130,10 @@ function registerDoctorCommand(program2, version2) {
50493
50130
 
50494
50131
  // src/cli/commands/audit.ts
50495
50132
  var import_chalk12 = __toESM(require("chalk"));
50496
- var import_fs55 = __toESM(require("fs"));
50497
- var import_path53 = __toESM(require("path"));
50133
+ var import_fs54 = __toESM(require("fs"));
50134
+ var import_path52 = __toESM(require("path"));
50498
50135
  init_decision();
50499
- var import_os49 = __toESM(require("os"));
50136
+ var import_os48 = __toESM(require("os"));
50500
50137
  function formatRelativeTime(timestamp) {
50501
50138
  const diff = Date.now() - new Date(timestamp).getTime();
50502
50139
  const sec = Math.floor(diff / 1e3);
@@ -50509,14 +50146,14 @@ function formatRelativeTime(timestamp) {
50509
50146
  }
50510
50147
  function registerAuditCommand(program2) {
50511
50148
  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) => {
50512
- const logPath = import_path53.default.join(import_os49.default.homedir(), ".node9", "audit.log");
50513
- if (!import_fs55.default.existsSync(logPath)) {
50149
+ const logPath = import_path52.default.join(import_os48.default.homedir(), ".node9", "audit.log");
50150
+ if (!import_fs54.default.existsSync(logPath)) {
50514
50151
  console.log(
50515
50152
  import_chalk12.default.yellow("No audit logs found. Run node9 with an agent to generate entries.")
50516
50153
  );
50517
50154
  return;
50518
50155
  }
50519
- const raw = import_fs55.default.readFileSync(logPath, "utf-8");
50156
+ const raw = import_fs54.default.readFileSync(logPath, "utf-8");
50520
50157
  const lines = raw.split("\n").filter((l) => l.trim() !== "");
50521
50158
  let entries = lines.flatMap((line) => {
50522
50159
  try {
@@ -50578,9 +50215,9 @@ function registerAuditCommand(program2) {
50578
50215
  var import_chalk13 = __toESM(require("chalk"));
50579
50216
 
50580
50217
  // src/cli/aggregate/report-audit.ts
50581
- var import_fs56 = __toESM(require("fs"));
50582
- var import_os50 = __toESM(require("os"));
50583
- var import_path54 = __toESM(require("path"));
50218
+ var import_fs55 = __toESM(require("fs"));
50219
+ var import_os49 = __toESM(require("os"));
50220
+ var import_path53 = __toESM(require("path"));
50584
50221
  init_costSync();
50585
50222
  init_litellm();
50586
50223
  init_cost_codex();
@@ -50664,8 +50301,8 @@ function getDateRange(period, now) {
50664
50301
  }
50665
50302
  }
50666
50303
  function parseAuditLog(logPath) {
50667
- if (!import_fs56.default.existsSync(logPath)) return [];
50668
- const raw = import_fs56.default.readFileSync(logPath, "utf-8");
50304
+ if (!import_fs55.default.existsSync(logPath)) return [];
50305
+ const raw = import_fs55.default.readFileSync(logPath, "utf-8");
50669
50306
  return raw.split("\n").flatMap((line) => {
50670
50307
  if (!line.trim()) return [];
50671
50308
  try {
@@ -50719,25 +50356,25 @@ function freezeClaudeCost(acc) {
50719
50356
  };
50720
50357
  }
50721
50358
  function processClaudeCostProject(proj, projectsDir, start, end, acc) {
50722
- const projPath = import_path54.default.join(projectsDir, proj);
50359
+ const projPath = import_path53.default.join(projectsDir, proj);
50723
50360
  let files;
50724
50361
  try {
50725
- const stat = import_fs56.default.statSync(projPath);
50362
+ const stat = import_fs55.default.statSync(projPath);
50726
50363
  if (!stat.isDirectory()) return;
50727
- files = import_fs56.default.readdirSync(projPath).filter((f) => f.endsWith(".jsonl") && !f.startsWith("agent-"));
50364
+ files = import_fs55.default.readdirSync(projPath).filter((f) => f.endsWith(".jsonl") && !f.startsWith("agent-"));
50728
50365
  } catch {
50729
50366
  return;
50730
50367
  }
50731
50368
  const startMs = start.getTime();
50732
50369
  for (const file of files) {
50733
- const filePath = import_path54.default.join(projPath, file);
50370
+ const filePath = import_path53.default.join(projPath, file);
50734
50371
  try {
50735
- if (import_fs56.default.statSync(filePath).mtimeMs < startMs) continue;
50372
+ if (import_fs55.default.statSync(filePath).mtimeMs < startMs) continue;
50736
50373
  } catch {
50737
50374
  continue;
50738
50375
  }
50739
50376
  try {
50740
- const raw = import_fs56.default.readFileSync(filePath, "utf-8");
50377
+ const raw = import_fs55.default.readFileSync(filePath, "utf-8");
50741
50378
  for (const line of raw.split("\n")) {
50742
50379
  if (!line.trim()) continue;
50743
50380
  let entry;
@@ -50787,10 +50424,10 @@ function processClaudeCostProject(proj, projectsDir, start, end, acc) {
50787
50424
  }
50788
50425
  function loadClaudeCost(start, end, projectsDir) {
50789
50426
  const acc = emptyClaudeCostAccumulator();
50790
- if (!import_fs56.default.existsSync(projectsDir)) return freezeClaudeCost(acc);
50427
+ if (!import_fs55.default.existsSync(projectsDir)) return freezeClaudeCost(acc);
50791
50428
  let dirs;
50792
50429
  try {
50793
- dirs = import_fs56.default.readdirSync(projectsDir);
50430
+ dirs = import_fs55.default.readdirSync(projectsDir);
50794
50431
  } catch {
50795
50432
  return freezeClaudeCost(acc);
50796
50433
  }
@@ -50802,7 +50439,7 @@ function loadClaudeCost(start, end, projectsDir) {
50802
50439
  function processCodexCostFile(filePath, start, end, acc) {
50803
50440
  let lines;
50804
50441
  try {
50805
- lines = import_fs56.default.readFileSync(filePath, "utf-8").split("\n");
50442
+ lines = import_fs55.default.readFileSync(filePath, "utf-8").split("\n");
50806
50443
  } catch {
50807
50444
  return;
50808
50445
  }
@@ -50857,31 +50494,31 @@ function processCodexCostFile(filePath, start, end, acc) {
50857
50494
  }
50858
50495
  function listCodexSessionFiles2(sessionsBase) {
50859
50496
  const jsonlFiles = [];
50860
- if (!import_fs56.default.existsSync(sessionsBase)) return jsonlFiles;
50497
+ if (!import_fs55.default.existsSync(sessionsBase)) return jsonlFiles;
50861
50498
  try {
50862
- for (const year of import_fs56.default.readdirSync(sessionsBase)) {
50863
- const yearPath = import_path54.default.join(sessionsBase, year);
50499
+ for (const year of import_fs55.default.readdirSync(sessionsBase)) {
50500
+ const yearPath = import_path53.default.join(sessionsBase, year);
50864
50501
  try {
50865
- if (!import_fs56.default.statSync(yearPath).isDirectory()) continue;
50502
+ if (!import_fs55.default.statSync(yearPath).isDirectory()) continue;
50866
50503
  } catch {
50867
50504
  continue;
50868
50505
  }
50869
- for (const month of import_fs56.default.readdirSync(yearPath)) {
50870
- const monthPath = import_path54.default.join(yearPath, month);
50506
+ for (const month of import_fs55.default.readdirSync(yearPath)) {
50507
+ const monthPath = import_path53.default.join(yearPath, month);
50871
50508
  try {
50872
- if (!import_fs56.default.statSync(monthPath).isDirectory()) continue;
50509
+ if (!import_fs55.default.statSync(monthPath).isDirectory()) continue;
50873
50510
  } catch {
50874
50511
  continue;
50875
50512
  }
50876
- for (const day of import_fs56.default.readdirSync(monthPath)) {
50877
- const dayPath = import_path54.default.join(monthPath, day);
50513
+ for (const day of import_fs55.default.readdirSync(monthPath)) {
50514
+ const dayPath = import_path53.default.join(monthPath, day);
50878
50515
  try {
50879
- if (!import_fs56.default.statSync(dayPath).isDirectory()) continue;
50516
+ if (!import_fs55.default.statSync(dayPath).isDirectory()) continue;
50880
50517
  } catch {
50881
50518
  continue;
50882
50519
  }
50883
- for (const file of import_fs56.default.readdirSync(dayPath)) {
50884
- if (file.endsWith(".jsonl")) jsonlFiles.push(import_path54.default.join(dayPath, file));
50520
+ for (const file of import_fs55.default.readdirSync(dayPath)) {
50521
+ if (file.endsWith(".jsonl")) jsonlFiles.push(import_path53.default.join(dayPath, file));
50885
50522
  }
50886
50523
  }
50887
50524
  }
@@ -50946,13 +50583,13 @@ function freezeGeminiCost(acc) {
50946
50583
  function processGeminiCostFile(filePath, projectKey, start, end, acc) {
50947
50584
  const startMs = start.getTime();
50948
50585
  try {
50949
- if (import_fs56.default.statSync(filePath).mtimeMs < startMs) return;
50586
+ if (import_fs55.default.statSync(filePath).mtimeMs < startMs) return;
50950
50587
  } catch {
50951
50588
  return;
50952
50589
  }
50953
50590
  let raw;
50954
50591
  try {
50955
- raw = import_fs56.default.readFileSync(filePath, "utf-8");
50592
+ raw = import_fs55.default.readFileSync(filePath, "utf-8");
50956
50593
  } catch {
50957
50594
  return;
50958
50595
  }
@@ -51001,30 +50638,30 @@ function listGeminiSessionFiles2(geminiTmpDir2) {
51001
50638
  const out = [];
51002
50639
  let dirs;
51003
50640
  try {
51004
- if (!import_fs56.default.statSync(geminiTmpDir2).isDirectory()) return out;
51005
- dirs = import_fs56.default.readdirSync(geminiTmpDir2);
50641
+ if (!import_fs55.default.statSync(geminiTmpDir2).isDirectory()) return out;
50642
+ dirs = import_fs55.default.readdirSync(geminiTmpDir2);
51006
50643
  } catch {
51007
50644
  return out;
51008
50645
  }
51009
50646
  for (const proj of dirs) {
51010
- const chatsDir = import_path54.default.join(geminiTmpDir2, proj, "chats");
50647
+ const chatsDir = import_path53.default.join(geminiTmpDir2, proj, "chats");
51011
50648
  let files;
51012
50649
  try {
51013
- if (!import_fs56.default.statSync(chatsDir).isDirectory()) continue;
51014
- files = import_fs56.default.readdirSync(chatsDir);
50650
+ if (!import_fs55.default.statSync(chatsDir).isDirectory()) continue;
50651
+ files = import_fs55.default.readdirSync(chatsDir);
51015
50652
  } catch {
51016
50653
  continue;
51017
50654
  }
51018
50655
  for (const f of files) {
51019
50656
  if (!f.endsWith(".jsonl")) continue;
51020
- out.push({ projectKey: proj, file: import_path54.default.join(chatsDir, f) });
50657
+ out.push({ projectKey: proj, file: import_path53.default.join(chatsDir, f) });
51021
50658
  }
51022
50659
  }
51023
50660
  return out;
51024
50661
  }
51025
50662
  function loadGeminiCost(start, end, geminiTmpDir2) {
51026
50663
  const acc = emptyGeminiAccumulator();
51027
- if (!import_fs56.default.existsSync(geminiTmpDir2)) return freezeGeminiCost(acc);
50664
+ if (!import_fs55.default.existsSync(geminiTmpDir2)) return freezeGeminiCost(acc);
51028
50665
  for (const { projectKey, file } of listGeminiSessionFiles2(geminiTmpDir2)) {
51029
50666
  processGeminiCostFile(file, projectKey, start, end, acc);
51030
50667
  }
@@ -51042,11 +50679,11 @@ function dimensionOfBlock(checkedBy, ruleName) {
51042
50679
  }
51043
50680
  function aggregateReportFromAudit(period, opts = {}) {
51044
50681
  const now = opts.now ?? /* @__PURE__ */ new Date();
51045
- const auditLogPath = opts.auditLogPath ?? import_path54.default.join(import_os50.default.homedir(), ".node9", "audit.log");
51046
- const claudeProjectsDir = opts.claudeProjectsDir ?? import_path54.default.join(import_os50.default.homedir(), ".claude", "projects");
51047
- const codexSessionsDir2 = opts.codexSessionsDir ?? import_path54.default.join(import_os50.default.homedir(), ".codex", "sessions");
51048
- const geminiTmpDir2 = opts.geminiTmpDir ?? import_path54.default.join(import_os50.default.homedir(), ".gemini", "tmp");
51049
- const hasAuditFile = import_fs56.default.existsSync(auditLogPath);
50682
+ const auditLogPath = opts.auditLogPath ?? import_path53.default.join(import_os49.default.homedir(), ".node9", "audit.log");
50683
+ const claudeProjectsDir = opts.claudeProjectsDir ?? import_path53.default.join(import_os49.default.homedir(), ".claude", "projects");
50684
+ const codexSessionsDir2 = opts.codexSessionsDir ?? import_path53.default.join(import_os49.default.homedir(), ".codex", "sessions");
50685
+ const geminiTmpDir2 = opts.geminiTmpDir ?? import_path53.default.join(import_os49.default.homedir(), ".gemini", "tmp");
50686
+ const hasAuditFile = import_fs55.default.existsSync(auditLogPath);
51050
50687
  const allEntries = opts.preloadedAuditEntries ?? parseAuditLog(auditLogPath);
51051
50688
  const unackedDlp = allEntries.filter((e) => e.source === "response-dlp");
51052
50689
  const { start, end } = getDateRange(period, now);
@@ -51752,9 +51389,9 @@ function renderTerminalReport(data, responseDlpEntries, excludeTests) {
51752
51389
 
51753
51390
  // src/cli/commands/daemon-cmd.ts
51754
51391
  var import_chalk14 = __toESM(require("chalk"));
51755
- var import_child_process9 = require("child_process");
51392
+ var import_child_process8 = require("child_process");
51756
51393
  init_daemon();
51757
- var import_fs57 = __toESM(require("fs"));
51394
+ var import_fs56 = __toESM(require("fs"));
51758
51395
  init_startup_log();
51759
51396
  init_daemon2();
51760
51397
  var VALID_ACTIONS = "start | stop | restart | status | install | uninstall";
@@ -51799,7 +51436,7 @@ function registerDaemonCommand(program2) {
51799
51436
  }
51800
51437
  const restartFd = openStartupLogFd();
51801
51438
  recordStartupState("starting");
51802
- const child = (0, import_child_process9.spawn)(process.execPath, [process.argv[1], "daemon"], {
51439
+ const child = (0, import_child_process8.spawn)(process.execPath, [process.argv[1], "daemon"], {
51803
51440
  detached: true,
51804
51441
  stdio: ["ignore", "ignore", restartFd ?? "ignore"],
51805
51442
  env: { ...process.env, NODE9_AUTO_STARTED: "1" }
@@ -51811,7 +51448,7 @@ function registerDaemonCommand(program2) {
51811
51448
  child.unref();
51812
51449
  if (restartFd !== void 0) {
51813
51450
  try {
51814
- import_fs57.default.closeSync(restartFd);
51451
+ import_fs56.default.closeSync(restartFd);
51815
51452
  } catch {
51816
51453
  }
51817
51454
  }
@@ -51843,7 +51480,7 @@ function registerDaemonCommand(program2) {
51843
51480
  const startupFd = openStartupLogFd();
51844
51481
  try {
51845
51482
  recordStartupState("starting");
51846
- const child = (0, import_child_process9.spawn)(process.execPath, [process.argv[1], "daemon"], {
51483
+ const child = (0, import_child_process8.spawn)(process.execPath, [process.argv[1], "daemon"], {
51847
51484
  detached: true,
51848
51485
  // Capture the child's stderr: a module-load crash prints its stack there
51849
51486
  // and dies before it can record anything itself.
@@ -51862,7 +51499,7 @@ function registerDaemonCommand(program2) {
51862
51499
  } finally {
51863
51500
  if (startupFd !== void 0) {
51864
51501
  try {
51865
- import_fs57.default.closeSync(startupFd);
51502
+ import_fs56.default.closeSync(startupFd);
51866
51503
  } catch {
51867
51504
  }
51868
51505
  }
@@ -51876,9 +51513,9 @@ function registerDaemonCommand(program2) {
51876
51513
 
51877
51514
  // src/cli/commands/status.ts
51878
51515
  var import_chalk15 = __toESM(require("chalk"));
51879
- var import_fs58 = __toESM(require("fs"));
51880
- var import_path55 = __toESM(require("path"));
51881
- var import_os51 = __toESM(require("os"));
51516
+ var import_fs57 = __toESM(require("fs"));
51517
+ var import_path54 = __toESM(require("path"));
51518
+ var import_os50 = __toESM(require("os"));
51882
51519
  init_core();
51883
51520
  init_daemon();
51884
51521
  init_build_id();
@@ -51965,20 +51602,20 @@ function registerStatusCommand(program2) {
51965
51602
  console.log("");
51966
51603
  const modeLabel = settings.mode === "audit" ? import_chalk15.default.blue("audit") : settings.mode === "strict" ? import_chalk15.default.red("strict") : import_chalk15.default.white("standard");
51967
51604
  console.log(` Mode: ${modeLabel}`);
51968
- const projectConfig = import_path55.default.join(process.cwd(), "node9.config.json");
51969
- const globalConfig = import_path55.default.join(import_os51.default.homedir(), ".node9", "config.json");
51605
+ const projectConfig = import_path54.default.join(process.cwd(), "node9.config.json");
51606
+ const globalConfig = import_path54.default.join(import_os50.default.homedir(), ".node9", "config.json");
51970
51607
  console.log(
51971
- ` Local: ${import_fs58.default.existsSync(projectConfig) ? import_chalk15.default.green("Active (node9.config.json)") : import_chalk15.default.gray("Not present")}`
51608
+ ` Local: ${import_fs57.default.existsSync(projectConfig) ? import_chalk15.default.green("Active (node9.config.json)") : import_chalk15.default.gray("Not present")}`
51972
51609
  );
51973
51610
  console.log(
51974
- ` Global: ${import_fs58.default.existsSync(globalConfig) ? import_chalk15.default.green("Active (~/.node9/config.json)") : import_chalk15.default.gray("Not present")}`
51611
+ ` Global: ${import_fs57.default.existsSync(globalConfig) ? import_chalk15.default.green("Active (~/.node9/config.json)") : import_chalk15.default.gray("Not present")}`
51975
51612
  );
51976
51613
  if (mergedConfig.policy.sandboxPaths.length > 0) {
51977
51614
  console.log(
51978
51615
  ` Sandbox: ${import_chalk15.default.green(`${mergedConfig.policy.sandboxPaths.length} safe zones active`)}`
51979
51616
  );
51980
51617
  }
51981
- const wiring = getAgentWiring(import_os51.default.homedir()).filter((a) => a.present);
51618
+ const wiring = getAgentWiring(import_os50.default.homedir()).filter((a) => a.present);
51982
51619
  if (wiring.length > 0) {
51983
51620
  console.log("");
51984
51621
  console.log(import_chalk15.default.bold(" Agent Wiring:"));
@@ -52013,9 +51650,9 @@ function registerStatusCommand(program2) {
52013
51650
 
52014
51651
  // src/cli/commands/init.ts
52015
51652
  var import_chalk16 = __toESM(require("chalk"));
52016
- var import_fs59 = __toESM(require("fs"));
52017
- var import_path56 = __toESM(require("path"));
52018
- var import_os52 = __toESM(require("os"));
51653
+ var import_fs58 = __toESM(require("fs"));
51654
+ var import_path55 = __toESM(require("path"));
51655
+ var import_os51 = __toESM(require("os"));
52019
51656
  var import_https6 = __toESM(require("https"));
52020
51657
  init_core();
52021
51658
  init_setup();
@@ -52106,16 +51743,16 @@ function registerInitCommand(program2) {
52106
51743
  }
52107
51744
  console.log("");
52108
51745
  }
52109
- const configPath = import_path56.default.join(import_os52.default.homedir(), ".node9", "config.json");
52110
- const isFirstInstall = !import_fs59.default.existsSync(configPath);
52111
- if (import_fs59.default.existsSync(configPath) && !options.force) {
51746
+ const configPath = import_path55.default.join(import_os51.default.homedir(), ".node9", "config.json");
51747
+ const isFirstInstall = !import_fs58.default.existsSync(configPath);
51748
+ if (import_fs58.default.existsSync(configPath) && !options.force) {
52112
51749
  try {
52113
- const existing = JSON.parse(import_fs59.default.readFileSync(configPath, "utf-8"));
51750
+ const existing = JSON.parse(import_fs58.default.readFileSync(configPath, "utf-8"));
52114
51751
  const settings = existing.settings ?? {};
52115
51752
  if (settings.mode !== chosenMode) {
52116
51753
  settings.mode = chosenMode;
52117
51754
  existing.settings = settings;
52118
- import_fs59.default.writeFileSync(configPath, JSON.stringify(existing, null, 2) + "\n");
51755
+ import_fs58.default.writeFileSync(configPath, JSON.stringify(existing, null, 2) + "\n");
52119
51756
  console.log(import_chalk16.default.green(`\u2705 Mode updated: ${chosenMode}`));
52120
51757
  } else {
52121
51758
  console.log(import_chalk16.default.blue(`\u2139\uFE0F Config already exists: ${configPath}`));
@@ -52128,9 +51765,9 @@ function registerInitCommand(program2) {
52128
51765
  ...DEFAULT_CONFIG,
52129
51766
  settings: { ...DEFAULT_CONFIG.settings, mode: chosenMode }
52130
51767
  };
52131
- const dir = import_path56.default.dirname(configPath);
52132
- if (!import_fs59.default.existsSync(dir)) import_fs59.default.mkdirSync(dir, { recursive: true });
52133
- import_fs59.default.writeFileSync(configPath, JSON.stringify(configToSave, null, 2) + "\n");
51768
+ const dir = import_path55.default.dirname(configPath);
51769
+ if (!import_fs58.default.existsSync(dir)) import_fs58.default.mkdirSync(dir, { recursive: true });
51770
+ import_fs58.default.writeFileSync(configPath, JSON.stringify(configToSave, null, 2) + "\n");
52134
51771
  console.log(import_chalk16.default.green(`\u2705 Config created: ${configPath}`));
52135
51772
  console.log(import_chalk16.default.gray(` Mode: ${chosenMode}`));
52136
51773
  }
@@ -52230,14 +51867,14 @@ function registerInitCommand(program2) {
52230
51867
 
52231
51868
  // src/cli/commands/heal.ts
52232
51869
  var import_chalk17 = __toESM(require("chalk"));
52233
- var import_fs60 = __toESM(require("fs"));
51870
+ var import_fs59 = __toESM(require("fs"));
52234
51871
  init_agent_wiring();
52235
51872
  init_setup();
52236
51873
  init_hook_baseline();
52237
51874
  var hasHookSurface = (a) => a.hooks.length > 0;
52238
51875
  function backupForHeal(file) {
52239
51876
  try {
52240
- if (file && import_fs60.default.existsSync(file)) import_fs60.default.copyFileSync(file, `${file}.node9-heal-bak`);
51877
+ if (file && import_fs59.default.existsSync(file)) import_fs59.default.copyFileSync(file, `${file}.node9-heal-bak`);
52241
51878
  } catch {
52242
51879
  }
52243
51880
  }
@@ -52469,7 +52106,7 @@ function registerUndoCommand(program2) {
52469
52106
  // src/mcp-gateway/index.ts
52470
52107
  var import_readline3 = __toESM(require("readline"));
52471
52108
  var import_chalk20 = __toESM(require("chalk"));
52472
- var import_child_process10 = require("child_process");
52109
+ var import_child_process9 = require("child_process");
52473
52110
  var import_execa3 = require("execa");
52474
52111
  init_orchestrator();
52475
52112
  init_cloud();
@@ -52601,7 +52238,7 @@ async function runMcpGateway(upstreamCommand, configName) {
52601
52238
  const safeEnv = Object.fromEntries(
52602
52239
  Object.entries(process.env).filter(([k]) => !UPSTREAM_INJECTOR_VARS.has(k))
52603
52240
  );
52604
- const child = (0, import_child_process10.spawn)(executable, cmdArgs, {
52241
+ const child = (0, import_child_process9.spawn)(executable, cmdArgs, {
52605
52242
  stdio: ["pipe", "pipe", "inherit"],
52606
52243
  // control stdin/stdout; inherit stderr
52607
52244
  shell: false,
@@ -52974,19 +52611,19 @@ function registerMcpGatewayCommand(program2) {
52974
52611
 
52975
52612
  // src/mcp-server/index.ts
52976
52613
  var import_readline4 = __toESM(require("readline"));
52977
- var import_fs62 = __toESM(require("fs"));
52978
- var import_os54 = __toESM(require("os"));
52979
- var import_path58 = __toESM(require("path"));
52980
- var import_child_process11 = require("child_process");
52614
+ var import_fs61 = __toESM(require("fs"));
52615
+ var import_os53 = __toESM(require("os"));
52616
+ var import_path57 = __toESM(require("path"));
52617
+ var import_child_process10 = require("child_process");
52981
52618
  init_decision();
52982
52619
  init_core();
52983
52620
  init_daemon();
52984
52621
  init_shields();
52985
52622
 
52986
52623
  // src/auth/egress-config.ts
52987
- var import_fs61 = __toESM(require("fs"));
52988
- var import_os53 = __toESM(require("os"));
52989
- var import_path57 = __toESM(require("path"));
52624
+ var import_fs60 = __toESM(require("fs"));
52625
+ var import_os52 = __toESM(require("os"));
52626
+ var import_path56 = __toESM(require("path"));
52990
52627
  var DEFAULT_EGRESS = {
52991
52628
  enabled: false,
52992
52629
  mode: "review",
@@ -52995,12 +52632,12 @@ var DEFAULT_EGRESS = {
52995
52632
  allowPrivate: true
52996
52633
  };
52997
52634
  function egressConfigPath() {
52998
- return import_path57.default.join(import_os53.default.homedir(), ".node9", "config.json");
52635
+ return import_path56.default.join(import_os52.default.homedir(), ".node9", "config.json");
52999
52636
  }
53000
52637
  function readEgressRawConfig() {
53001
52638
  let text;
53002
52639
  try {
53003
- text = import_fs61.default.readFileSync(egressConfigPath(), "utf8");
52640
+ text = import_fs60.default.readFileSync(egressConfigPath(), "utf8");
53004
52641
  } catch (err2) {
53005
52642
  if (err2.code === "ENOENT") return {};
53006
52643
  throw err2;
@@ -53015,8 +52652,8 @@ function readEgressRawConfig() {
53015
52652
  }
53016
52653
  function writeEgressRawConfig(config) {
53017
52654
  const p = egressConfigPath();
53018
- import_fs61.default.mkdirSync(import_path57.default.dirname(p), { recursive: true });
53019
- import_fs61.default.writeFileSync(p, JSON.stringify(config, null, 2) + "\n", { mode: 384 });
52655
+ import_fs60.default.mkdirSync(import_path56.default.dirname(p), { recursive: true });
52656
+ import_fs60.default.writeFileSync(p, JSON.stringify(config, null, 2) + "\n", { mode: 384 });
53020
52657
  }
53021
52658
  function applyEgress(config, change) {
53022
52659
  const policy = config.policy = config.policy ?? {};
@@ -53350,13 +52987,13 @@ function handleStatus() {
53350
52987
  lines.push(`Active shields: ${activeShields.length > 0 ? activeShields.join(", ") : "none"}`);
53351
52988
  lines.push(`Smart rules: ${config.policy.smartRules.length} loaded`);
53352
52989
  lines.push(`DLP: ${config.policy.dlp?.enabled !== false ? "enabled" : "disabled"}`);
53353
- const projectConfig = import_path58.default.join(process.cwd(), "node9.config.json");
53354
- const globalConfig = import_path58.default.join(import_os54.default.homedir(), ".node9", "config.json");
52990
+ const projectConfig = import_path57.default.join(process.cwd(), "node9.config.json");
52991
+ const globalConfig = import_path57.default.join(import_os53.default.homedir(), ".node9", "config.json");
53355
52992
  lines.push(
53356
- `Project config (node9.config.json): ${import_fs62.default.existsSync(projectConfig) ? "present" : "not found"}`
52993
+ `Project config (node9.config.json): ${import_fs61.default.existsSync(projectConfig) ? "present" : "not found"}`
53357
52994
  );
53358
52995
  lines.push(
53359
- `Global config (~/.node9/config.json): ${import_fs62.default.existsSync(globalConfig) ? "present" : "not found"}`
52996
+ `Global config (~/.node9/config.json): ${import_fs61.default.existsSync(globalConfig) ? "present" : "not found"}`
53360
52997
  );
53361
52998
  return lines.join("\n");
53362
52999
  }
@@ -53461,21 +53098,21 @@ function handleEgressDeny(args) {
53461
53098
  addEgressHost("deny", host);
53462
53099
  return `Denied egress to ${host} (deny always wins over allow).`;
53463
53100
  }
53464
- var GLOBAL_CONFIG_PATH = import_path58.default.join(import_os54.default.homedir(), ".node9", "config.json");
53101
+ var GLOBAL_CONFIG_PATH = import_path57.default.join(import_os53.default.homedir(), ".node9", "config.json");
53465
53102
  var APPROVER_CHANNELS = ["native", "browser", "cloud", "terminal"];
53466
53103
  function readGlobalConfigRaw() {
53467
53104
  try {
53468
- if (import_fs62.default.existsSync(GLOBAL_CONFIG_PATH)) {
53469
- return JSON.parse(import_fs62.default.readFileSync(GLOBAL_CONFIG_PATH, "utf-8"));
53105
+ if (import_fs61.default.existsSync(GLOBAL_CONFIG_PATH)) {
53106
+ return JSON.parse(import_fs61.default.readFileSync(GLOBAL_CONFIG_PATH, "utf-8"));
53470
53107
  }
53471
53108
  } catch {
53472
53109
  }
53473
53110
  return {};
53474
53111
  }
53475
53112
  function writeGlobalConfigRaw(data) {
53476
- const dir = import_path58.default.dirname(GLOBAL_CONFIG_PATH);
53477
- if (!import_fs62.default.existsSync(dir)) import_fs62.default.mkdirSync(dir, { recursive: true });
53478
- import_fs62.default.writeFileSync(GLOBAL_CONFIG_PATH, JSON.stringify(data, null, 2) + "\n");
53113
+ const dir = import_path57.default.dirname(GLOBAL_CONFIG_PATH);
53114
+ if (!import_fs61.default.existsSync(dir)) import_fs61.default.mkdirSync(dir, { recursive: true });
53115
+ import_fs61.default.writeFileSync(GLOBAL_CONFIG_PATH, JSON.stringify(data, null, 2) + "\n");
53479
53116
  }
53480
53117
  function handleApproverList() {
53481
53118
  const config = getConfig();
@@ -53519,9 +53156,9 @@ function handleApproverSet(args) {
53519
53156
  function handleAuditGet(args) {
53520
53157
  const limit = Math.min(typeof args.limit === "number" ? args.limit : 20, 100);
53521
53158
  const filter = typeof args.filter === "string" && args.filter !== "all" ? args.filter : null;
53522
- const auditPath = import_path58.default.join(import_os54.default.homedir(), ".node9", "audit.log");
53523
- if (!import_fs62.default.existsSync(auditPath)) return "No audit log found.";
53524
- const rawLines = import_fs62.default.readFileSync(auditPath, "utf-8").trim().split("\n").filter(Boolean);
53159
+ const auditPath = import_path57.default.join(import_os53.default.homedir(), ".node9", "audit.log");
53160
+ if (!import_fs61.default.existsSync(auditPath)) return "No audit log found.";
53161
+ const rawLines = import_fs61.default.readFileSync(auditPath, "utf-8").trim().split("\n").filter(Boolean);
53525
53162
  const wanted = filter === "block" ? "deny" : filter;
53526
53163
  const parsed = [];
53527
53164
  for (const line of rawLines) {
@@ -53607,7 +53244,7 @@ function handleRuleAdd(args) {
53607
53244
  return `Rule "${name}" added to ~/.node9/config.json \u2014 verdict: ${verdict} when ${field} matches "${pattern}"`;
53608
53245
  }
53609
53246
  function runCliCommand(subArgs) {
53610
- const result = (0, import_child_process11.spawnSync)(process.execPath, [process.argv[1], ...subArgs], {
53247
+ const result = (0, import_child_process10.spawnSync)(process.execPath, [process.argv[1], ...subArgs], {
53611
53248
  encoding: "utf-8",
53612
53249
  timeout: 6e4,
53613
53250
  // Disable colors — stdout is piped (not a TTY), chalk auto-detects, but be explicit
@@ -53823,7 +53460,7 @@ function registerTrustCommand(program2) {
53823
53460
  // src/cli/commands/mcp-pin.ts
53824
53461
  var import_chalk23 = __toESM(require("chalk"));
53825
53462
  init_mcp_pin();
53826
- var import_fs63 = __toESM(require("fs"));
53463
+ var import_fs62 = __toESM(require("fs"));
53827
53464
 
53828
53465
  // src/cli/commands/mcp-gateway-cmd.ts
53829
53466
  var import_chalk22 = __toESM(require("chalk"));
@@ -54031,7 +53668,7 @@ function registerMcpPinCommand(program2) {
54031
53668
  let repoCorrupt = false;
54032
53669
  if (found.source === "repo") {
54033
53670
  try {
54034
- const raw = import_fs63.default.readFileSync(found.path, "utf-8");
53671
+ const raw = import_fs62.default.readFileSync(found.path, "utf-8");
54035
53672
  const parsed = JSON.parse(raw);
54036
53673
  repoEntries = parsed.servers ?? {};
54037
53674
  } catch {
@@ -54624,8 +54261,8 @@ function registerPostureCommand(program2) {
54624
54261
  var import_chalk29 = __toESM(require("chalk"));
54625
54262
 
54626
54263
  // src/ci-check/fetch.ts
54627
- var import_fs64 = __toESM(require("fs"));
54628
- var import_path59 = __toESM(require("path"));
54264
+ var import_fs63 = __toESM(require("fs"));
54265
+ var import_path58 = __toESM(require("path"));
54629
54266
  var import_node_child_process = require("child_process");
54630
54267
  var import_undici = __toESM(require_undici());
54631
54268
  var cachedGhToken;
@@ -54709,7 +54346,7 @@ function parseRepoUrl(input) {
54709
54346
  function isLocalPath(input) {
54710
54347
  if (input.startsWith(".") || input.startsWith("/") || input.startsWith("~")) return true;
54711
54348
  try {
54712
- return import_fs64.default.existsSync(input) && import_fs64.default.statSync(input).isDirectory();
54349
+ return import_fs63.default.existsSync(input) && import_fs63.default.statSync(input).isDirectory();
54713
54350
  } catch {
54714
54351
  return false;
54715
54352
  }
@@ -54824,10 +54461,10 @@ function readLocalTree(dir) {
54824
54461
  const files = [];
54825
54462
  const notes = [];
54826
54463
  const add = (rel) => {
54827
- const abs = import_path59.default.join(root, rel);
54464
+ const abs = import_path58.default.join(root, rel);
54828
54465
  try {
54829
- if (import_fs64.default.existsSync(abs) && import_fs64.default.statSync(abs).isFile()) {
54830
- files.push({ path: rel, content: import_fs64.default.readFileSync(abs, "utf8") });
54466
+ if (import_fs63.default.existsSync(abs) && import_fs63.default.statSync(abs).isFile()) {
54467
+ files.push({ path: rel, content: import_fs63.default.readFileSync(abs, "utf8") });
54831
54468
  }
54832
54469
  } catch {
54833
54470
  }
@@ -54847,7 +54484,7 @@ function readLocalTree(dir) {
54847
54484
  dirsVisited++;
54848
54485
  let entries;
54849
54486
  try {
54850
- entries = import_fs64.default.readdirSync(import_path59.default.join(root, relDir), { withFileTypes: true });
54487
+ entries = import_fs63.default.readdirSync(import_path58.default.join(root, relDir), { withFileTypes: true });
54851
54488
  } catch {
54852
54489
  return;
54853
54490
  }
@@ -54868,11 +54505,11 @@ function readLocalTree(dir) {
54868
54505
  `repo is large \u2014 some agent-surface files may be INCOMPLETE (capped at ${MAX_SURFACE_FILES} files / ${MAX_DIRS} dirs).`
54869
54506
  );
54870
54507
  for (const rel of matches) collect(rel);
54871
- const wfDir = import_path59.default.join(root, WORKFLOW_DIR);
54508
+ const wfDir = import_path58.default.join(root, WORKFLOW_DIR);
54872
54509
  try {
54873
- if (import_fs64.default.existsSync(wfDir)) {
54874
- for (const name of import_fs64.default.readdirSync(wfDir)) {
54875
- if (/\.ya?ml$/.test(name)) add(import_path59.default.join(WORKFLOW_DIR, name));
54510
+ if (import_fs63.default.existsSync(wfDir)) {
54511
+ for (const name of import_fs63.default.readdirSync(wfDir)) {
54512
+ if (/\.ya?ml$/.test(name)) add(import_path58.default.join(WORKFLOW_DIR, name));
54876
54513
  }
54877
54514
  }
54878
54515
  } catch {
@@ -55177,7 +54814,7 @@ function severityFromScore(score) {
55177
54814
  if (score >= 1) return "advisory";
55178
54815
  return null;
55179
54816
  }
55180
- function analyzeWorkflow(path72, content) {
54817
+ function analyzeWorkflow(path71, content) {
55181
54818
  let raw;
55182
54819
  try {
55183
54820
  raw = (0, import_yaml.parse)(content) ?? {};
@@ -55303,7 +54940,7 @@ function analyzeWorkflow(path72, content) {
55303
54940
  dimension: "workflows",
55304
54941
  severity,
55305
54942
  title,
55306
- file: path72,
54943
+ file: path71,
55307
54944
  signals,
55308
54945
  mitigations: mitigations.length ? mitigations : void 0,
55309
54946
  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."
@@ -55379,7 +55016,7 @@ function evalAgentJob(job, wf, raw, untrustedTrigger, reusable) {
55379
55016
  if (reusable && !loadedGun && SEVERITY_RANK2[severity] > SEVERITY_RANK2.medium) severity = "medium";
55380
55017
  return { severity, secrets, injectable, canReadEnv };
55381
55018
  }
55382
- function analyzeWorkflowSecrets(path72, content) {
55019
+ function analyzeWorkflowSecrets(path71, content) {
55383
55020
  let raw;
55384
55021
  try {
55385
55022
  raw = (0, import_yaml.parse)(content) ?? {};
@@ -55399,7 +55036,7 @@ function analyzeWorkflowSecrets(path72, content) {
55399
55036
  dimension: "data",
55400
55037
  severity: worst.severity,
55401
55038
  title: worst.severity === "advisory" ? "Secrets reachable by the agent \u2014 hardening" : "Exfiltratable secrets reachable by an injectable agent",
55402
- file: path72,
55039
+ file: path71,
55403
55040
  signals: [
55404
55041
  `agent can reach: ${worst.secrets.map((s) => s.name).join(", ")}`,
55405
55042
  worst.injectable ? "the agent is externally triggerable (untrusted trigger, no gate)" : "gated / not externally triggerable \u2014 latent risk only",
@@ -55426,7 +55063,7 @@ function hookCommands(hooks) {
55426
55063
  }
55427
55064
  return out;
55428
55065
  }
55429
- function analyzeAgentConfig(path72, content) {
55066
+ function analyzeAgentConfig(path71, content) {
55430
55067
  let cfg;
55431
55068
  try {
55432
55069
  cfg = JSON.parse(content);
@@ -55445,7 +55082,7 @@ function analyzeAgentConfig(path72, content) {
55445
55082
  dimension: "toolRules",
55446
55083
  severity: high ? "high" : "medium",
55447
55084
  title: high ? "Agent hook runs UNPINNED/remote third-party code on every action" : "Agent hook runs third-party code in the agent hot path",
55448
- file: path72,
55085
+ file: path71,
55449
55086
  signals: [
55450
55087
  `hook command: \`${cmd.slice(0, 120)}\``,
55451
55088
  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"
@@ -55465,7 +55102,7 @@ function analyzeAgentConfig(path72, content) {
55465
55102
  dimension: "toolRules",
55466
55103
  severity: hasBackstop ? "medium" : "high",
55467
55104
  title: hasBackstop ? "Committed agent config pre-authorizes broad tools" : "Committed agent config pre-authorizes broad tools with no deny backstop",
55468
- file: path72,
55105
+ file: path71,
55469
55106
  signals: [
55470
55107
  `broad allow(s): ${broad.slice(0, 5).join(", ")}`,
55471
55108
  hasBackstop ? "a `deny` list backstops the broad allow" : "no `deny` entry covers Bash/Write/Edit \u2014 every contributor is pre-authorized for catastrophic tools"
@@ -55478,16 +55115,16 @@ function analyzeAgentConfig(path72, content) {
55478
55115
 
55479
55116
  // src/ci-check/mcp.ts
55480
55117
  init_dist();
55481
- function analyzeMcp(path72, content) {
55118
+ function analyzeMcp(path71, content) {
55482
55119
  let cfg;
55483
55120
  try {
55484
55121
  cfg = JSON.parse(content);
55485
55122
  } catch {
55486
55123
  return [];
55487
55124
  }
55488
- return analyzeMcpServers(cfg.mcpServers ?? {}, path72);
55125
+ return analyzeMcpServers(cfg.mcpServers ?? {}, path71);
55489
55126
  }
55490
- function analyzeMcpServers(servers, path72) {
55127
+ function analyzeMcpServers(servers, path71) {
55491
55128
  const findings = [];
55492
55129
  for (const [name, srv] of Object.entries(servers ?? {})) {
55493
55130
  if (!srv || srv.disabled) continue;
@@ -55498,7 +55135,7 @@ function analyzeMcpServers(servers, path72) {
55498
55135
  dimension: "mcp",
55499
55136
  severity: "medium",
55500
55137
  title: `MCP server "${name}" runs an unpinned executable`,
55501
- file: path72,
55138
+ file: path71,
55502
55139
  signals: [`\`${argv.slice(0, 120)}\` \u2014 unversioned/@latest npx`],
55503
55140
  fix: "Pin the MCP server package to an exact version so a PR (or a registry compromise) can\u2019t swap the toolchain."
55504
55141
  });
@@ -55512,7 +55149,7 @@ function analyzeMcpServers(servers, path72) {
55512
55149
  dimension: "mcp",
55513
55150
  severity: "high",
55514
55151
  title: `MCP server "${name}" has an inline credential`,
55515
- file: path72,
55152
+ file: path71,
55516
55153
  signals: [
55517
55154
  `env.${k} matches ${hit.patternName} \u2014 agent-reachable secret committed to the repo`
55518
55155
  ],
@@ -55526,7 +55163,7 @@ function analyzeMcpServers(servers, path72) {
55526
55163
 
55527
55164
  // src/ci-check/codex.ts
55528
55165
  var import_smol_toml5 = require("smol-toml");
55529
- function analyzeCodexConfig(path72, content) {
55166
+ function analyzeCodexConfig(path71, content) {
55530
55167
  let cfg;
55531
55168
  try {
55532
55169
  cfg = (0, import_smol_toml5.parse)(content);
@@ -55534,7 +55171,7 @@ function analyzeCodexConfig(path72, content) {
55534
55171
  return [];
55535
55172
  }
55536
55173
  const findings = [];
55537
- findings.push(...analyzeMcpServers(cfg.mcp_servers ?? {}, path72));
55174
+ findings.push(...analyzeMcpServers(cfg.mcp_servers ?? {}, path71));
55538
55175
  const sandbox = typeof cfg.sandbox_mode === "string" ? cfg.sandbox_mode : "";
55539
55176
  const approval = typeof cfg.approval_policy === "string" ? cfg.approval_policy : "";
55540
55177
  const fullAccess = /danger-full-access/i.test(sandbox);
@@ -55549,7 +55186,7 @@ function analyzeCodexConfig(path72, content) {
55549
55186
  dimension: "toolRules",
55550
55187
  severity: fullAccess ? "high" : "medium",
55551
55188
  title: fullAccess ? "Codex config grants a full-access sandbox" : "Codex config never requires approval",
55552
- file: path72,
55189
+ file: path71,
55553
55190
  signals,
55554
55191
  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.'
55555
55192
  });
@@ -55605,10 +55242,10 @@ function decodeSuspiciousBase64(text) {
55605
55242
  }
55606
55243
  return out;
55607
55244
  }
55608
- function mk(severity, title, signals, fix, path72) {
55609
- return { check: "CI-6", dimension: "instructions", severity, title, file: path72, signals, fix };
55245
+ function mk(severity, title, signals, fix, path71) {
55246
+ return { check: "CI-6", dimension: "instructions", severity, title, file: path71, signals, fix };
55610
55247
  }
55611
- function analyzeInstructionFile(path72, content) {
55248
+ function analyzeInstructionFile(path71, content) {
55612
55249
  const findings = [];
55613
55250
  const decoded = decodeSuspiciousBase64(content);
55614
55251
  if (TAG_CHARS.test(content))
@@ -55620,7 +55257,7 @@ function analyzeInstructionFile(path72, content) {
55620
55257
  "contains Unicode tag characters (U+E0000\u2013E007F) \u2014 an invisible instruction-smuggling channel with no legitimate use in text"
55621
55258
  ],
55622
55259
  "Remove the tag characters. Instruction files must be plain, reviewable text.",
55623
- path72
55260
+ path71
55624
55261
  )
55625
55262
  );
55626
55263
  if (BIDI_OVERRIDE.test(content))
@@ -55632,7 +55269,7 @@ function analyzeInstructionFile(path72, content) {
55632
55269
  "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"
55633
55270
  ],
55634
55271
  "Remove the bidi override characters.",
55635
- path72
55272
+ path71
55636
55273
  )
55637
55274
  );
55638
55275
  else if (BIDI_EMBED_ISOLATE.test(content))
@@ -55644,7 +55281,7 @@ function analyzeInstructionFile(path72, content) {
55644
55281
  "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"
55645
55282
  ],
55646
55283
  "Confirm the bidi marks are legitimate RTL formatting; remove otherwise.",
55647
- path72
55284
+ path71
55648
55285
  )
55649
55286
  );
55650
55287
  const zw = suspiciousZeroWidth(content);
@@ -55658,7 +55295,7 @@ function analyzeInstructionFile(path72, content) {
55658
55295
  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)"
55659
55296
  ],
55660
55297
  "Remove the zero-width characters. Instruction files must be plain, reviewable text.",
55661
- path72
55298
+ path71
55662
55299
  )
55663
55300
  );
55664
55301
  }
@@ -55674,7 +55311,7 @@ function analyzeInstructionFile(path72, content) {
55674
55311
  `contains a prompt-override / role-impersonation directive (\`${m[0].slice(0, 60).trim()}\`)${ovEnc ? " \u2014 concealed in a base64 blob" : ""}`
55675
55312
  ],
55676
55313
  "Remove the override text. An instruction file should not tell the agent to ignore its own rules.",
55677
- path72
55314
+ path71
55678
55315
  )
55679
55316
  );
55680
55317
  }
@@ -55686,7 +55323,7 @@ function analyzeInstructionFile(path72, content) {
55686
55323
  "Instruction directs the agent to fetch and run remote code",
55687
55324
  [`\`${fo[0].slice(0, 70).trim()}\` \u2014 fetch-and-obey, outside an install/setup section`],
55688
55325
  "Do not instruct the agent to pipe remote content into a shell; pin and vendor scripts instead.",
55689
- path72
55326
+ path71
55690
55327
  )
55691
55328
  );
55692
55329
  }
@@ -55698,7 +55335,7 @@ function analyzeInstructionFile(path72, content) {
55698
55335
  "Instruction points the agent at credential material",
55699
55336
  [`references \`${sp[0].slice(0, 50).trim()}\` \u2014 directs the agent toward secrets`],
55700
55337
  "Do not reference credential files or paths in agent instructions.",
55701
- path72
55338
+ path71
55702
55339
  )
55703
55340
  );
55704
55341
  }
@@ -55710,7 +55347,7 @@ function analyzeInstructionFile(path72, content) {
55710
55347
  "Instruction directs the agent to send data to an external endpoint",
55711
55348
  [`\`${ex[0].slice(0, 70).trim()}\` \u2014 possible exfiltration directive`],
55712
55349
  "Remove external post/upload directives from agent instructions.",
55713
- path72
55350
+ path71
55714
55351
  )
55715
55352
  );
55716
55353
  }
@@ -56106,14 +55743,14 @@ function registerJailCommand(program2) {
56106
55743
 
56107
55744
  // src/cli/commands/sandbox.ts
56108
55745
  var import_chalk32 = __toESM(require("chalk"));
56109
- var import_fs67 = __toESM(require("fs"));
56110
- var import_path62 = __toESM(require("path"));
56111
- var import_child_process13 = require("child_process");
55746
+ var import_fs66 = __toESM(require("fs"));
55747
+ var import_path61 = __toESM(require("path"));
55748
+ var import_child_process12 = require("child_process");
56112
55749
  init_config();
56113
55750
 
56114
55751
  // src/sandbox/config.ts
56115
- var import_fs65 = __toESM(require("fs"));
56116
- var import_path60 = __toESM(require("path"));
55752
+ var import_fs64 = __toESM(require("fs"));
55753
+ var import_path59 = __toESM(require("path"));
56117
55754
  var import_yaml2 = require("yaml");
56118
55755
  var SANDBOX_CONFIG_FILE = "node9.sandbox.yaml";
56119
55756
  var FORBIDDEN_ENV = /* @__PURE__ */ new Set(["NODE9_API_KEY", "NODE9_API_URL"]);
@@ -56186,16 +55823,16 @@ function scaffoldSandboxYaml(agent) {
56186
55823
  return header + (0, import_yaml2.stringify)(defaultSandboxConfig(agent));
56187
55824
  }
56188
55825
  function sandboxConfigPath(cwd = process.cwd()) {
56189
- return import_path60.default.join(cwd, SANDBOX_CONFIG_FILE);
55826
+ return import_path59.default.join(cwd, SANDBOX_CONFIG_FILE);
56190
55827
  }
56191
55828
  function loadSandboxConfig(cwd = process.cwd(), fallbackAgent = "claude") {
56192
55829
  const p = sandboxConfigPath(cwd);
56193
- if (!import_fs65.default.existsSync(p)) {
55830
+ if (!import_fs64.default.existsSync(p)) {
56194
55831
  throw new Error(`sandbox: ${SANDBOX_CONFIG_FILE} not found \u2014 run \`node9 sandbox new\` first.`);
56195
55832
  }
56196
55833
  let raw;
56197
55834
  try {
56198
- raw = (0, import_yaml2.parse)(import_fs65.default.readFileSync(p, "utf-8"));
55835
+ raw = (0, import_yaml2.parse)(import_fs64.default.readFileSync(p, "utf-8"));
56199
55836
  } catch (err2) {
56200
55837
  throw new Error(
56201
55838
  `sandbox: ${SANDBOX_CONFIG_FILE} is not valid YAML \u2014 ${err2.message}`
@@ -56253,17 +55890,17 @@ function compileAllowlist(input) {
56253
55890
  init_templates();
56254
55891
 
56255
55892
  // src/sandbox/runtime.ts
56256
- var import_fs66 = __toESM(require("fs"));
56257
- var import_os55 = __toESM(require("os"));
56258
- var import_path61 = __toESM(require("path"));
56259
- var import_crypto14 = __toESM(require("crypto"));
56260
- var import_child_process12 = require("child_process");
55893
+ var import_fs65 = __toESM(require("fs"));
55894
+ var import_os54 = __toESM(require("os"));
55895
+ var import_path60 = __toESM(require("path"));
55896
+ var import_crypto13 = __toESM(require("crypto"));
55897
+ var import_child_process11 = require("child_process");
56261
55898
  init_templates();
56262
55899
  function sandboxDataDir(cwd = process.cwd()) {
56263
- return import_path61.default.join(cwd, ".node9", "sandbox", "data");
55900
+ return import_path60.default.join(cwd, ".node9", "sandbox", "data");
56264
55901
  }
56265
55902
  function detectEngine(engine) {
56266
- const r = (0, import_child_process12.spawnSync)(engine, ["--version"], { encoding: "utf-8" });
55903
+ const r = (0, import_child_process11.spawnSync)(engine, ["--version"], { encoding: "utf-8" });
56267
55904
  if (r.status === 0 && typeof r.stdout === "string") {
56268
55905
  return { available: true, version: r.stdout.trim() };
56269
55906
  }
@@ -56271,7 +55908,7 @@ function detectEngine(engine) {
56271
55908
  }
56272
55909
  function agentCredentialsMount(agent) {
56273
55910
  const rel = agent === "codex" ? ".codex/auth.json" : ".claude/.credentials.json";
56274
- return { hostPath: import_path61.default.join(import_os55.default.homedir(), rel), target: `/home/${RUN_AS_USER}/${rel}` };
55911
+ return { hostPath: import_path60.default.join(import_os54.default.homedir(), rel), target: `/home/${RUN_AS_USER}/${rel}` };
56275
55912
  }
56276
55913
  function buildRunArgs(opts) {
56277
55914
  const { config, workspaceHostPath, dataHostPath, allowlistHostPath, agentArgs } = opts;
@@ -56281,7 +55918,7 @@ function buildRunArgs(opts) {
56281
55918
  args.push("-v", `${allowlistHostPath}:${ALLOWED_DOMAINS_PATH}:ro`);
56282
55919
  if (config.node9.mountAgentCredentials) {
56283
55920
  const creds = agentCredentialsMount(config.agent);
56284
- if (import_fs66.default.existsSync(creds.hostPath)) {
55921
+ if (import_fs65.default.existsSync(creds.hostPath)) {
56285
55922
  args.push("-v", `${creds.hostPath}:${creds.target}`);
56286
55923
  }
56287
55924
  }
@@ -56296,33 +55933,33 @@ function buildRunArgs(opts) {
56296
55933
  return args;
56297
55934
  }
56298
55935
  function imageContentHash(dockerfile, entrypoint) {
56299
- return import_crypto14.default.createHash("sha256").update(dockerfile).update("\0").update(entrypoint).digest("hex").slice(0, 16);
55936
+ return import_crypto13.default.createHash("sha256").update(dockerfile).update("\0").update(entrypoint).digest("hex").slice(0, 16);
56300
55937
  }
56301
55938
  function sandboxBuildDir(cwd = process.cwd()) {
56302
- return import_path61.default.join(cwd, ".node9", "sandbox", "build");
55939
+ return import_path60.default.join(cwd, ".node9", "sandbox", "build");
56303
55940
  }
56304
55941
  function writeBuildContext(cwd, dockerfile, entrypoint) {
56305
55942
  const dir = sandboxBuildDir(cwd);
56306
- import_fs66.default.mkdirSync(dir, { recursive: true });
56307
- import_fs66.default.writeFileSync(import_path61.default.join(dir, "Dockerfile"), dockerfile);
56308
- import_fs66.default.writeFileSync(import_path61.default.join(dir, "entrypoint.sh"), entrypoint);
55943
+ import_fs65.default.mkdirSync(dir, { recursive: true });
55944
+ import_fs65.default.writeFileSync(import_path60.default.join(dir, "Dockerfile"), dockerfile);
55945
+ import_fs65.default.writeFileSync(import_path60.default.join(dir, "entrypoint.sh"), entrypoint);
56309
55946
  return dir;
56310
55947
  }
56311
55948
  function writeAllowlist(cwd, hosts) {
56312
- const dir = import_path61.default.join(cwd, ".node9", "sandbox");
56313
- import_fs66.default.mkdirSync(dir, { recursive: true });
56314
- const p = import_path61.default.join(dir, "allowed-domains.txt");
56315
- import_fs66.default.writeFileSync(p, hosts.join("\n") + "\n");
55949
+ const dir = import_path60.default.join(cwd, ".node9", "sandbox");
55950
+ import_fs65.default.mkdirSync(dir, { recursive: true });
55951
+ const p = import_path60.default.join(dir, "allowed-domains.txt");
55952
+ import_fs65.default.writeFileSync(p, hosts.join("\n") + "\n");
56316
55953
  return p;
56317
55954
  }
56318
55955
  function resolveHomePath(p) {
56319
- return p.startsWith("~") ? import_path61.default.join(import_os55.default.homedir(), p.slice(1)) : import_path61.default.resolve(p);
55956
+ return p.startsWith("~") ? import_path60.default.join(import_os54.default.homedir(), p.slice(1)) : import_path60.default.resolve(p);
56320
55957
  }
56321
55958
 
56322
55959
  // src/cli/commands/sandbox.ts
56323
55960
  function seedDataDirConfig(dataDir, sandbox) {
56324
- import_fs67.default.mkdirSync(dataDir, { recursive: true });
56325
- const configPath = import_path62.default.join(dataDir, "config.json");
55961
+ import_fs66.default.mkdirSync(dataDir, { recursive: true });
55962
+ const configPath = import_path61.default.join(dataDir, "config.json");
56326
55963
  const seed = {
56327
55964
  settings: {
56328
55965
  approvers: {
@@ -56333,7 +55970,7 @@ function seedDataDirConfig(dataDir, sandbox) {
56333
55970
  }
56334
55971
  }
56335
55972
  };
56336
- import_fs67.default.writeFileSync(configPath, JSON.stringify(seed, null, 2), { mode: 384 });
55973
+ import_fs66.default.writeFileSync(configPath, JSON.stringify(seed, null, 2), { mode: 384 });
56337
55974
  }
56338
55975
  function registerSandboxCommand(program2, version2) {
56339
55976
  const node9Version2 = pinnedNode9Version(version2);
@@ -56341,13 +55978,13 @@ function registerSandboxCommand(program2, version2) {
56341
55978
  cmd.command("new").description(`Scaffold ${SANDBOX_CONFIG_FILE} in this project`).option("--agent <agent>", "claude (default) or codex", "claude").action((opts) => {
56342
55979
  const agent = opts.agent === "codex" ? "codex" : "claude";
56343
55980
  const p = sandboxConfigPath();
56344
- if (import_fs67.default.existsSync(p)) {
55981
+ if (import_fs66.default.existsSync(p)) {
56345
55982
  console.log(
56346
55983
  import_chalk32.default.yellow(` ${SANDBOX_CONFIG_FILE} already exists \u2014 leaving it untouched.`)
56347
55984
  );
56348
55985
  return;
56349
55986
  }
56350
- import_fs67.default.writeFileSync(p, scaffoldSandboxYaml(agent));
55987
+ import_fs66.default.writeFileSync(p, scaffoldSandboxYaml(agent));
56351
55988
  console.log(
56352
55989
  import_chalk32.default.green(` \u2713 wrote ${SANDBOX_CONFIG_FILE}`) + import_chalk32.default.dim(` (agent: ${agent})`)
56353
55990
  );
@@ -56387,20 +56024,20 @@ function registerSandboxCommand(program2, version2) {
56387
56024
  const buildDir = writeBuildContext(cwd, dockerfile, entrypoint);
56388
56025
  const hash = imageContentHash(dockerfile, entrypoint);
56389
56026
  const image = sandbox.runtime.image;
56390
- const hashFile = import_path62.default.join(sandboxBuildDir(cwd), ".image-hash");
56391
- const lastHash = import_fs67.default.existsSync(hashFile) ? import_fs67.default.readFileSync(hashFile, "utf-8").trim() : "";
56392
- const imageExists = (0, import_child_process13.spawnSync)(sandbox.runtime.engine, ["image", "inspect", image], { stdio: "ignore" }).status === 0;
56027
+ const hashFile = import_path61.default.join(sandboxBuildDir(cwd), ".image-hash");
56028
+ const lastHash = import_fs66.default.existsSync(hashFile) ? import_fs66.default.readFileSync(hashFile, "utf-8").trim() : "";
56029
+ const imageExists = (0, import_child_process12.spawnSync)(sandbox.runtime.engine, ["image", "inspect", image], { stdio: "ignore" }).status === 0;
56393
56030
  const needBuild = sandbox.runtime.rebuild === "always" || !imageExists || sandbox.runtime.rebuild !== "never" && lastHash !== hash;
56394
56031
  if (needBuild) {
56395
56032
  console.log(import_chalk32.default.dim(` building ${image} \u2026`));
56396
- const b = (0, import_child_process13.spawnSync)(sandbox.runtime.engine, ["build", "-t", image, buildDir], {
56033
+ const b = (0, import_child_process12.spawnSync)(sandbox.runtime.engine, ["build", "-t", image, buildDir], {
56397
56034
  stdio: "inherit"
56398
56035
  });
56399
56036
  if (b.status !== 0) {
56400
56037
  console.error(import_chalk32.default.red(" build failed."));
56401
56038
  process.exit(b.status ?? 1);
56402
56039
  }
56403
- import_fs67.default.writeFileSync(hashFile, hash);
56040
+ import_fs66.default.writeFileSync(hashFile, hash);
56404
56041
  }
56405
56042
  const dataDir = sandboxDataDir(cwd);
56406
56043
  seedDataDirConfig(dataDir, sandbox);
@@ -56414,7 +56051,7 @@ function registerSandboxCommand(program2, version2) {
56414
56051
  });
56415
56052
  if (sandbox.node9.mountAgentCredentials) {
56416
56053
  const creds = agentCredentialsMount(sandbox.agent);
56417
- if (import_fs67.default.existsSync(creds.hostPath)) {
56054
+ if (import_fs66.default.existsSync(creds.hostPath)) {
56418
56055
  console.log(import_chalk32.default.dim(` mounting ${creds.hostPath} (agent credentials, rw)`));
56419
56056
  } else {
56420
56057
  console.log(
@@ -56426,24 +56063,24 @@ function registerSandboxCommand(program2, version2) {
56426
56063
  import_chalk32.default.green(` \u{1F6E1}\uFE0F ${sandbox.agent} jailed \u2014 ${compiled.allow.length} hosts allowed
56427
56064
  `)
56428
56065
  );
56429
- const r = (0, import_child_process13.spawnSync)(sandbox.runtime.engine, runArgs, { stdio: "inherit" });
56066
+ const r = (0, import_child_process12.spawnSync)(sandbox.runtime.engine, runArgs, { stdio: "inherit" });
56430
56067
  process.exit(r.status ?? 0);
56431
56068
  });
56432
56069
  cmd.command("tail").description("Stream the sandbox's audit log (host-side)").action(() => {
56433
- const auditPath = import_path62.default.join(sandboxDataDir(), "audit.log");
56434
- if (!import_fs67.default.existsSync(auditPath)) {
56070
+ const auditPath = import_path61.default.join(sandboxDataDir(), "audit.log");
56071
+ if (!import_fs66.default.existsSync(auditPath)) {
56435
56072
  console.log(import_chalk32.default.dim(" no sandbox audit yet."));
56436
56073
  return;
56437
56074
  }
56438
- (0, import_child_process13.spawnSync)("tail", ["-f", auditPath], { stdio: "inherit" });
56075
+ (0, import_child_process12.spawnSync)("tail", ["-f", auditPath], { stdio: "inherit" });
56439
56076
  });
56440
56077
  cmd.command("logs").description("Dump the sandbox's audit log").action(() => {
56441
- const auditPath = import_path62.default.join(sandboxDataDir(), "audit.log");
56442
- if (!import_fs67.default.existsSync(auditPath)) {
56078
+ const auditPath = import_path61.default.join(sandboxDataDir(), "audit.log");
56079
+ if (!import_fs66.default.existsSync(auditPath)) {
56443
56080
  console.log(import_chalk32.default.dim(" no sandbox audit yet."));
56444
56081
  return;
56445
56082
  }
56446
- process.stdout.write(import_fs67.default.readFileSync(auditPath, "utf-8"));
56083
+ process.stdout.write(import_fs66.default.readFileSync(auditPath, "utf-8"));
56447
56084
  });
56448
56085
  cmd.command("clean").description("Remove the sandbox image, build context, and data").action(() => {
56449
56086
  const cwd = process.cwd();
@@ -56453,21 +56090,21 @@ function registerSandboxCommand(program2, version2) {
56453
56090
  } catch {
56454
56091
  }
56455
56092
  if (sandbox) {
56456
- (0, import_child_process13.spawnSync)(sandbox.runtime.engine, ["image", "rm", "-f", sandbox.runtime.image], {
56093
+ (0, import_child_process12.spawnSync)(sandbox.runtime.engine, ["image", "rm", "-f", sandbox.runtime.image], {
56457
56094
  stdio: "ignore"
56458
56095
  });
56459
56096
  }
56460
- import_fs67.default.rmSync(import_path62.default.join(cwd, ".node9", "sandbox"), { recursive: true, force: true });
56097
+ import_fs66.default.rmSync(import_path61.default.join(cwd, ".node9", "sandbox"), { recursive: true, force: true });
56461
56098
  console.log(import_chalk32.default.green(" \u2713 sandbox image + build + data removed."));
56462
56099
  });
56463
56100
  }
56464
56101
 
56465
56102
  // src/cli/commands/sessions.ts
56466
56103
  var import_chalk33 = __toESM(require("chalk"));
56467
- var import_fs68 = __toESM(require("fs"));
56468
- var import_path63 = __toESM(require("path"));
56104
+ var import_fs67 = __toESM(require("fs"));
56105
+ var import_path62 = __toESM(require("path"));
56469
56106
  init_decision();
56470
- var import_os56 = __toESM(require("os"));
56107
+ var import_os55 = __toESM(require("os"));
56471
56108
  init_scan_summary();
56472
56109
  init_litellm();
56473
56110
  init_cost_gemini();
@@ -56488,10 +56125,10 @@ function encodeProjectPath(projectPath) {
56488
56125
  }
56489
56126
  function sessionJsonlPath(projectPath, sessionId) {
56490
56127
  const encoded = encodeProjectPath(projectPath);
56491
- return import_path63.default.join(import_os56.default.homedir(), ".claude", "projects", encoded, `${sessionId}.jsonl`);
56128
+ return import_path62.default.join(import_os55.default.homedir(), ".claude", "projects", encoded, `${sessionId}.jsonl`);
56492
56129
  }
56493
56130
  function projectLabel(projectPath) {
56494
- return projectPath.replace(import_os56.default.homedir(), "~");
56131
+ return projectPath.replace(import_os55.default.homedir(), "~");
56495
56132
  }
56496
56133
  function parseHistoryLines(lines) {
56497
56134
  const entries = [];
@@ -56560,10 +56197,10 @@ function parseSessionLines(lines) {
56560
56197
  return { toolCalls, costUSD, hasSnapshot, modifiedFiles };
56561
56198
  }
56562
56199
  function loadAuditEntries(auditPath) {
56563
- const aPath = auditPath ?? import_path63.default.join(import_os56.default.homedir(), ".node9", "audit.log");
56200
+ const aPath = auditPath ?? import_path62.default.join(import_os55.default.homedir(), ".node9", "audit.log");
56564
56201
  let raw;
56565
56202
  try {
56566
- raw = import_fs68.default.readFileSync(aPath, "utf-8");
56203
+ raw = import_fs67.default.readFileSync(aPath, "utf-8");
56567
56204
  } catch {
56568
56205
  return [];
56569
56206
  }
@@ -56599,8 +56236,8 @@ function auditEntriesInWindow(entries, windowStart, windowEnd) {
56599
56236
  return result;
56600
56237
  }
56601
56238
  function buildGeminiSessions(days, allAuditEntries) {
56602
- const tmpDir = import_path63.default.join(import_os56.default.homedir(), ".gemini", "tmp");
56603
- if (!import_fs68.default.existsSync(tmpDir)) return [];
56239
+ const tmpDir = import_path62.default.join(import_os55.default.homedir(), ".gemini", "tmp");
56240
+ if (!import_fs67.default.existsSync(tmpDir)) return [];
56604
56241
  const cutoff = days !== null ? (() => {
56605
56242
  const d = /* @__PURE__ */ new Date();
56606
56243
  d.setDate(d.getDate() - days);
@@ -56609,35 +56246,35 @@ function buildGeminiSessions(days, allAuditEntries) {
56609
56246
  })() : null;
56610
56247
  let slugDirs;
56611
56248
  try {
56612
- slugDirs = import_fs68.default.readdirSync(tmpDir);
56249
+ slugDirs = import_fs67.default.readdirSync(tmpDir);
56613
56250
  } catch {
56614
56251
  return [];
56615
56252
  }
56616
56253
  const summaries = [];
56617
56254
  for (const slug2 of slugDirs) {
56618
- const slugPath = import_path63.default.join(tmpDir, slug2);
56255
+ const slugPath = import_path62.default.join(tmpDir, slug2);
56619
56256
  try {
56620
- if (!import_fs68.default.statSync(slugPath).isDirectory()) continue;
56257
+ if (!import_fs67.default.statSync(slugPath).isDirectory()) continue;
56621
56258
  } catch {
56622
56259
  continue;
56623
56260
  }
56624
- let projectRoot = import_path63.default.join(import_os56.default.homedir(), slug2);
56261
+ let projectRoot = import_path62.default.join(import_os55.default.homedir(), slug2);
56625
56262
  try {
56626
- projectRoot = import_fs68.default.readFileSync(import_path63.default.join(slugPath, ".project_root"), "utf-8").trim();
56263
+ projectRoot = import_fs67.default.readFileSync(import_path62.default.join(slugPath, ".project_root"), "utf-8").trim();
56627
56264
  } catch {
56628
56265
  }
56629
- const chatsDir = import_path63.default.join(slugPath, "chats");
56630
- if (!import_fs68.default.existsSync(chatsDir)) continue;
56266
+ const chatsDir = import_path62.default.join(slugPath, "chats");
56267
+ if (!import_fs67.default.existsSync(chatsDir)) continue;
56631
56268
  let chatFiles;
56632
56269
  try {
56633
- chatFiles = import_fs68.default.readdirSync(chatsDir).filter((f) => f.endsWith(".json"));
56270
+ chatFiles = import_fs67.default.readdirSync(chatsDir).filter((f) => f.endsWith(".json"));
56634
56271
  } catch {
56635
56272
  continue;
56636
56273
  }
56637
56274
  for (const chatFile of chatFiles) {
56638
56275
  let raw;
56639
56276
  try {
56640
- raw = import_fs68.default.readFileSync(import_path63.default.join(chatsDir, chatFile), "utf-8");
56277
+ raw = import_fs67.default.readFileSync(import_path62.default.join(chatsDir, chatFile), "utf-8");
56641
56278
  } catch {
56642
56279
  continue;
56643
56280
  }
@@ -56717,8 +56354,8 @@ function buildGeminiSessions(days, allAuditEntries) {
56717
56354
  return summaries;
56718
56355
  }
56719
56356
  function buildCodexSessions(days, allAuditEntries) {
56720
- const sessionsBase = import_path63.default.join(import_os56.default.homedir(), ".codex", "sessions");
56721
- if (!import_fs68.default.existsSync(sessionsBase)) return [];
56357
+ const sessionsBase = import_path62.default.join(import_os55.default.homedir(), ".codex", "sessions");
56358
+ if (!import_fs67.default.existsSync(sessionsBase)) return [];
56722
56359
  const cutoff = days !== null ? (() => {
56723
56360
  const d = /* @__PURE__ */ new Date();
56724
56361
  d.setDate(d.getDate() - days);
@@ -56727,29 +56364,29 @@ function buildCodexSessions(days, allAuditEntries) {
56727
56364
  })() : null;
56728
56365
  const jsonlFiles = [];
56729
56366
  try {
56730
- for (const year of import_fs68.default.readdirSync(sessionsBase)) {
56731
- const yearPath = import_path63.default.join(sessionsBase, year);
56367
+ for (const year of import_fs67.default.readdirSync(sessionsBase)) {
56368
+ const yearPath = import_path62.default.join(sessionsBase, year);
56732
56369
  try {
56733
- if (!import_fs68.default.statSync(yearPath).isDirectory()) continue;
56370
+ if (!import_fs67.default.statSync(yearPath).isDirectory()) continue;
56734
56371
  } catch {
56735
56372
  continue;
56736
56373
  }
56737
- for (const month of import_fs68.default.readdirSync(yearPath)) {
56738
- const monthPath = import_path63.default.join(yearPath, month);
56374
+ for (const month of import_fs67.default.readdirSync(yearPath)) {
56375
+ const monthPath = import_path62.default.join(yearPath, month);
56739
56376
  try {
56740
- if (!import_fs68.default.statSync(monthPath).isDirectory()) continue;
56377
+ if (!import_fs67.default.statSync(monthPath).isDirectory()) continue;
56741
56378
  } catch {
56742
56379
  continue;
56743
56380
  }
56744
- for (const day of import_fs68.default.readdirSync(monthPath)) {
56745
- const dayPath = import_path63.default.join(monthPath, day);
56381
+ for (const day of import_fs67.default.readdirSync(monthPath)) {
56382
+ const dayPath = import_path62.default.join(monthPath, day);
56746
56383
  try {
56747
- if (!import_fs68.default.statSync(dayPath).isDirectory()) continue;
56384
+ if (!import_fs67.default.statSync(dayPath).isDirectory()) continue;
56748
56385
  } catch {
56749
56386
  continue;
56750
56387
  }
56751
- for (const file of import_fs68.default.readdirSync(dayPath)) {
56752
- if (file.endsWith(".jsonl")) jsonlFiles.push(import_path63.default.join(dayPath, file));
56388
+ for (const file of import_fs67.default.readdirSync(dayPath)) {
56389
+ if (file.endsWith(".jsonl")) jsonlFiles.push(import_path62.default.join(dayPath, file));
56753
56390
  }
56754
56391
  }
56755
56392
  }
@@ -56761,7 +56398,7 @@ function buildCodexSessions(days, allAuditEntries) {
56761
56398
  for (const filePath of jsonlFiles) {
56762
56399
  let lines;
56763
56400
  try {
56764
- lines = import_fs68.default.readFileSync(filePath, "utf-8").split("\n");
56401
+ lines = import_fs67.default.readFileSync(filePath, "utf-8").split("\n");
56765
56402
  } catch {
56766
56403
  continue;
56767
56404
  }
@@ -56847,10 +56484,10 @@ function buildCodexSessions(days, allAuditEntries) {
56847
56484
  return summaries;
56848
56485
  }
56849
56486
  function buildSessions(days, historyPath) {
56850
- const hPath = historyPath ?? import_path63.default.join(import_os56.default.homedir(), ".claude", "history.jsonl");
56487
+ const hPath = historyPath ?? import_path62.default.join(import_os55.default.homedir(), ".claude", "history.jsonl");
56851
56488
  let historyRaw = "";
56852
56489
  try {
56853
- historyRaw = import_fs68.default.readFileSync(hPath, "utf-8");
56490
+ historyRaw = import_fs67.default.readFileSync(hPath, "utf-8");
56854
56491
  } catch {
56855
56492
  }
56856
56493
  const cutoff = days !== null ? (() => {
@@ -56874,7 +56511,7 @@ function buildSessions(days, historyPath) {
56874
56511
  const jsonlFile = sessionJsonlPath(entry.project, entry.sessionId);
56875
56512
  let sessionLines = [];
56876
56513
  try {
56877
- sessionLines = import_fs68.default.readFileSync(jsonlFile, "utf-8").split("\n");
56514
+ sessionLines = import_fs67.default.readFileSync(jsonlFile, "utf-8").split("\n");
56878
56515
  } catch {
56879
56516
  }
56880
56517
  const { toolCalls, costUSD, hasSnapshot, modifiedFiles } = parseSessionLines(sessionLines);
@@ -57268,12 +56905,12 @@ function registerSessionTaintCommand(program2) {
57268
56905
 
57269
56906
  // src/cli/commands/skill-pin.ts
57270
56907
  var import_chalk35 = __toESM(require("chalk"));
57271
- var import_fs69 = __toESM(require("fs"));
57272
- var import_os57 = __toESM(require("os"));
57273
- var import_path64 = __toESM(require("path"));
56908
+ var import_fs68 = __toESM(require("fs"));
56909
+ var import_os56 = __toESM(require("os"));
56910
+ var import_path63 = __toESM(require("path"));
57274
56911
  function wipeSkillSessions() {
57275
56912
  try {
57276
- import_fs69.default.rmSync(import_path64.default.join(import_os57.default.homedir(), ".node9", "skill-sessions"), {
56913
+ import_fs68.default.rmSync(import_path63.default.join(import_os56.default.homedir(), ".node9", "skill-sessions"), {
57277
56914
  recursive: true,
57278
56915
  force: true
57279
56916
  });
@@ -57355,15 +56992,15 @@ function registerSkillPinCommand(program2) {
57355
56992
  }
57356
56993
 
57357
56994
  // src/cli/commands/decisions.ts
57358
- var import_fs70 = __toESM(require("fs"));
57359
- var import_os58 = __toESM(require("os"));
57360
- var import_path65 = __toESM(require("path"));
56995
+ var import_fs69 = __toESM(require("fs"));
56996
+ var import_os57 = __toESM(require("os"));
56997
+ var import_path64 = __toESM(require("path"));
57361
56998
  var import_chalk36 = __toESM(require("chalk"));
57362
- var DECISIONS_FILE2 = import_path65.default.join(import_os58.default.homedir(), ".node9", "decisions.json");
56999
+ var DECISIONS_FILE2 = import_path64.default.join(import_os57.default.homedir(), ".node9", "decisions.json");
57363
57000
  function readDecisions() {
57364
57001
  try {
57365
- if (!import_fs70.default.existsSync(DECISIONS_FILE2)) return {};
57366
- const raw = import_fs70.default.readFileSync(DECISIONS_FILE2, "utf-8");
57002
+ if (!import_fs69.default.existsSync(DECISIONS_FILE2)) return {};
57003
+ const raw = import_fs69.default.readFileSync(DECISIONS_FILE2, "utf-8");
57367
57004
  const parsed = JSON.parse(raw);
57368
57005
  const out = {};
57369
57006
  for (const [k, v] of Object.entries(parsed)) {
@@ -57375,11 +57012,11 @@ function readDecisions() {
57375
57012
  }
57376
57013
  }
57377
57014
  function writeDecisions(d) {
57378
- const dir = import_path65.default.dirname(DECISIONS_FILE2);
57379
- if (!import_fs70.default.existsSync(dir)) import_fs70.default.mkdirSync(dir, { recursive: true });
57015
+ const dir = import_path64.default.dirname(DECISIONS_FILE2);
57016
+ if (!import_fs69.default.existsSync(dir)) import_fs69.default.mkdirSync(dir, { recursive: true });
57380
57017
  const tmp = `${DECISIONS_FILE2}.${process.pid}.tmp`;
57381
- import_fs70.default.writeFileSync(tmp, JSON.stringify(d, null, 2));
57382
- import_fs70.default.renameSync(tmp, DECISIONS_FILE2);
57018
+ import_fs69.default.writeFileSync(tmp, JSON.stringify(d, null, 2));
57019
+ import_fs69.default.renameSync(tmp, DECISIONS_FILE2);
57383
57020
  }
57384
57021
  function registerDecisionsCommand(program2) {
57385
57022
  const cmd = program2.command("decisions").description('Manage persistent "Always Allow" / "Always Deny" tool decisions');
@@ -57436,18 +57073,18 @@ Persistent decisions (${entries.length})
57436
57073
 
57437
57074
  // src/cli/commands/dlp.ts
57438
57075
  var import_chalk37 = __toESM(require("chalk"));
57439
- var import_fs71 = __toESM(require("fs"));
57440
- var import_path66 = __toESM(require("path"));
57441
- var import_os59 = __toESM(require("os"));
57442
- var AUDIT_LOG = import_path66.default.join(import_os59.default.homedir(), ".node9", "audit.log");
57443
- var RESOLVED_FILE = import_path66.default.join(import_os59.default.homedir(), ".node9", "dlp-resolved.json");
57076
+ var import_fs70 = __toESM(require("fs"));
57077
+ var import_path65 = __toESM(require("path"));
57078
+ var import_os58 = __toESM(require("os"));
57079
+ var AUDIT_LOG = import_path65.default.join(import_os58.default.homedir(), ".node9", "audit.log");
57080
+ var RESOLVED_FILE = import_path65.default.join(import_os58.default.homedir(), ".node9", "dlp-resolved.json");
57444
57081
  var ANSI_RE = /\x1b(?:\[[0-9;?]*[a-zA-Z]|\][^\x07\x1b]*(?:\x07|\x1b\\)|[@-_])/g;
57445
57082
  function stripAnsi(s) {
57446
57083
  return s.replace(ANSI_RE, "");
57447
57084
  }
57448
57085
  function loadResolved() {
57449
57086
  try {
57450
- const raw = JSON.parse(import_fs71.default.readFileSync(RESOLVED_FILE, "utf-8"));
57087
+ const raw = JSON.parse(import_fs70.default.readFileSync(RESOLVED_FILE, "utf-8"));
57451
57088
  return new Set(raw);
57452
57089
  } catch {
57453
57090
  return /* @__PURE__ */ new Set();
@@ -57455,13 +57092,13 @@ function loadResolved() {
57455
57092
  }
57456
57093
  function saveResolved(resolved) {
57457
57094
  try {
57458
- import_fs71.default.writeFileSync(RESOLVED_FILE, JSON.stringify([...resolved], null, 2), { mode: 384 });
57095
+ import_fs70.default.writeFileSync(RESOLVED_FILE, JSON.stringify([...resolved], null, 2), { mode: 384 });
57459
57096
  } catch {
57460
57097
  }
57461
57098
  }
57462
57099
  function loadDlpFindings() {
57463
- if (!import_fs71.default.existsSync(AUDIT_LOG)) return [];
57464
- return import_fs71.default.readFileSync(AUDIT_LOG, "utf-8").split("\n").flatMap((line) => {
57100
+ if (!import_fs70.default.existsSync(AUDIT_LOG)) return [];
57101
+ return import_fs70.default.readFileSync(AUDIT_LOG, "utf-8").split("\n").flatMap((line) => {
57465
57102
  if (!line.trim()) return [];
57466
57103
  try {
57467
57104
  const e = JSON.parse(line);
@@ -57559,15 +57196,15 @@ function registerDlpCommand(program2) {
57559
57196
 
57560
57197
  // src/cli/commands/mask.ts
57561
57198
  var import_chalk38 = __toESM(require("chalk"));
57562
- var import_fs72 = __toESM(require("fs"));
57563
- var import_path67 = __toESM(require("path"));
57564
- var import_os60 = __toESM(require("os"));
57199
+ var import_fs71 = __toESM(require("fs"));
57200
+ var import_path66 = __toESM(require("path"));
57201
+ var import_os59 = __toESM(require("os"));
57565
57202
  init_dlp();
57566
57203
  function findJsonlFiles(dir) {
57567
57204
  const results = [];
57568
- if (!import_fs72.default.existsSync(dir)) return results;
57569
- for (const entry of import_fs72.default.readdirSync(dir, { withFileTypes: true })) {
57570
- const full = import_path67.default.join(dir, entry.name);
57205
+ if (!import_fs71.default.existsSync(dir)) return results;
57206
+ for (const entry of import_fs71.default.readdirSync(dir, { withFileTypes: true })) {
57207
+ const full = import_path66.default.join(dir, entry.name);
57571
57208
  if (entry.isDirectory()) results.push(...findJsonlFiles(full));
57572
57209
  else if (entry.isFile() && entry.name.endsWith(".jsonl")) results.push(full);
57573
57210
  }
@@ -57610,7 +57247,7 @@ function redactJson(obj) {
57610
57247
  function processFile(filePath, dryRun) {
57611
57248
  let raw;
57612
57249
  try {
57613
- raw = import_fs72.default.readFileSync(filePath, "utf-8");
57250
+ raw = import_fs71.default.readFileSync(filePath, "utf-8");
57614
57251
  } catch {
57615
57252
  return { redactedLines: 0, patterns: [] };
57616
57253
  }
@@ -57642,14 +57279,14 @@ function processFile(filePath, dryRun) {
57642
57279
  }
57643
57280
  }
57644
57281
  if (!dryRun && redactedLines > 0) {
57645
- import_fs72.default.writeFileSync(filePath, newLines.join("\n"), "utf-8");
57282
+ import_fs71.default.writeFileSync(filePath, newLines.join("\n"), "utf-8");
57646
57283
  }
57647
57284
  return { redactedLines, patterns };
57648
57285
  }
57649
57286
  function processJsonFile(filePath, dryRun) {
57650
57287
  let raw;
57651
57288
  try {
57652
- raw = import_fs72.default.readFileSync(filePath, "utf-8");
57289
+ raw = import_fs71.default.readFileSync(filePath, "utf-8");
57653
57290
  } catch {
57654
57291
  return { redactedLines: 0, patterns: [] };
57655
57292
  }
@@ -57662,15 +57299,15 @@ function processJsonFile(filePath, dryRun) {
57662
57299
  const { value, modified, found } = redactJson(parsed);
57663
57300
  if (!modified) return { redactedLines: 0, patterns: [] };
57664
57301
  if (!dryRun) {
57665
- import_fs72.default.writeFileSync(filePath, JSON.stringify(value, null, 2), "utf-8");
57302
+ import_fs71.default.writeFileSync(filePath, JSON.stringify(value, null, 2), "utf-8");
57666
57303
  }
57667
57304
  return { redactedLines: 1, patterns: found };
57668
57305
  }
57669
57306
  function findJsonFiles(dir) {
57670
57307
  const results = [];
57671
- if (!import_fs72.default.existsSync(dir)) return results;
57672
- for (const entry of import_fs72.default.readdirSync(dir, { withFileTypes: true })) {
57673
- const full = import_path67.default.join(dir, entry.name);
57308
+ if (!import_fs71.default.existsSync(dir)) return results;
57309
+ for (const entry of import_fs71.default.readdirSync(dir, { withFileTypes: true })) {
57310
+ const full = import_path66.default.join(dir, entry.name);
57674
57311
  if (entry.isDirectory()) results.push(...findJsonFiles(full));
57675
57312
  else if (entry.isFile() && entry.name.endsWith(".json")) results.push(full);
57676
57313
  }
@@ -57679,9 +57316,9 @@ function findJsonFiles(dir) {
57679
57316
  function registerMaskCommand(program2) {
57680
57317
  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) => {
57681
57318
  const dryRun = !!options.dryRun;
57682
- const home = import_os60.default.homedir();
57683
- const claudeDir = import_path67.default.join(home, ".claude", "projects");
57684
- const geminiDir = import_path67.default.join(home, ".gemini", "tmp");
57319
+ const home = import_os59.default.homedir();
57320
+ const claudeDir = import_path66.default.join(home, ".claude", "projects");
57321
+ const geminiDir = import_path66.default.join(home, ".gemini", "tmp");
57685
57322
  const allFiles = [
57686
57323
  ...findJsonlFiles(claudeDir).map((p) => ({ path: p, type: "jsonl" })),
57687
57324
  ...findJsonFiles(geminiDir).map((p) => ({ path: p, type: "json" }))
@@ -57689,7 +57326,7 @@ function registerMaskCommand(program2) {
57689
57326
  const cutoff = options.all ? null : new Date(Date.now() - 30 * 24 * 60 * 60 * 1e3);
57690
57327
  const filtered = cutoff ? allFiles.filter((f) => {
57691
57328
  try {
57692
- return import_fs72.default.statSync(f.path).mtime >= cutoff;
57329
+ return import_fs71.default.statSync(f.path).mtime >= cutoff;
57693
57330
  } catch {
57694
57331
  return false;
57695
57332
  }
@@ -57745,7 +57382,7 @@ function registerMaskCommand(program2) {
57745
57382
  // src/cli.ts
57746
57383
  init_blast();
57747
57384
  var { version } = JSON.parse(
57748
- import_fs75.default.readFileSync(import_path70.default.join(__dirname, "../package.json"), "utf-8")
57385
+ import_fs74.default.readFileSync(import_path69.default.join(__dirname, "../package.json"), "utf-8")
57749
57386
  );
57750
57387
  var program = new import_commander.Command();
57751
57388
  program.name("node9").description("The Sudo Command for AI Agents").version(version);
@@ -57785,7 +57422,7 @@ program.command("signup").description("Create your node9 account / open the dash
57785
57422
  console.log(" " + import_chalk40.default.dim("Opening ") + import_chalk40.default.cyan.underline(url));
57786
57423
  const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
57787
57424
  try {
57788
- const child = (0, import_child_process15.spawn)(opener, [url], {
57425
+ const child = (0, import_child_process14.spawn)(opener, [url], {
57789
57426
  stdio: "ignore",
57790
57427
  detached: true,
57791
57428
  shell: process.platform === "win32"
@@ -57928,16 +57565,16 @@ program.command("uninstall").description("Remove all Node9 hooks and optionally
57928
57565
  } catch {
57929
57566
  }
57930
57567
  if (options.purge) {
57931
- const node9Dir = import_path70.default.join(import_os63.default.homedir(), ".node9");
57932
- if (import_fs75.default.existsSync(node9Dir)) {
57568
+ const node9Dir = import_path69.default.join(import_os62.default.homedir(), ".node9");
57569
+ if (import_fs74.default.existsSync(node9Dir)) {
57933
57570
  const alsoSnapshots = undoLeftoverPaths().length > 0 ? ", old undo snapshots" : "";
57934
57571
  const confirmed = await (0, import_prompts3.confirm)({
57935
57572
  message: `Permanently delete ${node9Dir} (config, audit log, credentials${alsoSnapshots})?`,
57936
57573
  default: false
57937
57574
  });
57938
57575
  if (confirmed) {
57939
- import_fs75.default.rmSync(node9Dir, { recursive: true });
57940
- if (import_fs75.default.existsSync(node9Dir)) {
57576
+ import_fs74.default.rmSync(node9Dir, { recursive: true });
57577
+ if (import_fs74.default.existsSync(node9Dir)) {
57941
57578
  console.error(
57942
57579
  import_chalk40.default.red("\n \u26A0\uFE0F ~/.node9/ could not be fully deleted \u2014 remove it manually.")
57943
57580
  );
@@ -58073,7 +57710,7 @@ program.command("tail").description("Stream live agent activity to the terminal"
58073
57710
  });
58074
57711
  program.command("monitor").description("Live interactive dashboard \u2014 activity feed, approvals, security signals").action(async () => {
58075
57712
  try {
58076
- const dashboardPath = import_path70.default.join(__dirname, "dashboard.mjs");
57713
+ const dashboardPath = import_path69.default.join(__dirname, "dashboard.mjs");
58077
57714
  const dynamicImport = new Function("id", "return import(id)");
58078
57715
  const mod = await dynamicImport(`file://${dashboardPath}`);
58079
57716
  await mod.startMonitor();
@@ -58111,14 +57748,14 @@ Claude Code spawns this command every ~300ms and writes a JSON payload to stdin.
58111
57748
  Run "node9 addto claude" to register it as the statusLine.`
58112
57749
  ).argument("[subcommand]", 'Optional: "debug on" / "debug off" to toggle stdin logging').argument("[state]", 'on|off \u2014 used with "debug" subcommand').action(async (subcommand, state) => {
58113
57750
  if (subcommand === "debug") {
58114
- const flagFile = import_path70.default.join(import_os63.default.homedir(), ".node9", "hud-debug");
57751
+ const flagFile = import_path69.default.join(import_os62.default.homedir(), ".node9", "hud-debug");
58115
57752
  if (state === "on") {
58116
- import_fs75.default.mkdirSync(import_path70.default.dirname(flagFile), { recursive: true });
58117
- import_fs75.default.writeFileSync(flagFile, "");
57753
+ import_fs74.default.mkdirSync(import_path69.default.dirname(flagFile), { recursive: true });
57754
+ import_fs74.default.writeFileSync(flagFile, "");
58118
57755
  console.log("HUD debug logging enabled \u2192 ~/.node9/hud-debug.log");
58119
57756
  console.log("Tail it with: tail -f ~/.node9/hud-debug.log");
58120
57757
  } else if (state === "off") {
58121
- if (import_fs75.default.existsSync(flagFile)) import_fs75.default.unlinkSync(flagFile);
57758
+ if (import_fs74.default.existsSync(flagFile)) import_fs74.default.unlinkSync(flagFile);
58122
57759
  console.log("HUD debug logging disabled.");
58123
57760
  } else {
58124
57761
  console.error("Usage: node9 hud debug on|off");
@@ -58241,9 +57878,9 @@ if (process.argv[2] !== "daemon") {
58241
57878
  const isCheckHook = process.argv[2] === "check";
58242
57879
  if (isCheckHook) {
58243
57880
  if (process.env.NODE9_DEBUG === "1" || getConfig().settings.enableHookLogDebug) {
58244
- const logPath = import_path70.default.join(import_os63.default.homedir(), ".node9", "hook-debug.log");
57881
+ const logPath = import_path69.default.join(import_os62.default.homedir(), ".node9", "hook-debug.log");
58245
57882
  const msg = reason instanceof Error ? reason.message : String(reason);
58246
- import_fs75.default.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] UNHANDLED: ${msg}
57883
+ import_fs74.default.appendFileSync(logPath, `[${(/* @__PURE__ */ new Date()).toISOString()}] UNHANDLED: ${msg}
58247
57884
  `);
58248
57885
  }
58249
57886
  process.exit(0);