ghostterm 1.1.0 → 1.1.1

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
@@ -9,15 +9,17 @@
9
9
  ## Screenshots
10
10
 
11
11
  <p align="center">
12
- <img src="https://ghostterm.pages.dev/img/claude-code.jpg" width="250" alt="Claude Code running on phone">
13
- <img src="https://ghostterm.pages.dev/img/terminal.jpg" width="250" alt="Terminal with dangerous mode">
14
- <img src="https://ghostterm.pages.dev/img/pixel-office.jpg" width="250" alt="4 terminal sessions">
12
+ <img src="https://ghostterm.pages.dev/img/banner.png" width="500" alt="GhostTerm Banner">
15
13
  </p>
16
14
 
17
15
  <p align="center">
18
- <em>Left: Claude Code with <code>--dangerously-skip-permissions</code> running on your phone</em><br>
19
- <em>Center: Full terminal + custom shortcut keys (y/n, Tab, Ctrl+C, arrows...)</em><br>
20
- <em>Right: 4 ghost terminals in pixel office view</em>
16
+ <img src="https://ghostterm.pages.dev/img/office-busy.jpg" width="220" alt="Ghosts working">
17
+ <img src="https://ghostterm.pages.dev/img/pixel-office.jpg" width="220" alt="Pixel office overview">
18
+ <img src="https://ghostterm.pages.dev/img/claude-code.jpg" width="220" alt="Claude Code on phone">
19
+ </p>
20
+
21
+ <p align="center">
22
+ <em>Halloween-themed pixel office · 4 animated ghost terminals · Claude Code on your phone</em>
21
23
  </p>
22
24
 
23
25
  ---
package/bin/ghostterm.js CHANGED
@@ -37,11 +37,23 @@ function loadToken() {
37
37
  if (fs.existsSync(CRED_FILE)) {
38
38
  const cred = JSON.parse(fs.readFileSync(CRED_FILE, 'utf8'));
39
39
  if (cred.id_token) {
40
- const payload = JSON.parse(Buffer.from(cred.id_token.split('.')[1], 'base64').toString());
41
- if (payload.exp * 1000 > Date.now()) {
42
- return cred.id_token;
40
+ // Long token format: base64payload.signature (no dots in payload)
41
+ const parts = cred.id_token.split('.');
42
+ if (parts.length === 2) {
43
+ // Long token — check our own expiry
44
+ try {
45
+ const data = JSON.parse(Buffer.from(parts[0], 'base64').toString());
46
+ if (data.exp > Date.now()) return cred.id_token;
47
+ console.log(' Long token expired, need to re-login');
48
+ } catch {}
49
+ } else if (parts.length === 3) {
50
+ // Google JWT — check Google expiry
51
+ try {
52
+ const payload = JSON.parse(Buffer.from(parts[1], 'base64').toString());
53
+ if (payload.exp * 1000 > Date.now()) return cred.id_token;
54
+ console.log(' Google token expired, need to re-login');
55
+ } catch {}
43
56
  }
44
- console.log(' Token expired, need to re-login');
45
57
  }
46
58
  }
47
59
  } catch {}
@@ -303,7 +315,12 @@ function handleRelayMessage(msg) {
303
315
  case 'auth_ok':
304
316
  console.log(` Authenticated as: ${msg.email}`);
305
317
  console.log(' Phone will auto-connect with same Google account');
306
- // Pre-spawn a standby terminal so first open is instant
318
+ // Save long token if provided (valid 30 days, no more Google expiry issues)
319
+ if (msg.longToken) {
320
+ saveToken(msg.longToken);
321
+ googleToken = msg.longToken;
322
+ console.log(' Long-lived token saved (30 days)');
323
+ }
307
324
  prepareStandby();
308
325
  break;
309
326
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ghostterm",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "Mobile terminal for Claude Code — control your PC from your phone",
5
5
  "bin": {
6
6
  "ghostterm": "bin/ghostterm.js"