Metadata-Version: 2.5
Name: btview
Version: 0.2.0
Summary: Terminal monitor for BehaviorTree.CPP and Groot2 — live behavior trees without leaving the shell
Project-URL: Homepage, https://github.com/guilyx/btview
Project-URL: Repository, https://github.com/guilyx/btview
Project-URL: Issues, https://github.com/guilyx/btview/issues
Project-URL: Changelog, https://github.com/guilyx/btview/blob/main/CHANGELOG.md
Author: Erwin Lejeune
License:                                  Apache License
                                   Version 2.0, January 2004
                                http://www.apache.org/licenses/
        
           TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
        
           [Full license text: https://www.apache.org/licenses/LICENSE-2.0]
        
           Copyright 2026 Erwin Lejeune and contributors
        
           Licensed under the Apache License, Version 2.0 (the "License");
           you may not use this file except in compliance with the License.
           You may obtain a copy of the License at
        
               http://www.apache.org/licenses/LICENSE-2.0
        
           Unless required by applicable law or agreed to in writing, software
           distributed under the License is distributed on an "AS IS" BASIS,
           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
           See the License for the specific language governing permissions and
           limitations under the License.
License-File: LICENSE
Keywords: behaviortree,behaviortree-cpp,groot,groot2,nav2,robotics,ros2,tui,zmq
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Software Development :: Debuggers
Classifier: Topic :: Terminals
Requires-Python: >=3.9
Requires-Dist: flatbuffers>=2.0
Requires-Dist: msgpack>=1.0
Requires-Dist: pyzmq>=23
Requires-Dist: rich>=13
Requires-Dist: textual>=0.47
Provides-Extra: dev
Requires-Dist: mypy>=1.8; extra == 'dev'
Requires-Dist: pytest-timeout>=2; extra == 'dev'
Requires-Dist: pytest>=7; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Provides-Extra: media
Requires-Dist: imageio-ffmpeg>=0.4; extra == 'media'
Requires-Dist: pillow>=10; extra == 'media'
Requires-Dist: pyte>=0.8; extra == 'media'
Description-Content-Type: text/markdown

<div align="center">

# btview

**Watch your behaviour tree run — in the terminal, over SSH, on the robot.**

A live monitor for [BehaviorTree.CPP](https://github.com/BehaviorTree/BehaviorTree.CPP) and
[Nav2](https://github.com/ros-navigation/navigation2) that needs no GUI, no X11, no ROS
client library — just the ZMQ port your tree already publishes on.

[![CI](https://github.com/guilyx/btview/actions/workflows/ci.yml/badge.svg)](https://github.com/guilyx/btview/actions/workflows/ci.yml)
[![Python](https://img.shields.io/badge/python-3.9%2B-blue)](https://www.python.org/)
[![License](https://img.shields.io/badge/license-Apache--2.0-green)](LICENSE)

![btview demo](media/demo.gif)

**[▶ Watch the 75-second tour](media/btview-promo.mp4)** — install, live monitoring, the
line-based commands, and record/replay.

</div>

---

## Why

Debugging a behaviour tree usually means running Groot2 on a laptop, on the same network,
with a display. Robots are rarely that convenient: you are on a serial console in a lab, or
SSH'd into a machine over a flaky link, or reading a bag from a run that already ended.

`btview` puts the tree where you already are.

```bash
pipx install git+https://github.com/guilyx/btview
btview demo        # a synthetic Nav2 robot, no hardware required
btview             # the real thing, on 127.0.0.1:1667
```

## What it does

- **Live tree view** — every node, its status, and what changed, refreshed as the tree ticks.
- **Two ways to look at it** — an indented list for hunting a node, or a drawn graph
  (<kbd>g</kbd>, or `--graph`) for seeing which branch the robot is down. Per-node
  sparklines make a flapping node obvious at a glance.
- **Both wire protocols** — Groot2 / BehaviorTree.CPP **4.x** (`Groot2Publisher`, what Nav2
  uses) and BehaviorTree.CPP **3.x** (`PublisherZMQ`).
- **Works on a dumb terminal** — `--ascii` drops every box-drawing and unicode glyph;
  `NO_COLOR` is honoured. Fine over a 9600-baud serial console.
- **More than a UI** — `snapshot` for scripts, `echo` for logs and CI, `export` for issues
  and docs, `record`/`play` for after the fact.
- **No ROS dependency** — pure Python over ZMQ. It does not import `rclpy`, and it does not
  care which distro you run.
- **Try before you connect** — `btview demo` runs a synthetic Nav2 tree through the *real*
  protocol stack, so you can learn the tool (and verify your install) with no robot.

## Install

```bash
pipx install git+https://github.com/guilyx/btview     # isolated, recommended
pip install git+https://github.com/guilyx/btview      # into the current environment
```

Python 3.9+ and nothing else — the ZMQ, Rich and Textual wheels come from PyPI. Full
instructions, including ROS 2 workspaces, Docker and robots without internet access, are in
**[docs/install.md](docs/install.md)**.

## Use it

### On a robot running Nav2

Enable monitoring in your BT navigator, then point `btview` at the port:

```yaml
bt_navigator:
  ros__parameters:
    enable_groot_monitoring: true
    groot_server_port: 1667
```

```bash
btview --host 192.168.1.42          # full-screen monitor
btview snapshot --host 192.168.1.42 # one shot, then exit
```

See **[docs/nav2.md](docs/nav2.md)** for BehaviorTree.CPP 3.x, custom stacks, and ports.

### Without a screen

```bash
btview watch --ascii                # redraw in place, ASCII only
btview echo --json | tee bt.jsonl   # one line per status change
btview snapshot --active            # only what is running or failing
```

### Capture now, debug later

```bash
btview record -o run.btv.jsonl --duration 120   # on the robot
btview play run.btv.jsonl --speed 2             # on your laptop, same UI
```

### Get the tree out

```bash
btview export --format mermaid -o tree.mmd   # paste into a GitHub issue
btview export --format dot | dot -Tpng > tree.png
btview show my_tree.xml                      # render a file, no server at all
```

## Commands

| Command | What it is for |
|---|---|
| `btview` / `btview tui` | Full-screen live monitor |
| `btview demo` | Synthetic robot + monitor in one process |
| `btview snapshot` | Print the tree once and exit — scriptable |
| `btview watch` | Refresh in place, no alternate screen |
| `btview echo` | Stream transitions, one line each (`--json`) |
| `btview show FILE` | Render a behaviour tree XML file |
| `btview export` | XML, Graphviz, Mermaid or JSON |
| `btview info` | Endpoint, tree size, round-trip latency |
| `btview blackboard` | Dump blackboard entries (v4 publishers) |
| `btview record` / `btview play` | Capture a session, replay it anywhere |
| `btview mock` | Serve a synthetic tree for another btview or Groot2 |
| `btview bridge` | Read one transport, republish on another |
| `btview transports` | List the transports this build speaks |

Every command takes `--host`, `--port`, `--protocol v4|v3`, or a `--source` URI. Full
reference: **[docs/cli.md](docs/cli.md)**.

### Transports are pluggable

The wire format and the transport are separate, so a live robot, a recording and (soon) a
ROS 2 topic are interchangeable everywhere:

```bash
btview --source replay://run.btv.jsonl?speed=4
btview bridge --from btcpp3://robot:1667 --to groot2://0.0.0.0:1667  # Groot2 can watch a v3 robot
```

Adding a transport is one class and one decorator — **[docs/transports.md](docs/transports.md)**.

## Reading the tree

```
[!] NavigateRecovery [RecoveryNode]                          ▶ RUNNING
├─ [=] NavigateWithReplanning [PipelineSequence]             ▶ RUNNING
│  ├─ -^- RateController                                     ▶ RUNNING
│  │  └─ [!] ComputePathToPose [RecoveryNode]                ✔ SUCCESS
│  │     ├─ --> ComputePathToPose                       · was SUCCESS
│  │     └─ --> ClearGlobalCostmap-Context                      · IDLE
│  └─ [!] FollowPath [RecoveryNode]                          ▶ RUNNING
└─ [o] RecoveryFallback [ReactiveFallback]                      · IDLE
```

Node-type glyphs follow [py_trees](https://github.com/splintered-reality/py_trees)
convention, so they read the same in both ecosystems:

| Glyph | Meaning | | Glyph | Meaning |
|---|---|---|---|---|
| `[-]` | sequence | | `▶` | running |
| `[o]` | fallback | | `✔` | success |
| `[=]` | pipeline sequence | | `✖` | failure |
| `[!]` | recovery | | `⊘` | skipped |
| `-^-` | decorator | | `·` | idle |
| `-->` | action | | `· was X` | idle, ran earlier |
| `(?)` | condition | | | |

## Documentation

| Doc | Contents |
|---|---|
| [docs/install.md](docs/install.md) | Install, first run, ROS 2 and offline robots |
| [docs/cli.md](docs/cli.md) | Every command and flag, with examples |
| [docs/tui.md](docs/tui.md) | Layout, keys, panels |
| [docs/nav2.md](docs/nav2.md) | Connecting to Nav2 and BehaviorTree.CPP |
| [docs/protocol.md](docs/protocol.md) | Groot2 v4 and BTCPP v3 wire formats |
| [docs/transports.md](docs/transports.md) | Source/sink URIs, the bridge, adding a transport |
| [docs/docker.md](docs/docker.md) | Container and compose usage |
| [docs/development.md](docs/development.md) | Tests, lint, the Python API |

## Contributing

Issues and pull requests are welcome — this is a tool for a community that mostly debugs
robots without a monitor attached, so field reports are especially useful. Start with
[docs/development.md](docs/development.md); `pip install -e ".[dev]" && pytest` is the whole
setup, and no robot is needed to run the suite.

## License

Apache-2.0 — see [LICENSE](LICENSE).
