> ## Documentation Index
> Fetch the complete documentation index at: https://radiusbrowser.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Event streams

> Experimentally observe Radius CLI commands and browser workspace changes.

<Warning>
  Event streams are an experimental advanced API intended for automation hooks.
  The event contract may evolve as we learn from real use cases.
</Warning>

## What event streams are

Event streams are read-only notifications emitted by Radius. They let another
process observe CLI commands and browser workspace changes as they happen.
They are not hooks: receiving an event does not run a command, intercept a
change, or give the subscriber control of a tab.

Start the stream and leave it running:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
radius events
```

Radius prints each event as one line of JSON until you interrupt the command.

When you connect, Radius first prints a `workspace.snapshot` for every ready
browser window. It then prints new command and workspace events as they happen:

```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
connect
  → workspace.snapshot for each ready window
  → future live events
```

Radius does not store a historical event log. Reconnecting produces fresh
snapshots followed by events emitted after the new subscription starts.

Filter the stream to one window, one group, or both:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
radius events --window window_1
radius events --group group_development
radius events --window window_1 --group group_development
```

A group-filtered snapshot contains that group, its tabs, its relevant split
layout, and its filtered tab order. If the window or group is not currently
live, Radius returns `WINDOW_NOT_FOUND` or `GROUP_NOT_FOUND`.

## Command lifecycle events

When an automation client sends a command to Radius, the normal lifecycle is:

```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
CLI request
  → command.started
  → Radius executes the command
  → command.finished or command.failed
```

For example, when another process runs `radius tab open ...`:

* `command.started` includes the command that Radius began executing.
* `command.finished` includes the command's returned value, such as a new tab
  ID.
* `command.failed` includes the structured error.
* `requestId` connects the started event to its finished or failed event.
* `timestamp` records when each event was emitted.

For example, a completed tab-open command currently looks like this:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "schemaVersion": 1,
  "event": "command.finished",
  "timestamp": "2026-08-21T20:02:01.000Z",
  "scope": {
    "instanceId": "instance-id",
    "windowId": "window_1",
    "groupIds": ["group_development"],
    "tabIds": ["tab_42"]
  },
  "windowId": "window_1",
  "payload": {
    "command": {
      "resource": "tab",
      "verb": "open",
      "subject": "https://example.com"
    },
    "requestId": "request-123",
    "value": {
      "id": "tab_42"
    }
  }
}
```

These events are emitted for Radius automation commands—not every shell
command. A setup script running `pnpm install` emits nothing. A
`radius tab open ...` command inside that script does emit lifecycle events.

## Workspace events

Radius also emits state notifications:

* `workspace.snapshot` is the current state sent when a subscriber connects.
* `window.ready` means a browser window's automation bridge is available.
* `workspace.changed` means tabs, groups, focus, ordering, or splits changed.

`workspace.changed` can be caused by either a CLI command or an action in the
Radius interface. Its payload is a snapshot of the window's current tabs,
groups, split layout, active tab, and workspace revision.

For a group-filtered subscriber, subsequent `workspace.changed` payloads use
the same group-only shape as the initial snapshot. The event scope can include
both the previous and current group when a tab moves between groups.

## Event shape

Every event uses the same outer envelope:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "schemaVersion": 1,
  "event": "workspace.changed",
  "timestamp": "2026-08-21T20:02:01.000Z",
  "scope": {
    "instanceId": "instance-id",
    "windowId": "window_1",
    "groupIds": ["group_development"],
    "tabIds": ["tab_42"]
  },
  "windowId": "window_1",
  "payload": {
    "workspaceRevision": 93,
    "activeTabId": "tab_42"
  }
}
```

* `schemaVersion` identifies the event envelope contract.
* `event` identifies what happened.
* `timestamp` records when Radius emitted it.
* `scope.instanceId` identifies the Radius instance and is always present.
* `scope.windowId` identifies the browser window when the event is associated
  with one.
* `scope.groupIds` and `scope.tabIds` list the affected resources in stable,
  sorted order.
* The top-level `windowId` mirrors `scope.windowId` for compatibility.
* `payload` contains fields specific to that event type.

Window filters match `scope.windowId`. Group filters match
`scope.groupIds`. Events without a matching window or group are omitted.

JSON Lines keeps each event on one line, so logging tools and long-running
processes can read the stream one event at a time.

## Who should use this

This is an experimental feature intended for automation hooks. Let us know at
[founders@radiusbrowser.com](mailto:founders@radiusbrowser.com) if you have
specific feature requests or use cases for event streams.

<Note>
  Events describe activity that has already occurred. Subscribing does not give
  the subscriber ownership of tabs, intercept or cancel changes, or cause Radius
  to keep enforcing a layout. A hook can react by running a separate Radius CLI
  command.
</Note>
