claude-relay 1.4.0 → 1.5.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 +68 -64
- package/bin/cli.js +22 -3
- package/lib/pages.js +604 -0
- package/lib/public/app.js +142 -2387
- package/lib/public/css/base.css +99 -0
- package/lib/public/css/input.css +436 -0
- package/lib/public/css/menus.css +263 -0
- package/lib/public/css/messages.css +770 -0
- package/lib/public/css/overlays.css +558 -0
- package/lib/public/css/rewind.css +529 -0
- package/lib/public/css/sidebar.css +350 -0
- package/lib/public/icon-mono.svg +19 -0
- package/lib/public/index.html +18 -3
- package/lib/public/manifest.json +1 -1
- package/lib/public/modules/events.js +21 -0
- package/lib/public/modules/icons.js +54 -0
- package/lib/public/modules/input.js +374 -0
- package/lib/public/modules/markdown.js +149 -0
- package/lib/public/modules/notifications.js +562 -0
- package/lib/public/modules/rewind.js +285 -0
- package/lib/public/modules/sidebar.js +265 -0
- package/lib/public/modules/state.js +3 -0
- package/lib/public/modules/tools.js +876 -0
- package/lib/public/modules/utils.js +32 -0
- package/lib/public/style.css +7 -2861
- package/lib/sdk-bridge.js +529 -0
- package/lib/server.js +55 -1386
- package/lib/sessions.js +300 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,125 +1,129 @@
|
|
|
1
1
|
# claude-relay
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="media/phone.gif" alt="claude-relay on phone" width="300">
|
|
5
|
+
</p>
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
<h3 align="center">Claude Code on your phone. Push notifications. Zero install.</h3>
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
[](https://www.npmjs.com/package/claude-relay) [](https://www.npmjs.com/package/claude-relay)
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
You step away. Claude Code stops.
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
```
|
|
13
|
+
> "A 10-second approval can block it for hours if you're not at your desk."
|
|
14
|
+
> — [#25115](https://github.com/anthropics/claude-code/issues/25115)
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
> "I don't need to write code on my phone. I need to approve, reject, continue, stop. That's it."
|
|
17
|
+
> — [#18189](https://github.com/anthropics/claude-code/issues/18189)
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
**claude-relay fixes this.** Your phone buzzes when Claude needs you. Tap approve. Claude keeps working. You keep doing whatever you were doing.
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
No app. No cloud. No account. Your code never touches a third-party server.
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
Runs a Claude Code session on your machine via the [Claude Agent SDK](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk) and streams it to your browser over WebSocket. Nothing is proxied through external servers.
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
Your phone/tablet <--> claude-relay (your machine) <--> Claude Code
|
|
25
|
-
browser WebSocket + HTTPS
|
|
26
|
-
```
|
|
25
|
+
---
|
|
27
26
|
|
|
28
27
|
## Push notifications for Claude Code
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
No app required. Add to your home screen and notifications work like a native app (PWA). The built-in setup wizard walks you through it in 3 steps.
|
|
29
|
+
Permission request. Task done. Error. Question. Your phone buzzes. Browser can be closed.
|
|
33
30
|
|
|
34
|
-
|
|
31
|
+
Add to home screen → PWA → push notifications work like a native app. Setup wizard handles everything.
|
|
35
32
|
|
|
36
|
-
|
|
33
|
+
<p align="center">
|
|
34
|
+
<img src="media/push-notification.jpg" alt="push notification" width="300">
|
|
35
|
+
</p>
|
|
37
36
|
|
|
38
|
-
|
|
37
|
+
## Use Claude Code from any device
|
|
39
38
|
|
|
40
|
-
|
|
39
|
+
Open claude-relay on your phone, tablet, or any browser. Type a prompt, watch Claude work, review code — all in real time. Every connected device sees the same session live.
|
|
41
40
|
|
|
42
|
-
|
|
41
|
+
Permission prompt? Approve from whichever device is closest. The session updates everywhere instantly.
|
|
43
42
|
|
|
44
|
-
##
|
|
43
|
+
## Quick start
|
|
45
44
|
|
|
46
|
-
|
|
45
|
+
```bash
|
|
46
|
+
# Run in your project directory
|
|
47
|
+
npx claude-relay
|
|
47
48
|
|
|
48
|
-
|
|
49
|
+
# Scan the QR code with your phone — opens Claude Code in your browser
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
# Press 's' → setup wizard → push + remote access in 3 steps
|
|
52
|
+
```
|
|
51
53
|
|
|
52
|
-
|
|
54
|
+
<p align="center">
|
|
55
|
+
<img src="media/start.gif" alt="npx claude-relay" width="600">
|
|
56
|
+
</p>
|
|
53
57
|
|
|
54
|
-
##
|
|
58
|
+
## All features
|
|
55
59
|
|
|
56
|
-
- **Push notifications**
|
|
57
|
-
- **Real-time sync**
|
|
58
|
-
- **Session persistence**
|
|
59
|
-
- **
|
|
60
|
-
- **
|
|
61
|
-
- **
|
|
62
|
-
- **
|
|
63
|
-
- **
|
|
64
|
-
- **
|
|
65
|
-
- **
|
|
60
|
+
- **Push notifications** — permission requests, completions, errors, questions. Works with browser closed.
|
|
61
|
+
- **Real-time sync** — every device sees the same session live via WebSocket. Type on desktop, see it on phone.
|
|
62
|
+
- **Session persistence** — server restarts, browser crashes, network drops. Session survives. Conversation is never lost.
|
|
63
|
+
- **Session handoff** — start in the terminal, pick it up on your phone, hand it back. Seamless.
|
|
64
|
+
- **Conversation rewind** — click any previous message to roll back conversation and files together, with full diffs
|
|
65
|
+
- **Mobile-first UI** — big approve/deny buttons, one-handed use
|
|
66
|
+
- **iPad and tablet support** — full Claude Code from any browser. Your actual machine, your tools, your MCP servers, your files.
|
|
67
|
+
- **Setup wizard** — Tailscale, HTTPS, push. Step by step.
|
|
68
|
+
- **Multi-session** — multiple projects, automatic port selection
|
|
69
|
+
- **PIN protection** — access control beyond network security
|
|
70
|
+
- **HTTPS** — automatic certs via mkcert
|
|
71
|
+
- **Slash commands** — with autocomplete
|
|
72
|
+
- **Zero config** — works with your existing Claude Code setup
|
|
66
73
|
|
|
67
|
-
##
|
|
74
|
+
## Network access
|
|
68
75
|
|
|
69
|
-
|
|
70
|
-
# 1. Run in your project directory
|
|
71
|
-
npx claude-relay
|
|
76
|
+
On the same Wi-Fi? It just works. Open the URL shown in the terminal from any device on your network.
|
|
72
77
|
|
|
73
|
-
|
|
74
|
-
# or open the URL shown in the terminal
|
|
78
|
+
Outside your network? [Tailscale](https://tailscale.com) creates an encrypted tunnel between your devices. No port forwarding. No cloud relay. Your code never leaves your control.
|
|
75
79
|
|
|
76
|
-
|
|
77
|
-
# to enable push notifications and remote access
|
|
78
|
-
```
|
|
80
|
+
Install on both devices. Same account. Done. claude-relay detects it automatically. Free for personal use.
|
|
79
81
|
|
|
80
|
-
## HTTPS
|
|
82
|
+
## HTTPS for push notifications
|
|
81
83
|
|
|
82
|
-
Push
|
|
84
|
+
Push needs HTTPS. [mkcert](https://github.com/FiloSottile/mkcert) makes it painless:
|
|
83
85
|
|
|
84
86
|
```bash
|
|
85
87
|
brew install mkcert
|
|
86
88
|
mkcert -install
|
|
87
89
|
```
|
|
88
90
|
|
|
89
|
-
Certificates
|
|
91
|
+
Certificates generate automatically. Setup wizard handles the rest.
|
|
90
92
|
|
|
91
93
|
## CLI options
|
|
92
94
|
|
|
93
95
|
```bash
|
|
94
|
-
npx claude-relay #
|
|
95
|
-
npx claude-relay -p 8080 #
|
|
96
|
-
npx claude-relay --no-https #
|
|
97
|
-
npx claude-relay --no-update #
|
|
98
|
-
npx claude-relay --debug #
|
|
96
|
+
npx claude-relay # defaults
|
|
97
|
+
npx claude-relay -p 8080 # custom port (default: 2633)
|
|
98
|
+
npx claude-relay --no-https # disable HTTPS
|
|
99
|
+
npx claude-relay --no-update # skip update check
|
|
100
|
+
npx claude-relay --debug # debug panel
|
|
99
101
|
```
|
|
100
102
|
|
|
101
103
|
## Requirements
|
|
102
104
|
|
|
103
105
|
- [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code) installed and authenticated
|
|
104
106
|
- Node.js 18+
|
|
105
|
-
- [mkcert](https://github.com/FiloSottile/mkcert)
|
|
106
|
-
- [Tailscale](https://tailscale.com)
|
|
107
|
+
- [mkcert](https://github.com/FiloSottile/mkcert) for HTTPS and push
|
|
108
|
+
- [Tailscale](https://tailscale.com) for remote access
|
|
107
109
|
|
|
108
110
|
## Security
|
|
109
111
|
|
|
110
|
-
**Anyone with
|
|
112
|
+
**Anyone with the URL gets full Claude Code access to your machine.** Read, write, execute — your user permissions.
|
|
113
|
+
|
|
114
|
+
PIN protection is enabled during setup — every new device must enter the PIN shown in your terminal before accessing any session. This prevents casual shoulder-surfing of the QR code, but is not a substitute for network-level security.
|
|
111
115
|
|
|
112
|
-
|
|
116
|
+
Private network only. [Tailscale](https://tailscale.com), WireGuard, or a VPN. Never expose to the public internet.
|
|
113
117
|
|
|
114
|
-
**Entirely at your own risk.**
|
|
118
|
+
**Entirely at your own risk.**
|
|
115
119
|
|
|
116
|
-
##
|
|
120
|
+
## Contributing
|
|
117
121
|
|
|
118
|
-
|
|
122
|
+
Bug fixes and typos — PR welcome. Feature ideas — [open an issue](https://github.com/chadbyte/claude-relay/issues) first. See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
119
123
|
|
|
120
124
|
## Disclaimer
|
|
121
125
|
|
|
122
|
-
|
|
126
|
+
Independent project. Not affiliated with Anthropic. "Claude" is a trademark of Anthropic.
|
|
123
127
|
|
|
124
128
|
## License
|
|
125
129
|
|
package/bin/cli.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const os = require("os");
|
|
4
4
|
const fs = require("fs");
|
|
5
5
|
const path = require("path");
|
|
6
|
-
const { execSync } = require("child_process");
|
|
6
|
+
const { execSync, execFileSync } = require("child_process");
|
|
7
7
|
const qrcode = require("qrcode-terminal");
|
|
8
8
|
const { createServer } = require("../lib/server");
|
|
9
9
|
|
|
@@ -116,10 +116,21 @@ function startCaffeinate() {
|
|
|
116
116
|
|
|
117
117
|
// --- Certs ---
|
|
118
118
|
function ensureCerts(ip) {
|
|
119
|
-
var
|
|
119
|
+
var homeDir = process.env.HOME || process.env.USERPROFILE || os.homedir();
|
|
120
|
+
var certDir = path.join(homeDir, ".claude-relay", "certs");
|
|
120
121
|
var keyPath = path.join(certDir, "key.pem");
|
|
121
122
|
var certPath = path.join(certDir, "cert.pem");
|
|
122
123
|
|
|
124
|
+
// Migrate from legacy per-project certs to shared home dir
|
|
125
|
+
var legacyDir = path.join(cwd, ".claude-relay", "certs");
|
|
126
|
+
var legacyKey = path.join(legacyDir, "key.pem");
|
|
127
|
+
var legacyCert = path.join(legacyDir, "cert.pem");
|
|
128
|
+
if (!fs.existsSync(keyPath) && fs.existsSync(legacyKey) && fs.existsSync(legacyCert)) {
|
|
129
|
+
fs.mkdirSync(certDir, { recursive: true });
|
|
130
|
+
fs.copyFileSync(legacyKey, keyPath);
|
|
131
|
+
fs.copyFileSync(legacyCert, certPath);
|
|
132
|
+
}
|
|
133
|
+
|
|
123
134
|
var caRoot = null;
|
|
124
135
|
try {
|
|
125
136
|
caRoot = path.join(
|
|
@@ -130,7 +141,15 @@ function ensureCerts(ip) {
|
|
|
130
141
|
} catch (e) { }
|
|
131
142
|
|
|
132
143
|
if (fs.existsSync(keyPath) && fs.existsSync(certPath)) {
|
|
133
|
-
|
|
144
|
+
// Re-generate if current IP is not in the cert's SAN
|
|
145
|
+
var needRegen = false;
|
|
146
|
+
if (ip && ip !== "localhost") {
|
|
147
|
+
try {
|
|
148
|
+
var certText = execFileSync("openssl", ["x509", "-in", certPath, "-text", "-noout"], { encoding: "utf8" });
|
|
149
|
+
if (certText.indexOf(ip) === -1) needRegen = true;
|
|
150
|
+
} catch (e) { /* openssl not available, skip check */ }
|
|
151
|
+
}
|
|
152
|
+
if (!needRegen) return { key: keyPath, cert: certPath, caRoot: caRoot };
|
|
134
153
|
}
|
|
135
154
|
|
|
136
155
|
fs.mkdirSync(certDir, { recursive: true });
|