From b326153d263cb628d573211957e148ff1a3f6e62 Mon Sep 17 00:00:00 2001 From: Stefano Fiorini Date: Wed, 11 Mar 2026 22:59:08 -0500 Subject: [PATCH] fix: clarify mac nordvpn app-only mode --- docs/nordvpn-client.md | 2 ++ skills/nordvpn-client/SKILL.md | 2 ++ .../nordvpn-client/scripts/nordvpn-client.js | 26 +++++++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/docs/nordvpn-client.md b/docs/nordvpn-client.md index 77163ea..dc430eb 100644 --- a/docs/nordvpn-client.md +++ b/docs/nordvpn-client.md @@ -60,6 +60,7 @@ Do not put secrets in the skill docs or repo. - platform - install state +- control mode (`cli` vs `app-manual`) - auth state - connection state - requested target @@ -75,3 +76,4 @@ After `connect`, the intended workflow is: - Linux city targeting is attempted through the CLI target string and then validated by public IP/location checks. - macOS app-only fallback cannot guarantee non-interactive control if the app does not expose a CLI. +- On macOS, the Homebrew cask may install only the GUI app. That is still a supported install state; `status` reports `controlMode: "app-manual"` so agents should continue with the app flow instead of concluding NordVPN is unavailable. diff --git a/skills/nordvpn-client/SKILL.md b/skills/nordvpn-client/SKILL.md index 4f0eb2b..b547289 100644 --- a/skills/nordvpn-client/SKILL.md +++ b/skills/nordvpn-client/SKILL.md @@ -63,6 +63,7 @@ Optional credential file env vars: - platform - install state +- control mode (`cli` vs `app-manual`) - auth state - connection state - requested target @@ -76,3 +77,4 @@ Use `verify` when you want an explicit post-connect location check without chang - Linux country connect is official CLI behavior. - Linux city connect is attempted through the CLI target string and then validated by post-connect IP/location checks. - macOS app-only fallback cannot guarantee non-interactive login/connect if the installed app does not expose a CLI. In that case the skill will open the app and return a clear manual-action-required result. +- On macOS, Homebrew can install only the GUI app. That still counts as a supported install state; `status` will report `controlMode: "app-manual"` rather than treating the app as missing. diff --git a/skills/nordvpn-client/scripts/nordvpn-client.js b/skills/nordvpn-client/scripts/nordvpn-client.js index 1190b83..e73e466 100644 --- a/skills/nordvpn-client/scripts/nordvpn-client.js +++ b/skills/nordvpn-client/scripts/nordvpn-client.js @@ -235,6 +235,27 @@ function inferConnectionState(probe) { function buildStateSummary(installProbe, ipInfo) { const cliProbe = installProbe.cliProbe; + let controlMode = "unavailable"; + let automaticControl = false; + let loginMode = "unsupported"; + let connectMode = "unsupported"; + let recommendedAction = "Install NordVPN first."; + + if (installProbe.cliPath) { + controlMode = "cli"; + automaticControl = true; + loginMode = "cli"; + connectMode = "cli"; + recommendedAction = "Use login/connect/disconnect through the nordvpn CLI."; + } else if (installProbe.platform === "darwin" && installProbe.appInstalled) { + controlMode = "app-manual"; + automaticControl = false; + loginMode = "app-manual"; + connectMode = "app-manual"; + recommendedAction = + "NordVPN is installed as a macOS app without a PATH-visible CLI. Use login/connect to open NordVPN.app and complete the action there."; + } + return { platform: installProbe.platform, installed: installProbe.installed, @@ -243,6 +264,11 @@ function buildStateSummary(installProbe, ipInfo) { appInstalled: installProbe.appInstalled, appPath: installProbe.appInstalled ? installProbe.appPath : null, brewAvailable: Boolean(installProbe.brewPath), + controlMode, + automaticControl, + loginMode, + connectMode, + recommendedAction, authenticated: inferAuthState(cliProbe), connected: inferConnectionState(cliProbe), localStatusRaw: cliProbe && cliProbe.status ? (cliProbe.status.stdout || cliProbe.status.stderr).trim() : "",