# JSON events

Every event espx prints with --json, its fields, and the JSON documents the data commands print.

`--json` puts machine-readable output on stdout and nothing else. Progress and warnings stay on stderr, and child processes have their stdout sent to stderr, so stdout parses line by line. Every type here is defined in espx's core and published as one JSON Schema, `schema/espx.json` in the [espx repository](https://github.com/arc1hq/espx), generated from the Rust types.

## Event streams

`build`, `flash`, `run`, `monitor`, `replay` and `devices --watch` print one JSON object per line. Each has an `event` field naming what happened and a `ts` field, host milliseconds since the Unix epoch:

```json
{ "ts": 1789180727730, "event": "line", "text": "Hello world!" }
```

A recording made with `monitor --record` holds the same objects, plus `bytes` events. Fields marked optional are left out when they have no value.

## Monitor events

### line

One line of serial output.

| Field      | Type             | Meaning                                                                               |
| ---------- | ---------------- | ------------------------------------------------------------------------------------- |
| `text`     | string           | The line, without the trailing newline. Plain-text logs keep their ANSI colour codes  |
| `level`    | string, optional | For a decoded defmt line: `trace`, `debug`, `info`, `warn` or `error`                 |
| `module`   | string, optional | For a decoded defmt line: the module path                                             |
| `location` | string, optional | For a decoded defmt line: `file:line`, relative to the project when the file is in it |

### reset

espx reset the board through the serial lines, on opening the port or after a flash. No fields.

### boot

The ROM's reset banner (`rst:0x..`), sent right before the `line` that holds it.

| Field    | Type              | Meaning                                                                                               |
| -------- | ----------------- | ----------------------------------------------------------------------------------------------------- |
| `reason` | string            | `power_on`, `software`, `watchdog`, `brownout`, `panic`, `deep_sleep`, `external`, `usb` or `unknown` |
| `code`   | integer, optional | The ROM's reset code                                                                                  |
| `raw`    | string            | The banner line                                                                                       |

`panic` means a software reset right after a panic or exception in the same session. The reasons are explained in [Monitor and replay](https://www.espx.dev/docs/cli/monitor#names-each-boot).

### panic

An esp-backtrace panic, collected from its banner, message and addresses.

| Field     | Type                       | Meaning                                                       |
| --------- | -------------------------- | ------------------------------------------------------------- |
| `message` | string                     | The panic message                                             |
| `frames`  | array of [frames](#frames) | One per address, and one per inlined function at that address |

### exception

A CPU exception, such as a load from an invalid address or an illegal instruction.

| Field     | Type                       | Meaning                                                                                                     |
| --------- | -------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `kind`    | string                     | The exception as the chip names it                                                                          |
| `address` | integer, optional          | The faulting address, for access faults, misaligned accesses and the load, store, fetch, TLB and PIF causes |
| `frames`  | array of [frames](#frames) | The faulting instruction first, then the backtrace                                                          |

### warning

Something the user should know that did not stop the monitor, such as a missing release binary to decode against, or events dropped because a reader fell behind.

| Field     | Type   | Meaning       |
| --------- | ------ | ------------- |
| `message` | string | What happened |

### detached

The board dropped off USB (deep sleep, a replug).

| Field  | Type   | Meaning            |
| ------ | ------ | ------------------ |
| `path` | string | The port it was on |

### reconnected

The board is back, possibly on another port path. espx follows a board by its USB serial number.

| Field  | Type   | Meaning               |
| ------ | ------ | --------------------- |
| `path` | string | The port it is on now |

### bytes

Raw serial bytes. Only in recordings, never on stdout.

| Field | Type   | Meaning                                  |
| ----- | ------ | ---------------------------------------- |
| `hex` | string | The bytes, two lowercase hex digits each |

## Watch events

These come from `--until`, `--expect`, `--reject` and `--timeout`. A stream ends with `matched`, `rejected`, `timeout` or `done`.

| Event      | Fields                                        | Meaning                                             |
| ---------- | --------------------------------------------- | --------------------------------------------------- |
| `expected` | `pattern` (string), `index` (integer, from 0) | An `--expect` pattern (or `--until`) matched a line |
| `matched`  | `pattern` (string)                            | The last expectation matched; the command exits `0` |
| `rejected` | `pattern` (string)                            | A `--reject` pattern matched; the command exits `1` |
| `timeout`  | `after_ms` (integer)                          | The timeout ran out; the command exits `124`        |
| `done`     | none                                          | The stream ended, or `build` or `flash` finished    |

## Build events

### diagnostic

One compiler message from cargo.

| Field      | Type            | Meaning                                                             |
| ---------- | --------------- | ------------------------------------------------------------------- |
| `level`    | string          | As cargo spells it: `error`, `warning`, `note`, `failure-note`, ... |
| `code`     | string or null  | The error code, such as `E0308`                                     |
| `message`  | string          | The message                                                         |
| `file`     | string or null  | The primary span's file                                             |
| `line`     | integer or null | Its line                                                            |
| `column`   | integer or null | Its column                                                          |
| `rendered` | string or null  | cargo's rendered text, exactly what cargo would print               |

### size

The built image, after a successful build.

| Field           | Type            | Meaning                                       |
| --------------- | --------------- | --------------------------------------------- |
| `flash`         | integer         | Bytes of the image that go to flash           |
| `ram`           | integer         | Bytes of static RAM, not counting the stack   |
| `app_partition` | integer or null | Bytes in the app partition the image must fit |

## Flash events

| Event      | Fields                                                     | Meaning                                                                                                                                       |
| ---------- | ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `flashing` | `percent` (integer 0 to 100), `offset` (integer, optional) | Flash progress. With `offset`, the progress of the region written at that address. Without it, the start (0) and end (100) of the whole flash |
| `flashed`  | `bytes` (integer), `ms` (integer)                          | The flash finished: the image size (0 when espflash did not report it) and how long the write took                                            |

`run` and `flash --monitor` emit `flashing`, `flashed`, then `reconnected` once the board is back, then `reset` and the boot log. Plain `flash --json` emits the per-region `flashing` events and ends with `done`.

## Device events

`devices --watch --json` prints these:

| Event      | Fields                   | Meaning                |
| ---------- | ------------------------ | ---------------------- |
| `attached` | `port` (a [port](#port)) | A board was plugged in |
| `detached` | `path` (string)          | A board was unplugged  |

## Shared types

### frames

| Field      | Type            | Meaning                                           |
| ---------- | --------------- | ------------------------------------------------- |
| `address`  | integer         | The code address                                  |
| `function` | string or null  | The function, when the release binary resolves it |
| `file`     | string or null  | The source file; relative when inside the project |
| `line`     | integer or null | The source line                                   |

### port

| Field         | Type             | Meaning                                                                                                          |
| ------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------- |
| `path`        | string           | The serial port, such as `/dev/cu.usbmodem101`                                                                   |
| `usb`         | object or null   | `vid` and `pid` (integers), and `serial_number`, `manufacturer` and `product` when the device reports them       |
| `description` | string           | Manufacturer and product, or the port type                                                                       |
| `board_id`    | string, optional | The board model id from `espx boards`, only when the USB ids identify exactly one model                          |
| `warning`     | object, optional | A likely driver problem: `problem` (`system_driver`), `message`, and `driver` (the URL of the driver to install) |

A board's id, which `espx.toml`, names and agent policies use, is `usb.serial_number` when present, else `path`.

## Data documents

These commands print one pretty-printed JSON document with `--json`:

| Command           | Document                                                                                                                                                                                   |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `devices`         | Array of [ports](#port)                                                                                                                                                                    |
| `devices --probe` | Array of devices: `port`, `board` (the `info` document or null), `error` (string or null), `lease` (`board` and `holder` while another process holds it, or null)                          |
| `info`            | `chip`, and `revision`, `crystal`, `flash_size`, `features`, `mac` as strings or null                                                                                                      |
| `chips`           | Array of chips: `id`, `name`, `arch` (`xtensa` or `riscv`), `rust_target`, `stable` (boolean)                                                                                              |
| `boards`          | Array of board models: `id`, `name`, `chip`, `usb` (array of `vid` and `pid`), `led` (GPIO or null), `led_kind`, `button`, `uart_tx`, `uart_rx`, `link`                                    |
| `board`           | One board model, as in `boards`                                                                                                                                                            |
| `deps`            | Array of `name`, `version`, `source` (string or null)                                                                                                                                      |
| `doctor`          | Array of checks: `name`, `status` (`ok`, `missing` or `outdated`), `detail` (the version for `ok`, `installed` and `latest` for `outdated`), `optional`, `fix` (the command that fixes it) |
| `context`         | `project`, `chip`, `board`, `bound`, `locked`, `crates`, `hal_features`, `binary`, `examples`, `attached`                                                                                  |
| `agent`           | `boards` (array of board ids), `flash`, `erase`                                                                                                                                            |
| `log`             | Array of audit entries; see [Agent policy](https://www.espx.dev/docs/agents/policy#the-audit-log)                                                                                          |

In `context`, `project` holds `dir`, `name`, `channel`, `target`, `chip` and `defmt`; `bound` is the `[board] id` from `espx.toml`; `locked` says whether the versions in `crates` come from `Cargo.lock` (true) or from `Cargo.toml`'s requirements; `examples` is the esp-hal examples URL or null.

## Errors

A failing command prints one `error:` line on stderr, as text, even with `--json`. The error codes in the schema's `ErrorCode` type appear in MCP tool results and the audit log; see [Exit codes](https://www.espx.dev/docs/reference/exit-codes#error-codes).
