@node9/proxy 1.19.2 → 1.19.4

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
@@ -3601,7 +3601,6 @@ var import_fs8 = __toESM(require("fs"));
3601
3601
  var import_net = __toESM(require("net"));
3602
3602
  var import_path8 = __toESM(require("path"));
3603
3603
  var import_os7 = __toESM(require("os"));
3604
- var import_child_process = require("child_process");
3605
3604
  var ACTIVITY_SOCKET_PATH = process.platform === "win32" ? "\\\\.\\pipe\\node9-activity" : import_path8.default.join(import_os7.default.tmpdir(), "node9-activity.sock");
3606
3605
  function notifyActivitySocket(data) {
3607
3606
  return new Promise((resolve) => {
@@ -3674,22 +3673,9 @@ function isDaemonRunning() {
3674
3673
  }
3675
3674
  return false;
3676
3675
  }
3677
- const r = (0, import_child_process.spawnSync)("ss", ["-Htnp", `sport = :${DAEMON_PORT}`], {
3678
- encoding: "utf8",
3679
- timeout: 300
3680
- });
3681
- if (r.status === 0 && (r.stdout ?? "").includes(`:${DAEMON_PORT}`)) return true;
3682
- return false;
3683
- }
3684
- try {
3685
- const r = (0, import_child_process.spawnSync)("ss", ["-Htnp", `sport = :${DAEMON_PORT}`], {
3686
- encoding: "utf8",
3687
- timeout: 300
3688
- });
3689
- return r.status === 0 && (r.stdout ?? "").includes(`:${DAEMON_PORT}`);
3690
- } catch {
3691
- return false;
3676
+ return true;
3692
3677
  }
3678
+ return false;
3693
3679
  }
3694
3680
  async function registerDaemonEntry(toolName, args, meta, riskMetadata, activityId, cwd, recoveryCommand, skipBackgroundAuth, viewOnly, localSmartRuleMatched, socketActivitySent) {
3695
3681
  const base = `http://${DAEMON_HOST}:${DAEMON_PORT}`;
@@ -3745,7 +3731,7 @@ async function waitForDaemonDecision(id, signal) {
3745
3731
  if (signal) signal.removeEventListener("abort", onAbort);
3746
3732
  }
3747
3733
  }
3748
- async function notifyDaemonViewer(toolName, args, meta, riskMetadata) {
3734
+ async function notifyDaemonViewer(toolName, args, meta, riskMetadata, activityId, socketActivitySent) {
3749
3735
  const base = `http://${DAEMON_HOST}:${DAEMON_PORT}`;
3750
3736
  const res = await fetch(`${base}/check`, {
3751
3737
  method: "POST",
@@ -3756,7 +3742,12 @@ async function notifyDaemonViewer(toolName, args, meta, riskMetadata) {
3756
3742
  slackDelegated: true,
3757
3743
  agent: meta?.agent,
3758
3744
  mcpServer: meta?.mcpServer,
3759
- ...riskMetadata && { riskMetadata }
3745
+ ...riskMetadata && { riskMetadata },
3746
+ // fromCLI=true tells the daemon the CLI already sent the activity
3747
+ // event via socket. Same contract as registerDaemonEntry — without
3748
+ // it the daemon double-emits 'activity' for cloud-enforced flows.
3749
+ fromCLI: socketActivitySent !== false,
3750
+ activityId
3760
3751
  }),
3761
3752
  signal: AbortSignal.timeout(3e3)
3762
3753
  });
@@ -3817,7 +3808,7 @@ async function resolveViaDaemon(id, decision, internalToken, source) {
3817
3808
  var import_crypto3 = require("crypto");
3818
3809
 
3819
3810
  // src/ui/native.ts
3820
- var import_child_process2 = require("child_process");
3811
+ var import_child_process = require("child_process");
3821
3812
  var import_path10 = __toESM(require("path"));
3822
3813
 
3823
3814
  // src/context-sniper.ts
@@ -4091,7 +4082,7 @@ activate
4091
4082
  display dialog (item 1 of argv) with title (item 2 of argv) ${buttons}
4092
4083
  end tell
4093
4084
  end run`;
4094
- childProcess = (0, import_child_process2.spawn)("osascript", ["-e", script, "--", message, title]);
4085
+ childProcess = (0, import_child_process.spawn)("osascript", ["-e", script, "--", message, title]);
4095
4086
  } else if (process.platform === "linux") {
4096
4087
  const pangoMessage = buildPangoMessage(
4097
4088
  toolName,
@@ -4117,12 +4108,12 @@ end run`;
4117
4108
  argsList.push("--cancel-label", "Block \u238B");
4118
4109
  argsList.push("--extra-button", "Always Allow");
4119
4110
  }
4120
- childProcess = (0, import_child_process2.spawn)("zenity", argsList);
4111
+ childProcess = (0, import_child_process.spawn)("zenity", argsList);
4121
4112
  } else if (process.platform === "win32") {
4122
4113
  const b64Msg = Buffer.from(message).toString("base64");
4123
4114
  const b64Title = Buffer.from(title).toString("base64");
4124
4115
  const ps = `Add-Type -AssemblyName PresentationFramework; $msg = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("${b64Msg}")); $title = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String("${b64Title}")); $res = [System.Windows.MessageBox]::Show($msg, $title, "${locked ? "OK" : "YesNo"}", "Warning", "Button2", "DefaultDesktopOnly"); if ($res -eq "Yes") { exit 0 } else { exit 1 }`;
4125
- childProcess = (0, import_child_process2.spawn)("powershell", ["-Command", ps]);
4116
+ childProcess = (0, import_child_process.spawn)("powershell", ["-Command", ps]);
4126
4117
  }
4127
4118
  let output = "";
4128
4119
  childProcess?.stdout?.on("data", (d) => output += d.toString());
@@ -4851,7 +4842,14 @@ async function _authorizeHeadlessCore(toolName, args, meta, options) {
4851
4842
  let daemonAllowCount = 1;
4852
4843
  if (approvers.terminal && isDaemonRunning() && !options?.calledFromDaemon) {
4853
4844
  if (cloudEnforced && cloudRequestId) {
4854
- const viewer = await notifyDaemonViewer(toolName, args, meta, riskMetadata).catch(() => null);
4845
+ const viewer = await notifyDaemonViewer(
4846
+ toolName,
4847
+ args,
4848
+ meta,
4849
+ riskMetadata,
4850
+ options?.activityId,
4851
+ options?.socketActivitySent
4852
+ ).catch(() => null);
4855
4853
  viewerId = viewer?.id ?? null;
4856
4854
  daemonEntryId = viewerId;
4857
4855
  if (viewer) daemonAllowCount = viewer.allowCount;
package/dist/index.mjs CHANGED
@@ -3571,7 +3571,6 @@ import fs8 from "fs";
3571
3571
  import net from "net";
3572
3572
  import path8 from "path";
3573
3573
  import os7 from "os";
3574
- import { spawnSync } from "child_process";
3575
3574
  var ACTIVITY_SOCKET_PATH = process.platform === "win32" ? "\\\\.\\pipe\\node9-activity" : path8.join(os7.tmpdir(), "node9-activity.sock");
3576
3575
  function notifyActivitySocket(data) {
3577
3576
  return new Promise((resolve) => {
@@ -3644,22 +3643,9 @@ function isDaemonRunning() {
3644
3643
  }
3645
3644
  return false;
3646
3645
  }
3647
- const r = spawnSync("ss", ["-Htnp", `sport = :${DAEMON_PORT}`], {
3648
- encoding: "utf8",
3649
- timeout: 300
3650
- });
3651
- if (r.status === 0 && (r.stdout ?? "").includes(`:${DAEMON_PORT}`)) return true;
3652
- return false;
3653
- }
3654
- try {
3655
- const r = spawnSync("ss", ["-Htnp", `sport = :${DAEMON_PORT}`], {
3656
- encoding: "utf8",
3657
- timeout: 300
3658
- });
3659
- return r.status === 0 && (r.stdout ?? "").includes(`:${DAEMON_PORT}`);
3660
- } catch {
3661
- return false;
3646
+ return true;
3662
3647
  }
3648
+ return false;
3663
3649
  }
3664
3650
  async function registerDaemonEntry(toolName, args, meta, riskMetadata, activityId, cwd, recoveryCommand, skipBackgroundAuth, viewOnly, localSmartRuleMatched, socketActivitySent) {
3665
3651
  const base = `http://${DAEMON_HOST}:${DAEMON_PORT}`;
@@ -3715,7 +3701,7 @@ async function waitForDaemonDecision(id, signal) {
3715
3701
  if (signal) signal.removeEventListener("abort", onAbort);
3716
3702
  }
3717
3703
  }
3718
- async function notifyDaemonViewer(toolName, args, meta, riskMetadata) {
3704
+ async function notifyDaemonViewer(toolName, args, meta, riskMetadata, activityId, socketActivitySent) {
3719
3705
  const base = `http://${DAEMON_HOST}:${DAEMON_PORT}`;
3720
3706
  const res = await fetch(`${base}/check`, {
3721
3707
  method: "POST",
@@ -3726,7 +3712,12 @@ async function notifyDaemonViewer(toolName, args, meta, riskMetadata) {
3726
3712
  slackDelegated: true,
3727
3713
  agent: meta?.agent,
3728
3714
  mcpServer: meta?.mcpServer,
3729
- ...riskMetadata && { riskMetadata }
3715
+ ...riskMetadata && { riskMetadata },
3716
+ // fromCLI=true tells the daemon the CLI already sent the activity
3717
+ // event via socket. Same contract as registerDaemonEntry — without
3718
+ // it the daemon double-emits 'activity' for cloud-enforced flows.
3719
+ fromCLI: socketActivitySent !== false,
3720
+ activityId
3730
3721
  }),
3731
3722
  signal: AbortSignal.timeout(3e3)
3732
3723
  });
@@ -4821,7 +4812,14 @@ async function _authorizeHeadlessCore(toolName, args, meta, options) {
4821
4812
  let daemonAllowCount = 1;
4822
4813
  if (approvers.terminal && isDaemonRunning() && !options?.calledFromDaemon) {
4823
4814
  if (cloudEnforced && cloudRequestId) {
4824
- const viewer = await notifyDaemonViewer(toolName, args, meta, riskMetadata).catch(() => null);
4815
+ const viewer = await notifyDaemonViewer(
4816
+ toolName,
4817
+ args,
4818
+ meta,
4819
+ riskMetadata,
4820
+ options?.activityId,
4821
+ options?.socketActivitySent
4822
+ ).catch(() => null);
4825
4823
  viewerId = viewer?.id ?? null;
4826
4824
  daemonEntryId = viewerId;
4827
4825
  if (viewer) daemonAllowCount = viewer.allowCount;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@node9/proxy",
3
- "version": "1.19.2",
3
+ "version": "1.19.4",
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",
@@ -77,8 +77,10 @@
77
77
  "chalk": "^4.1.2",
78
78
  "commander": "^14.0.3",
79
79
  "execa": "^9.6.1",
80
+ "ink": "^7.0.2",
80
81
  "mvdan-sh": "^0.10.1",
81
82
  "picomatch": "^4.0.3",
83
+ "react": "^19.2.6",
82
84
  "safe-regex2": "^5.1.0",
83
85
  "smol-toml": "^1.6.1",
84
86
  "zod": "^3.25.76"
@@ -96,6 +98,7 @@
96
98
  "@semantic-release/release-notes-generator": "^14.1.0",
97
99
  "@types/node": "^25.3.1",
98
100
  "@types/picomatch": "^4.0.2",
101
+ "@types/react": "^19.2.14",
99
102
  "@vitest/coverage-v8": "4.1.2",
100
103
  "cross-env": "^10.1.0",
101
104
  "prettier": "^3.4.2",