Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ twd-relay is a WebSocket relay that lets AI agents and external tools trigger an

**Browser Client** (`src/browser/`, exported as `twd-relay/browser`) — Runs in the browser. Connects to the relay, listens for commands, dynamically imports `twd-js/runner` to execute tests, and streams results back. Uses native browser `WebSocket` with auto-reconnect. Reads test state from `window.__TWD_STATE__` (set by twd-js). A small `faviconManager` (in `src/browser/faviconManager.ts`) sets a colored favicon + `document.title` prefix based on connection/run state so the active TWD tab is identifiable among multiple tabs to the same origin. A sibling `runMonitor` (in `src/browser/runMonitor.ts`) tracks per-test wall-clock time; on the 3 s heartbeat tick AND at the end of every test, the browser checks whether the test exceeded `maxTestDurationMs` (default 10 s) and, if so, emits a `run:aborted` event so the CLI can exit with a clear error instead of hanging on a throttled tab.

**Vite Plugin** (`src/vite/`, exported as `twd-relay/vite`) — A Vite plugin that hooks into `configureServer` to attach the relay to the dev server's HTTP instance.
**Vite Plugin** (`src/vite/`, exported as `twd-relay/vite`) — A Vite plugin that hooks into `configureServer` to attach the relay to the dev server's HTTP instance, and (in `apply: 'serve'` mode) auto-injects a `<script type="module">` that imports `createBrowserClient` and calls `.connect()` via a virtual module (`virtual:twd-relay/connect`). Auto-injection is on by default; set `autoConnect: false` to opt out and wire `createBrowserClient` manually (required for non-Vite consumers). Both the relay-server path and the injected client path use the same formula (`options.path ?? base + '/__twd/ws'`); `configResolved` sets the `base` for both.

**CLI** (`src/cli/`, bin: `twd-relay`) — Two subcommands: `serve` (default) starts a standalone HTTP server with the relay on port 9876; `run` connects to an existing relay as a client, sends a `run` command, streams test output, and exits with code 0/1 based on results. The `run` subcommand defaults to port 5173 (Vite dev server) and has a 180s timeout. Use `--test "name"` (repeatable) to filter tests by name substring match.

Expand Down
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,9 @@ Change the URL if your relay uses another port or path.

## Vite plugin (optional)

If you use Vite, you can attach the relay to the dev server so the WebSocket is on the same host/port:
If you use Vite, the plugin attaches the relay to the dev server **and** auto-injects the browser client into your `index.html` — so you don't need to call `createBrowserClient` yourself:

```js
```ts
// vite.config.ts
import { twdRemote } from 'twd-relay/vite';

Expand All @@ -126,7 +126,18 @@ export default defineConfig({
});
```

Then in your app you can omit the URL; the client defaults to `ws(s)://<current host>/__twd/ws`.
That's the whole setup. The plugin only runs in dev (`apply: 'serve'`); production builds are untouched.

### Plugin options

| Option | Type | Default | Description |
|---|---|---|---|
| `path` | `string` | `'/__twd/ws'` (relative to Vite `base`) | WebSocket path. Used both by the relay and by the injected client — single source of truth. |
| `autoConnect` | `boolean \| AutoConnectOptions` | `true` | Inject the browser client connect script into `index.html`. Set to `false` to wire `createBrowserClient` manually in your entry file. Pass an object to forward options (`reconnect`, `reconnectInterval`, `log`, `maxTestDurationMs`) into the injected `createBrowserClient` call. |

### Manual usage (non-Vite, or opting out)

`twd-relay/browser` is the supported public API for any setup the Vite plugin doesn't cover (Webpack, Angular, Rollup, esbuild, Rspack), and for advanced Vite users who want to subscribe to client events or coordinate connect timing. See the [Quick start](#quick-start-standalone-relay) section above for the manual snippet. To use the manual snippet **with** the Vite plugin, set `autoConnect: false` so the plugin doesn't also inject one — otherwise two clients connect.

---

Expand Down
Loading
Loading