6 Commits

Author SHA1 Message Date
Stefano Fiorini
d1b4d58c5d Merge branch 'feature/nordvpn-wireguard' 2026-03-11 23:44:26 -05:00
Stefano Fiorini
4a539a33c9 feat: add mac wireguard nordvpn backend 2026-03-11 23:44:22 -05:00
Stefano Fiorini
b326153d26 fix: clarify mac nordvpn app-only mode 2026-03-11 22:59:08 -05:00
Stefano Fiorini
2612cef1dc Merge branch 'feature/nordvpn-client' 2026-03-11 22:36:03 -05:00
Stefano Fiorini
120721bbc6 feat: add nordvpn client skill 2026-03-11 22:35:50 -05:00
Stefano Fiorini
fe5b4659fe docs: add nordvpn client plan 2026-03-11 22:02:49 -05:00
9 changed files with 1437 additions and 0 deletions

View File

@@ -18,6 +18,7 @@ This repository contains practical OpenClaw skills and companion integrations. I
|---|---|---|
| `elevenlabs-stt` | Transcribe local audio files with ElevenLabs Speech-to-Text, with diarization, language hints, event tags, and JSON output. | `skills/elevenlabs-stt` |
| `gitea-api` | Interact with Gitea via REST API (repos, issues, PRs, releases, branches, user info). | `skills/gitea-api` |
| `nordvpn-client` | Install, log in to, connect, disconnect, and verify NordVPN sessions across Linux CLI and macOS NordLynx/WireGuard backends. | `skills/nordvpn-client` |
| `portainer` | Manage Portainer stacks via API (list, start/stop/restart, update, prune images). | `skills/portainer` |
| `searxng` | Search through a local or self-hosted SearXNG instance for web, news, images, and more. | `skills/searxng` |
| `web-automation` | One-shot extraction plus broader browsing/scraping with Playwright-compatible CloakBrowser (auth flows, extraction, bot-protected sites). | `skills/web-automation` |

View File

@@ -6,6 +6,7 @@ This folder contains detailed docs for each skill in this repository.
- [`elevenlabs-stt`](elevenlabs-stt.md) — Local audio transcription through ElevenLabs Speech-to-Text
- [`gitea-api`](gitea-api.md) — REST-based Gitea automation (no `tea` CLI required)
- [`nordvpn-client`](nordvpn-client.md) — Cross-platform NordVPN install, login, connect, disconnect, and verification with Linux CLI and macOS NordLynx/WireGuard support
- [`portainer`](portainer.md) — Portainer stack management (list, lifecycle, updates, image pruning)
- [`searxng`](searxng.md) — Privacy-respecting metasearch via a local or self-hosted SearXNG instance
- [`web-automation`](web-automation.md) — One-shot extraction plus Playwright-compatible CloakBrowser browser automation and scraping

82
docs/nordvpn-client.md Normal file
View File

@@ -0,0 +1,82 @@
# nordvpn-client
Cross-platform NordVPN lifecycle skill for macOS and Linux.
## What it does
- Probes whether NordVPN is already installed or automation-ready
- Bootstraps the required backend if missing
- Handles login/bootstrap
- Connects to a country or city target
- Disconnects and reports status
- Verifies public IP and geolocation after connect
## Commands
```bash
node skills/nordvpn-client/scripts/nordvpn-client.js status
node skills/nordvpn-client/scripts/nordvpn-client.js install
node skills/nordvpn-client/scripts/nordvpn-client.js login
node skills/nordvpn-client/scripts/nordvpn-client.js verify
node skills/nordvpn-client/scripts/nordvpn-client.js verify --country "Italy"
node skills/nordvpn-client/scripts/nordvpn-client.js verify --country "Italy" --city "Milan"
node skills/nordvpn-client/scripts/nordvpn-client.js connect --country "Italy"
node skills/nordvpn-client/scripts/nordvpn-client.js connect --city "Milan"
node skills/nordvpn-client/scripts/nordvpn-client.js disconnect
```
## Platform behavior
### macOS
- preferred backend: NordLynx/WireGuard
- install path: `brew install wireguard-go wireguard-tools`
- automation requirements:
- `NORDVPN_TOKEN` or `NORDVPN_TOKEN_FILE`
- `wireguard-go`
- `wireguard-tools`
- non-interactive `sudo` for `wg-quick`
- `NordVPN.app` may stay installed but is only the manual fallback
- the app login is not reused by the automated WireGuard backend
### Linux
- install path follows NordVPN's official installer script
- primary control path is the official `nordvpn` CLI
- token login is supported through `nordvpn login --token <token>`
## Credentials
Supported env vars:
- `NORDVPN_TOKEN`
- `NORDVPN_TOKEN_FILE`
- `NORDVPN_USERNAME`
- `NORDVPN_PASSWORD`
- `NORDVPN_PASSWORD_FILE`
Do not put secrets in the skill docs or repo.
## Verification model
`status`, `verify`, and `connect` emit JSON suitable for agent use:
- platform
- install state
- control mode (`cli`, `wireguard`, `app-manual`)
- auth state
- connection state
- requested target
- public IP / geolocation lookup
After `connect`, the intended workflow is:
1. `nordvpn-client connect ...`
2. `nordvpn-client verify ...` if an explicit location check is needed
3. run the follow-up task such as `web-automation`
## Limitations
- Linux behavior still depends on the official `nordvpn` CLI.
- macOS automated connects require token-based WireGuard setup; GUI-app login alone is insufficient.
- The Homebrew `nordvpn` app does not need to be uninstalled.

View File

@@ -0,0 +1,40 @@
# NordVPN Client Skill Design
## Goal
Create a `nordvpn-client` skill that works on macOS and Linux gateway hosts. It should detect whether NordVPN is already installed, bootstrap it if missing, handle login/auth setup, connect to a requested country or city, verify the VPN state and public IP location, disconnect when requested, and then be usable alongside other skills like `web-automation`.
## Architecture
The skill exposes one logical interface with platform-specific backends. Linux uses the official NordVPN CLI path. macOS probes for a usable CLI first, but falls back to the official app workflow when needed. The skill is responsible only for VPN lifecycle and verification, not for wrapping arbitrary commands inside a VPN session.
## Interface
Single script entrypoint:
- `node scripts/nordvpn-client.js install`
- `node scripts/nordvpn-client.js login`
- `node scripts/nordvpn-client.js connect --country "Italy"`
- `node scripts/nordvpn-client.js connect --city "Milan"`
- `node scripts/nordvpn-client.js disconnect`
- `node scripts/nordvpn-client.js status`
## Platform Model
### Linux
- Probe for `nordvpn`
- If missing, bootstrap official NordVPN package/CLI
- Prefer token-based login for non-interactive auth
- Connect/disconnect/status through official CLI
### macOS
- Probe for `nordvpn` CLI if available
- Otherwise probe/install the official app
- Use CLI when present, otherwise automate the app/login flow
- Verify connection using app/CLI state plus external IP/geolocation
## Auth and Safety
- Do not store raw NordVPN secrets in skill docs
- Read token/credentials from env vars or a local credential file path
- Keep the skill focused on install/login/connect/disconnect/status
- After `connect`, verify both local VPN state and external IP/location before the agent proceeds to tasks like `web-automation`
## Verification
- `status` reports platform, install state, auth state, connection state, and public IP/location check
- `connect` verifies the requested target as closely as available data allows
- Local validation happens first in the OpenClaw workspace, then the proven skill is copied into `stef-openclaw-skills`, documented, committed, and pushed

View File

@@ -0,0 +1,127 @@
# NordVPN Client Skill Implementation Plan
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
**Goal:** Build a cross-platform `nordvpn-client` skill for macOS and Linux that can install/bootstrap NordVPN, log in, connect to a target country or city, verify the VPN session, disconnect, and report status.
**Architecture:** Implement one skill with one script entrypoint and platform-specific backends. Linux uses the official NordVPN CLI. macOS uses a CLI path when present and otherwise falls back to the NordVPN app workflow. The skill manages VPN state only, leaving follow-up operations like `web-automation` to separate agent steps.
**Tech Stack:** Node.js, shell/OS commands, NordVPN CLI/app integration, OpenClaw skills, git
---
### Task 1: Create isolated worktree
**Files:**
- Modify: repo git metadata only
**Step 1: Create worktree**
Run:
```bash
git -C /Users/stefano/.openclaw/workspace/projects/stef-openclaw-skills worktree add /Users/stefano/.openclaw/workspace/projects/stef-openclaw-skills/.worktrees/nordvpn-client -b feature/nordvpn-client
```
**Step 2: Verify baseline**
Run:
```bash
git -C /Users/stefano/.openclaw/workspace/projects/stef-openclaw-skills/.worktrees/nordvpn-client status --short --branch
```
Expected: clean feature branch
### Task 2: Create the local skill runtime
**Files:**
- Create: `skills/nordvpn-client/SKILL.md`
- Create: `skills/nordvpn-client/scripts/nordvpn-client.js`
- Optional Create: helper files under `skills/nordvpn-client/scripts/`
**Step 1: Write the failing checks**
- Missing command/action should fail with clear usage output
- Unsupported platform should fail clearly
**Step 2: Implement platform detection and install probe**
- detect `darwin` vs `linux`
- detect whether NordVPN CLI/app is already present
- expose `status` with install/auth/connect fields
### Task 3: Implement install and auth bootstrap
**Files:**
- Modify: `skills/nordvpn-client/scripts/nordvpn-client.js`
**Step 1: Linux install/login path**
- implement official CLI probe/install path
- implement token-based login path
**Step 2: macOS install/login path**
- probe CLI first
- if absent, probe/install NordVPN app path
- implement login/bootstrap state verification for the app workflow
**Step 3: Keep secrets external**
- env vars or local credential path only
- no raw secrets in docs or skill text
### Task 4: Implement connect/disconnect/status/verification
**Files:**
- Modify: `skills/nordvpn-client/scripts/nordvpn-client.js`
**Step 1: Connect**
- support `--country` and `--city`
- normalize target handling per platform
**Step 2: Verify**
- report local connection state
- run public IP / geolocation verification
- fail if connection target cannot be reasonably verified
**Step 3: Disconnect and status**
- implement clean disconnect
- ensure `status` emits machine-readable output for agent use
### Task 5: Validate locally in OpenClaw workspace
**Files:**
- Test: local workspace copy of `nordvpn-client`
**Step 1: Direct command validation**
- usage errors are correct
- install probe works on this host
- status output is coherent before login/connect
**Step 2: One real connect flow**
- connect to a test country/city if credentials are available
- verify local state + external IP/location
- disconnect cleanly
### Task 6: Promote to repo docs and publish
**Files:**
- Modify: `README.md`
- Modify: `docs/README.md`
- Create: `docs/nordvpn-client.md`
- Create/Modify: `skills/nordvpn-client/...`
**Step 1: Document the skill**
- install/bootstrap behavior
- auth expectations
- connect/disconnect/status commands
- macOS vs Linux notes
**Step 2: Commit and push**
Run:
```bash
git add skills/nordvpn-client docs README.md
git commit -m "feat: add nordvpn client skill"
git push -u origin feature/nordvpn-client
```
**Step 3: Merge and cleanup**
- fast-forward or merge to `main`
- push `main`
- remove the worktree
- delete the feature branch

View File

@@ -0,0 +1,34 @@
# NordVPN macOS WireGuard Backend Design
## Goal
Replace the current macOS app-manual fallback in `nordvpn-client` with a scripted WireGuard/NordLynx backend inspired by `wg-nord` and `wgnord`, while preserving the official Linux `nordvpn` CLI backend.
## Key decisions
- Keep Linux on the official `nordvpn` CLI.
- Prefer a native macOS WireGuard backend over the GUI app.
- Do not vendor third-party scripts directly; reimplement the needed logic in our own JSON-based Node skill.
- Do not require uninstalling the Homebrew `nordvpn` app. The new backend can coexist with it.
## macOS backend model
- Bootstrap via Homebrew:
- `wireguard-tools`
- `wireguard-go`
- Read NordVPN token from existing env/file inputs.
- Discover a WireGuard-capable NordVPN server via the public Nord API.
- Generate a private key locally.
- Exchange the private key for Nord-provided interface credentials using the token.
- Materialize a temporary WireGuard config under a skill-owned state directory.
- Connect and disconnect via `wg-quick`.
- Verify with public IP/geolocation after connect.
## Data/state
- Keep state under a skill-owned directory in the user's home, not `/etc`.
- Persist only what is needed for reconnect/disconnect/status.
- Never store secrets in docs.
## Rollout
1. Implement the macOS WireGuard backend in the skill.
2. Update status output so backend selection is explicit.
3. Update skill docs and repo docs.
4. Verify non-destructive flows on this host.
5. Commit, push, and then decide whether to run a live connect test.

View File

@@ -0,0 +1,11 @@
# NordVPN macOS WireGuard Backend Plan
1. Add a backend selector to `nordvpn-client`.
2. Keep Linux CLI behavior unchanged.
3. Add macOS WireGuard dependency probing and install guidance.
4. Implement token-based NordLynx config generation inspired by `wg-nord`/`wgnord`.
5. Replace the current preferred macOS control mode from `app-manual` to WireGuard when dependencies and token are available.
6. Keep app-manual as the last fallback only.
7. Update `status`, `login`, `connect`, `disconnect`, and `verify` JSON to expose the backend in use.
8. Update repo docs and skill docs to reflect the new model and required token/dependencies.
9. Verify command behavior locally without forcing a live VPN connection unless requested.

View File

@@ -0,0 +1,85 @@
---
name: nordvpn-client
description: Use when managing NordVPN on macOS or Linux, including install/bootstrap, login, connect, disconnect, status checks, or verifying a VPN location before running another skill.
---
# NordVPN Client
Cross-platform NordVPN lifecycle management for macOS and Linux hosts.
## What This Skill Is For
- Probing whether NordVPN is already installed or automation-ready
- Bootstrapping the required NordVPN backend if it is missing
- Logging in through the Linux CLI or validating a NordVPN token for the macOS WireGuard backend
- Connecting to a country or city before a follow-up action such as `web-automation`
- Disconnecting and checking VPN status
- Verifying public IP and geolocation after connect
## Command Surface
```bash
node scripts/nordvpn-client.js status
node scripts/nordvpn-client.js install
node scripts/nordvpn-client.js login
node scripts/nordvpn-client.js verify
node scripts/nordvpn-client.js verify --country "Italy"
node scripts/nordvpn-client.js verify --country "Italy" --city "Milan"
node scripts/nordvpn-client.js connect --country "Italy"
node scripts/nordvpn-client.js connect --city "Milan"
node scripts/nordvpn-client.js connect --country "Italy" --city "Milan"
node scripts/nordvpn-client.js disconnect
```
## Platform Notes
- Linux:
- uses the official `nordvpn` CLI
- install path follows NordVPN's Linux installer
- token login is supported through `NORDVPN_TOKEN`
- macOS:
- preferred backend is NordLynx/WireGuard using `wireguard-go` and `wireguard-tools`
- `install` bootstraps those tools with Homebrew
- `login` validates `NORDVPN_TOKEN` / `NORDVPN_TOKEN_FILE` for the WireGuard backend
- `NordVPN.app` can remain installed, but it is only the manual fallback
## Credentials
Do not store secrets in this skill.
Supported env vars:
- `NORDVPN_TOKEN`
- `NORDVPN_USERNAME`
- `NORDVPN_PASSWORD`
Optional credential file env vars:
- `NORDVPN_TOKEN_FILE`
- `NORDVPN_PASSWORD_FILE`
## Verification Behavior
`status`, `verify`, and `connect` report machine-readable JSON including:
- platform
- install state
- control mode (`cli`, `wireguard`, `app-manual`)
- auth state
- connection state
- requested target
- public IP lookup and geolocation
Use this skill first, then run the follow-up task under the active VPN session.
Use `verify` when you want an explicit post-connect location check without changing VPN state.
## Known Boundaries
- Linux country/city connect remains whatever the official `nordvpn` CLI supports.
- macOS automated connects require all of:
- `NORDVPN_TOKEN` or `NORDVPN_TOKEN_FILE`
- `wireguard-go`
- `wireguard-tools`
- non-interactive `sudo` for `wg-quick`
- `NordVPN.app` login on macOS is not reused by the WireGuard backend.
- The Homebrew `nordvpn` app does not need to be uninstalled. It can coexist with the WireGuard backend.

File diff suppressed because it is too large Load Diff