@node9/proxy 1.10.1 → 1.10.3

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/index.js CHANGED
@@ -239,7 +239,8 @@ var ConfigFileSchema = import_zod.z.object({
239
239
  enableTrustSessions: import_zod.z.boolean().optional(),
240
240
  allowGlobalPause: import_zod.z.boolean().optional(),
241
241
  auditHashArgs: import_zod.z.boolean().optional(),
242
- agentPolicy: import_zod.z.enum(["require_approval", "block_on_rules"]).optional()
242
+ agentPolicy: import_zod.z.enum(["require_approval", "block_on_rules"]).optional(),
243
+ cloudSyncIntervalHours: import_zod.z.number().positive().optional()
243
244
  }).optional(),
244
245
  policy: import_zod.z.object({
245
246
  sandboxPaths: import_zod.z.array(import_zod.z.string()).optional(),
@@ -441,7 +442,8 @@ var DEFAULT_CONFIG = {
441
442
  // 120-second auto-deny timeout
442
443
  flightRecorder: true,
443
444
  auditHashArgs: true,
444
- approvers: { native: true, browser: true, cloud: false, terminal: true }
445
+ approvers: { native: true, browser: true, cloud: false, terminal: true },
446
+ cloudSyncIntervalHours: 5
445
447
  },
446
448
  policy: {
447
449
  sandboxPaths: ["/tmp/**", "**/sandbox/**", "**/test-results/**"],
@@ -756,6 +758,8 @@ function getConfig(cwd) {
756
758
  if (s.approvalTimeoutSeconds !== void 0 && s.approvalTimeoutMs === void 0)
757
759
  mergedSettings.approvalTimeoutMs = s.approvalTimeoutSeconds * 1e3;
758
760
  if (s.environment !== void 0) mergedSettings.environment = s.environment;
761
+ if (s.cloudSyncIntervalHours !== void 0)
762
+ mergedSettings.cloudSyncIntervalHours = s.cloudSyncIntervalHours;
759
763
  if (s.hud !== void 0) mergedSettings.hud = { ...mergedSettings.hud, ...s.hud };
760
764
  if (p.sandboxPaths) mergedPolicy.sandboxPaths.push(...p.sandboxPaths);
761
765
  if (p.ignoredTools) mergedPolicy.ignoredTools.push(...p.ignoredTools);
@@ -765,7 +769,12 @@ function getConfig(cwd) {
765
769
  if (p.smartRules) {
766
770
  const defaultBlocks = mergedPolicy.smartRules.filter((r) => r.verdict === "block");
767
771
  const defaultNonBlocks = mergedPolicy.smartRules.filter((r) => r.verdict !== "block");
768
- mergedPolicy.smartRules = [...defaultBlocks, ...p.smartRules, ...defaultNonBlocks];
772
+ const userRuleNames = new Set(p.smartRules.filter((r) => r.name).map((r) => r.name));
773
+ const filteredBlocks = defaultBlocks.filter((r) => !r.name || !userRuleNames.has(r.name));
774
+ const filteredNonBlocks = defaultNonBlocks.filter(
775
+ (r) => !r.name || !userRuleNames.has(r.name)
776
+ );
777
+ mergedPolicy.smartRules = [...filteredBlocks, ...p.smartRules, ...filteredNonBlocks];
769
778
  }
770
779
  if (p.snapshot) {
771
780
  const s2 = p.snapshot;
@@ -799,6 +808,16 @@ function getConfig(cwd) {
799
808
  };
800
809
  applyLayer(globalConfig);
801
810
  applyLayer(projectConfig);
811
+ {
812
+ const cacheFile = import_path3.default.join(import_os3.default.homedir(), ".node9", "rules-cache.json");
813
+ try {
814
+ const raw = JSON.parse(import_fs3.default.readFileSync(cacheFile, "utf-8"));
815
+ if (Array.isArray(raw.rules) && raw.rules.length > 0) {
816
+ applyLayer({ policy: { smartRules: raw.rules } });
817
+ }
818
+ } catch {
819
+ }
820
+ }
802
821
  const shieldOverrides = readShieldOverrides();
803
822
  for (const shieldName of readActiveShields()) {
804
823
  const shield = getShield(shieldName);
@@ -1990,19 +2009,44 @@ function getInternalToken() {
1990
2009
  function isDaemonRunning() {
1991
2010
  const pidFile = import_path10.default.join(import_os7.default.homedir(), ".node9", "daemon.pid");
1992
2011
  if (import_fs8.default.existsSync(pidFile)) {
2012
+ let pid;
2013
+ let port;
1993
2014
  try {
1994
- const { pid, port } = JSON.parse(import_fs8.default.readFileSync(pidFile, "utf-8"));
1995
- if (port !== DAEMON_PORT) return false;
1996
- process.kill(pid, 0);
1997
- return true;
2015
+ const data = JSON.parse(import_fs8.default.readFileSync(pidFile, "utf-8"));
2016
+ pid = data.pid;
2017
+ port = data.port;
1998
2018
  } catch {
1999
2019
  return false;
2000
2020
  }
2021
+ if (port !== DAEMON_PORT) {
2022
+ return false;
2023
+ }
2024
+ const MAX_PID = 4194304;
2025
+ if (typeof pid !== "number" || !Number.isInteger(pid) || pid <= 0 || pid > MAX_PID) {
2026
+ return false;
2027
+ }
2028
+ try {
2029
+ process.kill(pid, 0);
2030
+ } catch (err) {
2031
+ if (err instanceof Error && "code" in err && err.code === "ESRCH") {
2032
+ try {
2033
+ import_fs8.default.unlinkSync(pidFile);
2034
+ } catch {
2035
+ }
2036
+ }
2037
+ return false;
2038
+ }
2039
+ const r = (0, import_child_process.spawnSync)("ss", ["-Htnp", `sport = :${DAEMON_PORT}`], {
2040
+ encoding: "utf8",
2041
+ timeout: 300
2042
+ });
2043
+ if (r.status === 0 && (r.stdout ?? "").includes(`:${DAEMON_PORT}`)) return true;
2044
+ return false;
2001
2045
  }
2002
2046
  try {
2003
2047
  const r = (0, import_child_process.spawnSync)("ss", ["-Htnp", `sport = :${DAEMON_PORT}`], {
2004
2048
  encoding: "utf8",
2005
- timeout: 500
2049
+ timeout: 300
2006
2050
  });
2007
2051
  return r.status === 0 && (r.stdout ?? "").includes(`:${DAEMON_PORT}`);
2008
2052
  } catch {
package/dist/index.mjs CHANGED
@@ -209,7 +209,8 @@ var ConfigFileSchema = z.object({
209
209
  enableTrustSessions: z.boolean().optional(),
210
210
  allowGlobalPause: z.boolean().optional(),
211
211
  auditHashArgs: z.boolean().optional(),
212
- agentPolicy: z.enum(["require_approval", "block_on_rules"]).optional()
212
+ agentPolicy: z.enum(["require_approval", "block_on_rules"]).optional(),
213
+ cloudSyncIntervalHours: z.number().positive().optional()
213
214
  }).optional(),
214
215
  policy: z.object({
215
216
  sandboxPaths: z.array(z.string()).optional(),
@@ -411,7 +412,8 @@ var DEFAULT_CONFIG = {
411
412
  // 120-second auto-deny timeout
412
413
  flightRecorder: true,
413
414
  auditHashArgs: true,
414
- approvers: { native: true, browser: true, cloud: false, terminal: true }
415
+ approvers: { native: true, browser: true, cloud: false, terminal: true },
416
+ cloudSyncIntervalHours: 5
415
417
  },
416
418
  policy: {
417
419
  sandboxPaths: ["/tmp/**", "**/sandbox/**", "**/test-results/**"],
@@ -726,6 +728,8 @@ function getConfig(cwd) {
726
728
  if (s.approvalTimeoutSeconds !== void 0 && s.approvalTimeoutMs === void 0)
727
729
  mergedSettings.approvalTimeoutMs = s.approvalTimeoutSeconds * 1e3;
728
730
  if (s.environment !== void 0) mergedSettings.environment = s.environment;
731
+ if (s.cloudSyncIntervalHours !== void 0)
732
+ mergedSettings.cloudSyncIntervalHours = s.cloudSyncIntervalHours;
729
733
  if (s.hud !== void 0) mergedSettings.hud = { ...mergedSettings.hud, ...s.hud };
730
734
  if (p.sandboxPaths) mergedPolicy.sandboxPaths.push(...p.sandboxPaths);
731
735
  if (p.ignoredTools) mergedPolicy.ignoredTools.push(...p.ignoredTools);
@@ -735,7 +739,12 @@ function getConfig(cwd) {
735
739
  if (p.smartRules) {
736
740
  const defaultBlocks = mergedPolicy.smartRules.filter((r) => r.verdict === "block");
737
741
  const defaultNonBlocks = mergedPolicy.smartRules.filter((r) => r.verdict !== "block");
738
- mergedPolicy.smartRules = [...defaultBlocks, ...p.smartRules, ...defaultNonBlocks];
742
+ const userRuleNames = new Set(p.smartRules.filter((r) => r.name).map((r) => r.name));
743
+ const filteredBlocks = defaultBlocks.filter((r) => !r.name || !userRuleNames.has(r.name));
744
+ const filteredNonBlocks = defaultNonBlocks.filter(
745
+ (r) => !r.name || !userRuleNames.has(r.name)
746
+ );
747
+ mergedPolicy.smartRules = [...filteredBlocks, ...p.smartRules, ...filteredNonBlocks];
739
748
  }
740
749
  if (p.snapshot) {
741
750
  const s2 = p.snapshot;
@@ -769,6 +778,16 @@ function getConfig(cwd) {
769
778
  };
770
779
  applyLayer(globalConfig);
771
780
  applyLayer(projectConfig);
781
+ {
782
+ const cacheFile = path3.join(os3.homedir(), ".node9", "rules-cache.json");
783
+ try {
784
+ const raw = JSON.parse(fs3.readFileSync(cacheFile, "utf-8"));
785
+ if (Array.isArray(raw.rules) && raw.rules.length > 0) {
786
+ applyLayer({ policy: { smartRules: raw.rules } });
787
+ }
788
+ } catch {
789
+ }
790
+ }
772
791
  const shieldOverrides = readShieldOverrides();
773
792
  for (const shieldName of readActiveShields()) {
774
793
  const shield = getShield(shieldName);
@@ -1960,19 +1979,44 @@ function getInternalToken() {
1960
1979
  function isDaemonRunning() {
1961
1980
  const pidFile = path10.join(os7.homedir(), ".node9", "daemon.pid");
1962
1981
  if (fs8.existsSync(pidFile)) {
1982
+ let pid;
1983
+ let port;
1963
1984
  try {
1964
- const { pid, port } = JSON.parse(fs8.readFileSync(pidFile, "utf-8"));
1965
- if (port !== DAEMON_PORT) return false;
1966
- process.kill(pid, 0);
1967
- return true;
1985
+ const data = JSON.parse(fs8.readFileSync(pidFile, "utf-8"));
1986
+ pid = data.pid;
1987
+ port = data.port;
1968
1988
  } catch {
1969
1989
  return false;
1970
1990
  }
1991
+ if (port !== DAEMON_PORT) {
1992
+ return false;
1993
+ }
1994
+ const MAX_PID = 4194304;
1995
+ if (typeof pid !== "number" || !Number.isInteger(pid) || pid <= 0 || pid > MAX_PID) {
1996
+ return false;
1997
+ }
1998
+ try {
1999
+ process.kill(pid, 0);
2000
+ } catch (err) {
2001
+ if (err instanceof Error && "code" in err && err.code === "ESRCH") {
2002
+ try {
2003
+ fs8.unlinkSync(pidFile);
2004
+ } catch {
2005
+ }
2006
+ }
2007
+ return false;
2008
+ }
2009
+ const r = spawnSync("ss", ["-Htnp", `sport = :${DAEMON_PORT}`], {
2010
+ encoding: "utf8",
2011
+ timeout: 300
2012
+ });
2013
+ if (r.status === 0 && (r.stdout ?? "").includes(`:${DAEMON_PORT}`)) return true;
2014
+ return false;
1971
2015
  }
1972
2016
  try {
1973
2017
  const r = spawnSync("ss", ["-Htnp", `sport = :${DAEMON_PORT}`], {
1974
2018
  encoding: "utf8",
1975
- timeout: 500
2019
+ timeout: 300
1976
2020
  });
1977
2021
  return r.status === 0 && (r.stdout ?? "").includes(`:${DAEMON_PORT}`);
1978
2022
  } catch {
@@ -10,7 +10,7 @@
10
10
  {
11
11
  "field": "command",
12
12
  "op": "matches",
13
- "value": "(curl|wget)\\s+[^|]*\\|\\s*(bash|sh|zsh|fish|python3?|ruby|perl|node)",
13
+ "value": "(curl|wget)\\s+[^|]*\\|\\s*(?:(bash|sh|zsh|fish)|(python3?|ruby|perl|node)\\b(?!\\s+-[cem]\\b))",
14
14
  "flags": "i"
15
15
  }
16
16
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@node9/proxy",
3
- "version": "1.10.1",
3
+ "version": "1.10.3",
4
4
  "description": "The Sudo Command for AI Agents. Execution Security for Claude Code & MCP.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",