aigo 1.0.0
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/AGENTS.md +1 -0
- package/README.md +453 -0
- package/bin/vigo.js +282 -0
- package/lib/cli.js +81 -0
- package/lib/config.js +80 -0
- package/lib/cursor.js +74 -0
- package/lib/port.js +39 -0
- package/lib/server.js +284 -0
- package/lib/tmux.js +86 -0
- package/lib/tunnel.js +150 -0
- package/package.json +27 -0
- package/public/index.html +545 -0
- package/public/terminal.js +759 -0
- package/specs/claude-code-web-terminal.md +258 -0
- package/specs/cursor-cli-support.md +139 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
- Always update README.md if there's changes to the code. Ensure that README.md would always reflect the latest state of this codebase
|
package/README.md
ADDED
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
# vigo
|
|
2
|
+
|
|
3
|
+
Stream AI coding assistants to the web - run Claude Code or Cursor Agent remotely from any device.
|
|
4
|
+
|
|
5
|
+
**vigo** wraps Claude Code or Cursor Agent in a tmux session and streams it to your browser via WebSocket, letting you access your AI coding sessions from your phone, tablet, or any browser.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Install dependencies
|
|
11
|
+
npm install
|
|
12
|
+
|
|
13
|
+
# Install globally (optional)
|
|
14
|
+
npm link
|
|
15
|
+
|
|
16
|
+
# Start Claude Code with web access (ngrok tunnel enabled by default)
|
|
17
|
+
vigo claude
|
|
18
|
+
|
|
19
|
+
# Or start Cursor Agent
|
|
20
|
+
vigo cursor
|
|
21
|
+
|
|
22
|
+
# Local only (no tunnel)
|
|
23
|
+
vigo --tunnel none claude
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Requirements
|
|
27
|
+
|
|
28
|
+
- **Node.js** 18+
|
|
29
|
+
- **tmux** installed and in PATH
|
|
30
|
+
- **Claude Code CLI** installed (`claude` command) - for Claude Code support
|
|
31
|
+
- **Cursor Agent CLI** installed (`agent` command) - for Cursor support
|
|
32
|
+
- **ngrok** (required for default remote access) - sign up at [ngrok.com](https://ngrok.com)
|
|
33
|
+
|
|
34
|
+
### Installing tmux
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# macOS
|
|
38
|
+
brew install tmux
|
|
39
|
+
|
|
40
|
+
# Ubuntu/Debian
|
|
41
|
+
sudo apt install tmux
|
|
42
|
+
|
|
43
|
+
# Arch Linux
|
|
44
|
+
sudo pacman -S tmux
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Installing ngrok
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# macOS
|
|
51
|
+
brew install ngrok
|
|
52
|
+
|
|
53
|
+
# Or download from https://ngrok.com/download
|
|
54
|
+
|
|
55
|
+
# Then authenticate (required)
|
|
56
|
+
ngrok config add-authtoken YOUR_TOKEN
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Installing Cursor Agent CLI
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# Install Cursor CLI
|
|
63
|
+
curl https://cursor.com/install -fsS | bash
|
|
64
|
+
|
|
65
|
+
# Authenticate (required before first use)
|
|
66
|
+
agent login
|
|
67
|
+
|
|
68
|
+
# Or use API key for headless/automation
|
|
69
|
+
export CURSOR_API_KEY=your_api_key_here
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Usage
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
vigo [options] claude [claude-args]
|
|
76
|
+
vigo [options] cursor [cursor-args]
|
|
77
|
+
vigo [options] agent [agent-args]
|
|
78
|
+
vigo [options] --attach <session>
|
|
79
|
+
|
|
80
|
+
Tools:
|
|
81
|
+
claude Use Claude Code CLI
|
|
82
|
+
cursor, agent Use Cursor Agent CLI
|
|
83
|
+
|
|
84
|
+
Options:
|
|
85
|
+
--port, -p <port> Web server port (default: 3000, auto-selects if busy)
|
|
86
|
+
--session, -s <name> tmux session name (default: claude-code or cursor-agent)
|
|
87
|
+
--tunnel, -t <type> Tunnel: ngrok, cloudflared, none (default: ngrok)
|
|
88
|
+
--attach, -a <session> Attach to existing tmux session
|
|
89
|
+
--password, -P <pass> Custom password (default: auto-generated 6-char)
|
|
90
|
+
--timeout, -T <mins> Lock screen after inactivity (default: 0=disabled)
|
|
91
|
+
--exit-timeout, -E <mins> Exit session after inactivity (default: 0=disabled)
|
|
92
|
+
--help, -h Show help
|
|
93
|
+
--version, -v Show version
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Examples
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
# Claude Code Examples (ngrok tunnel by default)
|
|
100
|
+
vigo claude # Start Claude with ngrok tunnel
|
|
101
|
+
vigo --tunnel none claude # Local only (no tunnel)
|
|
102
|
+
vigo -p 8080 -s myproject claude # Custom port and session
|
|
103
|
+
vigo claude --model sonnet # Pass args to Claude
|
|
104
|
+
|
|
105
|
+
# Cursor Agent Examples
|
|
106
|
+
vigo cursor # Start Cursor Agent with ngrok tunnel
|
|
107
|
+
vigo --tunnel cloudflared cursor # Use cloudflared instead of ngrok
|
|
108
|
+
vigo -p 8080 -s myproject cursor # Custom port and session
|
|
109
|
+
vigo cursor --model gpt-5 # Pass args to Cursor Agent
|
|
110
|
+
|
|
111
|
+
# General Examples
|
|
112
|
+
vigo --attach myproject # Attach to existing tmux session
|
|
113
|
+
vigo -P mypass123 claude # Custom password
|
|
114
|
+
vigo -T 15 -E 30 cursor # 15min lock, 30min exit timeout
|
|
115
|
+
vigo -T 0 -E 0 claude # Disable timeouts (default behavior)
|
|
116
|
+
|
|
117
|
+
# Run multiple sessions (ports auto-selected)
|
|
118
|
+
vigo -s project-a claude # Gets port 3000
|
|
119
|
+
vigo -s project-b cursor # Gets port 3001 (auto)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Configuration
|
|
123
|
+
|
|
124
|
+
All defaults can be customized by editing `lib/config.js`:
|
|
125
|
+
|
|
126
|
+
```javascript
|
|
127
|
+
export const config = {
|
|
128
|
+
// Server Settings
|
|
129
|
+
defaultPort: 3000,
|
|
130
|
+
defaultTunnel: 'ngrok', // 'ngrok', 'cloudflared', or 'none'
|
|
131
|
+
|
|
132
|
+
// Session Timeouts (minutes, 0 = disabled)
|
|
133
|
+
lockTimeout: 0, // Lock screen after inactivity (default: disabled)
|
|
134
|
+
exitTimeout: 0, // Exit session after inactivity (default: disabled)
|
|
135
|
+
|
|
136
|
+
// Tool Settings
|
|
137
|
+
defaultTool: 'claude', // 'claude' or 'cursor'
|
|
138
|
+
|
|
139
|
+
// Security Settings
|
|
140
|
+
passwordLength: 6,
|
|
141
|
+
tokenBytes: 2, // URL token length (hex = 2x chars)
|
|
142
|
+
|
|
143
|
+
// ... more options
|
|
144
|
+
};
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## How It Works
|
|
148
|
+
|
|
149
|
+
1. **vigo** creates a tmux session and runs `claude` or `agent` inside it
|
|
150
|
+
2. A local web server starts, serving an xterm.js terminal
|
|
151
|
+
3. The server attaches to the tmux session via node-pty
|
|
152
|
+
4. Your browser connects via WebSocket for real-time terminal streaming
|
|
153
|
+
5. ngrok creates a public HTTPS tunnel for remote access (default)
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
┌────────────────────────────────────────┐
|
|
157
|
+
│ vigo - Claude Code Web Terminal │
|
|
158
|
+
├────────────────────────────────────────┤
|
|
159
|
+
│ Session: claude-code │
|
|
160
|
+
│ Local: http://localhost:3000 │
|
|
161
|
+
│ Tunnel: https://abc123.ngrok.io │
|
|
162
|
+
│ Password: Xk7mNp │
|
|
163
|
+
│ Timeout: lock:off exit:off │
|
|
164
|
+
└────────────────────────────────────────┘
|
|
165
|
+
|
|
166
|
+
Access URL:
|
|
167
|
+
https://abc123.ngrok.io/t/a1b2c3d4...
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Cursor vs Claude Code
|
|
171
|
+
|
|
172
|
+
| Feature | Claude Code | Cursor Agent |
|
|
173
|
+
|---------|-------------|--------------|
|
|
174
|
+
| Command | `vigo claude` | `vigo cursor` |
|
|
175
|
+
| CLI Binary | `claude` | `agent` |
|
|
176
|
+
| Authentication | Claude API key / OAuth | Browser login or `CURSOR_API_KEY` |
|
|
177
|
+
| Models | Claude models | Multiple (GPT-5, Claude, etc.) via subscription |
|
|
178
|
+
| Session Default | `claude-code` | `cursor-agent` |
|
|
179
|
+
|
|
180
|
+
**When to use Cursor:** If you have a Cursor subscription but don't have direct Claude API access, Cursor Agent provides an alternative way to access AI coding assistance remotely.
|
|
181
|
+
|
|
182
|
+
## Security
|
|
183
|
+
|
|
184
|
+
vigo uses multiple layers of security:
|
|
185
|
+
|
|
186
|
+
1. **URL Token** - A random 4-character token in the URL path (`/t/<token>`)
|
|
187
|
+
2. **Password** - A 6-character alphanumeric password (or custom password via `-P`)
|
|
188
|
+
3. **Session Lock** - Screen locks after inactivity (disabled by default, enable with `-T <mins>`)
|
|
189
|
+
4. **Auto Exit** - Session terminates after inactivity (disabled by default, enable with `-E <mins>`)
|
|
190
|
+
|
|
191
|
+
**Security features:**
|
|
192
|
+
- Token required in URL (403 Forbidden without it)
|
|
193
|
+
- Password required before terminal access
|
|
194
|
+
- Password uses unambiguous characters (no 0/O, 1/l/I)
|
|
195
|
+
- Lock screen requires re-entering password after inactivity (when enabled)
|
|
196
|
+
- Session auto-terminates and kills tmux after extended inactivity (when enabled)
|
|
197
|
+
- HTTPS via ngrok (encrypted in transit)
|
|
198
|
+
|
|
199
|
+
**Recommendations:**
|
|
200
|
+
- Use HTTPS (ngrok provides this automatically)
|
|
201
|
+
- Don't share your access URL or password publicly
|
|
202
|
+
- Use strong custom passwords for sensitive sessions
|
|
203
|
+
- Enable timeouts (`-T 15 -E 30`) for shared or sensitive environments
|
|
204
|
+
|
|
205
|
+
## Session Timeouts
|
|
206
|
+
|
|
207
|
+
vigo has two optional timeout mechanisms (both disabled by default for persistent sessions):
|
|
208
|
+
|
|
209
|
+
### Lock Timeout (default: disabled)
|
|
210
|
+
When enabled with `-T <minutes>`, the session locks after the specified period of no interaction (mouse movement, typing, etc.) and requires password re-entry. The WebSocket connection stays open, so you don't lose any terminal state.
|
|
211
|
+
|
|
212
|
+
### Exit Timeout (default: disabled)
|
|
213
|
+
When enabled with `-E <minutes>`, the session completely terminates after the specified period of total inactivity (no user login or interaction):
|
|
214
|
+
- The tmux session is killed
|
|
215
|
+
- Claude Code / Cursor Agent is stopped
|
|
216
|
+
- The server exits
|
|
217
|
+
|
|
218
|
+
Enable timeouts for security in shared environments: `vigo -T 15 -E 30 claude`
|
|
219
|
+
|
|
220
|
+
## Browser Notifications
|
|
221
|
+
|
|
222
|
+
vigo can send browser notifications when:
|
|
223
|
+
- The AI assistant is waiting for input
|
|
224
|
+
- The WebSocket connection is lost
|
|
225
|
+
|
|
226
|
+
Notifications are only sent when the browser tab is not active. Allow notifications when prompted for the best experience.
|
|
227
|
+
|
|
228
|
+
## Mobile Controls
|
|
229
|
+
|
|
230
|
+
When accessing vigo from a mobile device (phone or tablet), control buttons appear at the bottom of the screen:
|
|
231
|
+
|
|
232
|
+
| Button | Action | Description |
|
|
233
|
+
|--------|--------|-------------|
|
|
234
|
+
| **Mode** | `Shift+Tab` | Toggle between chat/edit modes in Claude Code or switch modes in Cursor Agent |
|
|
235
|
+
| **Enter** | `Enter` | Send Enter key to confirm prompts or submit input |
|
|
236
|
+
| **Stop** | `Ctrl+C` | Interrupt the current operation (stop running commands or cancel AI responses) |
|
|
237
|
+
| **Exit** | Cleanup | Shows confirmation dialog, then kills tmux session and stops the server |
|
|
238
|
+
|
|
239
|
+
These buttons are useful because mobile keyboards don't easily support modifier key combinations like Ctrl+C or Shift+Tab.
|
|
240
|
+
|
|
241
|
+
The buttons are automatically shown based on:
|
|
242
|
+
- Touch screen capability
|
|
243
|
+
- Mobile user agent detection
|
|
244
|
+
- Screen width (768px or less)
|
|
245
|
+
- Coarse pointer media query (touch screens)
|
|
246
|
+
|
|
247
|
+
## Running Persistently
|
|
248
|
+
|
|
249
|
+
To keep vigo running indefinitely (even after closing your terminal), run it inside tmux or use a process manager:
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
# Run vigo inside its own tmux session
|
|
253
|
+
tmux new-session -d -s vigo-server 'vigo claude'
|
|
254
|
+
|
|
255
|
+
# Attach to check status
|
|
256
|
+
tmux attach -t vigo-server
|
|
257
|
+
|
|
258
|
+
# Or use pm2 for auto-restart on crash
|
|
259
|
+
pm2 start "vigo claude" --name vigo-session
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
When the vigo server stays running, your ngrok URL remains stable and you can return to the same URL anytime.
|
|
263
|
+
|
|
264
|
+
## Auto Port Selection
|
|
265
|
+
|
|
266
|
+
If the default port (3000) or your specified port is already in use, vigo automatically finds the next available port:
|
|
267
|
+
|
|
268
|
+
```
|
|
269
|
+
⚠ Port 3000 in use, using port 3001 instead
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
This allows running multiple vigo sessions simultaneously without manual port management.
|
|
273
|
+
|
|
274
|
+
## Exiting and Cleanup
|
|
275
|
+
|
|
276
|
+
vigo provides different exit behaviors depending on how you terminate the session:
|
|
277
|
+
|
|
278
|
+
### Exit Behavior Summary
|
|
279
|
+
|
|
280
|
+
| Action | tmux Session | Server | Web Clients |
|
|
281
|
+
|--------|-------------|--------|-------------|
|
|
282
|
+
| **Web Exit button** | Killed | Stopped | Shows "Session Ended" |
|
|
283
|
+
| **Console Ctrl+C** | **Persists** | Stopped | Disconnected |
|
|
284
|
+
| **Inactivity timeout** | Killed | Stopped | Shows "Session Expired" |
|
|
285
|
+
|
|
286
|
+
### Full Cleanup (from web interface)
|
|
287
|
+
|
|
288
|
+
Click the **Exit** button in the top-right corner of the web interface to:
|
|
289
|
+
1. Show a confirmation dialog
|
|
290
|
+
2. Kill the PTY process
|
|
291
|
+
3. Kill the tmux session
|
|
292
|
+
4. Close all WebSocket connections
|
|
293
|
+
5. Shut down the vigo server
|
|
294
|
+
6. Exit the process
|
|
295
|
+
|
|
296
|
+
**Result:** Everything is cleaned up - tmux session, server, and process all terminate. The web client shows a "Session Ended" message.
|
|
297
|
+
|
|
298
|
+
This is useful when you're completely done with a session and want to free all resources.
|
|
299
|
+
|
|
300
|
+
### Session Persistence (Ctrl+C on console)
|
|
301
|
+
|
|
302
|
+
When you press `Ctrl+C` on the terminal running vigo:
|
|
303
|
+
1. The web server stops
|
|
304
|
+
2. The tunnel closes (if running)
|
|
305
|
+
3. **The tmux session keeps running!**
|
|
306
|
+
4. Connected web clients are disconnected
|
|
307
|
+
|
|
308
|
+
**Result:** Server stops but the tmux session persists. This is useful when you want to temporarily stop web access but keep the AI session alive.
|
|
309
|
+
|
|
310
|
+
Re-attach later:
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
# Via vigo (starts new web server for existing session)
|
|
314
|
+
vigo --attach claude-code
|
|
315
|
+
vigo --attach cursor-agent
|
|
316
|
+
|
|
317
|
+
# Or directly with tmux (local terminal only)
|
|
318
|
+
tmux attach -t claude-code
|
|
319
|
+
tmux attach -t cursor-agent
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Inactivity Timeout Exit
|
|
323
|
+
|
|
324
|
+
When the exit timeout is enabled and reached:
|
|
325
|
+
1. Server detects no user activity for the configured duration
|
|
326
|
+
2. Kills the tmux session
|
|
327
|
+
3. Notifies all connected clients with "Session Expired" message
|
|
328
|
+
4. Closes all WebSocket connections
|
|
329
|
+
5. Shuts down the server
|
|
330
|
+
6. Exits the process
|
|
331
|
+
|
|
332
|
+
**Result:** Full cleanup, similar to web exit. Web clients see a "Session Expired" overlay.
|
|
333
|
+
|
|
334
|
+
**Note:** Exit timeout is disabled by default. Enable with `--exit-timeout <mins>` or `-E <mins>` for security in shared environments.
|
|
335
|
+
|
|
336
|
+
## Troubleshooting
|
|
337
|
+
|
|
338
|
+
### "tmux: command not found"
|
|
339
|
+
|
|
340
|
+
Install tmux (see Requirements section above).
|
|
341
|
+
|
|
342
|
+
### "claude: command not found"
|
|
343
|
+
|
|
344
|
+
Make sure Claude Code CLI is installed and in your PATH:
|
|
345
|
+
|
|
346
|
+
```bash
|
|
347
|
+
# Check if claude is available
|
|
348
|
+
which claude
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### "agent: command not found" (Cursor)
|
|
352
|
+
|
|
353
|
+
Install the Cursor Agent CLI:
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
# Install
|
|
357
|
+
curl https://cursor.com/install -fsS | bash
|
|
358
|
+
|
|
359
|
+
# Verify installation
|
|
360
|
+
which agent
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
### Cursor authentication issues
|
|
364
|
+
|
|
365
|
+
Make sure you're authenticated:
|
|
366
|
+
|
|
367
|
+
```bash
|
|
368
|
+
# Interactive login (opens browser)
|
|
369
|
+
agent login
|
|
370
|
+
|
|
371
|
+
# Check status
|
|
372
|
+
agent status
|
|
373
|
+
|
|
374
|
+
# Or use API key
|
|
375
|
+
export CURSOR_API_KEY=your_api_key_here
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### "posix_spawnp failed" error
|
|
379
|
+
|
|
380
|
+
This can happen if node-pty's spawn-helper isn't executable. Fix with:
|
|
381
|
+
|
|
382
|
+
```bash
|
|
383
|
+
chmod +x node_modules/node-pty/prebuilds/darwin-*/spawn-helper
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
Or reinstall dependencies:
|
|
387
|
+
|
|
388
|
+
```bash
|
|
389
|
+
rm -rf node_modules && npm install
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### ngrok authentication error
|
|
393
|
+
|
|
394
|
+
Sign up at [ngrok.com](https://ngrok.com) and authenticate:
|
|
395
|
+
|
|
396
|
+
```bash
|
|
397
|
+
ngrok config add-authtoken YOUR_TOKEN
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### "ngrok already running" / simultaneous session error
|
|
401
|
+
|
|
402
|
+
Free ngrok accounts are limited to 1 simultaneous tunnel. If you see this error, it means an ngrok process from a previous session is still running.
|
|
403
|
+
|
|
404
|
+
vigo will detect this and show you the command to kill it:
|
|
405
|
+
|
|
406
|
+
```
|
|
407
|
+
Error: An ngrok process is already running.
|
|
408
|
+
Free ngrok accounts only allow 1 simultaneous tunnel.
|
|
409
|
+
|
|
410
|
+
To kill the existing ngrok process, run:
|
|
411
|
+
kill 12345
|
|
412
|
+
|
|
413
|
+
Or to run without a tunnel:
|
|
414
|
+
vigo --tunnel none cursor
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
You can also find and kill ngrok manually:
|
|
418
|
+
|
|
419
|
+
```bash
|
|
420
|
+
# Find ngrok processes
|
|
421
|
+
pgrep -f "ngrok http"
|
|
422
|
+
|
|
423
|
+
# Kill by PID
|
|
424
|
+
kill <pid>
|
|
425
|
+
|
|
426
|
+
# Or kill all ngrok processes
|
|
427
|
+
pkill -f "ngrok http"
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### WebSocket connection fails
|
|
431
|
+
|
|
432
|
+
- Check that the server is running
|
|
433
|
+
- Ensure the URL includes the correct token
|
|
434
|
+
- If using a tunnel, make sure it's still active
|
|
435
|
+
|
|
436
|
+
### Terminal looks broken / garbled
|
|
437
|
+
|
|
438
|
+
Try resizing your browser window to trigger a terminal resize.
|
|
439
|
+
|
|
440
|
+
## Development
|
|
441
|
+
|
|
442
|
+
```bash
|
|
443
|
+
# Run without installing globally
|
|
444
|
+
node bin/vigo.js claude
|
|
445
|
+
node bin/vigo.js cursor
|
|
446
|
+
|
|
447
|
+
# Watch for changes (requires nodemon)
|
|
448
|
+
npx nodemon bin/vigo.js claude
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
## License
|
|
452
|
+
|
|
453
|
+
MIT
|