ghostterm 2.1.0 → 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 +77 -22
- package/lib/pty-manager.js +8 -1
- package/package.json +3 -6
package/README.md
CHANGED
|
@@ -1,6 +1,50 @@
|
|
|
1
|
-
# GhostTerm
|
|
1
|
+
# GhostTerm — Control Claude Code from Your Phone
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> **v2.0: Complete P2P Rewrite** — Your terminal data never touches any server. Direct encrypted connection between your phone and PC.
|
|
4
|
+
|
|
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
|
+
|
|
7
|
+
## Why GhostTerm?
|
|
8
|
+
|
|
9
|
+
### Run Claude Code in Dangerous Mode — From Your Phone
|
|
10
|
+
|
|
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
|
|
4
48
|
|
|
5
49
|
## Quick Start
|
|
6
50
|
|
|
@@ -8,34 +52,45 @@ Control your PC terminal from your phone — direct P2P, no relay server.
|
|
|
8
52
|
npx ghostterm
|
|
9
53
|
```
|
|
10
54
|
|
|
11
|
-
|
|
55
|
+
1. Run the command above on your PC (requires [Node.js 18+](https://nodejs.org))
|
|
56
|
+
2. First time: browser opens for Google sign-in (one-time, remembered after)
|
|
57
|
+
3. Open **[ghostterm.pages.dev](https://ghostterm.pages.dev)** on your phone
|
|
58
|
+
4. Sign in with the same Google account → **auto-connects, no pairing codes**
|
|
12
59
|
|
|
13
|
-
##
|
|
60
|
+
## Security
|
|
14
61
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
62
|
+
```
|
|
63
|
+
Phone ──── WebRTC DataChannel (DTLS encrypted) ────── PC
|
|
64
|
+
│
|
|
65
|
+
(pairing only)
|
|
66
|
+
│
|
|
67
|
+
Signaling Server
|
|
68
|
+
(exchanges connection info, never sees terminal data)
|
|
69
|
+
```
|
|
21
70
|
|
|
22
|
-
- **
|
|
23
|
-
- **
|
|
24
|
-
- **Google
|
|
25
|
-
- **
|
|
26
|
-
- **
|
|
27
|
-
- **One-tap y/n** — approve Claude Code prompts instantly
|
|
28
|
-
- **File upload** — send files from phone to PC
|
|
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
|
|
29
76
|
|
|
30
77
|
## Options
|
|
31
78
|
|
|
32
79
|
```
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
-
|
|
80
|
+
npx ghostterm [options]
|
|
81
|
+
|
|
82
|
+
-s, --signal <url> Custom signaling server URL
|
|
83
|
+
--site <url> Custom mobile site URL
|
|
84
|
+
-h, --help Show help
|
|
36
85
|
```
|
|
37
86
|
|
|
38
87
|
## Requirements
|
|
39
88
|
|
|
40
|
-
- Node.js
|
|
41
|
-
-
|
|
89
|
+
- **Node.js 18+** on your PC
|
|
90
|
+
- **Modern browser** on your phone (Safari, Chrome, Firefox)
|
|
91
|
+
- **Google account** for auto-pairing
|
|
92
|
+
|
|
93
|
+
## Links
|
|
94
|
+
|
|
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",
|