ghostterm 2.2.0 → 2.2.2
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 +26 -11
- package/lib/pty-manager.js +29 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://ghostterm.pages.dev/img/banner.png" alt="GhostTerm" width="400">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">GhostTerm</h1>
|
|
6
|
+
<p align="center"><strong>Control Claude Code from Your Phone</strong></p>
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://www.npmjs.com/package/ghostterm"><img src="https://img.shields.io/npm/v/ghostterm.svg" alt="npm version"></a>
|
|
9
|
+
<a href="https://ghostterm.pages.dev"><img src="https://img.shields.io/badge/mobile-ghostterm.pages.dev-8b5cf6" alt="Mobile App"></a>
|
|
10
|
+
</p>
|
|
2
11
|
|
|
3
12
|
> **v2.0: Complete P2P Rewrite** — Your terminal data never touches any server. Direct encrypted connection between your phone and PC.
|
|
4
13
|
|
|
@@ -26,13 +35,12 @@ Run up to **4 concurrent terminal sessions** with ghost cell tabs. Have Claude C
|
|
|
26
35
|
|
|
27
36
|
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
37
|
|
|
29
|
-
###
|
|
38
|
+
### Encrypted Direct Connection
|
|
30
39
|
|
|
31
|
-
|
|
40
|
+
The remote control link between your phone and PC is a **direct WebRTC connection with DTLS encryption**. Your keystrokes and terminal output travel straight between devices — they never pass through GhostTerm's servers or any third party.
|
|
32
41
|
|
|
33
|
-
|
|
34
|
-
- **
|
|
35
|
-
- **GhostTerm**: Your phone ↔ Your PC (direct, encrypted, no middleman)
|
|
42
|
+
- **How it works**: Phone ↔ PC direct (the signaling server only helps with pairing, then gets out of the way)
|
|
43
|
+
- **What's encrypted**: Everything you see and type in the remote terminal session
|
|
36
44
|
|
|
37
45
|
### Send Files from Phone to PC
|
|
38
46
|
|
|
@@ -48,14 +56,21 @@ Purpose-built buttons for Claude Code workflows:
|
|
|
48
56
|
|
|
49
57
|
## Quick Start
|
|
50
58
|
|
|
59
|
+
**Install once:**
|
|
51
60
|
```bash
|
|
52
|
-
|
|
61
|
+
npm install -g ghostterm
|
|
53
62
|
```
|
|
54
63
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
64
|
+
**Then just run:**
|
|
65
|
+
```bash
|
|
66
|
+
ghostterm
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
1. First time: browser opens for Google sign-in (one-time, remembered after)
|
|
70
|
+
2. Open **[ghostterm.pages.dev](https://ghostterm.pages.dev)** on your phone
|
|
71
|
+
3. Sign in with the same Google account → **auto-connects, no pairing codes**
|
|
72
|
+
|
|
73
|
+
> Don't want to install? Use `npx ghostterm` to run without installing.
|
|
59
74
|
|
|
60
75
|
## Security
|
|
61
76
|
|
package/lib/pty-manager.js
CHANGED
|
@@ -269,11 +269,15 @@ class PtyManager extends EventEmitter {
|
|
|
269
269
|
}
|
|
270
270
|
|
|
271
271
|
case 'file-upload': {
|
|
272
|
-
// Handle file upload: write base64 content to temp file
|
|
273
272
|
this._handleFileUpload(msg, responses);
|
|
274
273
|
break;
|
|
275
274
|
}
|
|
276
275
|
|
|
276
|
+
case 'file-chunk': {
|
|
277
|
+
this._handleFileChunk(msg, responses);
|
|
278
|
+
break;
|
|
279
|
+
}
|
|
280
|
+
|
|
277
281
|
default:
|
|
278
282
|
break;
|
|
279
283
|
}
|
|
@@ -315,6 +319,30 @@ class PtyManager extends EventEmitter {
|
|
|
315
319
|
}
|
|
316
320
|
}
|
|
317
321
|
|
|
322
|
+
_handleFileChunk(msg, responses) {
|
|
323
|
+
if (!this._fileChunks) this._fileChunks = {};
|
|
324
|
+
const key = msg.filename;
|
|
325
|
+
if (!this._fileChunks[key]) {
|
|
326
|
+
this._fileChunks[key] = { chunks: [], total: msg.total, ext: msg.ext, size: msg.size };
|
|
327
|
+
}
|
|
328
|
+
const entry = this._fileChunks[key];
|
|
329
|
+
entry.chunks[msg.index] = msg.chunk;
|
|
330
|
+
|
|
331
|
+
// Check if all chunks received
|
|
332
|
+
const received = entry.chunks.filter(Boolean).length;
|
|
333
|
+
if (received === entry.total) {
|
|
334
|
+
// Reassemble
|
|
335
|
+
const fullBase64 = entry.chunks.join('');
|
|
336
|
+
delete this._fileChunks[key];
|
|
337
|
+
this._handleFileUpload({
|
|
338
|
+
data: fullBase64,
|
|
339
|
+
filename: msg.filename,
|
|
340
|
+
ext: entry.ext,
|
|
341
|
+
size: entry.size,
|
|
342
|
+
}, responses);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
318
346
|
_sessionList() {
|
|
319
347
|
const list = [];
|
|
320
348
|
for (const [id, session] of this.sessions) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ghostterm",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.2",
|
|
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,7 +20,7 @@
|
|
|
20
20
|
"engines": {
|
|
21
21
|
"node": ">=18.0.0"
|
|
22
22
|
},
|
|
23
|
-
"license": "
|
|
23
|
+
"license": "MIT",
|
|
24
24
|
"homepage": "https://ghostterm.pages.dev",
|
|
25
25
|
"keywords": [
|
|
26
26
|
"terminal",
|