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 CHANGED
@@ -1,4 +1,13 @@
1
- # GhostTerm — Control Claude Code from Your Phone
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
- ### True End-to-End Encryption
38
+ ### Encrypted Direct Connection
30
39
 
31
- Your terminal data travels directly between your phone and PC over **WebRTC with DTLS encryption**. The signaling server only handles the initial pairing handshakeit never sees your terminal data. Not even GhostTerm's servers can read what you type.
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 devicesthey never pass through GhostTerm's servers or any third party.
32
41
 
33
- Compare:
34
- - **Official app**: Your data Anthropic's servers Your PC
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
- npx ghostterm
61
+ npm install -g ghostterm
53
62
  ```
54
63
 
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**
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
 
@@ -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.0",
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": "UNLICENSED",
23
+ "license": "MIT",
24
24
  "homepage": "https://ghostterm.pages.dev",
25
25
  "keywords": [
26
26
  "terminal",