clay-server 2.9.3-beta.2 → 2.9.3-beta.4

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
@@ -4,226 +4,226 @@
4
4
  <img src="media/phone.gif" alt="Clay on phone" width="300">
5
5
  </p>
6
6
 
7
- <h3 align="center">Web UI for Claude Code. Any device. Push notifications.</h3>
7
+ <h3 align="center">A multi-user web UI for Claude Code, built on the Agent SDK.</h3>
8
8
 
9
- [![npm version](https://img.shields.io/npm/v/claude-relay)](https://www.npmjs.com/package/claude-relay) [![npm downloads](https://img.shields.io/npm/dw/claude-relay)](https://www.npmjs.com/package/claude-relay) [![GitHub stars](https://img.shields.io/github/stars/chadbyte/claude-relay)](https://github.com/chadbyte/claude-relay) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/chadbyte/claude-relay/blob/main/LICENSE)
9
+ [![npm version](https://img.shields.io/npm/v/clay-server)](https://www.npmjs.com/package/clay-server) [![npm downloads](https://img.shields.io/npm/dw/clay-server)](https://www.npmjs.com/package/clay-server) [![GitHub stars](https://img.shields.io/github/stars/chadbyte/clay)](https://github.com/chadbyte/clay) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/chadbyte/clay/blob/main/LICENSE)
10
10
 
11
- Claude Code. Anywhere.
12
- Same session. Same files. Same machine.
13
- Your files stay on your computer. Nothing leaves for the cloud.
11
+ Clay extends Claude Code from a single-user CLI into a multi-user, multi-session web platform. It runs locally as a daemon, serves a browser UI over WebSocket, and lets non-technical teammates use Claude Code without touching the terminal.
14
12
 
15
- Pick up the same Claude Code session on your phone.
16
- Start in the terminal, continue on your phone, switch back anytime.
13
+ No relay server in the cloud. Your machine is the server. Zero install — one command:
17
14
 
18
- Claude Code is automating more of your editing and execution workflow.
19
- But when it needs approval or asks a question, it halts in the terminal. If you walk away, it just sits there waiting.
15
+ ```bash
16
+ npx clay-server
17
+ # Scan the QR code to connect from any device
18
+ ```
20
19
 
21
- claude-relay eliminates this bottleneck.
22
- It is not a thin wrapper that intercepts input/output. It drives Claude Code via the Claude Agent SDK and relays the stream from your local machine to your browser.
20
+ ---
23
21
 
24
- Get approval notifications while grabbing a coffee.
25
- Continue working from the sofa on your iPad.
26
- Split your browser: claude-relay on one side, your app preview on the other, and watch the code change in real time.
22
+ ## Getting Started
23
+
24
+ **Requirements:** Node.js 20+, Claude Code CLI (authenticated).
27
25
 
28
26
  ```bash
29
- cd ~/your-project
30
- npx claude-relay
31
- # First run: Set Port/PIN -> Scan QR -> Connect
27
+ npx clay-server
32
28
  ```
33
29
 
34
- ---
35
-
36
- ## Never Miss an Approval
30
+ On first run, it walks you through port and PIN setup.
31
+ Scan the QR code to connect from your phone instantly.
37
32
 
38
- When Claude Code requests permission before executing a tool, you get a notification on your phone.
39
- One tap, and Claude Code gets back to work.
33
+ For remote access, use a VPN like Tailscale.
40
34
 
41
35
  <p align="center">
42
- <img src="media/push-notification.jpg" alt="push notification" width="300">
36
+ <img src="media/start.gif" alt="Clay starting from CLI" width="600">
43
37
  </p>
44
38
 
45
- It works in browser tabs too. When input is awaited, the favicon blinks and the tab title changes to alert you.
39
+ ---
40
+
41
+ ## Multi-session, multi-project
46
42
 
47
- ## Side by Side Workflow
43
+ Add a project in the browser and an agent attaches to it.
44
+ Run backend, frontend, and docs simultaneously. Switch between them in the sidebar.
45
+
46
+ The server runs as a background daemon. Sessions persist even after you close the terminal.
47
+
48
+ Mermaid diagrams render as diagrams. Tables render as tables.
49
+ Code blocks highlight 180+ languages.
50
+ Browse project files in the file browser — changes reflect live while the agent works.
48
51
 
49
52
  <p align="center">
50
53
  <img src="media/split.gif" alt="split-screen workflow" width="700">
51
54
  </p>
52
55
 
53
- Keep claude-relay on one side and your localhost on the other.
54
- Watch the results update live while Claude Code fixes your source files.
55
-
56
- Mermaid diagrams render as diagrams, and tables appear as actual tables.
57
- You can explore files in the sidebar and use the built-in terminal to run shell commands.
56
+ ---
58
57
 
59
- ## All in One Place
58
+ ## Multi-user
60
59
 
61
- Run `npx claude-relay` in each project to register them to the same server.
62
- Manage all your active sessions from a single dashboard.
60
+ Invite teammates and give them access to a project. They talk to Claude Code directly in the browser — no terminal, no setup on their end.
63
61
 
64
- ```bash
65
- cd ~/projects/backend && npx claude-relay # Register project
66
- cd ~/projects/frontend && npx claude-relay # Adds to the same server
67
- ```
62
+ Add a CLAUDE.md and the AI operates within those rules: explains technical terms in plain language, escalates risky operations to seniors, summarizes changes in simple words.
68
63
 
69
- The server runs in the background. Even if you close the terminal window, your sessions and the server remain active.
64
+ If someone gets stuck, join their session to unblock them in real time. Permissions can be separated per project and per session. Real-time presence shows who's where.
70
65
 
71
66
  ---
72
67
 
73
- ## Getting Started
68
+ ## Mobile & notifications
74
69
 
75
- ```bash
76
- npx claude-relay
77
- ```
70
+ Phone, tablet, couch. All you need is a browser.
71
+ Pick up a terminal session in the browser. Continue a browser session from another device.
72
+ One QR code to connect. Install as a PWA for a native-like experience.
73
+
74
+ When Claude asks for approval, your phone buzzes. You also get notified on completion or error. No need to keep the browser open.
78
75
 
79
76
  <p align="center">
80
- <img src="media/start.gif" alt="npx claude-relay" width="600">
77
+ <img src="media/push-notification.jpg" alt="push notification" width="300">
81
78
  </p>
82
79
 
83
- On the first run, you'll set a port and PIN to launch the server.
84
- Scan the QR code with your phone to connect instantly, or open the URL displayed in your terminal.
80
+ ---
85
81
 
86
- ## Key Features
82
+ ## Automation
83
+
84
+ The scheduler kicks off agents at set times.
85
+ Have it check open issues and submit PRs every morning at 8 AM.
86
+ Or compile world news and email you a digest every day.
87
+
88
+ Take it further with Ralph Loop — autonomous iteration built into Clay. Define a task (`PROMPT.md`) and success criteria (`JUDGE.md`), then start the loop. The agent works, commits, and a judge evaluates the git diff as PASS or FAIL. On FAIL, a fresh session starts over. Each iteration has **no memory of previous conversations** — only the code carries over. Based on [Geoffrey Huntley's Ralph Wiggum technique](https://ghuntley.com/loop/).
89
+
90
+ ---
91
+
92
+ ## Security & Privacy
93
+
94
+ Clay turns your machine into the relay server. There is no intermediary server on the internet. No third-party service sits between your browser and your code.
95
+
96
+ The best relay server to trust is the one that doesn't exist. Clay has none. Your data flows directly from your machine to the Anthropic API — exactly as it does when you use the CLI. No one intercepts, collects, or reroutes it. Clay adds a browser layer on top, not a middleman.
97
+
98
+ PIN authentication, per-project/session permissions, and HTTPS are supported by default. For local network use, this is sufficient. For remote access, we recommend a VPN like Tailscale.
99
+
100
+ ---
87
101
 
88
- * **Push Approvals** - Approve or reject from your phone while away, so Claude Code does not get stuck waiting.
89
- * **Multi Project Daemon** - Manage all projects via a single port. Add and remove projects from the browser.
90
- * **Usage and Model Switching** - View token usage, rate limit bars, and switch models from the browser.
91
- * **Session Search** - Full-text search across all session messages with hit timeline.
92
- * **Auto Session Logs (JSONL)** - Conversations and execution history are always saved locally. No data loss on crashes or restarts. Location: `./.claude-relay/sessions/`
93
- * **File Browser and Terminal** - Inspect files, execute commands, and manage multiple terminal tabs from the browser.
102
+ ## Why Clay?
94
103
 
95
- > Note: Session logs may contain prompts, outputs, and commands. Do not share this folder.
104
+ *As of March 2026.*
96
105
 
97
- <details>
98
- <summary>View Full Feature List</summary>
106
+ | | CLI + Remote Control | tmux | Desktop | Cowork | **Clay** |
107
+ |---|---|---|---|---|---|
108
+ | Multi-user | ❌ | ✅ | ❌ | ❌ | ✅ |
109
+ | Mobile / PWA | ✅ | ➖ | ➖ | ➖ | ✅ |
110
+ | Push notifications | 🟠 | ❌ | 🟠 | ❌ | ✅ |
111
+ | GUI | 🟠 | ❌ | ✅ | ✅ | ✅ |
112
+ | Scheduler (cron) | 🟠 | ❌ | ✅ | ✅ | ✅ |
113
+ | Scheduler survives logout | ❌ | ➖ | 🟠 | 🟠 | ✅ |
114
+ | Join teammate's session | ❌ | 🟠 | ❌ | ❌ | ✅ |
99
115
 
100
- **Notifications**
116
+ ✅ Supported · 🟠 Partial / limited · ❌ Not supported · ➖ N/A
101
117
 
102
- * **Push Notifications** - Approvals, completions, errors, and questions. Add to Home Screen (PWA) to receive notifications without opening the app. Behavior depends on OS and browser. Tested on iPhone (Home Screen PWA) and desktop Chrome.
103
- * **Favicon and Title Blinking** - Visual cues when input is awaited.
104
- * **Sound Alerts** - Supports browser notifications, desktop notifications, and audio alerts.
118
+ ---
119
+
120
+ ## Key Features
121
+
122
+ * **Multi-user** - Accounts, invitations, per-project/session permissions, real-time presence.
123
+ * **Multi-agent** - Parallel agents per project, sidebar switching.
124
+ * **Push notifications** - Approval, completion, error. Native-like PWA experience.
125
+ * **Scheduler** - Cron-based automatic agent execution.
126
+ * **Ralph Loop** - Autonomous coding loop with PROMPT.md + JUDGE.md. Iterates until the judge says PASS.
127
+ * **File browser** - File exploration, syntax highlighting, live reload.
128
+ * **Built-in terminal** - Multi-tab terminal, mobile keyboard support.
129
+ * **Session search** - Full-text search across all conversation history.
130
+ * **Session persistence** - Survives crashes, restarts, and network drops.
131
+
132
+ ---
105
133
 
106
- **Projects and Sessions**
134
+ ## FAQ
107
135
 
108
- * **Multi Project** - Single port management for all projects. Add and remove projects from the browser with path autocomplete.
109
- * **Project Names** - Custom names make it easy to distinguish tabs.
110
- * **Session Persistence** - Sessions survive server restarts, browser crashes, and network drops.
111
- * **Session Handoff** - Start in the terminal, continue on your phone, pass back to desktop. Browse and resume CLI sessions directly from the web UI.
112
- * **Session Search** - Full-text search across all session content with highlighted results and a rewind-style hit timeline.
113
- * **Rewind (Native Claude Code)** - Accessible directly from the browser UI.
114
- * **Draft Persistence** - Unsent messages are saved per session and restored when you switch back.
136
+ **"Is this just a terminal wrapper?"**
137
+ No. Clay runs on the Claude Agent SDK. It doesn't wrap terminal output. It communicates directly with the agent through the SDK.
115
138
 
116
- **Rendering and Tools**
139
+ **"Is it free? Open source?"**
140
+ Free. MIT-licensed open source. All code is public.
117
141
 
118
- * **Mermaid and Markdown** - Proper rendering for diagrams, tables, and code blocks.
119
- * **Syntax Highlighting** - Support for over 180 languages with copy buttons on every block.
120
- * **File Browser** - Sidebar navigation with file previews, markdown rendering, and live-reload on external changes.
121
- * **Built in Terminal** - Multi-tab terminal sessions with rename, reorder, and a mobile special-key toolbar.
122
- * **Slash Commands** - Execute standard Claude Code commands from the browser, with autocomplete.
123
- * **Usage Panel** - View token counts and rate limit progress bars via `/usage` command or header button.
124
- * **Model Switching** - Change the active model directly from the browser header.
125
- * **Plan Approval** - Review and approve Claude implementation plans from the browser UI.
142
+ **"Do I need to install anything?"**
143
+ No. `npx clay-server` runs it directly. No global install, no build step, no Docker. Node.js and Claude Code are the only prerequisites.
126
144
 
127
- **UI**
145
+ **"Does my code leave my machine?"**
146
+ The Clay server runs locally. Files stay local. Only Claude API calls go out, which is the same as using the CLI.
128
147
 
129
- * **Mobile Optimized** - Large approve and reject buttons. Behaves like a native app via PWA.
130
- * **Real time Sync** - All devices view the exact same session state.
131
- * **QR Code** - Scan to connect instantly.
132
- * **Image Paste and Camera** - Paste images from clipboard or attach photos directly from your camera.
133
- * **Send While Processing** - Queue messages without waiting for the current response to finish.
134
- * **Sticky Todo Overlay** - TodoWrite tasks float as a progress bar while you scroll through the conversation.
135
- * **Scroll Position Hold** - Reading earlier messages will not get interrupted by new content arriving.
136
- * **RTL Text Support** - Automatic bidirectional text rendering for Arabic, Hebrew, and other RTL languages.
148
+ **"Is it secure?"**
149
+ PIN authentication, per-project/session permissions, and HTTPS are supported by default. See [Security & Privacy](#security--privacy) for details.
137
150
 
138
- **Server and Security**
151
+ **"What OS does it run on?"**
152
+ Windows, Linux, and macOS are all supported.
139
153
 
140
- * **Background Daemon** - Server persists even if the CLI is closed.
141
- * **Keep Awake** - Prevents macOS sleep to keep sessions alive. Configurable toggle.
142
- * **PIN Protection** - Restrict access with a 6 digit PIN.
143
- * **HTTPS** - Automatic certificate generation via mkcert.
144
- * **Zero Config** - Inherits your existing Claude Code configuration.
154
+ **"Can I continue a CLI session?"**
155
+ Yes. Pick up a CLI session in the browser, or continue a browser session in the CLI.
145
156
 
146
- </details>
157
+ **"Does my existing CLAUDE.md work?"**
158
+ Yes. If your project has a CLAUDE.md, it works in Clay as-is.
147
159
 
148
- ## Network
160
+ **"Can I use it as an app?"**
161
+ PWA is supported. On mobile, tap the download icon in the top-left corner to open the PWA install guide. Once installed, it provides a native-like experience.
149
162
 
150
- On the same Wi Fi, it just works. Open the URL shown in the terminal on any device.
163
+ **"Can I use the terminal on mobile?"**
164
+ Yes. Clay provides a built-in terminal with mobile keyboard support.
151
165
 
152
- For remote access, [Tailscale](https://tailscale.com) is recommended. Install it on both devices and log in with the same account to connect via an encrypted tunnel without port forwarding. Free for personal use.
166
+ **"Does each teammate need their own API key?"**
167
+ No. Teammates share the Claude Code session logged in on the server. If needed, you can configure per-project environment variables to use different API keys.
153
168
 
154
- ## Security
169
+ **"Does it work with MCP servers?"**
170
+ Yes. MCP configurations from the CLI carry over as-is.
155
171
 
156
- claude-relay opens on your local network to allow access from other devices such as phones and tablets on the same Wi Fi.
157
- Setting a PIN is highly recommended.
172
+ **"How do I update?"**
173
+ Auto-update is supported. When a new version is available, apply it with one click.
158
174
 
159
- Anyone on your network with the URL and PIN can access the session. PIN protection can be enabled during the initial setup.
175
+ **"Can I use other AI models besides Claude?"**
176
+ Currently Clay is Claude Code only. Other model support is on the roadmap.
160
177
 
161
- Do not expose this directly to the public internet. Usage on public or shared networks is not recommended.
162
- For remote access, use [Tailscale](https://tailscale.com) or a VPN.
178
+ **"Can I run it in Docker?"**
179
+ There's no official Docker image yet, but it can run in a container with a Node.js environment.
163
180
 
164
- Users are responsible for their network configuration and exposure scope.
181
+ ---
165
182
 
166
183
  ## HTTPS for Push
167
184
 
168
- Basic features work out of the box. Only push notifications require HTTPS.
185
+ Everything works out of the box. Only push notifications require HTTPS.
169
186
 
170
- Set it up once using [mkcert](https://github.com/FiloSottile/mkcert):
187
+ Set it up once with [mkcert](https://github.com/FiloSottile/mkcert):
171
188
 
172
189
  ```bash
173
190
  brew install mkcert
174
191
  mkcert -install
175
192
  ```
176
193
 
177
- Certificates are generated automatically. The setup wizard handles the rest.
194
+ Certificates are auto-generated. The setup wizard handles the rest.
195
+
196
+ If push registration fails: check that your browser trusts the HTTPS certificate and that your phone can reach the server address.
178
197
 
179
- If push registration fails: check whether your browser trusts HTTPS and whether your phone can access the address.
198
+ ---
180
199
 
181
200
  ## CLI Options
182
201
 
183
202
  ```bash
184
- npx claude-relay # Default (port 2633)
185
- npx claude-relay -p 8080 # Specify port
186
- npx claude-relay --yes # Skip interactive prompts (accept defaults)
187
- npx claude-relay -y --pin 123456
188
- # Non-interactive with PIN (for scripts/CI)
189
- npx claude-relay --no-https # Disable HTTPS
190
- npx claude-relay --no-update # Skip update check
191
- npx claude-relay --debug # Enable debug panel
192
- npx claude-relay --add . # Add current directory to running daemon
193
- npx claude-relay --add /path # Add a project by path
194
- npx claude-relay --remove . # Remove a project
195
- npx claude-relay --list # List registered projects
196
- npx claude-relay --shutdown # Stop the running daemon
197
- npx claude-relay --dangerously-skip-permissions
198
- # Bypass all permission prompts (PIN required during setup)
199
- npx claude-relay --dev # Development mode (foreground, auto-restart on lib/ changes, port 2635)
203
+ npx clay-server # Default (port 2633)
204
+ npx clay-server -p 8080 # Specify port
205
+ npx clay-server --yes # Skip interactive prompts (use defaults)
206
+ npx clay-server -y --pin 123456
207
+ # Non-interactive + PIN (for scripts/CI)
208
+ npx clay-server --no-https # Disable HTTPS
209
+ npx clay-server --no-update # Skip update check
210
+ npx clay-server --debug # Enable debug panel
211
+ npx clay-server --add . # Add current directory to running daemon
212
+ npx clay-server --add /path # Add project by path
213
+ npx clay-server --remove . # Remove project
214
+ npx clay-server --list # List registered projects
215
+ npx clay-server --shutdown # Stop running daemon
216
+ npx clay-server --dangerously-skip-permissions
217
+ # Bypass all permission prompts (requires PIN at setup)
218
+ npx clay-server --dev # Dev mode (foreground, auto-restart on lib/ changes, port 2635)
200
219
  ```
201
220
 
202
- ## Requirements
203
-
204
- * [Claude Code CLI](https://docs.anthropic.com/en/docs/claude-code) installed and authenticated
205
- * Node.js 18+
206
- * [mkcert](https://github.com/FiloSottile/mkcert) - For push notifications (optional)
207
- * [Tailscale](https://tailscale.com) - For remote access (optional)
208
-
209
- ## Why claude-relay?
210
-
211
- **Why not just use tmux + Termius?**
212
- You can monitor the terminal remotely, but there are no push notifications and no way to approve permission requests without switching back to the terminal. On a phone, navigating a raw terminal session is clunky. You end up checking manually instead of getting notified, and the experience never feels native.
213
-
214
- **Why not just add hooks to send notifications?**
215
- Hooks with ntfy or Pushover can get you push notifications, but you still need shell scripts, config files, and third-party accounts just to get alerts. And once you get the notification, there is no UI to approve or reject from. You are back to opening a terminal. claude-relay gives you notifications, a one-tap approval UI, and a full web interface with a single command.
216
-
217
- **Why not use Claude Code Desktop?**
218
- The desktop app works great on your computer, but there is no mobile version. To access sessions from your phone, you need remote sessions on Anthropic's cloud, which requires pushing your code to GitHub first. claude-relay runs entirely on your machine and lets you connect from any device on your network.
219
-
220
- **Why not use Happy Coder?**
221
- Happy Coder requires installing a native app and routes through its own relay server with end-to-end encryption. claude-relay *is* the relay server, running on your machine. Open a URL and you are in. No app install, no signup, nothing leaves your network.
221
+ ---
222
222
 
223
223
  ## Architecture
224
224
 
225
- claude-relay is not a wrapper that intercepts standard input/output.
226
- It is a local relay server that drives Claude Code execution via the [Claude Agent SDK](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk) and streams data to the browser via WebSocket.
225
+ Clay is not a wrapper that intercepts stdio.
226
+ It's a local relay server that drives Claude Code execution through the [Claude Agent SDK](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk) and streams it to the browser over WebSocket.
227
227
 
228
228
  ```mermaid
229
229
  graph LR
@@ -244,39 +244,29 @@ graph LR
244
244
  Push -->|Notification| Browser
245
245
  ```
246
246
 
247
- For a detailed sequence diagram, daemon structure, and design decisions, refer to [docs/architecture.md](docs/architecture.md).
248
-
249
- ## Star History
250
-
251
- <a href="https://star-history.com/#chadbyte/claude-relay&Date">
252
- <picture>
253
- <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=chadbyte/claude-relay&type=Date&theme=dark" />
254
- <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=chadbyte/claude-relay&type=Date" />
255
- <img alt="Star History Chart" src="https://api.star-history.com/svg?repos=chadbyte/claude-relay&type=Date" width="600" />
256
- </picture>
257
- </a>
247
+ For detailed sequence diagrams, daemon architecture, and design decisions, see [docs/architecture.md](docs/architecture.md).
258
248
 
259
249
  ---
260
250
 
261
251
  ## Contributors
262
252
 
263
- <a href="https://github.com/chadbyte/claude-relay/graphs/contributors">
264
- <img src="https://contrib.rocks/image?repo=chadbyte/claude-relay" />
253
+ <a href="https://github.com/chadbyte/clay/graphs/contributors">
254
+ <img src="https://contrib.rocks/image?repo=chadbyte/clay" />
265
255
  </a>
266
256
 
267
257
  ## Contributing
268
258
 
269
- Bug fixes and typos are welcome. For feature suggestions, please open an issue first:
270
- [https://github.com/chadbyte/claude-relay/issues](https://github.com/chadbyte/claude-relay/issues)
259
+ Bug fixes and typo corrections are welcome. For feature suggestions, please open an issue first:
260
+ [https://github.com/chadbyte/clay/issues](https://github.com/chadbyte/clay/issues)
271
261
 
272
- If you are using claude-relay, let us know how you are using it in Discussions:
273
- [https://github.com/chadbyte/claude-relay/discussions](https://github.com/chadbyte/claude-relay/discussions)
262
+ If you're using Clay, let us know how in Discussions:
263
+ [https://github.com/chadbyte/clay/discussions](https://github.com/chadbyte/clay/discussions)
274
264
 
275
265
  ## Disclaimer
276
266
 
277
267
  This is an independent project and is not affiliated with Anthropic. Claude is a trademark of Anthropic.
278
268
 
279
- Clay is provided "as is" without warranty of any kind. Users are responsible for ensuring their use of this software complies with all applicable terms of service of the underlying AI providers (e.g., Anthropic, OpenAI) and any other third-party services. Features such as multi-user mode are experimental and may involve sharing access to API-backed services please review your provider's usage policies regarding account sharing, acceptable use, and any applicable rate limits or restrictions before enabling such features. The authors assume no liability for any misuse or violations arising from the use of this software.
269
+ Clay is provided "as is" without warranty of any kind. Users are responsible for complying with the terms of service of underlying AI providers (e.g., Anthropic, OpenAI) and all applicable terms of any third-party services. Features such as multi-user mode are experimental and may involve sharing access to API-based services. Before enabling such features, review your provider's usage policies regarding account sharing, acceptable use, and any applicable rate limits or restrictions. The authors assume no liability for misuse or violations arising from the use of this software.
280
270
 
281
271
  ## License
282
272
 
package/bin/cli.js CHANGED
@@ -23,7 +23,11 @@ var net = require("net");
23
23
 
24
24
  // Detect dev mode — dev and prod use separate daemon files so they can run simultaneously
25
25
  var _isDev = (process.argv[1] && path.basename(process.argv[1]) === "clay-dev") || process.argv.includes("--dev");
26
- if (_isDev) process.env.CLAY_DEV = "1";
26
+ if (_isDev) {
27
+ process.env.CLAY_DEV = "1";
28
+ // Preserve console output in dev mode so logs remain readable
29
+ console.clear = function() {};
30
+ }
27
31
 
28
32
  var { loadConfig, saveConfig, configPath, socketPath, logPath, ensureConfigDir, isDaemonAlive, isDaemonAliveAsync, generateSlug, clearStaleConfig, loadClayrc, saveClayrc, readCrashInfo } = require("../lib/config");
29
33
  var { sendIPCCommand } = require("../lib/ipc");
package/lib/project.js CHANGED
@@ -3047,6 +3047,7 @@ function createProjectContext(opts) {
3047
3047
  stopAllDirWatches();
3048
3048
  // Abort all active sessions
3049
3049
  sm.sessions.forEach(function (session) {
3050
+ session.destroying = true;
3050
3051
  if (session.abortController) {
3051
3052
  try { session.abortController.abort(); } catch (e) {}
3052
3053
  }
package/lib/public/app.js CHANGED
@@ -2557,6 +2557,10 @@ import { initAdmin, checkAdminAccess } from './modules/admin.js';
2557
2557
  break;
2558
2558
 
2559
2559
  case "info":
2560
+ if (msg.text && !msg.project && !msg.cwd) {
2561
+ addSystemMessage(msg.text, false);
2562
+ break;
2563
+ }
2560
2564
  projectName = msg.project || msg.cwd;
2561
2565
  if (msg.slug) currentSlug = msg.slug;
2562
2566
  try { localStorage.setItem("clay-project-name-" + (currentSlug || "default"), projectName); } catch (e) {}
@@ -2994,10 +2998,6 @@ import { initAdmin, checkAdminAccess } from './modules/admin.js';
2994
2998
  addSystemMessage(msg.text, false);
2995
2999
  break;
2996
3000
 
2997
- case "info":
2998
- addSystemMessage(msg.text, false);
2999
- break;
3000
-
3001
3001
  case "error":
3002
3002
  setActivity(null);
3003
3003
  addSystemMessage(msg.text, true);
package/lib/sdk-bridge.js CHANGED
@@ -626,13 +626,27 @@ function createSDKBridge(opts) {
626
626
  for await (var msg of session.queryInstance) {
627
627
  processSDKMessage(session, msg);
628
628
  }
629
+ // Stream ended normally after a task stop — no "result" message was sent,
630
+ // so the session is still marked as processing. Send interrupted feedback.
631
+ if (session.isProcessing && session.taskStopRequested) {
632
+ session.isProcessing = false;
633
+ onProcessingChanged();
634
+ sendAndRecord(session, { type: "info", text: "Interrupted \u00b7 What should Claude do instead?" });
635
+ sendAndRecord(session, { type: "done", code: 0 });
636
+ sm.broadcastSessionList();
637
+ }
629
638
  } catch (err) {
630
639
  if (session.isProcessing) {
631
640
  session.isProcessing = false;
632
641
  onProcessingChanged();
633
- if (err.name === "AbortError" || (session.abortController && session.abortController.signal.aborted)) {
634
- sendAndRecord(session, { type: "info", text: "Interrupted \u00b7 What should Claude do instead?" });
635
- sendAndRecord(session, { type: "done", code: 0 });
642
+ if (err.name === "AbortError" || (session.abortController && session.abortController.signal.aborted) || session.taskStopRequested) {
643
+ if (!session.destroying) {
644
+ sendAndRecord(session, { type: "info", text: "Interrupted \u00b7 What should Claude do instead?" });
645
+ sendAndRecord(session, { type: "done", code: 0 });
646
+ }
647
+ } else if (session.destroying) {
648
+ // Suppress error messages during shutdown
649
+ console.log("[sdk-bridge] Suppressing stream error during shutdown for session " + session.localId);
636
650
  } else {
637
651
  var errDetail = err.message || String(err);
638
652
  if (err.stderr) errDetail += "\nstderr: " + err.stderr;
@@ -681,6 +695,7 @@ function createSDKBridge(opts) {
681
695
  session.queryInstance = null;
682
696
  session.messageQueue = null;
683
697
  session.abortController = null;
698
+ session.taskStopRequested = false;
684
699
  session.pendingPermissions = {};
685
700
  session.pendingAskUser = {};
686
701
  }
@@ -1007,11 +1022,17 @@ function createSDKBridge(opts) {
1007
1022
  async function stopTask(taskId) {
1008
1023
  var session = sm.getActiveSession();
1009
1024
  if (!session || !session.queryInstance) return;
1025
+ session.taskStopRequested = true;
1010
1026
  try {
1011
1027
  await session.queryInstance.stopTask(taskId);
1012
1028
  } catch (e) {
1013
1029
  console.error("[sdk-bridge] stopTask error:", e.message);
1014
1030
  }
1031
+ // SDK stopTask doesn't reliably stop the sub-agent, so abort the entire
1032
+ // session as a fallback to ensure the process actually stops.
1033
+ if (session.abortController) {
1034
+ session.abortController.abort();
1035
+ }
1015
1036
  }
1016
1037
 
1017
1038
  return {
package/lib/server.js CHANGED
@@ -390,7 +390,7 @@ function createServer(opts) {
390
390
  var securityHeaders = {
391
391
  "X-Content-Type-Options": "nosniff",
392
392
  "X-Frame-Options": "DENY",
393
- "Content-Security-Policy": "default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://esm.sh; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://cdn.jsdelivr.net; img-src 'self' data: blob: https://cdn.jsdelivr.net https://api.dicebear.com; connect-src 'self' ws: wss: https://cdn.jsdelivr.net https://esm.sh; font-src 'self' data: https://fonts.gstatic.com https://cdn.jsdelivr.net;",
393
+ "Content-Security-Policy": "default-src 'self'; script-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://esm.sh; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://cdn.jsdelivr.net; img-src * data: blob:; connect-src 'self' ws: wss: https://cdn.jsdelivr.net https://esm.sh https://api.dicebear.com https://api.open-meteo.com; font-src 'self' data: https://fonts.gstatic.com https://cdn.jsdelivr.net;",
394
394
  };
395
395
  if (tlsOptions) {
396
396
  securityHeaders["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clay-server",
3
- "version": "2.9.3-beta.2",
3
+ "version": "2.9.3-beta.4",
4
4
  "description": "Web UI for Claude Code. Any device. Push notifications.",
5
5
  "bin": {
6
6
  "clay-server": "./bin/cli.js",