@node9/proxy 2.45.0 → 2.46.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/dist/cli.js +8644 -8729
  2. package/dist/cli.mjs +8629 -8714
  3. package/dist/dashboard.mjs +395 -314
  4. package/package.json +1 -1
@@ -18747,79 +18747,6 @@ var init_credential_files = __esm({
18747
18747
  }
18748
18748
  });
18749
18749
 
18750
- // src/cli/commands/blast.ts
18751
- import chalk from "chalk";
18752
- import fs5 from "fs";
18753
- import path6 from "path";
18754
- import os4 from "os";
18755
- function buildSensitivePaths(home, cwd) {
18756
- const homeFiles = homeCredentialFiles(home).map(({ full, label: label2, description, score }) => ({
18757
- full,
18758
- label: label2,
18759
- description,
18760
- score
18761
- }));
18762
- return [
18763
- ...homeFiles,
18764
- {
18765
- full: path6.join(cwd, ".env"),
18766
- label: ".env (current folder)",
18767
- description: "App secrets: database passwords, API keys",
18768
- score: 20
18769
- },
18770
- {
18771
- full: path6.join(cwd, ".env.local"),
18772
- label: ".env.local (current folder)",
18773
- description: "Local overrides: often contains real credentials",
18774
- score: 15
18775
- },
18776
- {
18777
- full: path6.join(cwd, ".env.production"),
18778
- label: ".env.production (current folder)",
18779
- description: "Production secrets",
18780
- score: 20
18781
- }
18782
- ];
18783
- }
18784
- function isReadable(filePath) {
18785
- try {
18786
- fs5.accessSync(filePath, fs5.constants.R_OK);
18787
- return true;
18788
- } catch {
18789
- return false;
18790
- }
18791
- }
18792
- function runBlast() {
18793
- const home = os4.homedir();
18794
- const cwd = process.cwd();
18795
- const paths = buildSensitivePaths(home, cwd);
18796
- let scoreDeduction = 0;
18797
- const reachable = [];
18798
- for (const p of paths) {
18799
- if (fs5.existsSync(p.full) && isReadable(p.full)) {
18800
- reachable.push(p);
18801
- scoreDeduction += p.score;
18802
- }
18803
- }
18804
- const envFindings = [];
18805
- for (const [key, value] of Object.entries(process.env)) {
18806
- if (!value) continue;
18807
- const match = scanArgs({ [key]: value });
18808
- if (match) {
18809
- envFindings.push({ key, patternName: match.patternName });
18810
- scoreDeduction += 10;
18811
- }
18812
- }
18813
- return { reachable, envFindings, score: Math.max(0, 100 - scoreDeduction) };
18814
- }
18815
- var init_blast = __esm({
18816
- "src/cli/commands/blast.ts"() {
18817
- "use strict";
18818
- init_dlp();
18819
- init_credential_files();
18820
- }
18821
- });
18822
-
18823
18750
  // src/mcp-cmd.ts
18824
18751
  var init_mcp_cmd = __esm({
18825
18752
  "src/mcp-cmd.ts"() {
@@ -18872,14 +18799,14 @@ var init_codex_trust = __esm({
18872
18799
  });
18873
18800
 
18874
18801
  // src/daemon/hook-baseline.ts
18875
- import path7 from "path";
18876
- import os5 from "os";
18802
+ import path6 from "path";
18803
+ import os4 from "os";
18877
18804
  var BASELINE_FILE, NOTIFIED_FILE;
18878
18805
  var init_hook_baseline = __esm({
18879
18806
  "src/daemon/hook-baseline.ts"() {
18880
18807
  "use strict";
18881
- BASELINE_FILE = path7.join(os5.homedir(), ".node9", "hooks-baseline.json");
18882
- NOTIFIED_FILE = path7.join(os5.homedir(), ".node9", "hook-heal-notified.json");
18808
+ BASELINE_FILE = path6.join(os4.homedir(), ".node9", "hooks-baseline.json");
18809
+ NOTIFIED_FILE = path6.join(os4.homedir(), ".node9", "hook-heal-notified.json");
18883
18810
  }
18884
18811
  });
18885
18812
 
@@ -18898,27 +18825,27 @@ var init_setup_pi_shim = __esm({
18898
18825
  });
18899
18826
 
18900
18827
  // src/utils/atomic-write.ts
18901
- import fs6 from "fs";
18902
- import path8 from "path";
18828
+ import fs5 from "fs";
18829
+ import path7 from "path";
18903
18830
  import { randomUUID } from "crypto";
18904
18831
  function atomicWriteSync(filePath, data, options) {
18905
- const dir2 = path8.dirname(filePath);
18906
- if (!fs6.existsSync(dir2)) fs6.mkdirSync(dir2, { recursive: true });
18832
+ const dir2 = path7.dirname(filePath);
18833
+ if (!fs5.existsSync(dir2)) fs5.mkdirSync(dir2, { recursive: true });
18907
18834
  const tmpPath = `${filePath}.${randomUUID()}.tmp`;
18908
18835
  try {
18909
- fs6.writeFileSync(tmpPath, data, options);
18836
+ fs5.writeFileSync(tmpPath, data, options);
18910
18837
  } catch (err) {
18911
18838
  try {
18912
- fs6.unlinkSync(tmpPath);
18839
+ fs5.unlinkSync(tmpPath);
18913
18840
  } catch {
18914
18841
  }
18915
18842
  throw err;
18916
18843
  }
18917
18844
  try {
18918
- fs6.renameSync(tmpPath, filePath);
18845
+ fs5.renameSync(tmpPath, filePath);
18919
18846
  } catch (err) {
18920
18847
  try {
18921
- fs6.unlinkSync(tmpPath);
18848
+ fs5.unlinkSync(tmpPath);
18922
18849
  } catch {
18923
18850
  }
18924
18851
  throw err;
@@ -18931,10 +18858,10 @@ var init_atomic_write = __esm({
18931
18858
  });
18932
18859
 
18933
18860
  // src/setup.ts
18934
- import fs7 from "fs";
18935
- import path9 from "path";
18936
- import os6 from "os";
18937
- import chalk2 from "chalk";
18861
+ import fs6 from "fs";
18862
+ import path8 from "path";
18863
+ import os5 from "os";
18864
+ import chalk from "chalk";
18938
18865
  import { confirm as rawConfirm } from "@inquirer/prompts";
18939
18866
  import { parse as parseToml4, stringify as stringifyToml2 } from "smol-toml";
18940
18867
  import * as yaml from "yaml";
@@ -18946,9 +18873,9 @@ function isNode9Hook(cmd) {
18946
18873
  // fell into after #185.
18947
18874
  /[/\\]\.node9[/\\]bin[/\\]hook"? (?:check|log)/.test(cmd);
18948
18875
  }
18949
- function claudeDesktopConfigPath(homeDir = os6.homedir()) {
18876
+ function claudeDesktopConfigPath(homeDir = os5.homedir()) {
18950
18877
  if (process.platform === "darwin") {
18951
- return path9.join(
18878
+ return path8.join(
18952
18879
  homeDir,
18953
18880
  "Library",
18954
18881
  "Application Support",
@@ -18957,47 +18884,47 @@ function claudeDesktopConfigPath(homeDir = os6.homedir()) {
18957
18884
  );
18958
18885
  }
18959
18886
  if (process.platform === "linux") {
18960
- return path9.join(homeDir, ".config", "Claude", "claude_desktop_config.json");
18887
+ return path8.join(homeDir, ".config", "Claude", "claude_desktop_config.json");
18961
18888
  }
18962
18889
  if (process.platform === "win32") {
18963
- const appData = process.env.APPDATA || path9.join(homeDir, "AppData", "Roaming");
18964
- return path9.join(appData, "Claude", "claude_desktop_config.json");
18890
+ const appData = process.env.APPDATA || path8.join(homeDir, "AppData", "Roaming");
18891
+ return path8.join(appData, "Claude", "claude_desktop_config.json");
18965
18892
  }
18966
18893
  return null;
18967
18894
  }
18968
- function opencodeConfigDir(home = os6.homedir()) {
18895
+ function opencodeConfigDir(home = os5.homedir()) {
18969
18896
  const xdg = process.env.XDG_CONFIG_HOME;
18970
- const base2 = xdg && path9.isAbsolute(xdg) ? xdg : path9.join(home, ".config");
18971
- return path9.join(base2, "opencode");
18897
+ const base2 = xdg && path8.isAbsolute(xdg) ? xdg : path8.join(home, ".config");
18898
+ return path8.join(base2, "opencode");
18972
18899
  }
18973
18900
  function commonBinDirs(home) {
18974
18901
  return [
18975
- path9.join(home, ".local", "bin"),
18976
- path9.join(home, ".bun", "bin"),
18977
- path9.join(home, ".npm-global", "bin"),
18902
+ path8.join(home, ".local", "bin"),
18903
+ path8.join(home, ".bun", "bin"),
18904
+ path8.join(home, ".npm-global", "bin"),
18978
18905
  "/usr/local/bin",
18979
18906
  "/opt/homebrew/bin"
18980
18907
  ];
18981
18908
  }
18982
- function binaryInPath(binary, home = os6.homedir()) {
18909
+ function binaryInPath(binary, home = os5.homedir()) {
18983
18910
  const pathEnv = process.env.PATH ?? "";
18984
- const dirs = [...pathEnv.split(path9.delimiter), ...commonBinDirs(home)];
18911
+ const dirs = [...pathEnv.split(path8.delimiter), ...commonBinDirs(home)];
18985
18912
  const seen = /* @__PURE__ */ new Set();
18986
18913
  for (const dir2 of dirs) {
18987
18914
  if (!dir2 || seen.has(dir2)) continue;
18988
18915
  seen.add(dir2);
18989
18916
  try {
18990
- fs7.accessSync(path9.join(dir2, binary), fs7.constants.X_OK);
18917
+ fs6.accessSync(path8.join(dir2, binary), fs6.constants.X_OK);
18991
18918
  return true;
18992
18919
  } catch {
18993
18920
  }
18994
18921
  }
18995
18922
  return false;
18996
18923
  }
18997
- function detectAgents(homeDir = os6.homedir()) {
18924
+ function detectAgents(homeDir = os5.homedir()) {
18998
18925
  const exists2 = (p) => {
18999
18926
  try {
19000
- return fs7.existsSync(p);
18927
+ return fs6.existsSync(p);
19001
18928
  } catch (err) {
19002
18929
  const code = err.code;
19003
18930
  if (code !== "ENOENT") {
@@ -19009,7 +18936,7 @@ function detectAgents(homeDir = os6.homedir()) {
19009
18936
  };
19010
18937
  const desktopPath = claudeDesktopConfigPath(homeDir);
19011
18938
  return {
19012
- claude: exists2(path9.join(homeDir, ".claude")) || exists2(path9.join(homeDir, ".claude.json")),
18939
+ claude: exists2(path8.join(homeDir, ".claude")) || exists2(path8.join(homeDir, ".claude.json")),
19013
18940
  // Antigravity (agy) shares the ~/.gemini root, so a bare
19014
18941
  // `exists(~/.gemini)` would report the (EOL'd) Gemini CLI as
19015
18942
  // installed on every agy machine — and `node9 init` would then
@@ -19019,19 +18946,19 @@ function detectAgents(homeDir = os6.homedir()) {
19019
18946
  // creates ~/.gemini/settings.json on first run; agy does not touch
19020
18947
  // it (it uses antigravity-cli/settings.json) — that file is the
19021
18948
  // legacy-CLI discriminator.
19022
- gemini: exists2(path9.join(homeDir, ".gemini", "settings.json")) || binaryInPath("gemini", homeDir),
18949
+ gemini: exists2(path8.join(homeDir, ".gemini", "settings.json")) || binaryInPath("gemini", homeDir),
19023
18950
  // agy creates ~/.gemini/antigravity-cli/ on first launch; the IDE
19024
18951
  // creates antigravity-ide/. PATH fallback covers installed-but-
19025
18952
  // never-launched (same class as opencode #186).
19026
- antigravity: exists2(path9.join(homeDir, ".gemini", "antigravity-cli")) || exists2(path9.join(homeDir, ".gemini", "antigravity-ide")) || binaryInPath("agy", homeDir),
18953
+ antigravity: exists2(path8.join(homeDir, ".gemini", "antigravity-cli")) || exists2(path8.join(homeDir, ".gemini", "antigravity-ide")) || binaryInPath("agy", homeDir),
19027
18954
  // GitHub Copilot CLI creates ~/.copilot on first launch; PATH
19028
18955
  // fallback covers installed-but-never-launched (same as opencode #186).
19029
- copilot: exists2(path9.join(homeDir, ".copilot")) || binaryInPath("copilot", homeDir),
19030
- cursor: exists2(path9.join(homeDir, ".cursor")),
19031
- codex: exists2(path9.join(homeDir, ".codex")),
19032
- windsurf: exists2(path9.join(homeDir, ".codeium", "windsurf")),
19033
- vscode: exists2(path9.join(homeDir, ".vscode")),
19034
- claudeDesktop: desktopPath !== null && exists2(path9.dirname(desktopPath)),
18956
+ copilot: exists2(path8.join(homeDir, ".copilot")) || binaryInPath("copilot", homeDir),
18957
+ cursor: exists2(path8.join(homeDir, ".cursor")),
18958
+ codex: exists2(path8.join(homeDir, ".codex")),
18959
+ windsurf: exists2(path8.join(homeDir, ".codeium", "windsurf")),
18960
+ vscode: exists2(path8.join(homeDir, ".vscode")),
18961
+ claudeDesktop: desktopPath !== null && exists2(path8.dirname(desktopPath)),
19035
18962
  // Opencode creates its config dir lazily on first launch — fall back to a
19036
18963
  // PATH lookup so installed-but-never-launched CLIs are still wired. Config
19037
18964
  // dir honors $XDG_CONFIG_HOME via opencodeConfigDir (#186, custom-XDG).
@@ -19042,7 +18969,7 @@ function detectAgents(homeDir = os6.homedir()) {
19042
18969
  // dir lazily on first launch — same class of bug as opencode's #186
19043
18970
  // (design R6) — so fall back to PATH lookup for installed-but-never-
19044
18971
  // launched pi.
19045
- pi: exists2(path9.join(homeDir, ".pi", "agent")) || binaryInPath("pi", homeDir),
18972
+ pi: exists2(path8.join(homeDir, ".pi", "agent")) || binaryInPath("pi", homeDir),
19046
18973
  // Hermes Agent (https://github.com/NousResearch/hermes-agent): home dir
19047
18974
  // is $HERMES_HOME (default ~/.hermes) per hermes_constants.py:30. config.yaml
19048
18975
  // appears after `hermes setup` has run; the directory alone exists from
@@ -19051,13 +18978,13 @@ function detectAgents(homeDir = os6.homedir()) {
19051
18978
  hermes: exists2(hermesHomeDir(homeDir)) || binaryInPath("hermes", homeDir)
19052
18979
  };
19053
18980
  }
19054
- function hermesHomeDir(homeDir = os6.homedir()) {
18981
+ function hermesHomeDir(homeDir = os5.homedir()) {
19055
18982
  const env = process.env.HERMES_HOME?.trim();
19056
- if (env && path9.isAbsolute(env)) return env;
19057
- return path9.join(homeDir, ".hermes");
18983
+ if (env && path8.isAbsolute(env)) return env;
18984
+ return path8.join(homeDir, ".hermes");
19058
18985
  }
19059
- function hermesConfigPath(homeDir = os6.homedir()) {
19060
- return path9.join(hermesHomeDir(homeDir), HERMES_CONFIG_FILENAME);
18986
+ function hermesConfigPath(homeDir = os5.homedir()) {
18987
+ return path8.join(hermesHomeDir(homeDir), HERMES_CONFIG_FILENAME);
19061
18988
  }
19062
18989
  var HERMES_CONFIG_FILENAME;
19063
18990
  var init_setup = __esm({
@@ -19076,15 +19003,15 @@ var init_setup = __esm({
19076
19003
  });
19077
19004
 
19078
19005
  // src/agent-wiring.ts
19079
- import fs8 from "fs";
19080
- import path10 from "path";
19081
- import os7 from "os";
19006
+ import fs7 from "fs";
19007
+ import path9 from "path";
19008
+ import os6 from "os";
19082
19009
  import * as yaml2 from "yaml";
19083
19010
  import { parse as parseToml5 } from "smol-toml";
19084
19011
  function readJson(filePath) {
19085
- if (!fs8.existsSync(filePath)) return null;
19012
+ if (!fs7.existsSync(filePath)) return null;
19086
19013
  try {
19087
- return JSON.parse(fs8.readFileSync(filePath, "utf-8"));
19014
+ return JSON.parse(fs7.readFileSync(filePath, "utf-8"));
19088
19015
  } catch {
19089
19016
  return "invalid";
19090
19017
  }
@@ -19096,10 +19023,10 @@ function flatHaveNode9Hook(entries) {
19096
19023
  return (Array.isArray(entries) ? entries : []).some((h) => isNode9Hook(h.command));
19097
19024
  }
19098
19025
  function readHookRoot(filePath, format) {
19099
- if (!fs8.existsSync(filePath)) return "absent";
19026
+ if (!fs7.existsSync(filePath)) return "absent";
19100
19027
  let raw;
19101
19028
  try {
19102
- raw = fs8.readFileSync(filePath, "utf-8");
19029
+ raw = fs7.readFileSync(filePath, "utf-8");
19103
19030
  } catch {
19104
19031
  return "absent";
19105
19032
  }
@@ -19122,20 +19049,20 @@ function detectMcp(servers) {
19122
19049
  return { wrapped, present };
19123
19050
  }
19124
19051
  function readMcp(filePath, format) {
19125
- if (!fs8.existsSync(filePath)) return { wrapped: [], present: false };
19052
+ if (!fs7.existsSync(filePath)) return { wrapped: [], present: false };
19126
19053
  try {
19127
19054
  if (format === "toml") {
19128
- const parsed2 = parseToml5(fs8.readFileSync(filePath, "utf-8"));
19055
+ const parsed2 = parseToml5(fs7.readFileSync(filePath, "utf-8"));
19129
19056
  return detectMcp(parsed2?.mcp_servers);
19130
19057
  }
19131
19058
  const parsed = readJson(filePath);
19132
19059
  if (parsed === null || parsed === "invalid") return { wrapped: [], present: false };
19133
- return detectMcp(parsed.mcpServers);
19060
+ return detectMcp(format === "vscode" ? parsed.servers : parsed.mcpServers);
19134
19061
  } catch {
19135
19062
  return { wrapped: [], present: false };
19136
19063
  }
19137
19064
  }
19138
- function getAgentWiring(home = os7.homedir()) {
19065
+ function getAgentWiring(home = os6.homedir()) {
19139
19066
  const detected = detectAgents(home);
19140
19067
  return AGENT_SPECS.map((spec) => {
19141
19068
  const present = spec.present(home);
@@ -19179,7 +19106,8 @@ function getAgentWiring(home = os7.homedir()) {
19179
19106
  configFormat: spec.hookFormat === "yaml" ? "YAML" : "JSON",
19180
19107
  mcpServers: mcp ? mcp.wrapped : null,
19181
19108
  mcpProtected: mcp ? mcp.present : false,
19182
- isProtected: anyHookWired || (mcp?.present ?? false)
19109
+ isProtected: anyHookWired || (mcp?.present ?? false),
19110
+ protection: spec.hookEvents.length > 0 || spec.shimFile ? "hooks" : "mcp"
19183
19111
  };
19184
19112
  });
19185
19113
  }
@@ -19190,7 +19118,7 @@ var init_agent_wiring = __esm({
19190
19118
  init_setup();
19191
19119
  exists = (p) => {
19192
19120
  try {
19193
- return fs8.existsSync(p);
19121
+ return fs7.existsSync(p);
19194
19122
  } catch {
19195
19123
  return false;
19196
19124
  }
@@ -19204,55 +19132,55 @@ var init_agent_wiring = __esm({
19204
19132
  id: "claude",
19205
19133
  label: "Claude Code",
19206
19134
  setupCommand: "node9 agents add claude",
19207
- hookFile: (h) => path10.join(h, ".claude", "settings.json"),
19135
+ hookFile: (h) => path9.join(h, ".claude", "settings.json"),
19208
19136
  hookFormat: "matcher",
19209
19137
  // UserPromptSubmit is prompt DLP. setup.ts has written it for Claude since
19210
19138
  // that shipped; the spec must name it too, or status/doctor never show the
19211
19139
  // row and heal (which repairs via setupAgent) has no signal it is missing.
19212
19140
  hookEvents: [ck("PreToolUse"), lg("PostToolUse"), ck("UserPromptSubmit")],
19213
- mcpFile: (h) => path10.join(h, ".claude.json"),
19214
- present: (h) => exists(path10.join(h, ".claude", "settings.json")) || exists(path10.join(h, ".claude.json"))
19141
+ mcpFile: (h) => path9.join(h, ".claude.json"),
19142
+ present: (h) => exists(path9.join(h, ".claude", "settings.json")) || exists(path9.join(h, ".claude.json"))
19215
19143
  },
19216
19144
  {
19217
19145
  id: "gemini",
19218
19146
  label: "Gemini CLI",
19219
19147
  setupCommand: "node9 agents add gemini",
19220
- hookFile: (h) => path10.join(h, ".gemini", "settings.json"),
19148
+ hookFile: (h) => path9.join(h, ".gemini", "settings.json"),
19221
19149
  hookFormat: "matcher",
19222
19150
  hookEvents: [ck("BeforeTool"), lg("AfterTool")],
19223
- mcpFile: (h) => path10.join(h, ".gemini", "settings.json"),
19224
- present: (h) => exists(path10.join(h, ".gemini", "settings.json"))
19151
+ mcpFile: (h) => path9.join(h, ".gemini", "settings.json"),
19152
+ present: (h) => exists(path9.join(h, ".gemini", "settings.json"))
19225
19153
  },
19226
19154
  {
19227
19155
  id: "codex",
19228
19156
  label: "Codex",
19229
19157
  setupCommand: "node9 agents add codex",
19230
- hookFile: (h) => path10.join(h, ".codex", "hooks.json"),
19158
+ hookFile: (h) => path9.join(h, ".codex", "hooks.json"),
19231
19159
  hookFormat: "matcher",
19232
19160
  hookEvents: [ck("PreToolUse"), ck("UserPromptSubmit")],
19233
- mcpFile: (h) => path10.join(h, ".codex", "config.toml"),
19161
+ mcpFile: (h) => path9.join(h, ".codex", "config.toml"),
19234
19162
  mcpFormat: "toml",
19235
- present: (h) => exists(path10.join(h, ".codex"))
19163
+ present: (h) => exists(path9.join(h, ".codex"))
19236
19164
  },
19237
19165
  {
19238
19166
  id: "antigravity",
19239
19167
  label: "Antigravity",
19240
19168
  setupCommand: "node9 agents add antigravity",
19241
- hookFile: (h) => path10.join(h, ".gemini", "config", "hooks.json"),
19169
+ hookFile: (h) => path9.join(h, ".gemini", "config", "hooks.json"),
19242
19170
  hookFormat: "matcher",
19243
19171
  hookEvents: [ck("PreToolUse"), lg("PostToolUse")],
19244
- mcpFile: (h) => path10.join(h, ".gemini", "config", "mcp_config.json"),
19245
- present: (h) => exists(path10.join(h, ".gemini", "config", "hooks.json")) || exists(path10.join(h, ".gemini", "antigravity-cli")) || exists(path10.join(h, ".gemini", "antigravity-ide"))
19172
+ mcpFile: (h) => path9.join(h, ".gemini", "config", "mcp_config.json"),
19173
+ present: (h) => exists(path9.join(h, ".gemini", "config", "hooks.json")) || exists(path9.join(h, ".gemini", "antigravity-cli")) || exists(path9.join(h, ".gemini", "antigravity-ide"))
19246
19174
  },
19247
19175
  {
19248
19176
  id: "copilot",
19249
19177
  label: "GitHub Copilot",
19250
19178
  setupCommand: "node9 agents add copilot",
19251
- hookFile: (h) => path10.join(h, ".copilot", "hooks", "node9.json"),
19179
+ hookFile: (h) => path9.join(h, ".copilot", "hooks", "node9.json"),
19252
19180
  hookFormat: "flat",
19253
19181
  hookEvents: [ck("PreToolUse"), lg("PostToolUse"), ck("UserPromptSubmit")],
19254
- mcpFile: (h) => path10.join(h, ".copilot", "mcp-config.json"),
19255
- present: (h) => exists(path10.join(h, ".copilot"))
19182
+ mcpFile: (h) => path9.join(h, ".copilot", "mcp-config.json"),
19183
+ present: (h) => exists(path9.join(h, ".copilot"))
19256
19184
  },
19257
19185
  {
19258
19186
  id: "cursor",
@@ -19261,8 +19189,45 @@ var init_agent_wiring = __esm({
19261
19189
  // MCP-only — no hook file (see note above).
19262
19190
  hookFormat: "flat",
19263
19191
  hookEvents: [],
19264
- mcpFile: (h) => path10.join(h, ".cursor", "mcp.json"),
19265
- present: (h) => exists(path10.join(h, ".cursor", "mcp.json"))
19192
+ mcpFile: (h) => path9.join(h, ".cursor", "mcp.json"),
19193
+ present: (h) => exists(path9.join(h, ".cursor", "mcp.json"))
19194
+ },
19195
+ // The three MCP-only agents below came over from `getAgentsStatus` (fw#421
19196
+ // P3), so one registry answers every "is it wired" question.
19197
+ {
19198
+ id: "windsurf",
19199
+ label: "Windsurf",
19200
+ setupCommand: "node9 agents add windsurf",
19201
+ hookFormat: "flat",
19202
+ hookEvents: [],
19203
+ mcpFile: (h) => path9.join(h, ".codeium", "windsurf", "mcp_config.json"),
19204
+ mcpInventory: false,
19205
+ present: (h) => exists(path9.join(h, ".codeium", "windsurf"))
19206
+ },
19207
+ {
19208
+ id: "vscode",
19209
+ label: "VSCode",
19210
+ setupCommand: "node9 agents add vscode",
19211
+ hookFormat: "flat",
19212
+ hookEvents: [],
19213
+ mcpFile: (h) => path9.join(h, ".vscode", "mcp.json"),
19214
+ mcpFormat: "vscode",
19215
+ mcpInventory: false,
19216
+ present: (h) => exists(path9.join(h, ".vscode"))
19217
+ },
19218
+ {
19219
+ id: "claudeDesktop",
19220
+ label: "Claude Desktop",
19221
+ setupCommand: "node9 agents add claudeDesktop",
19222
+ hookFormat: "flat",
19223
+ hookEvents: [],
19224
+ // The per-platform config path; its parent directory is the footprint.
19225
+ mcpFile: (h) => claudeDesktopConfigPath(h) ?? path9.join(h, ".config", "Claude", "claude_desktop_config.json"),
19226
+ mcpInventory: false,
19227
+ present: (h) => {
19228
+ const p = claudeDesktopConfigPath(h);
19229
+ return p !== null && exists(path9.dirname(p));
19230
+ }
19266
19231
  },
19267
19232
  {
19268
19233
  id: "hermes",
@@ -19283,8 +19248,8 @@ var init_agent_wiring = __esm({
19283
19248
  setupCommand: "node9 agents add opencode",
19284
19249
  hookFormat: "flat",
19285
19250
  hookEvents: [],
19286
- shimFile: (h) => path10.join(opencodeConfigDir(h), "plugins", "node9.js"),
19287
- present: (h) => exists(opencodeConfigDir(h)) || exists(path10.join(opencodeConfigDir(h), "plugins", "node9.js"))
19251
+ shimFile: (h) => path9.join(opencodeConfigDir(h), "plugins", "node9.js"),
19252
+ present: (h) => exists(opencodeConfigDir(h)) || exists(path9.join(opencodeConfigDir(h), "plugins", "node9.js"))
19288
19253
  },
19289
19254
  {
19290
19255
  id: "pi",
@@ -19292,8 +19257,8 @@ var init_agent_wiring = __esm({
19292
19257
  setupCommand: "node9 agents add pi",
19293
19258
  hookFormat: "flat",
19294
19259
  hookEvents: [],
19295
- shimFile: (h) => path10.join(h, ".pi", "agent", "extensions", "node9.js"),
19296
- present: (h) => exists(path10.join(h, ".pi", "agent")) || exists(path10.join(h, ".pi", "agent", "extensions", "node9.js"))
19260
+ shimFile: (h) => path9.join(h, ".pi", "agent", "extensions", "node9.js"),
19261
+ present: (h) => exists(path9.join(h, ".pi", "agent")) || exists(path9.join(h, ".pi", "agent", "extensions", "node9.js"))
19297
19262
  }
19298
19263
  ];
19299
19264
  }
@@ -19383,14 +19348,14 @@ var init_build = __esm({
19383
19348
  });
19384
19349
 
19385
19350
  // src/shields.ts
19386
- import fs9 from "fs";
19387
- import path11 from "path";
19388
- import os8 from "os";
19351
+ import fs8 from "fs";
19352
+ import path10 from "path";
19353
+ import os7 from "os";
19389
19354
  function loadUserShields() {
19390
19355
  const result = {};
19391
19356
  let entries;
19392
19357
  try {
19393
- entries = fs9.readdirSync(USER_SHIELDS_DIR).filter((f) => f.endsWith(".json"));
19358
+ entries = fs8.readdirSync(USER_SHIELDS_DIR).filter((f) => f.endsWith(".json"));
19394
19359
  } catch (err) {
19395
19360
  if (err.code !== "ENOENT") {
19396
19361
  process.stderr.write(
@@ -19401,9 +19366,9 @@ function loadUserShields() {
19401
19366
  return result;
19402
19367
  }
19403
19368
  for (const file2 of entries) {
19404
- const filePath = path11.join(USER_SHIELDS_DIR, file2);
19369
+ const filePath = path10.join(USER_SHIELDS_DIR, file2);
19405
19370
  try {
19406
- const raw = JSON.parse(fs9.readFileSync(filePath, "utf-8"));
19371
+ const raw = JSON.parse(fs8.readFileSync(filePath, "utf-8"));
19407
19372
  const v = validateShieldDefinition(raw);
19408
19373
  if ("error" in v) {
19409
19374
  process.stderr.write(`[node9] ${v.error}: ${filePath}
@@ -19435,7 +19400,7 @@ function getShield(name) {
19435
19400
  }
19436
19401
  function readShieldsFile() {
19437
19402
  try {
19438
- const raw = fs9.readFileSync(SHIELDS_STATE_FILE, "utf-8");
19403
+ const raw = fs8.readFileSync(SHIELDS_STATE_FILE, "utf-8");
19439
19404
  if (!raw.trim()) return { active: [] };
19440
19405
  const parsed = JSON.parse(raw);
19441
19406
  const active = Array.isArray(parsed.active) ? parsed.active.filter(
@@ -19468,23 +19433,23 @@ var init_shields = __esm({
19468
19433
  init_dist();
19469
19434
  init_build();
19470
19435
  init_dist();
19471
- USER_SHIELDS_DIR = path11.join(os8.homedir(), ".node9", "shields");
19436
+ USER_SHIELDS_DIR = path10.join(os7.homedir(), ".node9", "shields");
19472
19437
  SHIELDS = buildSHIELDS();
19473
- SHIELDS_STATE_FILE = path11.join(os8.homedir(), ".node9", "shields.json");
19438
+ SHIELDS_STATE_FILE = path10.join(os7.homedir(), ".node9", "shields.json");
19474
19439
  }
19475
19440
  });
19476
19441
 
19477
19442
  // src/shields/jail.ts
19478
- import fs10 from "fs";
19479
- import os9 from "os";
19480
- import path12 from "path";
19443
+ import fs9 from "fs";
19444
+ import os8 from "os";
19445
+ import path11 from "path";
19481
19446
  function jailStorePath() {
19482
- return path12.join(os9.homedir(), ".node9", "jail-paths.json");
19447
+ return path11.join(os8.homedir(), ".node9", "jail-paths.json");
19483
19448
  }
19484
19449
  function readJailPaths() {
19485
19450
  let text;
19486
19451
  try {
19487
- text = fs10.readFileSync(jailStorePath(), "utf8");
19452
+ text = fs9.readFileSync(jailStorePath(), "utf8");
19488
19453
  } catch (err) {
19489
19454
  if (err.code === "ENOENT") return [];
19490
19455
  throw err;
@@ -19522,11 +19487,11 @@ var init_jail = __esm({
19522
19487
  });
19523
19488
 
19524
19489
  // src/canary/registry.ts
19525
- import fs11 from "fs";
19526
- import os10 from "os";
19527
- import path13 from "path";
19490
+ import fs10 from "fs";
19491
+ import os9 from "os";
19492
+ import path12 from "path";
19528
19493
  function canaryStorePath() {
19529
- return path13.join(os10.homedir(), ".node9", "canaries.json");
19494
+ return path12.join(os9.homedir(), ".node9", "canaries.json");
19530
19495
  }
19531
19496
  function isRecord(x) {
19532
19497
  if (!x || typeof x !== "object") return false;
@@ -19537,7 +19502,7 @@ function loadCanaries(opts) {
19537
19502
  const p = canaryStorePath();
19538
19503
  let raw;
19539
19504
  try {
19540
- raw = fs11.readFileSync(p, "utf-8");
19505
+ raw = fs10.readFileSync(p, "utf-8");
19541
19506
  } catch (e) {
19542
19507
  if (e.code === "ENOENT") return [];
19543
19508
  throw e;
@@ -19576,23 +19541,23 @@ var init_registry = __esm({
19576
19541
  });
19577
19542
 
19578
19543
  // src/utils/read-capped.ts
19579
- import fs12 from "fs";
19544
+ import fs11 from "fs";
19580
19545
  function readCapped(file2, maxBytes, openFlags = "r") {
19581
19546
  if (maxBytes < 0) return null;
19582
19547
  let fd;
19583
19548
  try {
19584
- fd = fs12.openSync(file2, openFlags);
19549
+ fd = fs11.openSync(file2, openFlags);
19585
19550
  } catch {
19586
19551
  return null;
19587
19552
  }
19588
19553
  try {
19589
- const st = fs12.fstatSync(fd);
19554
+ const st = fs11.fstatSync(fd);
19590
19555
  if (!st.isFile()) return null;
19591
19556
  const want = Math.min(st.size, maxBytes + 1);
19592
19557
  const buf = Buffer.alloc(want);
19593
19558
  let read2 = 0;
19594
19559
  while (read2 < want) {
19595
- const n = fs12.readSync(fd, buf, read2, want - read2, read2);
19560
+ const n = fs11.readSync(fd, buf, read2, want - read2, read2);
19596
19561
  if (n <= 0) break;
19597
19562
  read2 += n;
19598
19563
  }
@@ -19604,7 +19569,7 @@ function readCapped(file2, maxBytes, openFlags = "r") {
19604
19569
  return null;
19605
19570
  } finally {
19606
19571
  try {
19607
- fs12.closeSync(fd);
19572
+ fs11.closeSync(fd);
19608
19573
  } catch {
19609
19574
  }
19610
19575
  }
@@ -19620,13 +19585,13 @@ var init_read_capped = __esm({
19620
19585
  });
19621
19586
 
19622
19587
  // src/posture/secrets.ts
19623
- import fs13 from "fs";
19624
- import path14 from "path";
19625
- import os11 from "os";
19588
+ import fs12 from "fs";
19589
+ import path13 from "path";
19590
+ import os10 from "os";
19626
19591
  function displayPath(p, home) {
19627
19592
  if (p === home) return "~";
19628
- const prefix = home.endsWith(path14.sep) ? home : home + path14.sep;
19629
- if (p.startsWith(prefix)) return "~" + path14.sep + p.slice(prefix.length);
19593
+ const prefix = home.endsWith(path13.sep) ? home : home + path13.sep;
19594
+ if (p.startsWith(prefix)) return "~" + path13.sep + p.slice(prefix.length);
19630
19595
  return p;
19631
19596
  }
19632
19597
  function safeRead(file2) {
@@ -19637,8 +19602,8 @@ function safeRead(file2) {
19637
19602
  function candidateFiles(home, cwd) {
19638
19603
  const files = /* @__PURE__ */ new Set();
19639
19604
  try {
19640
- for (const name of fs13.readdirSync(cwd)) {
19641
- if (name === ".env" || name.startsWith(".env.")) files.add(path14.join(cwd, name));
19605
+ for (const name of fs12.readdirSync(cwd)) {
19606
+ if (name === ".env" || name.startsWith(".env.")) files.add(path13.join(cwd, name));
19642
19607
  }
19643
19608
  } catch {
19644
19609
  }
@@ -19646,7 +19611,7 @@ function candidateFiles(home, cwd) {
19646
19611
  if (spec.hookFile) files.add(spec.hookFile(home));
19647
19612
  if (spec.mcpFile) files.add(spec.mcpFile(home));
19648
19613
  }
19649
- files.add(path14.join(home, ".env"));
19614
+ files.add(path13.join(home, ".env"));
19650
19615
  return [...files];
19651
19616
  }
19652
19617
  function credentialMaterial(home) {
@@ -19660,7 +19625,7 @@ function plantedDecoyPaths() {
19660
19625
  }
19661
19626
  }
19662
19627
  function checkSecrets(ctx) {
19663
- const home = ctx.home || os11.homedir();
19628
+ const home = ctx.home || os10.homedir();
19664
19629
  const findings = [];
19665
19630
  const planted = plantedDecoyPaths();
19666
19631
  const plaintext = [];
@@ -19696,7 +19661,7 @@ function checkSecrets(ctx) {
19696
19661
  for (const file2 of credentialMaterial(home)) {
19697
19662
  if (planted.has(file2)) continue;
19698
19663
  try {
19699
- if (fs13.statSync(file2).isFile()) {
19664
+ if (fs12.statSync(file2).isFile()) {
19700
19665
  creds.push(displayPath(file2, home));
19701
19666
  credPaths.push(file2);
19702
19667
  }
@@ -19717,6 +19682,25 @@ function checkSecrets(ctx) {
19717
19682
  coverageProbe: { kind: "fileRead", paths: credPaths }
19718
19683
  });
19719
19684
  }
19685
+ const envSecrets = [];
19686
+ for (const [key, value] of Object.entries(ctx.env ?? process.env)) {
19687
+ if (!value) continue;
19688
+ const match = scanArgs({ [key]: value });
19689
+ if (match) envSecrets.push(`${key} (${match.patternName})`);
19690
+ }
19691
+ if (envSecrets.length > 0) {
19692
+ findings.push({
19693
+ category: "Secrets",
19694
+ severity: "high",
19695
+ title: `${envSecrets.length} secret environment variable${envSecrets.length === 1 ? "" : "s"} visible to the agent`,
19696
+ what: "A key or token is exported in the shell the agent runs from.",
19697
+ why: "Every program the agent starts inherits the environment, so the value is one `env` away.",
19698
+ who: "A tricked agent can read it and send it anywhere a command can reach.",
19699
+ detail: envSecrets,
19700
+ fix: "Unset it in the shell that starts the agent, or pass it to the one command that needs it (`env KEY=... cmd`) or a secrets manager.",
19701
+ owner: "os"
19702
+ });
19703
+ }
19720
19704
  if (planted.size > 0) {
19721
19705
  findings.push({
19722
19706
  category: "Secrets",
@@ -19739,6 +19723,7 @@ var init_secrets = __esm({
19739
19723
  init_registry();
19740
19724
  init_read_capped();
19741
19725
  init_credential_files();
19726
+ init_dlp();
19742
19727
  MAX_FILE_BYTES = 256 * 1024;
19743
19728
  }
19744
19729
  });
@@ -20149,15 +20134,15 @@ var init_managed = __esm({
20149
20134
  });
20150
20135
 
20151
20136
  // src/auth/trusted-hosts.ts
20152
- import fs14 from "fs";
20153
- import path15 from "path";
20154
- import os12 from "os";
20137
+ import fs13 from "fs";
20138
+ import path14 from "path";
20139
+ import os11 from "os";
20155
20140
  function getTrustedHostsPath() {
20156
- return path15.join(os12.homedir(), ".node9", "trusted-hosts.json");
20141
+ return path14.join(os11.homedir(), ".node9", "trusted-hosts.json");
20157
20142
  }
20158
20143
  function readTrustedHosts() {
20159
20144
  try {
20160
- const raw = fs14.readFileSync(getTrustedHostsPath(), "utf8");
20145
+ const raw = fs13.readFileSync(getTrustedHostsPath(), "utf8");
20161
20146
  const parsed = JSON.parse(raw);
20162
20147
  return Array.isArray(parsed.hosts) ? parsed.hosts : [];
20163
20148
  } catch {
@@ -20166,7 +20151,7 @@ function readTrustedHosts() {
20166
20151
  }
20167
20152
  function getFileMtime() {
20168
20153
  try {
20169
- return fs14.statSync(getTrustedHostsPath()).mtimeMs;
20154
+ return fs13.statSync(getTrustedHostsPath()).mtimeMs;
20170
20155
  } catch {
20171
20156
  return 0;
20172
20157
  }
@@ -20385,9 +20370,9 @@ var init_api_url = __esm({
20385
20370
  });
20386
20371
 
20387
20372
  // src/config/index.ts
20388
- import fs15 from "fs";
20389
- import path16 from "path";
20390
- import os13 from "os";
20373
+ import fs14 from "fs";
20374
+ import path15 from "path";
20375
+ import os12 from "os";
20391
20376
  function sanitizeSsrfAllow(entries, source) {
20392
20377
  const kept = [];
20393
20378
  for (const entry of entries) {
@@ -20409,8 +20394,8 @@ function noteRejectedApiUrl(raw) {
20409
20394
  if (rejectedApiUrlsSeen.has(key)) return;
20410
20395
  rejectedApiUrlsSeen.add(key);
20411
20396
  try {
20412
- fs15.appendFileSync(
20413
- path16.join(os13.homedir(), ".node9", "hook-debug.log"),
20397
+ fs14.appendFileSync(
20398
+ path15.join(os12.homedir(), ".node9", "hook-debug.log"),
20414
20399
  `[${(/* @__PURE__ */ new Date()).toISOString()}] REFUSED apiUrl, using the default instead: ${String(raw).slice(0, 200).replace(/[\r\n]+/g, " ")}
20415
20400
  `
20416
20401
  );
@@ -20427,9 +20412,9 @@ function getCredentials() {
20427
20412
  };
20428
20413
  }
20429
20414
  try {
20430
- const credPath = path16.join(os13.homedir(), ".node9", "credentials.json");
20431
- if (fs15.existsSync(credPath)) {
20432
- const creds = JSON.parse(fs15.readFileSync(credPath, "utf-8"));
20415
+ const credPath = path15.join(os12.homedir(), ".node9", "credentials.json");
20416
+ if (fs14.existsSync(credPath)) {
20417
+ const creds = JSON.parse(fs14.readFileSync(credPath, "utf-8"));
20433
20418
  const profileName = process.env.NODE9_PROFILE || "default";
20434
20419
  const profile = creds[profileName];
20435
20420
  if (typeof profile?.apiKey === "string" && profile.apiKey.length > 0) {
@@ -20461,7 +20446,7 @@ function readRulesCacheResilient(cacheFile) {
20461
20446
  for (let attempt = 0; attempt < 3; attempt++) {
20462
20447
  let content;
20463
20448
  try {
20464
- content = fs15.readFileSync(cacheFile, "utf-8");
20449
+ content = fs14.readFileSync(cacheFile, "utf-8");
20465
20450
  existed = true;
20466
20451
  } catch (err) {
20467
20452
  if (err.code === "ENOENT") return {};
@@ -20476,10 +20461,10 @@ function readRulesCacheResilient(cacheFile) {
20476
20461
  }
20477
20462
  }
20478
20463
  if (existed || sawReadError) {
20479
- const backup = path16.join(path16.dirname(cacheFile), "rules-cache.last-good.json");
20464
+ const backup = path15.join(path15.dirname(cacheFile), "rules-cache.last-good.json");
20480
20465
  if (backup !== cacheFile) {
20481
20466
  try {
20482
- const raw = JSON.parse(fs15.readFileSync(backup, "utf-8"));
20467
+ const raw = JSON.parse(fs14.readFileSync(backup, "utf-8"));
20483
20468
  logCacheReadIssue(cacheFile, "RULES_CACHE_CORRUPT_USED_BACKUP");
20484
20469
  lastParsedRulesCache = raw;
20485
20470
  return raw;
@@ -20499,8 +20484,8 @@ function logCacheReadIssue(cacheFile, kind) {
20499
20484
  if (now - cacheReadLastLoggedAt < CACHE_LOG_REARM_MS) return;
20500
20485
  cacheReadLastLoggedAt = now;
20501
20486
  try {
20502
- fs15.appendFileSync(
20503
- path16.join(os13.homedir(), ".node9", "hook-debug.log"),
20487
+ fs14.appendFileSync(
20488
+ path15.join(os12.homedir(), ".node9", "hook-debug.log"),
20504
20489
  `[${(/* @__PURE__ */ new Date()).toISOString()}] ${kind} ${cacheFile}
20505
20490
  `
20506
20491
  );
@@ -20517,8 +20502,8 @@ function catalogSettingsFrom(settings, policy) {
20517
20502
  }
20518
20503
  function getConfig(cwd) {
20519
20504
  if (!cwd && cachedConfig) return cachedConfig;
20520
- const globalPath = path16.join(os13.homedir(), ".node9", "config.json");
20521
- const projectPath = path16.join(cwd ?? process.cwd(), "node9.config.json");
20505
+ const globalPath = path15.join(os12.homedir(), ".node9", "config.json");
20506
+ const projectPath = path15.join(cwd ?? process.cwd(), "node9.config.json");
20522
20507
  const globalConfig = tryLoadConfig(globalPath);
20523
20508
  const projectConfig = tryLoadConfig(projectPath, { project: true });
20524
20509
  const mergedSettings = {
@@ -20763,7 +20748,7 @@ function getConfig(cwd) {
20763
20748
  let cloudMandatesEnforcement = false;
20764
20749
  let cloudMandatesAppPerm = false;
20765
20750
  {
20766
- const cacheFile = path16.join(os13.homedir(), ".node9", "rules-cache.json");
20751
+ const cacheFile = path15.join(os12.homedir(), ".node9", "rules-cache.json");
20767
20752
  try {
20768
20753
  const raw = readRulesCacheResilient(cacheFile);
20769
20754
  if (Array.isArray(raw.rules) && raw.rules.length > 0) {
@@ -21195,10 +21180,10 @@ function getConfig(cwd) {
21195
21180
  }
21196
21181
  function tryLoadConfig(filePath, options = {}) {
21197
21182
  v2ChecksByPath.delete(filePath);
21198
- if (!fs15.existsSync(filePath)) return null;
21183
+ if (!fs14.existsSync(filePath)) return null;
21199
21184
  let raw;
21200
21185
  try {
21201
- raw = JSON.parse(fs15.readFileSync(filePath, "utf-8"));
21186
+ raw = JSON.parse(fs14.readFileSync(filePath, "utf-8"));
21202
21187
  } catch (err) {
21203
21188
  const msg = err instanceof Error ? err.message : String(err);
21204
21189
  process.stderr.write(
@@ -21661,10 +21646,10 @@ var init_templates = __esm({
21661
21646
  });
21662
21647
 
21663
21648
  // src/posture/egress.ts
21664
- import fs16 from "fs";
21649
+ import fs15 from "fs";
21665
21650
  function sandboxEgressWallActive() {
21666
21651
  try {
21667
- return fs16.existsSync(ALLOWED_DOMAINS_PATH);
21652
+ return fs15.existsSync(ALLOWED_DOMAINS_PATH);
21668
21653
  } catch {
21669
21654
  return false;
21670
21655
  }
@@ -22011,29 +21996,29 @@ var init_gate_order = __esm({
22011
21996
  });
22012
21997
 
22013
21998
  // src/policy/file-access.ts
22014
- import fs17 from "fs";
22015
- import os14 from "os";
22016
- import path17 from "path";
21999
+ import fs16 from "fs";
22000
+ import os13 from "os";
22001
+ import path16 from "path";
22017
22002
  function absoluteSpelling(p, cwd, home) {
22018
22003
  if (p === "~" || p.startsWith("~/")) p = home + p.slice(1);
22019
- return path17.isAbsolute(p) ? p : `${cwd}/${p}`;
22004
+ return path16.isAbsolute(p) ? p : `${cwd}/${p}`;
22020
22005
  }
22021
22006
  function physical(p, followFinal, links = 0) {
22022
22007
  if (links > 40) throw new Error("Too many symbolic links");
22023
22008
  if (!followFinal) {
22024
- const parent = physical(path17.dirname(p), true, links);
22025
- return { path: `${parent.path}/${path17.basename(p)}`, missing: parent.missing };
22009
+ const parent = physical(path16.dirname(p), true, links);
22010
+ return { path: `${parent.path}/${path16.basename(p)}`, missing: parent.missing };
22026
22011
  }
22027
22012
  try {
22028
- return { path: fs17.realpathSync.native(p), missing: false };
22013
+ return { path: fs16.realpathSync.native(p), missing: false };
22029
22014
  } catch (error) {
22030
22015
  const code = error.code;
22031
22016
  if (!["ENOENT", "ENOTDIR"].includes(code ?? "")) throw error;
22032
22017
  try {
22033
- if (fs17.lstatSync(p).isSymbolicLink()) {
22034
- const target = fs17.readlinkSync(p);
22018
+ if (fs16.lstatSync(p).isSymbolicLink()) {
22019
+ const target = fs16.readlinkSync(p);
22035
22020
  return physical(
22036
- path17.isAbsolute(target) ? target : `${path17.dirname(p)}/${target}`,
22021
+ path16.isAbsolute(target) ? target : `${path16.dirname(p)}/${target}`,
22037
22022
  true,
22038
22023
  links + 1
22039
22024
  );
@@ -22042,13 +22027,13 @@ function physical(p, followFinal, links = 0) {
22042
22027
  if (!["ENOENT", "ENOTDIR"].includes(linkError.code ?? ""))
22043
22028
  throw linkError;
22044
22029
  }
22045
- const parent = path17.dirname(p);
22030
+ const parent = path16.dirname(p);
22046
22031
  if (parent === p) return { path: p, missing: true };
22047
22032
  const resolved = physical(parent, true, links);
22048
- return { path: `${resolved.path}/${path17.basename(p)}`, missing: true };
22033
+ return { path: `${resolved.path}/${path16.basename(p)}`, missing: true };
22049
22034
  }
22050
22035
  }
22051
- function prepareFileAccesses(tool, args, cwd = process.cwd(), inspection = {}, home = os14.homedir()) {
22036
+ function prepareFileAccesses(tool, args, cwd = process.cwd(), inspection = {}, home = os13.homedir()) {
22052
22037
  const context = { cwd, homeDirs: [home, "/root"] };
22053
22038
  const accesses = collectFileAccesses(tool, args, context, inspection);
22054
22039
  const handledPaths = /* @__PURE__ */ new Set();
@@ -22071,14 +22056,14 @@ function prepareFileAccesses(tool, args, cwd = process.cwd(), inspection = {}, h
22071
22056
  const raw = absoluteSpelling(access.path, access.cwd ?? cwd, home);
22072
22057
  if (access.directoryTarget) {
22073
22058
  try {
22074
- if (!fs17.statSync(absoluteSpelling(access.directoryTarget, access.cwd ?? cwd, home)).isDirectory())
22059
+ if (!fs16.statSync(absoluteSpelling(access.directoryTarget, access.cwd ?? cwd, home)).isDirectory())
22075
22060
  continue;
22076
22061
  } catch {
22077
22062
  }
22078
22063
  }
22079
22064
  if (access.operation === "create") {
22080
22065
  try {
22081
- fs17.statSync(raw);
22066
+ fs16.statSync(raw);
22082
22067
  continue;
22083
22068
  } catch {
22084
22069
  }
@@ -22133,15 +22118,15 @@ var init_file_access = __esm({
22133
22118
  });
22134
22119
 
22135
22120
  // src/supply-chain/osv-index.ts
22136
- import fs18 from "fs";
22137
- import os15 from "os";
22138
- import path18 from "path";
22121
+ import fs17 from "fs";
22122
+ import os14 from "os";
22123
+ import path17 from "path";
22139
22124
  import { createHash as createHash4 } from "crypto";
22140
22125
  function osvRoot() {
22141
- return path18.join(os15.homedir(), ".node9", "osv");
22126
+ return path17.join(os14.homedir(), ".node9", "osv");
22142
22127
  }
22143
22128
  function ecoDir(eco) {
22144
- return path18.join(osvRoot(), eco);
22129
+ return path17.join(osvRoot(), eco);
22145
22130
  }
22146
22131
  function indexKey(eco, name) {
22147
22132
  switch (eco) {
@@ -22160,11 +22145,11 @@ function shardOf(key) {
22160
22145
  return createHash4("sha1").update(key).digest("hex").slice(0, 2);
22161
22146
  }
22162
22147
  function shardPath(eco, shard) {
22163
- return path18.join(ecoDir(eco), "shards", `${shard}.json`);
22148
+ return path17.join(ecoDir(eco), "shards", `${shard}.json`);
22164
22149
  }
22165
22150
  function readMeta(eco) {
22166
22151
  try {
22167
- const m = JSON.parse(fs18.readFileSync(path18.join(ecoDir(eco), "meta.json"), "utf8"));
22152
+ const m = JSON.parse(fs17.readFileSync(path17.join(ecoDir(eco), "meta.json"), "utf8"));
22168
22153
  if (typeof m?.syncedAt !== "string" || typeof m?.lastModifiedMs !== "number") return null;
22169
22154
  return m;
22170
22155
  } catch {
@@ -22173,7 +22158,7 @@ function readMeta(eco) {
22173
22158
  }
22174
22159
  function readShard(eco, shard) {
22175
22160
  try {
22176
- const s = JSON.parse(fs18.readFileSync(shardPath(eco, shard), "utf8"));
22161
+ const s = JSON.parse(fs17.readFileSync(shardPath(eco, shard), "utf8"));
22177
22162
  return s && typeof s === "object" && !Array.isArray(s) ? s : {};
22178
22163
  } catch {
22179
22164
  return {};
@@ -22555,17 +22540,17 @@ var init_registry2 = __esm({
22555
22540
  });
22556
22541
 
22557
22542
  // src/supply-chain/local-resolve.ts
22558
- import fs19 from "fs";
22559
- import path19 from "path";
22543
+ import fs18 from "fs";
22544
+ import path18 from "path";
22560
22545
  function resolveInstalled(name, cwd) {
22561
- if (!cwd || !path19.isAbsolute(cwd)) return null;
22546
+ if (!cwd || !path18.isAbsolute(cwd)) return null;
22562
22547
  if (!/^(?:@[^/\\]+\/)?[^/\\]+$/.test(name)) return null;
22563
- let dir2 = path19.resolve(cwd);
22548
+ let dir2 = path18.resolve(cwd);
22564
22549
  for (let i = 0; i < MAX_LEVELS; i++) {
22565
- const pkgDir = path19.join(dir2, "node_modules", ...name.split("/"));
22566
- const manifest = path19.join(pkgDir, "package.json");
22550
+ const pkgDir = path18.join(dir2, "node_modules", ...name.split("/"));
22551
+ const manifest = path18.join(pkgDir, "package.json");
22567
22552
  try {
22568
- const raw = fs19.readFileSync(manifest, "utf8");
22553
+ const raw = fs18.readFileSync(manifest, "utf8");
22569
22554
  const parsed = JSON.parse(raw);
22570
22555
  if (typeof parsed.version === "string" && parsed.version.length > 0) {
22571
22556
  return { version: parsed.version, dir: pkgDir };
@@ -22573,7 +22558,7 @@ function resolveInstalled(name, cwd) {
22573
22558
  return null;
22574
22559
  } catch {
22575
22560
  }
22576
- const parent = path19.dirname(dir2);
22561
+ const parent = path18.dirname(dir2);
22577
22562
  if (parent === dir2) break;
22578
22563
  dir2 = parent;
22579
22564
  }
@@ -22590,7 +22575,7 @@ var init_local_resolve = __esm({
22590
22575
 
22591
22576
  // src/supply-chain/check.ts
22592
22577
  import picomatch2 from "picomatch";
22593
- import path20 from "path";
22578
+ import path19 from "path";
22594
22579
  function commandOf(toolName, args) {
22595
22580
  if (!isBashTool(toolName) || !args || typeof args !== "object") return null;
22596
22581
  const a = args;
@@ -22692,7 +22677,7 @@ function checkInstalled(p, version, misses) {
22692
22677
  }
22693
22678
  async function checkOne(p, cfg, misses, networkCapped, cwd) {
22694
22679
  if (p.ecosystem === "npm" && LOCAL_FIRST_MANAGERS.has(p.manager) && p.localCwd !== null && (p.raw === p.name || p.version)) {
22695
- const localCwd = cwd && path20.isAbsolute(cwd) ? (p.localCwd ?? []).reduce((dir2, step) => path20.resolve(dir2, step), cwd) : void 0;
22680
+ const localCwd = cwd && path19.isAbsolute(cwd) ? (p.localCwd ?? []).reduce((dir2, step) => path19.resolve(dir2, step), cwd) : void 0;
22696
22681
  const installed = resolveInstalled(p.name, localCwd);
22697
22682
  if (installed && (!p.version || p.version === installed.version))
22698
22683
  return checkInstalled(p, installed.version, misses);
@@ -22861,33 +22846,33 @@ var init_check = __esm({
22861
22846
  });
22862
22847
 
22863
22848
  // src/supply-chain/registries.ts
22864
- import os16 from "os";
22865
- import path21 from "path";
22866
- import fs20 from "fs";
22849
+ import os15 from "os";
22850
+ import path20 from "path";
22851
+ import fs19 from "fs";
22867
22852
  function userFiles(home, env) {
22868
- const xdg = env.XDG_CONFIG_HOME || path21.join(home, ".config");
22853
+ const xdg = env.XDG_CONFIG_HOME || path20.join(home, ".config");
22869
22854
  return [
22870
- env.NPM_CONFIG_USERCONFIG || env.npm_config_userconfig || path21.join(home, ".npmrc"),
22871
- path21.join(home, ".yarnrc"),
22872
- path21.join(home, ".yarnrc.yml"),
22873
- path21.join(home, ".bunfig.toml"),
22855
+ env.NPM_CONFIG_USERCONFIG || env.npm_config_userconfig || path20.join(home, ".npmrc"),
22856
+ path20.join(home, ".yarnrc"),
22857
+ path20.join(home, ".yarnrc.yml"),
22858
+ path20.join(home, ".bunfig.toml"),
22874
22859
  env.PIP_CONFIG_FILE || "",
22875
- path21.join(xdg, "pip", "pip.conf"),
22876
- path21.join(home, ".pip", "pip.conf"),
22860
+ path20.join(xdg, "pip", "pip.conf"),
22861
+ path20.join(home, ".pip", "pip.conf"),
22877
22862
  "/etc/pip.conf",
22878
- env.VIRTUAL_ENV ? path21.join(env.VIRTUAL_ENV, "pip.conf") : "",
22863
+ env.VIRTUAL_ENV ? path20.join(env.VIRTUAL_ENV, "pip.conf") : "",
22879
22864
  env.UV_CONFIG_FILE || "",
22880
- path21.join(xdg, "uv", "uv.toml"),
22865
+ path20.join(xdg, "uv", "uv.toml"),
22881
22866
  "/etc/uv/uv.toml"
22882
22867
  ].filter(Boolean);
22883
22868
  }
22884
22869
  function projectFiles(cwd) {
22885
- if (!cwd || !path21.isAbsolute(cwd)) return [];
22870
+ if (!cwd || !path20.isAbsolute(cwd)) return [];
22886
22871
  const out = [];
22887
22872
  let dir2 = cwd;
22888
22873
  for (let i = 0; i < MAX_PARENT_DIRS; i++) {
22889
- for (const f of PROJECT_FILES) out.push(path21.join(dir2, f));
22890
- const parent = path21.dirname(dir2);
22874
+ for (const f of PROJECT_FILES) out.push(path20.join(dir2, f));
22875
+ const parent = path20.dirname(dir2);
22891
22876
  if (parent === dir2) break;
22892
22877
  dir2 = parent;
22893
22878
  }
@@ -22926,7 +22911,7 @@ function hostsInText(text, out) {
22926
22911
  }
22927
22912
  }
22928
22913
  }
22929
- function configuredRegistryHosts(cwd, env = process.env, home = os16.homedir()) {
22914
+ function configuredRegistryHosts(cwd, env = process.env, home = os15.homedir()) {
22930
22915
  const key = [
22931
22916
  cwd ?? "",
22932
22917
  home,
@@ -22948,7 +22933,7 @@ function configuredRegistryHosts(cwd, env = process.env, home = os16.homedir())
22948
22933
  const r = readCappedText(
22949
22934
  file2,
22950
22935
  MAX_CONFIG_BYTES,
22951
- fs20.constants.O_RDONLY | (fs20.constants.O_NONBLOCK ?? 0)
22936
+ fs19.constants.O_RDONLY | (fs19.constants.O_NONBLOCK ?? 0)
22952
22937
  );
22953
22938
  if (r) hostsInText(r.text, hosts);
22954
22939
  }
@@ -23005,17 +22990,17 @@ var init_registries = __esm({
23005
22990
  });
23006
22991
 
23007
22992
  // src/utils/provenance.ts
23008
- import fs21 from "fs";
23009
- import path22 from "path";
23010
- import os17 from "os";
22993
+ import fs20 from "fs";
22994
+ import path21 from "path";
22995
+ import os16 from "os";
23011
22996
  function findInPath(cmd) {
23012
- if (path22.posix.isAbsolute(cmd)) return cmd;
22997
+ if (path21.posix.isAbsolute(cmd)) return cmd;
23013
22998
  const pathEnv = process.env.PATH ?? "";
23014
- for (const dir2 of pathEnv.split(path22.delimiter)) {
22999
+ for (const dir2 of pathEnv.split(path21.delimiter)) {
23015
23000
  if (!dir2) continue;
23016
- const full = path22.join(dir2, cmd);
23001
+ const full = path21.join(dir2, cmd);
23017
23002
  try {
23018
- fs21.accessSync(full, fs21.constants.X_OK);
23003
+ fs20.accessSync(full, fs20.constants.X_OK);
23019
23004
  return full;
23020
23005
  } catch {
23021
23006
  }
@@ -23026,7 +23011,7 @@ function _classifyPath(resolved, cwd) {
23026
23011
  if (cwd && resolved.startsWith(cwd + "/")) {
23027
23012
  return { trustLevel: "user", reason: "binary in project directory" };
23028
23013
  }
23029
- const osTmp = os17.tmpdir();
23014
+ const osTmp = os16.tmpdir();
23030
23015
  const allSuspect = osTmp ? [...SUSPECT_PREFIXES, osTmp] : SUSPECT_PREFIXES;
23031
23016
  if (allSuspect.some((p) => resolved === p || resolved.startsWith(p + "/"))) {
23032
23017
  return { trustLevel: "suspect", reason: `binary in temp directory: ${resolved}` };
@@ -23044,7 +23029,7 @@ function _classifyPath(resolved, cwd) {
23044
23029
  }
23045
23030
  function checkProvenance(cmd, cwd) {
23046
23031
  const bare = cmd.startsWith("./") ? cmd.slice(2) : cmd;
23047
- if (path22.posix.isAbsolute(bare)) {
23032
+ if (path21.posix.isAbsolute(bare)) {
23048
23033
  const early = _classifyPath(bare, cwd);
23049
23034
  if (early.trustLevel === "suspect") {
23050
23035
  return { resolvedPath: bare, ...early };
@@ -23060,7 +23045,7 @@ function checkProvenance(cmd, cwd) {
23060
23045
  reason: "binary not found in PATH"
23061
23046
  };
23062
23047
  }
23063
- resolved = fs21.realpathSync(found);
23048
+ resolved = fs20.realpathSync(found);
23064
23049
  } catch {
23065
23050
  return {
23066
23051
  resolvedPath: cmd,
@@ -23069,7 +23054,7 @@ function checkProvenance(cmd, cwd) {
23069
23054
  };
23070
23055
  }
23071
23056
  try {
23072
- const stat = fs21.statSync(resolved);
23057
+ const stat = fs20.statSync(resolved);
23073
23058
  if (stat.mode & 2) {
23074
23059
  return {
23075
23060
  resolvedPath: resolved,
@@ -23094,19 +23079,19 @@ var init_provenance2 = __esm({
23094
23079
  SYSTEM_PREFIXES = ["/usr/bin", "/usr/sbin", "/bin", "/sbin"];
23095
23080
  MANAGED_PREFIXES = ["/usr/local/bin", "/opt/homebrew", "/home/linuxbrew", "/nix/store"];
23096
23081
  USER_PREFIXES = [
23097
- path22.join(os17.homedir(), "bin"),
23098
- path22.join(os17.homedir(), ".local", "bin"),
23099
- path22.join(os17.homedir(), ".cargo", "bin"),
23100
- path22.join(os17.homedir(), ".npm-global", "bin"),
23101
- path22.join(os17.homedir(), ".volta", "bin")
23082
+ path21.join(os16.homedir(), "bin"),
23083
+ path21.join(os16.homedir(), ".local", "bin"),
23084
+ path21.join(os16.homedir(), ".cargo", "bin"),
23085
+ path21.join(os16.homedir(), ".npm-global", "bin"),
23086
+ path21.join(os16.homedir(), ".volta", "bin")
23102
23087
  ];
23103
23088
  SUSPECT_PREFIXES = ["/tmp", "/var/tmp", "/dev/shm"];
23104
23089
  }
23105
23090
  });
23106
23091
 
23107
23092
  // src/policy/index.ts
23108
- import fs22 from "fs";
23109
- import path23 from "path";
23093
+ import fs21 from "fs";
23094
+ import path22 from "path";
23110
23095
  async function evaluatePolicy2(toolName, args, agent, cwd, opts) {
23111
23096
  const config = opts?.config ?? getConfig(cwd);
23112
23097
  const prepared = opts?.fileAccess ?? prepareFileAccesses(toolName, args, cwd, inspectionLayers(config.policy));
@@ -23138,9 +23123,9 @@ async function evaluatePolicy2(toolName, args, agent, cwd, opts) {
23138
23123
  );
23139
23124
  }
23140
23125
  function isGitWorkTreeTop(dir2, cwd) {
23141
- if (!path23.isAbsolute(cwd)) return true;
23126
+ if (!path22.isAbsolute(cwd)) return true;
23142
23127
  try {
23143
- return fs22.existsSync(path23.join(path23.resolve(cwd, dir2), ".git"));
23128
+ return fs21.existsSync(path22.join(path22.resolve(cwd, dir2), ".git"));
23144
23129
  } catch {
23145
23130
  return true;
23146
23131
  }
@@ -23149,7 +23134,7 @@ function readAgentSettings(absPath) {
23149
23134
  const r = readCappedText(
23150
23135
  absPath,
23151
23136
  MAX_AGENT_SETTINGS_BYTES,
23152
- fs22.constants.O_RDONLY | (fs22.constants.O_NONBLOCK ?? 0)
23137
+ fs21.constants.O_RDONLY | (fs21.constants.O_NONBLOCK ?? 0)
23153
23138
  );
23154
23139
  return r && !r.truncated ? r.text : null;
23155
23140
  }
@@ -23218,14 +23203,14 @@ var init_gate = __esm({
23218
23203
  });
23219
23204
 
23220
23205
  // src/posture/supply-chain.ts
23221
- import os18 from "os";
23222
- import path24 from "path";
23206
+ import os17 from "os";
23207
+ import path23 from "path";
23223
23208
  import { parse as parseToml6 } from "smol-toml";
23224
23209
  function isNode9Managed(command, args = []) {
23225
23210
  if (!command) return false;
23226
- if (path24.basename(command).toLowerCase() === "node9") return true;
23227
- if (PACKAGE_RUNNERS.has(path24.basename(command).toLowerCase())) {
23228
- return args.some((a) => a === "node9" || path24.basename(a).toLowerCase() === "node9");
23211
+ if (path23.basename(command).toLowerCase() === "node9") return true;
23212
+ if (PACKAGE_RUNNERS.has(path23.basename(command).toLowerCase())) {
23213
+ return args.some((a) => a === "node9" || path23.basename(a).toLowerCase() === "node9");
23229
23214
  }
23230
23215
  return false;
23231
23216
  }
@@ -23247,10 +23232,10 @@ function readServers(file2, format, agent) {
23247
23232
  }
23248
23233
  }
23249
23234
  function checkSupplyChain(ctx) {
23250
- const home = ctx.home || os18.homedir();
23235
+ const home = ctx.home || os17.homedir();
23251
23236
  const servers = [];
23252
23237
  for (const spec of AGENT_SPECS) {
23253
- if (!spec.mcpFile) continue;
23238
+ if (!spec.mcpFile || spec.mcpInventory === false) continue;
23254
23239
  servers.push(...readServers(spec.mcpFile(home), spec.mcpFormat ?? "json", spec.label));
23255
23240
  }
23256
23241
  if (servers.length === 0) return [];
@@ -23346,11 +23331,11 @@ var init_privilege = __esm({
23346
23331
  });
23347
23332
 
23348
23333
  // src/posture/containment.ts
23349
- import fs23 from "fs";
23334
+ import fs22 from "fs";
23350
23335
  function inContainer() {
23351
- if (fs23.existsSync("/.dockerenv") || fs23.existsSync("/run/.containerenv")) return true;
23336
+ if (fs22.existsSync("/.dockerenv") || fs22.existsSync("/run/.containerenv")) return true;
23352
23337
  try {
23353
- const cgroup = fs23.readFileSync("/proc/1/cgroup", "utf8");
23338
+ const cgroup = fs22.readFileSync("/proc/1/cgroup", "utf8");
23354
23339
  if (/docker|kubepods|containerd|lxc|libpod/.test(cgroup)) return true;
23355
23340
  } catch {
23356
23341
  }
@@ -23396,7 +23381,7 @@ var init_containment = __esm({
23396
23381
  });
23397
23382
 
23398
23383
  // src/posture/inbound.ts
23399
- import fs24 from "fs";
23384
+ import fs23 from "fs";
23400
23385
  function buildNetworkFix(labels) {
23401
23386
  const shielded = [
23402
23387
  ...new Map(
@@ -23454,7 +23439,7 @@ function collectListeners() {
23454
23439
  const byPort = /* @__PURE__ */ new Map();
23455
23440
  for (const file2 of ["/proc/net/tcp", "/proc/net/tcp6"]) {
23456
23441
  try {
23457
- for (const l of parseListeners(fs24.readFileSync(file2, "utf8"))) {
23442
+ for (const l of parseListeners(fs23.readFileSync(file2, "utf8"))) {
23458
23443
  if (!byPort.has(l.port)) byPort.set(l.port, l);
23459
23444
  }
23460
23445
  } catch {
@@ -23466,11 +23451,11 @@ function readProc(pid) {
23466
23451
  let comm = "unknown";
23467
23452
  let cmdline = "";
23468
23453
  try {
23469
- comm = fs24.readFileSync(`/proc/${pid}/comm`, "utf8").trim().replace(/-MainThread$/, "") || "unknown";
23454
+ comm = fs23.readFileSync(`/proc/${pid}/comm`, "utf8").trim().replace(/-MainThread$/, "") || "unknown";
23470
23455
  } catch {
23471
23456
  }
23472
23457
  try {
23473
- cmdline = fs24.readFileSync(`/proc/${pid}/cmdline`).toString().replace(/\0/g, " ").trim();
23458
+ cmdline = fs23.readFileSync(`/proc/${pid}/cmdline`).toString().replace(/\0/g, " ").trim();
23474
23459
  } catch {
23475
23460
  }
23476
23461
  return { comm, cmdline };
@@ -23480,21 +23465,21 @@ function resolveProcesses(inodes) {
23480
23465
  if (inodes.size === 0) return map;
23481
23466
  let pids;
23482
23467
  try {
23483
- pids = fs24.readdirSync("/proc").filter((d) => /^\d+$/.test(d));
23468
+ pids = fs23.readdirSync("/proc").filter((d) => /^\d+$/.test(d));
23484
23469
  } catch {
23485
23470
  return map;
23486
23471
  }
23487
23472
  for (const pid of pids) {
23488
23473
  let fds;
23489
23474
  try {
23490
- fds = fs24.readdirSync(`/proc/${pid}/fd`);
23475
+ fds = fs23.readdirSync(`/proc/${pid}/fd`);
23491
23476
  } catch {
23492
23477
  continue;
23493
23478
  }
23494
23479
  for (const fd of fds) {
23495
23480
  let link;
23496
23481
  try {
23497
- link = fs24.readlinkSync(`/proc/${pid}/fd/${fd}`);
23482
+ link = fs23.readlinkSync(`/proc/${pid}/fd/${fd}`);
23498
23483
  } catch {
23499
23484
  continue;
23500
23485
  }
@@ -23599,9 +23584,9 @@ var init_inbound = __esm({
23599
23584
  });
23600
23585
 
23601
23586
  // src/posture/coverage.ts
23602
- import os19 from "os";
23587
+ import os18 from "os";
23603
23588
  function checkCoverage(ctx) {
23604
- const home = ctx.home || os19.homedir();
23589
+ const home = ctx.home || os18.homedir();
23605
23590
  const findings = [];
23606
23591
  const protectedAgents = getAgentWiring(home).filter((r) => r.isProtected);
23607
23592
  if (protectedAgents.length === 0) {
@@ -23645,7 +23630,7 @@ var init_coverage = __esm({
23645
23630
  });
23646
23631
 
23647
23632
  // src/posture/governance.ts
23648
- import path25 from "path";
23633
+ import path24 from "path";
23649
23634
  function checkData(ctx) {
23650
23635
  const dlp = getConfig(ctx.cwd).policy.dlp;
23651
23636
  if (!dlp?.enabled) {
@@ -23789,7 +23774,7 @@ var init_governance = __esm({
23789
23774
  "src/posture/governance.ts"() {
23790
23775
  "use strict";
23791
23776
  init_config();
23792
- jailProbePath = (home) => path25.join(home, ".aws", "credentials");
23777
+ jailProbePath = (home) => path24.join(home, ".aws", "credentials");
23793
23778
  }
23794
23779
  });
23795
23780
 
@@ -23968,7 +23953,7 @@ var init_enforcement = __esm({
23968
23953
  });
23969
23954
 
23970
23955
  // src/posture/index.ts
23971
- import os20 from "os";
23956
+ import os19 from "os";
23972
23957
  function dropEnforcementRedundant(findings) {
23973
23958
  const coveragePresent = findings.some((f) => f.category === "Coverage");
23974
23959
  if (!coveragePresent) return findings;
@@ -23994,9 +23979,10 @@ async function runChecks(checks, ctx) {
23994
23979
  }
23995
23980
  async function runPosture(opts = {}) {
23996
23981
  const ctx = {
23997
- home: opts.home ?? os20.homedir(),
23982
+ home: opts.home ?? os19.homedir(),
23998
23983
  cwd: opts.cwd ?? process.cwd(),
23999
- agent: opts.agent
23984
+ agent: opts.agent,
23985
+ env: opts.env
24000
23986
  };
24001
23987
  const {
24002
23988
  findings: rawFindings,
@@ -24055,6 +24041,102 @@ var init_posture = __esm({
24055
24041
  }
24056
24042
  });
24057
24043
 
24044
+ // src/posture/render.ts
24045
+ import chalk2 from "chalk";
24046
+ var ICON, TIER_LABEL;
24047
+ var init_render = __esm({
24048
+ "src/posture/render.ts"() {
24049
+ "use strict";
24050
+ init_score();
24051
+ ICON = {
24052
+ critical: chalk2.red("\u274C"),
24053
+ high: chalk2.red("\u274C"),
24054
+ medium: chalk2.yellow("\u26A0\uFE0F "),
24055
+ advisory: chalk2.gray("\u26A0\uFE0F ")
24056
+ };
24057
+ TIER_LABEL = {
24058
+ good: chalk2.green("Good"),
24059
+ "at-risk": chalk2.yellow("At risk"),
24060
+ critical: chalk2.red("Critical")
24061
+ };
24062
+ }
24063
+ });
24064
+
24065
+ // src/cli/commands/blast.ts
24066
+ import chalk3 from "chalk";
24067
+ import fs24 from "fs";
24068
+ import path25 from "path";
24069
+ import os20 from "os";
24070
+ function buildSensitivePaths(home, cwd) {
24071
+ const homeFiles = homeCredentialFiles(home).map(({ full, label: label2, description, score }) => ({
24072
+ full,
24073
+ label: label2,
24074
+ description,
24075
+ score
24076
+ }));
24077
+ return [
24078
+ ...homeFiles,
24079
+ {
24080
+ full: path25.join(cwd, ".env"),
24081
+ label: ".env (current folder)",
24082
+ description: "App secrets: database passwords, API keys",
24083
+ score: 20
24084
+ },
24085
+ {
24086
+ full: path25.join(cwd, ".env.local"),
24087
+ label: ".env.local (current folder)",
24088
+ description: "Local overrides: often contains real credentials",
24089
+ score: 15
24090
+ },
24091
+ {
24092
+ full: path25.join(cwd, ".env.production"),
24093
+ label: ".env.production (current folder)",
24094
+ description: "Production secrets",
24095
+ score: 20
24096
+ }
24097
+ ];
24098
+ }
24099
+ function isReadable(filePath) {
24100
+ try {
24101
+ fs24.accessSync(filePath, fs24.constants.R_OK);
24102
+ return true;
24103
+ } catch {
24104
+ return false;
24105
+ }
24106
+ }
24107
+ function runBlast() {
24108
+ const home = os20.homedir();
24109
+ const cwd = process.cwd();
24110
+ const paths = buildSensitivePaths(home, cwd);
24111
+ let scoreDeduction = 0;
24112
+ const reachable = [];
24113
+ for (const p of paths) {
24114
+ if (fs24.existsSync(p.full) && isReadable(p.full)) {
24115
+ reachable.push(p);
24116
+ scoreDeduction += p.score;
24117
+ }
24118
+ }
24119
+ const envFindings = [];
24120
+ for (const [key, value] of Object.entries(process.env)) {
24121
+ if (!value) continue;
24122
+ const match = scanArgs({ [key]: value });
24123
+ if (match) {
24124
+ envFindings.push({ key, patternName: match.patternName });
24125
+ scoreDeduction += 10;
24126
+ }
24127
+ }
24128
+ return { reachable, envFindings, score: Math.max(0, 100 - scoreDeduction) };
24129
+ }
24130
+ var init_blast = __esm({
24131
+ "src/cli/commands/blast.ts"() {
24132
+ "use strict";
24133
+ init_dlp();
24134
+ init_credential_files();
24135
+ init_posture();
24136
+ init_render();
24137
+ }
24138
+ });
24139
+
24058
24140
  // src/auth/decision-record.ts
24059
24141
  function personRecord(channel, decision, extra = {}, now = Date.now()) {
24060
24142
  return {
@@ -25535,7 +25617,7 @@ var init_report_audit = __esm({
25535
25617
  });
25536
25618
 
25537
25619
  // src/config/keyed-guard.ts
25538
- import chalk3 from "chalk";
25620
+ import chalk4 from "chalk";
25539
25621
  function isKeyedForPolicy() {
25540
25622
  try {
25541
25623
  return getConfig().policySource === "workspace";
@@ -29344,7 +29426,7 @@ var init_scan_summary = __esm({
29344
29426
  });
29345
29427
 
29346
29428
  // src/cli/render/scan-derive.ts
29347
- import chalk4 from "chalk";
29429
+ import chalk5 from "chalk";
29348
29430
  import stringWidth from "string-width";
29349
29431
  var init_scan_derive = __esm({
29350
29432
  "src/cli/render/scan-derive.ts"() {
@@ -29363,7 +29445,6 @@ var init_protection = __esm({
29363
29445
  var init_scan_json = __esm({
29364
29446
  "src/cli/render/scan-json.ts"() {
29365
29447
  "use strict";
29366
- init_scan_derive();
29367
29448
  }
29368
29449
  });
29369
29450
 
@@ -29376,7 +29457,7 @@ var init_scan_history = __esm({
29376
29457
  });
29377
29458
 
29378
29459
  // src/cli/commands/scan.ts
29379
- import chalk5 from "chalk";
29460
+ import chalk6 from "chalk";
29380
29461
  import fs43 from "fs";
29381
29462
  import path46 from "path";
29382
29463
  import os35 from "os";
@@ -30721,7 +30802,7 @@ var init_scan = __esm({
30721
30802
  init_hook_payload();
30722
30803
  init_dist();
30723
30804
  init_scan_summary();
30724
- init_setup();
30805
+ init_agent_wiring();
30725
30806
  init_blast();
30726
30807
  init_scan_derive();
30727
30808
  init_protection();