@statechange/ssh-tunnel-manager 0.1.0 → 0.1.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 (2) hide show
  1. package/README.md +148 -0
  2. package/package.json +6 -2
package/README.md ADDED
@@ -0,0 +1,148 @@
1
+ # SSH Tunnel Manager
2
+
3
+ Declarative SSH tunnel manager with a CLI and macOS menu bar app. Define your tunnels in a JSON config — the tool keeps them running.
4
+
5
+ ```
6
+ localhost:5432 ──► bastion.example.com ──► db.internal:5432
7
+ localhost:8080 ──► jump.example.com ──► admin.internal:8080
8
+ ```
9
+
10
+ ## Install
11
+
12
+ ### With an AI agent (recommended)
13
+
14
+ The best way to use SSH Tunnel Manager is through an AI agent skill. Install the skill, then just tell your agent what tunnels you need — it handles the rest.
15
+
16
+ ```bash
17
+ npx skills add statechangelabs/ssh-tunnel-manager
18
+ ```
19
+
20
+ This adds the `ssh-tunnel` and `ssh-tunnel-debug` skills to your agent. Then you can say things like:
21
+
22
+ > "Set up an SSH tunnel to my Postgres database on bastion.example.com"
23
+
24
+ > "My tunnel to the staging server isn't connecting"
25
+
26
+ The agent will install the CLI if needed, create the tunnel, verify it's working, and troubleshoot any issues.
27
+
28
+ ### Direct install
29
+
30
+ ```bash
31
+ npm install -g @statechange/ssh-tunnel-manager
32
+ ```
33
+
34
+ This single command:
35
+ - Installs the `ssh-tunnels` CLI globally
36
+ - Creates `~/.ssh-tunnels/` directories
37
+ - Sets up a macOS LaunchAgent for the menu bar app
38
+ - Starts the menu bar app automatically
39
+
40
+ ## CLI Usage
41
+
42
+ ```bash
43
+ # See all tunnels and their status
44
+ ssh-tunnels status
45
+
46
+ # Add a tunnel
47
+ ssh-tunnels add \
48
+ --name "Prod Postgres" \
49
+ --host bastion.example.com \
50
+ --user root \
51
+ --localPort 5433 \
52
+ --remoteHost db.internal \
53
+ --remotePort 5432 \
54
+ --enabled
55
+
56
+ # Enable / disable / remove
57
+ ssh-tunnels enable prod-postgres
58
+ ssh-tunnels disable prod-postgres
59
+ ssh-tunnels remove prod-postgres
60
+
61
+ # View logs (first place to look when a tunnel fails)
62
+ ssh-tunnels logs prod-postgres
63
+
64
+ # Sync all tunnels to match config
65
+ ssh-tunnels sync
66
+
67
+ # Watch config and auto-sync on changes
68
+ ssh-tunnels watch
69
+
70
+ # JSON output for scripting / AI agents
71
+ ssh-tunnels status --json
72
+ ssh-tunnels enable prod-postgres --json
73
+ ```
74
+
75
+ ## Menu Bar App
76
+
77
+ The Electron menu bar app runs as a macOS LaunchAgent and provides:
78
+
79
+ - **Tray icon** — green (all OK), yellow (partially running), red (failures)
80
+ - **Click to toggle** tunnels on/off
81
+ - **Add Tunnel** form
82
+ - **Sync Now** button
83
+ - **Auto-recovery** — syncs every 30 seconds, restarts crashed tunnels
84
+
85
+ The app and CLI share the same config file (`~/.ssh-tunnels/config.json`). Changes from either side are reflected in both.
86
+
87
+ ## How It Works
88
+
89
+ Tunnels are defined in `~/.ssh-tunnels/config.json`:
90
+
91
+ ```json
92
+ {
93
+ "tunnels": [
94
+ {
95
+ "id": "prod-postgres",
96
+ "name": "Prod Postgres",
97
+ "host": "bastion.example.com",
98
+ "user": "root",
99
+ "localPort": 5433,
100
+ "remoteHost": "db.internal",
101
+ "remotePort": 5432,
102
+ "enabled": true
103
+ }
104
+ ]
105
+ }
106
+ ```
107
+
108
+ When a tunnel is enabled, the manager spawns a detached `ssh -N -L ...` process and writes its PID to `~/.ssh-tunnels/pids/`. The `sync` command reconciles running processes against the config — starting missing tunnels and stopping ones that should be off.
109
+
110
+ ## Common Ports
111
+
112
+ | Port | Service |
113
+ |-------|-------------|
114
+ | 5432 | PostgreSQL |
115
+ | 3306 | MySQL |
116
+ | 6379 | Redis |
117
+ | 27017 | MongoDB |
118
+ | 8080 | Dev server |
119
+ | 9200 | Elasticsearch |
120
+
121
+ ## Troubleshooting
122
+
123
+ | Symptom | Likely cause | Fix |
124
+ |---------|-------------|-----|
125
+ | "Permission denied (publickey)" | Wrong SSH user | Recreate with `--user root` |
126
+ | Tunnel stops immediately | Auth failure or port conflict | `ssh-tunnels logs <id>` |
127
+ | "Address already in use" | Port conflict | `lsof -i :<port>` |
128
+ | Tunnel starts but port not open | Remote service down | SSH in and check the service |
129
+
130
+ For detailed diagnostics, install the `ssh-tunnel-debug` skill or check the [debug guide](skills/ssh-tunnel-debug/SKILL.md).
131
+
132
+ ## Uninstall
133
+
134
+ ```bash
135
+ # Stop the menu bar app and remove the LaunchAgent
136
+ launchctl unload ~/Library/LaunchAgents/com.statechange.ssh-tunnel-manager.plist
137
+ rm ~/Library/LaunchAgents/com.statechange.ssh-tunnel-manager.plist
138
+
139
+ # Remove the CLI
140
+ npm uninstall -g @statechange/ssh-tunnel-manager
141
+
142
+ # Optionally remove config and data
143
+ rm -rf ~/.ssh-tunnels
144
+ ```
145
+
146
+ ## License
147
+
148
+ MIT
package/package.json CHANGED
@@ -1,12 +1,16 @@
1
1
  {
2
2
  "name": "@statechange/ssh-tunnel-manager",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "ssh-tunnels": "dist/cli.mjs"
7
7
  },
8
8
  "main": "dist/cli.mjs",
9
- "files": ["dist/", "renderer/", "scripts/postinstall.mjs"],
9
+ "files": [
10
+ "dist/",
11
+ "renderer/",
12
+ "scripts/postinstall.mjs"
13
+ ],
10
14
  "scripts": {
11
15
  "build": "node scripts/build.mjs",
12
16
  "postinstall": "node scripts/postinstall.mjs",