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
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
# Vigo - Claude Code Web Terminal
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
**vigo** is a CLI tool that lets you run Claude Code remotely from any device. It wraps Claude in a tmux session and streams it to your browser via WebSocket.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Start Claude Code accessible from anywhere
|
|
9
|
+
vigo --tunnel ngrok claude --model sonnet
|
|
10
|
+
|
|
11
|
+
# Output:
|
|
12
|
+
# ✓ tmux session: claude-code
|
|
13
|
+
# ✓ Web server: http://localhost:3000
|
|
14
|
+
# ✓ ngrok tunnel: https://abc123.ngrok.io
|
|
15
|
+
#
|
|
16
|
+
# Access URL: https://abc123.ngrok.io/t/x7k9m2...
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## CLI Interface
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
vigo [vigo-options] claude [claude-args]
|
|
23
|
+
vigo [vigo-options] --attach <session>
|
|
24
|
+
|
|
25
|
+
Vigo Options:
|
|
26
|
+
--port, -p <port> Web server port (default: 3000)
|
|
27
|
+
--session, -s <name> tmux session name (default: claude-code)
|
|
28
|
+
--tunnel, -t <type> Auto-start tunnel: ngrok, cloudflared, none (default: none)
|
|
29
|
+
--attach, -a <session> Attach to existing tmux session (don't start claude)
|
|
30
|
+
--help, -h Show help
|
|
31
|
+
|
|
32
|
+
Examples:
|
|
33
|
+
vigo claude # Basic: start claude in tmux + web server
|
|
34
|
+
vigo --tunnel ngrok claude # With ngrok tunnel
|
|
35
|
+
vigo -p 8080 -s myproject claude # Custom port and session
|
|
36
|
+
vigo claude --model sonnet # Pass args to claude
|
|
37
|
+
vigo --attach myproject # Attach to existing session
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Architecture
|
|
41
|
+
|
|
42
|
+
```mermaid
|
|
43
|
+
flowchart TB
|
|
44
|
+
subgraph cli [vigo CLI]
|
|
45
|
+
CLI[bin/vigo.js]
|
|
46
|
+
CLI --> TMUX_MGR[tmux manager]
|
|
47
|
+
CLI --> SERVER[web server]
|
|
48
|
+
CLI --> TUNNEL[tunnel manager]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
subgraph local [Local Processes]
|
|
52
|
+
TMUX[tmux session]
|
|
53
|
+
CLAUDE[claude CLI]
|
|
54
|
+
TMUX_MGR --> TMUX
|
|
55
|
+
TMUX --> CLAUDE
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
subgraph web [Web Layer]
|
|
59
|
+
EXPRESS[Express :3000]
|
|
60
|
+
WS[WebSocket]
|
|
61
|
+
PTY[node-pty]
|
|
62
|
+
SERVER --> EXPRESS
|
|
63
|
+
SERVER --> WS
|
|
64
|
+
WS <--> PTY
|
|
65
|
+
PTY <-->|attach| TMUX
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
subgraph remote [Remote Access]
|
|
69
|
+
NGROK[ngrok/cloudflared]
|
|
70
|
+
BROWSER[Browser + xterm.js]
|
|
71
|
+
TUNNEL --> NGROK
|
|
72
|
+
NGROK <--> BROWSER
|
|
73
|
+
EXPRESS --> BROWSER
|
|
74
|
+
WS <--> BROWSER
|
|
75
|
+
end
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Project Structure
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
vigo/
|
|
82
|
+
├── package.json # dependencies + bin entry
|
|
83
|
+
├── bin/
|
|
84
|
+
│ └── vigo.js # CLI entry point (#!/usr/bin/env node)
|
|
85
|
+
├── lib/
|
|
86
|
+
│ ├── cli.js # Argument parsing
|
|
87
|
+
│ ├── tmux.js # tmux session management
|
|
88
|
+
│ ├── server.js # Express + WebSocket server
|
|
89
|
+
│ └── tunnel.js # ngrok/cloudflared spawning
|
|
90
|
+
├── public/
|
|
91
|
+
│ ├── index.html # Terminal UI
|
|
92
|
+
│ └── terminal.js # xterm.js setup
|
|
93
|
+
└── README.md
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Implementation Details
|
|
97
|
+
|
|
98
|
+
### 1. CLI Entry Point (bin/vigo.js)
|
|
99
|
+
|
|
100
|
+
- Shebang for direct execution: `#!/usr/bin/env node`
|
|
101
|
+
- Parse arguments, separating vigo args from claude args
|
|
102
|
+
- Orchestrate: tmux → server → tunnel (if requested)
|
|
103
|
+
- Handle graceful shutdown (Ctrl+C kills tunnel, keeps tmux alive)
|
|
104
|
+
|
|
105
|
+
### 2. Argument Parsing (lib/cli.js)
|
|
106
|
+
|
|
107
|
+
```javascript
|
|
108
|
+
// vigo --port 8080 --tunnel ngrok claude --model sonnet --allowedTools Bash
|
|
109
|
+
//
|
|
110
|
+
// Parsed as:
|
|
111
|
+
// vigoArgs = { port: 8080, tunnel: 'ngrok', session: 'claude-code' }
|
|
112
|
+
// claudeArgs = ['--model', 'sonnet', '--allowedTools', 'Bash']
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
- Split on `claude` keyword
|
|
116
|
+
- Everything before = vigo options
|
|
117
|
+
- Everything after = passed to claude CLI
|
|
118
|
+
|
|
119
|
+
### 3. tmux Manager (lib/tmux.js)
|
|
120
|
+
|
|
121
|
+
```javascript
|
|
122
|
+
// Check if session exists
|
|
123
|
+
tmux.hasSession(name) // returns boolean
|
|
124
|
+
|
|
125
|
+
// Create new session running claude
|
|
126
|
+
tmux.newSession(name, ['claude', ...claudeArgs])
|
|
127
|
+
|
|
128
|
+
// For --attach mode: just verify session exists
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Uses `child_process.execSync` for tmux commands.
|
|
132
|
+
|
|
133
|
+
### 4. Web Server (lib/server.js)
|
|
134
|
+
|
|
135
|
+
- Generate 32-byte secure token
|
|
136
|
+
- Serve static files from `public/`
|
|
137
|
+
- Validate token on all requests
|
|
138
|
+
- WebSocket endpoint spawns `tmux attach-session -t <name>`
|
|
139
|
+
- Bridge node-pty ↔ WebSocket
|
|
140
|
+
- Handle resize messages
|
|
141
|
+
|
|
142
|
+
### 5. Tunnel Manager (lib/tunnel.js)
|
|
143
|
+
|
|
144
|
+
```javascript
|
|
145
|
+
// Spawn ngrok and parse the public URL from stdout
|
|
146
|
+
const tunnel = await startTunnel('ngrok', port);
|
|
147
|
+
console.log(`Tunnel URL: ${tunnel.url}`);
|
|
148
|
+
|
|
149
|
+
// On exit, tunnel.kill() is called
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
- Spawn `ngrok http <port>` or `cloudflared tunnel --url http://localhost:<port>`
|
|
153
|
+
- Parse public URL from output
|
|
154
|
+
- Return URL for display
|
|
155
|
+
|
|
156
|
+
### 6. Frontend (public/index.html)
|
|
157
|
+
|
|
158
|
+
- Full-screen xterm.js terminal
|
|
159
|
+
- Dark aesthetic (deep black background, subtle glow)
|
|
160
|
+
- Load xterm.js + addons from CDN
|
|
161
|
+
- WebSocket connection to `/ws/:token`
|
|
162
|
+
- Auto-reconnect on disconnect
|
|
163
|
+
- Send resize events on window resize
|
|
164
|
+
|
|
165
|
+
## Token Security
|
|
166
|
+
|
|
167
|
+
- Generated once per `vigo` invocation
|
|
168
|
+
- 32 bytes from `crypto.randomBytes()` → 64 char hex
|
|
169
|
+
- Embedded in URL path: `/t/<token>`
|
|
170
|
+
- Required for both HTTP and WebSocket
|
|
171
|
+
- Printed to console on startup
|
|
172
|
+
|
|
173
|
+
## Usage Flow
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
# 1. Install globally (or use npx)
|
|
177
|
+
npm install -g .
|
|
178
|
+
|
|
179
|
+
# 2. Run vigo with Claude
|
|
180
|
+
vigo --tunnel ngrok claude --model sonnet
|
|
181
|
+
|
|
182
|
+
# 3. Output shows access URL
|
|
183
|
+
# ┌─────────────────────────────────────────────────┐
|
|
184
|
+
# │ vigo - Claude Code Web Terminal │
|
|
185
|
+
# ├─────────────────────────────────────────────────┤
|
|
186
|
+
# │ tmux session: claude-code │
|
|
187
|
+
# │ Local server: http://localhost:3000 │
|
|
188
|
+
# │ Tunnel: https://a1b2c3.ngrok.io │
|
|
189
|
+
# │ │
|
|
190
|
+
# │ Access URL: │
|
|
191
|
+
# │ https://a1b2c3.ngrok.io/t/f8e2a1... │
|
|
192
|
+
# └─────────────────────────────────────────────────┘
|
|
193
|
+
|
|
194
|
+
# 4. Open URL on phone/tablet - full Claude Code access!
|
|
195
|
+
|
|
196
|
+
# 5. Ctrl+C stops server + tunnel, tmux session persists
|
|
197
|
+
# Re-attach later with: vigo --attach claude-code
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Dependencies
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
{
|
|
204
|
+
"name": "vigo",
|
|
205
|
+
"version": "1.0.0",
|
|
206
|
+
"type": "module",
|
|
207
|
+
"bin": {
|
|
208
|
+
"vigo": "./bin/vigo.js"
|
|
209
|
+
},
|
|
210
|
+
"dependencies": {
|
|
211
|
+
"express": "^4.21.0",
|
|
212
|
+
"ws": "^8.18.0",
|
|
213
|
+
"node-pty": "^1.0.0"
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
No build step. Frontend loads xterm.js from CDN.
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Future: Phase 2 - WebRTC P2P Mode
|
|
223
|
+
|
|
224
|
+
> **Status:** Planned for future implementation
|
|
225
|
+
|
|
226
|
+
### New CLI option
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
vigo --tunnel relay claude # Use self-hosted WebRTC relay
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Architecture
|
|
233
|
+
|
|
234
|
+
```mermaid
|
|
235
|
+
sequenceDiagram
|
|
236
|
+
participant Local as vigo (local)
|
|
237
|
+
participant Signal as Railway Signaling Server
|
|
238
|
+
participant Browser as Mobile Browser
|
|
239
|
+
|
|
240
|
+
Local->>Signal: Register session
|
|
241
|
+
Browser->>Signal: Request connection
|
|
242
|
+
Signal-->>Local: SDP offer
|
|
243
|
+
Local-->>Signal: SDP answer
|
|
244
|
+
Note over Local,Browser: WebRTC DataChannel P2P
|
|
245
|
+
Browser<-->Local: Direct terminal stream
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Components to add
|
|
249
|
+
|
|
250
|
+
1. **Signaling server** (new repo, deploy to Railway)
|
|
251
|
+
2. **WebRTC module** in vigo (`lib/webrtc.js`)
|
|
252
|
+
3. **Frontend WebRTC client**
|
|
253
|
+
|
|
254
|
+
### Benefits
|
|
255
|
+
|
|
256
|
+
- No ngrok dependency
|
|
257
|
+
- Lower latency (direct P2P)
|
|
258
|
+
- Free Railway tier for signaling
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# Cursor CLI Support for vigo
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Add support for Cursor Agent CLI alongside Claude Code, allowing vigo to stream either tool to a browser via WebSocket. This enables users with Cursor subscriptions to access Cursor's AI features remotely.
|
|
6
|
+
|
|
7
|
+
## Architecture Comparison
|
|
8
|
+
|
|
9
|
+
```mermaid
|
|
10
|
+
flowchart TB
|
|
11
|
+
subgraph current [Current: Claude Code]
|
|
12
|
+
vigo1[vigo] --> tmux1[tmux session]
|
|
13
|
+
tmux1 --> claude[claude CLI]
|
|
14
|
+
claude --> ws1[WebSocket]
|
|
15
|
+
ws1 --> browser1[Browser xterm.js]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
subgraph new [New: Cursor Agent]
|
|
19
|
+
vigo2[vigo] --> tmux2[tmux session]
|
|
20
|
+
tmux2 --> agent[agent CLI]
|
|
21
|
+
agent --> ws2[WebSocket]
|
|
22
|
+
ws2 --> browser2[Browser xterm.js]
|
|
23
|
+
end
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The architecture is nearly identical - both are CLI-based terminal applications that can run in tmux.
|
|
27
|
+
|
|
28
|
+
## Technical Feasibility: HIGH
|
|
29
|
+
|
|
30
|
+
Cursor Agent CLI is architecturally similar to Claude Code:
|
|
31
|
+
|
|
32
|
+
- Both are terminal-based interactive CLI applications
|
|
33
|
+
- Both support conversational sessions (`agent` vs `claude`)
|
|
34
|
+
- Both can run headless in any terminal environment
|
|
35
|
+
|
|
36
|
+
## Key Differences to Handle
|
|
37
|
+
|
|
38
|
+
| Aspect | Claude Code | Cursor Agent |
|
|
39
|
+
|--------|-------------|--------------|
|
|
40
|
+
| Command | `claude` | `agent` |
|
|
41
|
+
| Install | npm/standalone | `curl https://cursor.com/install -fsS \| bash` |
|
|
42
|
+
| Auth | Claude API key / OAuth | Browser login or `CURSOR_API_KEY` |
|
|
43
|
+
| Models | Claude models | Multiple models (GPT-5, Claude, etc.) via subscription |
|
|
44
|
+
|
|
45
|
+
## Implementation Changes
|
|
46
|
+
|
|
47
|
+
### 1. CLI Argument Parsing ([lib/cli.js](lib/cli.js))
|
|
48
|
+
|
|
49
|
+
Add detection for `cursor` or `agent` command in addition to `claude`:
|
|
50
|
+
|
|
51
|
+
```javascript
|
|
52
|
+
// Current: looks for 'claude' keyword
|
|
53
|
+
if (arg === 'claude') { ... }
|
|
54
|
+
|
|
55
|
+
// New: also detect 'cursor' or 'agent'
|
|
56
|
+
if (arg === 'claude' || arg === 'cursor' || arg === 'agent') { ... }
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 2. Session Management ([lib/tmux.js](lib/tmux.js))
|
|
60
|
+
|
|
61
|
+
Generalize `createSession` to accept any command:
|
|
62
|
+
|
|
63
|
+
```javascript
|
|
64
|
+
// Current
|
|
65
|
+
export function createSession(name, claudeArgs = []) {
|
|
66
|
+
const claudeCmd = ['claude', ...claudeArgs].join(' ');
|
|
67
|
+
// ...
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// New: Parameterize the command
|
|
71
|
+
export function createSession(name, command, args = []) {
|
|
72
|
+
const cmd = [command, ...args].join(' ');
|
|
73
|
+
// ...
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### 3. Default Session Names
|
|
78
|
+
|
|
79
|
+
- Claude sessions: `claude-code` (unchanged)
|
|
80
|
+
- Cursor sessions: `cursor-agent` (new default)
|
|
81
|
+
|
|
82
|
+
### 4. Binary Detection
|
|
83
|
+
|
|
84
|
+
Add Cursor CLI detection similar to tmux detection:
|
|
85
|
+
|
|
86
|
+
```javascript
|
|
87
|
+
export function getCursorAgentPath() {
|
|
88
|
+
try {
|
|
89
|
+
return execSync('which agent', { encoding: 'utf-8' }).trim();
|
|
90
|
+
} catch { return null; }
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Authentication Considerations
|
|
95
|
+
|
|
96
|
+
**For Cursor CLI:**
|
|
97
|
+
|
|
98
|
+
1. **Browser login (recommended for interactive)**: User runs `agent login` before starting vigo
|
|
99
|
+
2. **API key (for headless/automation)**: Set `CURSOR_API_KEY` environment variable
|
|
100
|
+
|
|
101
|
+
vigo should:
|
|
102
|
+
|
|
103
|
+
- Check if authentication is configured before starting
|
|
104
|
+
- Provide clear error messages if not authenticated
|
|
105
|
+
- Document the authentication flow in README
|
|
106
|
+
|
|
107
|
+
## Usage Examples
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# Start Claude Code (existing)
|
|
111
|
+
vigo claude
|
|
112
|
+
|
|
113
|
+
# Start Cursor Agent (new)
|
|
114
|
+
vigo cursor
|
|
115
|
+
# or
|
|
116
|
+
vigo agent
|
|
117
|
+
|
|
118
|
+
# With tunnel for remote access
|
|
119
|
+
vigo --tunnel ngrok cursor
|
|
120
|
+
|
|
121
|
+
# Pass arguments to Cursor Agent
|
|
122
|
+
vigo cursor --model gpt-5
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Requirements Update
|
|
126
|
+
|
|
127
|
+
Add to README:
|
|
128
|
+
|
|
129
|
+
- **Cursor CLI** installed (`agent` command) - for Cursor support
|
|
130
|
+
- Install via: `curl https://cursor.com/install -fsS | bash`
|
|
131
|
+
- Authenticate via: `agent login`
|
|
132
|
+
|
|
133
|
+
## Files Modified
|
|
134
|
+
|
|
135
|
+
1. [lib/cli.js](lib/cli.js) - Add cursor/agent command detection
|
|
136
|
+
2. [lib/tmux.js](lib/tmux.js) - Generalize command execution
|
|
137
|
+
3. [bin/vigo.js](bin/vigo.js) - Update startup logic for both tools
|
|
138
|
+
4. [README.md](README.md) - Document Cursor support
|
|
139
|
+
5. [lib/cursor.js](lib/cursor.js) - Cursor-specific utilities
|