ghostterm 2.1.1 → 2.2.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/README.md +55 -62
- package/lib/pty-manager.js +8 -1
- package/package.json +3 -6
package/README.md
CHANGED
|
@@ -1,17 +1,50 @@
|
|
|
1
1
|
# GhostTerm — Control Claude Code from Your Phone
|
|
2
2
|
|
|
3
|
-
> **v2.0: Complete P2P Rewrite** —
|
|
3
|
+
> **v2.0: Complete P2P Rewrite** — Your terminal data never touches any server. Direct encrypted connection between your phone and PC.
|
|
4
4
|
|
|
5
|
-
GhostTerm
|
|
5
|
+
GhostTerm is a mobile companion for [Claude Code](https://docs.anthropic.com/en/docs/claude-code) that gives you **full terminal access from your phone** over a direct peer-to-peer connection.
|
|
6
6
|
|
|
7
7
|
## Why GhostTerm?
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
### Run Claude Code in Dangerous Mode — From Your Phone
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
```bash
|
|
12
|
+
claude --dangerously-skip-permissions
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The official Claude Code mobile app doesn't support `--dangerously-skip-permissions`. GhostTerm gives you **full terminal access**, so you can launch Claude in fully autonomous mode and let it work while you're away from your desk. One tap to start, one tap to stop.
|
|
16
|
+
|
|
17
|
+
### Not Just Claude — Full Terminal Access
|
|
18
|
+
|
|
19
|
+
GhostTerm isn't limited to Claude Code. It's a complete remote terminal. Run **any command** — `git`, `npm`, `python`, `vim`, `docker`, anything your terminal can do. The official app only gives you Claude.
|
|
20
|
+
|
|
21
|
+
### 4 Terminals at Once
|
|
22
|
+
|
|
23
|
+
Run up to **4 concurrent terminal sessions** with ghost cell tabs. Have Claude Code running in one, a dev server in another, git in the third. Switch between them instantly. The official app gives you one.
|
|
24
|
+
|
|
25
|
+
### See Everything at a Glance — Pixel Office
|
|
26
|
+
|
|
27
|
+
A unique animated workspace shows all your terminal sessions as pixel ghosts. See which ones are busy, idle, or waiting for input — **without switching tabs**. Know exactly what's happening on your PC from a single screen.
|
|
28
|
+
|
|
29
|
+
### True End-to-End Encryption
|
|
30
|
+
|
|
31
|
+
Your terminal data travels directly between your phone and PC over **WebRTC with DTLS encryption**. The signaling server only handles the initial pairing handshake — it never sees your terminal data. Not even GhostTerm's servers can read what you type.
|
|
32
|
+
|
|
33
|
+
Compare:
|
|
34
|
+
- **Official app**: Your data → Anthropic's servers → Your PC
|
|
35
|
+
- **GhostTerm**: Your phone ↔ Your PC (direct, encrypted, no middleman)
|
|
36
|
+
|
|
37
|
+
### Send Files from Phone to PC
|
|
38
|
+
|
|
39
|
+
Take a photo, pick a file, and send it straight to your PC terminal. Then tap paste to insert the file path. Perfect for sharing screenshots of bugs, uploading configs, or sending reference images to Claude.
|
|
40
|
+
|
|
41
|
+
### One-Tap Controls
|
|
42
|
+
|
|
43
|
+
Purpose-built buttons for Claude Code workflows:
|
|
44
|
+
- **y / n** — approve or deny permission prompts instantly
|
|
45
|
+
- **claude** — launch Claude Code with one tap
|
|
46
|
+
- **Stop** — send Ctrl+C immediately
|
|
47
|
+
- **Arrow keys, Tab, Escape** — all one tap, no keyboard fumbling
|
|
15
48
|
|
|
16
49
|
## Quick Start
|
|
17
50
|
|
|
@@ -22,58 +55,24 @@ npx ghostterm
|
|
|
22
55
|
1. Run the command above on your PC (requires [Node.js 18+](https://nodejs.org))
|
|
23
56
|
2. First time: browser opens for Google sign-in (one-time, remembered after)
|
|
24
57
|
3. Open **[ghostterm.pages.dev](https://ghostterm.pages.dev)** on your phone
|
|
25
|
-
4. Sign in with the same Google account → **auto-connects, no codes
|
|
26
|
-
|
|
27
|
-
## Features
|
|
28
|
-
|
|
29
|
-
| Feature | Description |
|
|
30
|
-
|---------|------------|
|
|
31
|
-
| **4 Concurrent Terminals** | Manage multiple Claude Code sessions with ghost cell tabs |
|
|
32
|
-
| **One-Tap y/n** | Approve or deny Claude Code permission prompts instantly |
|
|
33
|
-
| **Pixel Office** | Animated ghost workspace — see all terminals at a glance |
|
|
34
|
-
| **File Upload** | Send screenshots and files from phone to PC |
|
|
35
|
-
| **Dangerous Mode** | Launch Claude Code with `--dangerously-skip-permissions` |
|
|
36
|
-
| **Auto-Reconnect** | Seamless recovery when connection drops |
|
|
37
|
-
| **PWA Support** | Add to home screen for native app experience |
|
|
38
|
-
|
|
39
|
-
## What's New in v2.0
|
|
40
|
-
|
|
41
|
-
GhostTerm v2.0 is a **ground-up rewrite** replacing the relay architecture with peer-to-peer WebRTC:
|
|
58
|
+
4. Sign in with the same Google account → **auto-connects, no pairing codes**
|
|
42
59
|
|
|
43
|
-
|
|
44
|
-
- **After (v2):** Phone ↔ PC directly (server only helps with pairing)
|
|
45
|
-
|
|
46
|
-
This means:
|
|
47
|
-
- Your terminal data is **never stored or transmitted through any server**
|
|
48
|
-
- Latency drops from ~100ms (relay round-trip) to **<5ms** (direct P2P)
|
|
49
|
-
- Server costs are near-zero (signaling only, no data relay)
|
|
50
|
-
- Works even if the signaling server goes down (existing connections persist)
|
|
51
|
-
|
|
52
|
-
## Security Model
|
|
60
|
+
## Security
|
|
53
61
|
|
|
54
62
|
```
|
|
55
|
-
Phone ──── WebRTC DataChannel (DTLS
|
|
63
|
+
Phone ──── WebRTC DataChannel (DTLS encrypted) ────── PC
|
|
56
64
|
│
|
|
57
65
|
(pairing only)
|
|
58
66
|
│
|
|
59
67
|
Signaling Server
|
|
60
|
-
|
|
68
|
+
(exchanges connection info, never sees terminal data)
|
|
61
69
|
```
|
|
62
70
|
|
|
63
|
-
- **DTLS encryption
|
|
64
|
-
- **No data at rest
|
|
65
|
-
- **
|
|
66
|
-
- **Brute force protection
|
|
67
|
-
- **
|
|
68
|
-
|
|
69
|
-
## How It Works
|
|
70
|
-
|
|
71
|
-
1. Your PC connects to a lightweight signaling server and registers with your Google account
|
|
72
|
-
2. Your phone opens the web app and signs in with the same Google account
|
|
73
|
-
3. The signaling server matches the accounts and facilitates a WebRTC handshake
|
|
74
|
-
4. A direct peer-to-peer connection is established between your phone and PC
|
|
75
|
-
5. All terminal I/O flows directly over the encrypted P2P channel
|
|
76
|
-
6. The signaling server is no longer involved
|
|
71
|
+
- **DTLS encryption** on all terminal data — end-to-end, no exceptions
|
|
72
|
+
- **No data at rest** — the signaling server stores nothing
|
|
73
|
+
- **Google OAuth** — verified identity for secure auto-pairing
|
|
74
|
+
- **Brute force protection** — 3 wrong codes = 60s lockout
|
|
75
|
+
- **Private beta** — access controlled by email whitelist
|
|
77
76
|
|
|
78
77
|
## Options
|
|
79
78
|
|
|
@@ -87,17 +86,11 @@ npx ghostterm [options]
|
|
|
87
86
|
|
|
88
87
|
## Requirements
|
|
89
88
|
|
|
90
|
-
- **Node.js 18+**
|
|
91
|
-
- **Modern browser**
|
|
92
|
-
- **Google account**
|
|
93
|
-
|
|
94
|
-
## Privacy
|
|
95
|
-
|
|
96
|
-
- No analytics or tracking on the terminal data path
|
|
97
|
-
- Google Sign-In is used solely for pairing — we don't access your Google data
|
|
98
|
-
- The signaling server is open-source and can be self-hosted
|
|
99
|
-
- All WebRTC connections use DTLS encryption by default
|
|
89
|
+
- **Node.js 18+** on your PC
|
|
90
|
+
- **Modern browser** on your phone (Safari, Chrome, Firefox)
|
|
91
|
+
- **Google account** for auto-pairing
|
|
100
92
|
|
|
101
|
-
##
|
|
93
|
+
## Links
|
|
102
94
|
|
|
103
|
-
|
|
95
|
+
- **Mobile App**: [ghostterm.pages.dev](https://ghostterm.pages.dev)
|
|
96
|
+
- **npm**: [npmjs.com/package/ghostterm](https://www.npmjs.com/package/ghostterm)
|
package/lib/pty-manager.js
CHANGED
|
@@ -284,8 +284,15 @@ class PtyManager extends EventEmitter {
|
|
|
284
284
|
_handleFileUpload(msg, responses) {
|
|
285
285
|
const fs = require('fs');
|
|
286
286
|
const tmpDir = os.tmpdir();
|
|
287
|
-
|
|
287
|
+
// Sanitize filename: strip path traversal, only allow safe chars
|
|
288
|
+
const rawName = msg.filename || `upload_${Date.now()}${msg.ext || ''}`;
|
|
289
|
+
const filename = path.basename(rawName).replace(/[^a-zA-Z0-9._\-]/g, '_');
|
|
288
290
|
const filepath = path.join(tmpDir, filename);
|
|
291
|
+
// Verify resolved path is still inside tmpDir
|
|
292
|
+
if (!path.resolve(filepath).startsWith(path.resolve(tmpDir))) {
|
|
293
|
+
responses.push({ type: 'error', message: 'Invalid filename' });
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
289
296
|
|
|
290
297
|
try {
|
|
291
298
|
const data = Buffer.from(msg.data, 'base64');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ghostterm",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Control your PC terminal from your phone — direct P2P, no server in between",
|
|
5
5
|
"bin": {
|
|
6
6
|
"ghostterm": "bin/ghostterm-p2p.js"
|
|
@@ -20,11 +20,8 @@
|
|
|
20
20
|
"engines": {
|
|
21
21
|
"node": ">=18.0.0"
|
|
22
22
|
},
|
|
23
|
-
"license": "
|
|
24
|
-
"
|
|
25
|
-
"type": "git",
|
|
26
|
-
"url": "git+https://github.com/anthropic/ghostterm-p2p.git"
|
|
27
|
-
},
|
|
23
|
+
"license": "UNLICENSED",
|
|
24
|
+
"homepage": "https://ghostterm.pages.dev",
|
|
28
25
|
"keywords": [
|
|
29
26
|
"terminal",
|
|
30
27
|
"remote",
|