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

# Nets

> Create and manage nets (test points) on your Lager Box

Nets are the core abstraction in Lager for representing physical test points, signals, or buses on your device under test. Each net maps a friendly name to a specific instrument channel.

## Syntax

```bash theme={null}
lager nets [OPTIONS] [COMMAND]
```

## Global Options

| Option       | Description                 |
| ------------ | --------------------------- |
| `--box TEXT` | Lagerbox name or IP address |
| `--help`     | Show help message and exit  |

## Commands

| Command         | Description                                                                              |
| --------------- | ---------------------------------------------------------------------------------------- |
| (none)          | List all saved nets (default)                                                            |
| `delete`        | Delete a specific net by name and type                                                   |
| `delete-all`    | Delete all saved nets (dangerous)                                                        |
| `rename`        | Rename an existing net                                                                   |
| `add`           | Add a new net                                                                            |
| `add-all`       | Auto-create all available nets from connected instruments                                |
| `add-batch`     | Create multiple nets from a JSON file                                                    |
| `assign`        | Assign a USB-serial cable to an RS-232 instrument the box can't auto-detect              |
| `show`          | Show full details of a saved net, including metadata                                     |
| `describe`      | Set metadata on a saved net (purpose, notes, tags) for agent-assisted testing            |
| `tui`           | Launch interactive Net Manager TUI                                                       |
| `set-script`    | Attach a J-Link script *or* OpenOCD `.cfg`/`.tcl` to a debug net (backend auto-detected) |
| `remove-script` | Remove the debug script (J-Link or OpenOCD) attached to a debug net                      |
| `show-script`   | Display the debug script attached to a debug net                                         |

## Command Reference

### List Nets (Default)

List all saved nets on a Lager Box. This is the default behavior when no subcommand is provided.

```bash theme={null}
lager nets --box my-lager-box
```

**Output Columns:**

| Column       | Description                                                       |
| ------------ | ----------------------------------------------------------------- |
| `Name`       | User-friendly net identifier                                      |
| `Net Type`   | Role/type of net (power-supply, debug, adc, gpio, i2c, spi, etc.) |
| `Instrument` | Physical equipment (Rigol\_DP811, Keithley\_2281S, etc.)          |
| `Channel`    | Specific channel on the instrument                                |
| `Address`    | VISA or USB address of the instrument                             |
| `Script`     | Whether a J-Link script is attached (debug nets only)             |

The `Script` column only appears if any debug net has a J-Link script attached.

**Example Output:**

```
Name        Net Type    Instrument        Channel  Address
================================================================================
supply1     power-supply  Rigol_DP811     1        TCPIP::192.168.1.100::INSTR
battery1    battery       Keithley_2281S  1        TCPIP::192.168.1.101::INSTR
debug1      debug       J-Link            STM32F4  USB::001::002
adc1        adc         LabJack_T7        AIN0     USB::470026574
gpio1       gpio        LabJack_T7        FIO0     USB::470026574
i2c1        i2c         LabJack_T7        0        USB::470026574
spi1        spi         Aardvark          0        USB::2238595116
uart1       uart        Prolific_USB      0        /dev/ttyUSB0
```

### `add`

Create a new net by specifying its name, type, channel, and instrument address.

```bash theme={null}
lager nets add NAME ROLE CHANNEL ADDRESS [OPTIONS]
```

**Arguments:**

* `NAME` - Unique name for the net (e.g., `supply1`, `debug_main`)
* `ROLE` - Type of net: `power-supply`, `battery`, `solar`, `debug`, `adc`, `dac`, `gpio`, `scope`, `eload`, `uart`, `usb`, `camera`, `arm`, `watt-meter`, `thermocouple`, `i2c`, `spi`. The legacy tokens `supply` and `batt` are accepted as input aliases and normalized to `power-supply` / `battery` — saved nets always carry the canonical role.
* `CHANNEL` - Channel identifier (e.g., `1`, `AIN0`, `FIO0`, `STM32F4`, `0`)
* `ADDRESS` - VISA address or device path (e.g., `TCPIP::192.168.1.100::INSTR`)

**Options:**

* `--box TEXT` - Lagerbox name or IP
* `--jlink-script FILE` - J-Link script file for debug nets (stored on box)
* `--sda PIN` / `--scl PIN` - Custom LabJack pins for `i2c` nets
* `--cs PIN` / `--sck PIN` / `--mosi PIN` / `--miso PIN` - Custom LabJack pins for `spi` nets (`--cs` is optional; omit it for 3-pin SPI with manual chip select)

Pin values accept LabJack DIO names (`FIO0`-`FIO7`, `EIO0`-`EIO7`, `CIO0`-`CIO3`, `MIO0`-`MIO2`) or raw DIO numbers (`0`-`22`). When pin options are given, the `CHANNEL` argument is ignored — pass `custom`. If a chosen pin overlaps another saved LabJack net, a warning is printed but the net is still created.

**Examples:**

```bash theme={null}
# Create a power supply net
lager nets add supply1 power-supply 1 TCPIP::192.168.1.100::INSTR --box my-lager-box

# Create a debug net for STM32
lager nets add debug1 debug STM32F407VG USB::001::002 --box my-lager-box

# Create a debug net with J-Link script
lager nets add debug1 debug STM32F407VG USB::001::002 --jlink-script ./my_device.JLinkScript --box my-lager-box

# Create an ADC net on LabJack
lager nets add temp_sensor adc AIN0 USB::470026574 --box my-lager-box

# Create an I2C net on LabJack (default pins: SDA=FIO4, SCL=FIO5)
lager nets add i2c_bus i2c FIO4-FIO5 USB::470026574 --box my-lager-box

# Create an I2C net on LabJack with custom pins
lager nets add i2c_bus i2c custom USB::470026574 --sda EIO0 --scl EIO1 --box my-lager-box

# Create an I2C net on Aardvark
lager nets add i2c_aardvark i2c 0 USB::2238595116 --box my-lager-box

# Create an SPI net on LabJack (default pins: CS=FIO0, SCK=FIO1, MOSI=FIO2, MISO=FIO3)
lager nets add spi_bus spi FIO0-FIO3 USB::470026574 --box my-lager-box

# Create an SPI net on LabJack with custom pins
lager nets add spi_flash spi custom USB::470026574 --cs FIO6 --sck FIO7 --mosi EIO0 --miso EIO1 --box my-lager-box

# Custom-pin SPI without chip select (3-pin SPI, manual CS via gpio)
lager nets add spi_flash spi custom USB::470026574 --sck FIO7 --mosi EIO0 --miso EIO1 --box my-lager-box

# Create an SPI net on Aardvark
lager nets add spi_aardvark spi 0 USB::2238595116 --box my-lager-box

# Create a UART net
lager nets add serial1 uart 0 /dev/ttyUSB0 --box my-lager-box
```

<Note>
  The `--jlink-script` option is only applicable for debug nets. If used with other net types, a warning is printed and the option is ignored.
</Note>

**Validation Rules:**

* Net names must be globally unique across all types
* The (role, instrument, channel, address) tuple must match a connected instrument
* Channel binding follows the per-instrument rules described in [Channel & Role Constraints](#channel--role-constraints) below

### Channel & Role Constraints

Different instrument families bind nets to channels differently. Lager classifies every supported instrument into one of three categories and enforces the rules consistently across `add`, `add-all`, and the TUI.

#### 1. Multi-channel instruments

Instruments with physically independent outputs / inputs. Each channel is its own circuit and can host its own net.

| Instrument                                  | Channels                                           | Notes                              |
| ------------------------------------------- | -------------------------------------------------- | ---------------------------------- |
| `Rigol_DP811` / `DP821` / `DP831` / `DP832` | `1`, `2`, `3`                                      | One `power-supply` net per output  |
| `KEYSIGHT_E36233A`                          | `1`, `2`                                           | Dual-output supply                 |
| `KEYSIGHT_E36313A` / `E36312A`              | `1`, `2`, `3`                                      | Triple-output supply               |
| `LabJack_T7`                                | `AIN0`–`AIN13`, `FIO0`–`FIO7`, `DAC0`–`DAC1`, etc. | One net per pin                    |
| `Aardvark`                                  | `SPI0`, `I2C0`, GPIO pins                          | Mixed-mode multi-channel           |
| `MCC_USB-202`                               | `CH0`–`CH7`, `DIO0`–`DIO7`, `DAC0`–`DAC1`          | One net per channel                |
| `Phidget`                                   | `0`–`3`                                            | One `thermocouple` net per channel |
| `Acroname_8Port` / `4Port`, `YKUSH_Hub`     | Port indices                                       | One `usb` net per port             |

**Rule:** at most one net per `(instrument, address, role, channel)` tuple. Two nets that share `(instrument, address, role)` but differ in `channel` are fine — that's exactly what multi-channel is for.

#### 2. Single-channel, multi-mode instruments

Instruments with one physical channel that can run in one of several **modes** but not multiple modes at once. The role tells the box which firmware mode to flip the chip into.

| Instrument        | Allowed roles                                 | Why exclusive                                                                                |
| ----------------- | --------------------------------------------- | -------------------------------------------------------------------------------------------- |
| `Keithley_2281S`  | `battery` or `power-supply`                   | One channel: battery-simulator firmware OR power-supply firmware                             |
| `EA_PSB_10080_60` | `solar` or `power-supply`                     | One channel: solar-array simulator OR straight supply                                        |
| `EA_PSB_10060_60` | `solar` or `power-supply`                     | Same as above                                                                                |
| `FTDI_FT232H`     | `spi` or `i2c` or `gpio` or `debug` or `uart` | One channel hardware-multiplexed between MPSSE (libftdi) and async-serial (`ftdi_sio`) modes |

**Rule:** at most one net per `(instrument, address)`. Once any role is saved on the chip, every other role disappears from the add list. To switch modes, delete the existing net first.

These chips are tracked in `_SINGLE_CHANNEL_INST` (Keithley, EA) and `_MODE_EXCLUSIVE_INST` (FTDI\_FT232H) in `cli/commands/box/nets.py` and `cli/commands/box/net_tui.py`.

#### 3. Single-role debug probes

Standalone debugger boxes — one probe drives one target MCU.

| Instrument                                                      | Backend             | Role    |
| --------------------------------------------------------------- | ------------------- | ------- |
| `J-Link` / `J-Link_Plus` / `Flasher_ARM` / `J-Link_Flasher_Pro` | J-Link (SEGGER)     | `debug` |
| `STLink_v2` / `v2_1` / `v3` / `v3_Mini` / `v3_2VCP`             | OpenOCD             | `debug` |
| `RP2040_Picoprobe`                                              | OpenOCD (CMSIS-DAP) | `debug` |
| `Atmel_EDBG`                                                    | OpenOCD (CMSIS-DAP) | `debug` |
| `DAPLink`                                                       | OpenOCD (CMSIS-DAP) | `debug` |

**Rule:** at most one `debug` net per `(instrument, address)`.

#### 4. Multi-channel FTDI debug adapters

`FT2232H` (2 channels: A, B) and `FT4232H` (4 channels: A, B, C, D) physically expose multiple USB interfaces. Channels A and B are MPSSE-capable (JTAG/SWD via OpenOCD); channels C and D on the FT4232H are UART-only. The user picks an interface per net via an `@` suffix on the device type.

**Debug nets** encode the channel in the device field:

```bash theme={null}
# Channel A (interface 0) — by far the most common
lager nets add debug_a debug STM32F4x@A USB0::0x0403::0x6010::ABCDEF::INSTR

# Channel B (interface 1) — second target on the same FT2232H
lager nets add debug_b debug NRF52840_XXAA@B USB0::0x0403::0x6010::ABCDEF::INSTR
```

Equivalent forms: `@A`/`@0`, `@B`/`@1`, `@C`/`@2`, `@D`/`@3`. Devices without an `@` suffix default to the interface OpenOCD's interface config picks (typically channel A).

**UART nets** distinguish channels by their tty path. The USB scanner enumerates every `/dev/ttyUSB<N>` bound to the chip's USB serial; each shows up as a separate add-list entry, so on an FT4232H you'll see up to four UART options.

**Rule:** a debug net is unique per `(instrument, address, channel-suffix)`. So a single FT2232H can host:

* one `debug` net on `@A`
* one `debug` net on `@B`
* one `uart` net on a `/dev/ttyUSB<N>` belonging to whichever channels you didn't claim for MPSSE
* one each of `spi` / `i2c` / `gpio` (which all bind to channel A in the OpenOCD interface config — incompatible with `debug@A`)

The user is responsible for not double-booking channel A (e.g. picking `debug@A` *and* `spi`); the box doesn't validate that today.

#### Quick decision table

| You want to add a second net on the same chip                                     | Allowed?                     |
| --------------------------------------------------------------------------------- | ---------------------------- |
| `power-supply` on `Rigol_DP811` CH1 + `power-supply` on Rigol\_DP811 CH2          | Yes                          |
| `battery` on `Keithley_2281S` + `power-supply` on the same Keithley               | **No** — pick one            |
| `solar` on `EA_PSB_10080_60` + `power-supply` on the same EA                      | **No** — pick one            |
| `spi` on `FTDI_FT232H` + `uart` on the same FT232H                                | **No** — pick one            |
| `debug@A` on `FTDI_FT2232H` + `uart` on a different interface of the same FT2232H | Yes                          |
| Two `debug@A` nets on the same `FTDI_FT2232H`                                     | **No** — same channel        |
| Two `debug` nets on the same J-Link                                               | **No** — single-target probe |

### `add-all`

Automatically create nets for all available channels on all connected instruments. This is useful for quickly setting up a new Lager Box.

```bash theme={null}
lager nets add-all [OPTIONS]
```

**Options:**

* `--box TEXT` - Lagerbox name or IP
* `--yes` - Skip confirmation prompt

**Example:**

```bash theme={null}
# Preview what nets would be created
lager nets add-all --box my-lager-box

# Create all nets without prompting
lager nets add-all --box my-lager-box --yes
```

**Output:**

```
Found 8 nets that can be created:
  - supply1 (supply) on Rigol_DP811 channel 1
  - adc1 (adc) on LabJack_T7 channel AIN0
  - adc2 (adc) on LabJack_T7 channel AIN1
  - gpio1 (gpio) on LabJack_T7 channel FIO0
  - i2c1 (i2c) on LabJack_T7 channel 0
  - spi1 (spi) on LabJack_T7 channel 0
  - debug1 (debug) on J-Link channel STM32F4

Create all 8 nets on box <BOX_IP>? [y/N]:
```

### `add-batch`

Create multiple nets from a JSON file for efficient bulk setup.

```bash theme={null}
lager nets add-batch JSON_FILE [OPTIONS]
```

**Arguments:**

* `JSON_FILE` - Path to JSON file containing net definitions

**Options:**

* `--box TEXT` - Lagerbox name or IP

**JSON Format:**

```json theme={null}
[
  {
    "name": "supply1",
    "role": "supply",
    "channel": "1",
    "address": "TCPIP::192.168.1.100::INSTR"
  },
  {
    "name": "i2c_bus",
    "role": "i2c",
    "channel": "0",
    "address": "USB::470026574"
  },
  {
    "name": "spi_bus",
    "role": "spi",
    "channel": "0",
    "address": "USB::2238595116"
  }
]
```

**Example:**

```bash theme={null}
lager nets add-batch nets.json --box my-lager-box
```

### `assign`

Assign a USB-serial cable to a known instrument the box cannot auto-detect.

Some instruments have no USB control port and are reached over RS-232 through
a generic USB-serial adapter — for example, a **Rigol DP711** power supply
behind a Prolific cable. The box sees only the adapter (a `uart` device), not
the instrument behind it. `assign` records "this cable is the DP711's serial
line" on the box. From then on, the scanner reports the instrument itself:
it appears in `lager instruments`, in the TUI, and you can create nets for it
with `lager nets add` like any auto-detected device.

Assign **once per cable**; the assignment is stored on the box and survives
reboots and replugs. Creating nets stays the normal, repeatable step.

```bash theme={null}
lager nets assign --list [OPTIONS]                       # discover
lager nets assign DEVICE --serial|--port [OPTIONS]       # assign
lager nets assign --remove --serial|--port [OPTIONS]     # unassign
```

**Options:**

| Option            | Description                                                                                                                      |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `--list`          | List assignable devices, current assignments, and unassigned USB-serial cables                                                   |
| `--serial TEXT`   | USB serial number of the cable (durable; the assignment follows the cable across ports)                                          |
| `--port TEXT`     | USB port path (sysfs name, e.g. `1-1.2`); pins the assignment to a physical box port — for cables without a usable serial number |
| `--baud INTEGER`  | Baud-rate override; must match the instrument's front-panel setting (DP711 factory default: 9600)                                |
| `--remove`        | Remove the assignment matching `--serial`/`--port`                                                                               |
| `--as-net [NAME]` | Also create a net for the instrument right away (name defaults to the device name)                                               |
| `--box TEXT`      | Lagerbox name or IP                                                                                                              |

**End-to-end example (Rigol DP711):**

```bash theme={null}
# 1. Plug the instrument's USB-serial cable into the box, then find it:
lager nets assign --list --box my-lager-box
#   Unassigned USB-serial cables:
#     serial 00000006  port 1-1.2  [067b:23a3]  /dev/ttyUSB0

# 2. Assign the cable — and create a supply net in the same step:
lager nets assign Rigol_DP711 --serial 00000006 --as-net main_supply --box my-lager-box

# 3. Drive it like any other supply net:
lager supply main_supply --voltage 3.3 --box my-lager-box
```

Without `--as-net`, the command prints the exact `lager nets add` invocation
for the new instrument:

```bash theme={null}
lager nets add <name> power-supply 1 'serial://067b:23a3/serial/00000006'
```

**How it works:**

* The cable **must be plugged in** to assign it — its USB identity (vendor/product
  ID) is captured from the live device.
* Nets for assigned instruments use a durable `serial://<vid>:<pid>/serial/<s>`
  (or `.../port/<p>`) address instead of a `/dev/ttyUSB*` path, so they survive
  tty renumbering, reboots, and port moves.
* While a cable is assigned, it is **no longer offered as a generic UART
  device** — the serial line belongs to the instrument.

<Note>
  Some cheap USB-serial clones share one serial number (or have none). If
  `assign` reports multiple matching cables, pin the assignment to a physical
  box port with `--port` instead — the trade-off is that moving the cable to a
  different port breaks the assignment.
</Note>

**Removing an assignment:**

```bash theme={null}
lager nets assign --remove --serial 00000006 --box my-lager-box
```

The cable is offered as a generic UART device again. **Nets live and die with
their assignment**: any saved nets bound to the assignment's `serial://`
address are deleted automatically and reported in the output. The same cascade
applies when re-assigning a cable to a different instrument (or switching its
identity from `--serial` to `--port`) — only a baud-only re-assign keeps the
existing nets.

**Currently assignable devices:** Rigol DP711 (single-channel RS-232 power
supply). Run `lager nets assign --list` to see the catalog your box supports.

### `delete`

Delete a specific net by its name and type.

```bash theme={null}
lager nets delete NAME NET_TYPE [OPTIONS]
```

**Arguments:**

* `NAME` - Name of the net to delete
* `NET_TYPE` - Type of the net (supply, debug, adc, i2c, spi, etc.)

**Options:**

* `--box TEXT` - Lagerbox name or IP
* `--yes` - Skip confirmation prompt

**Example:**

```bash theme={null}
# Delete a supply net (with confirmation)
lager nets delete supply1 supply --box my-lager-box

# Delete without confirmation
lager nets delete temp_sensor adc --box my-lager-box --yes

# Delete an I2C net
lager nets delete i2c_bus i2c --box my-lager-box --yes
```

### `delete-all`

Delete all saved nets on a Lager Box. **This is a dangerous operation.**

```bash theme={null}
lager nets delete-all [OPTIONS]
```

**Options:**

* `--box TEXT` - Lagerbox name or IP
* `--yes` - Skip confirmation prompt

**Example:**

```bash theme={null}
# Delete all nets (requires confirmation)
lager nets delete-all --box my-lager-box

# Delete all nets without prompting
lager nets delete-all --box my-lager-box --yes
```

### `rename`

Rename an existing net.

```bash theme={null}
lager nets rename NAME NEW_NAME [OPTIONS]
```

**Arguments:**

* `NAME` - Current name of the net
* `NEW_NAME` - New name for the net (must be unique)

**Options:**

* `--box TEXT` - Lagerbox name or IP

**Example:**

```bash theme={null}
lager nets rename supply1 main_power --box my-lager-box
```

### `tui`

Launch an interactive terminal-based UI for managing nets. The TUI provides a visual interface for viewing, creating, and deleting nets.

```bash theme={null}
lager nets tui [OPTIONS]
```

**Options:**

* `--box TEXT` - Lagerbox name or IP

**Example:**

```bash theme={null}
lager nets tui --box my-lager-box
```

**TUI Features:**

* Browse all connected instruments and their channels
* Create new nets with guided prompts
* Pick custom LabJack pins when adding i2c/spi nets — a pin dialog opens with
  the defaults preselected (I2C: SDA=FIO4/SCL=FIO5; SPI: CS=FIO0/SCK=FIO1/
  MOSI=FIO2/MISO=FIO3); any DIO pin can be chosen per signal, CS can be set to
  none for 3-pin SPI, and pins already used by saved nets show a warning
* Assign custom serial devices (RS-232 instruments) to their USB cables — the
  interactive twin of [`assign`](#assign), including the optional
  create-the-net step (`--as-net`)
* Delete existing nets
* View net details and instrument information
* Keyboard navigation

### `set-script`

Attach a debug script — either a JLinkScript or an OpenOCD `.cfg`/`.tcl` — to an existing debug net. The file is stored on the box and used automatically during connect, flash, erase, and reset operations.

The backend (J-Link vs. OpenOCD) is auto-detected from two signals:

1. **The probe's USB VID** on the net's `address` field (J-Link → `jlink`; ST-Link, FTDI, CMSIS-DAP, etc. → `openocd`).
2. **The file** — extension first (`.JLinkScript` → jlink; `.cfg`/`.tcl`/`.ocd` → openocd), with a content sniff as a tie-breaker for extensionless files or stdin.

If the two signals disagree, `set-script` refuses with a clear error and asks you to pick one via `--backend`.

A debug net only carries **one** script at a time. If the other field is already set, `set-script` clears it and prints a yellow notice on stderr so nothing disappears silently.

```bash theme={null}
lager nets set-script NAME SCRIPT_PATH [OPTIONS]
```

**Arguments:**

* `NAME` - Name of the debug net
* `SCRIPT_PATH` - Path to the script file, or `-` to read from stdin

**Options:**

* `--backend [jlink|openocd]` - Force a specific backend instead of auto-detecting (required if the probe and file disagree)
* `--box TEXT` - Lagerbox name or IP

**Example:**

```bash theme={null}
# Attach a J-Link script to a J-Link net (auto-detected)
lager nets set-script debug1 ./custom_connect.JLinkScript --box my-lager-box

# Attach an OpenOCD config to an FTDI/ST-Link/CMSIS-DAP net (auto-detected)
lager nets set-script debug1 ./probe.cfg --box my-lager-box

# Read the script from stdin
cat probe.cfg | lager nets set-script debug1 - --box my-lager-box

# Force a specific backend when the file or probe is ambiguous
lager nets set-script debug1 ./generic_script --backend openocd --box my-lager-box
```

### `remove-script`

Remove the debug script (J-Link or OpenOCD) attached to a debug net.

```bash theme={null}
lager nets remove-script NAME [OPTIONS]
```

**Arguments:**

* `NAME` - Name of the debug net

**Options:**

* `--backend [jlink|openocd]` - Only remove the named backend's script (default: remove whichever is set)
* `--box TEXT` - Lagerbox name or IP

**Example:**

```bash theme={null}
# Remove whichever script is attached
lager nets remove-script debug1 --box my-lager-box

# Only remove the J-Link script (leave any OpenOCD config in place)
lager nets remove-script debug1 --backend jlink --box my-lager-box
```

### `show-script`

Display the contents of the debug script attached to a debug net. The script content is written to stdout (so `> out.cfg` works); a one-line summary like `# OpenOCD config, 1247 bytes` is written to stderr so interactive use tells you which backend's script you're looking at without polluting redirects.

```bash theme={null}
lager nets show-script NAME [OPTIONS]
```

**Arguments:**

* `NAME` - Name of the debug net

**Options:**

* `--backend [jlink|openocd]` - Only show the named backend's script (default: show whichever is set)
* `--box TEXT` - Lagerbox name or IP

**Example:**

```bash theme={null}
# Display the attached script (J-Link or OpenOCD)
lager nets show-script debug1 --box my-lager-box

# Save to a local file (the stderr banner doesn't end up in the file)
lager nets show-script debug1 --box my-lager-box > script.txt
```

### `show`

Display all fields of a saved net, including user-provided metadata (`purpose`,
`notes`, `tags`) set with `describe`.

```bash theme={null}
lager nets show NAME [OPTIONS]
```

**Arguments:**

* `NAME` - Name of the net

**Options:**

* `--json` - Output as raw JSON
* `--box TEXT` - Lagerbox name or IP

**Example:**

```bash theme={null}
lager nets show battery1 --box my-lager-box
lager nets show battery1 --json --box my-lager-box
```

### `describe`

Set metadata on a saved net so AI agents (and humans) understand what the net does
on the DUT. Introduced in **lager 0.24.0**; the fields feed agent-assisted testing
via the [MCP server](/source/reference/mcp/overview). At least one of `--purpose`,
`--notes`, or `--tag` (or `--clear-tags`) must be provided.

```bash theme={null}
lager nets describe NAME [OPTIONS]
```

**Arguments:**

* `NAME` - Name of the net

**Options:**

* `-p`, `--purpose TEXT` - One sentence: what this net does on the DUT
* `-n`, `--notes TEXT` - Optional notes (gotchas, jumper positions, scope probe points)
* `-t`, `--tag TEXT` - Tag for categorisation/matching (repeatable)
* `--clear-tags` - Remove all existing tags before adding new ones
* `--box TEXT` - Lagerbox name or IP

**Example:**

```bash theme={null}
# Describe a net's purpose and add tags
lager nets describe battery1 \
  --purpose "Main battery rail powering the MCU" \
  --tag power --tag critical \
  --box my-lager-box

# Replace the existing tags
lager nets describe battery1 --clear-tags --tag power --box my-lager-box

# View what was set
lager nets show battery1 --box my-lager-box
```

## Net Types Reference

| Net Type                        | Description         | Typical Instruments                                                                     |
| ------------------------------- | ------------------- | --------------------------------------------------------------------------------------- |
| `power-supply` (alias `supply`) | Power supply output | Rigol DP800, Rigol DP711 (via [`assign`](#assign)), Keithley 2200/2280, Keysight E36200 |
| `battery` (alias `batt`)        | Battery simulator   | Keithley 2281S                                                                          |
| `solar`                         | Solar simulator     | EA PSI/EL series                                                                        |
| `eload`                         | Electronic load     | Rigol DL3021                                                                            |
| `debug`                         | Debug probe         | J-Link, CMSIS-DAP, ST-Link                                                              |
| `adc`                           | Analog input        | LabJack T7                                                                              |
| `dac`                           | Analog output       | LabJack T7                                                                              |
| `gpio`                          | Digital I/O         | LabJack T7, MCC USB-202                                                                 |
| `i2c`                           | I2C bus             | LabJack T7, Aardvark                                                                    |
| `spi`                           | SPI bus             | LabJack T7, Aardvark                                                                    |
| `scope`                         | Oscilloscope        | Rigol MSO5000, PicoScope                                                                |
| `uart`                          | Serial port         | Prolific USB, SiLabs CP210x                                                             |
| `usb`                           | USB port control    | Acroname hub, YKUSH                                                                     |
| `camera`                        | Video capture       | Logitech BRIO                                                                           |
| `arm`                           | Robot arm           | Rotrics Dexarm                                                                          |
| `watt-meter`                    | Power measurement   | Yocto Watt                                                                              |
| `thermocouple`                  | Temperature sensor  | Phidget thermocouples                                                                   |

## Debug Script Workflow

Both J-Link and OpenOCD debug probes can carry a custom script for handling reset sequences, clock initialization, board-specific signal pinning, or other device-specific behavior. Lager stores one script per debug net (either a JLinkScript or an OpenOCD `.cfg`/`.tcl`, never both) and applies it automatically during connect, flash, erase, and reset operations.

```bash theme={null}
# Attach a J-Link script to a J-Link probe (auto-detected from .JLinkScript extension)
lager nets set-script debug1 ./my_device.JLinkScript --box my-lager-box

# Attach an OpenOCD config to an FTDI / ST-Link / CMSIS-DAP probe (auto-detected)
lager nets set-script debug1 ./probe.cfg --box my-lager-box

# Verify what's attached (stderr says which backend, stdout has the content)
lager nets show-script debug1 --box my-lager-box

# Scripts are used automatically for all debug operations:
lager debug debug1 flash --hex firmware.hex --box my-lager-box
lager debug debug1 gdbserver --box my-lager-box

# Remove the script when no longer needed
lager nets remove-script debug1 --box my-lager-box
```

You can also attach a script at net creation time:

```bash theme={null}
lager nets add debug1 debug STM32F407VG USB::001::002 \
  --jlink-script ./my_device.JLinkScript --box my-lager-box

lager nets add debug2 debug d2763 USB::003::004 \
  --openocd-config ./probe.cfg --box my-lager-box
```

You can also configure J-Link scripts per-project in the local `.lager` config file:

```json theme={null}
{
  "DEBUG": {
    "debug1": "./scripts/my_device.JLinkScript"
  }
}
```

When both a net-level script (via `set-script`) and a project-level script (via `.lager` config) exist, the project-level script takes priority.

## Examples

```bash theme={null}
# List all nets
lager nets --box my-lager-box

# Create a new power supply net
lager nets add vdd_main power-supply 1 TCPIP::192.168.1.100::INSTR --box my-lager-box

# Create I2C and SPI bus nets
lager nets add i2c_sensors i2c 0 USB::470026574 --box my-lager-box
lager nets add spi_flash spi 0 USB::2238595116 --box my-lager-box

# Auto-create all available nets
lager nets add-all --box my-lager-box --yes

# Delete a specific net
lager nets delete old_supply supply --box my-lager-box --yes

# Rename a net
lager nets rename supply1 main_power --box my-lager-box

# Launch interactive manager
lager nets tui --box my-lager-box

# Bulk create from JSON file
lager nets add-batch testbed-nets.json --box my-lager-box

# Manage debug-probe scripts (J-Link or OpenOCD, auto-detected)
lager nets set-script debug1 ./custom_init.JLinkScript --box my-lager-box
lager nets set-script debug2 ./probe.cfg --box my-lager-box
lager nets show-script debug1 --box my-lager-box
lager nets remove-script debug1 --box my-lager-box
```

## Notes

* Net names are globally unique regardless of type
* Use `lager instruments --box <lager-box>` to see available instruments and channels
* The TUI provides the easiest way to set up nets for the first time
* Use `add-all` to quickly configure a new Lager Box with sensible defaults
* I2C and SPI nets are supported on LabJack T7 and Aardvark adapters
* Debug scripts (both J-Link and OpenOCD) are base64-encoded for storage and decoded automatically during debug operations
* A debug net carries at most one script (`jlink_script` or `openocd_config`); `set-script` enforces this by clearing the other field when present
