Metadata-Version: 2.4
Name: axiometa-cli
Version: 1.0.1
Summary: Prompt to hardware, in your terminal: detect a board, chat to build, deploy, watch serial.
Author-email: Axiometa <dr.dumcius@gmail.com>
Project-URL: Homepage, https://axiometa.io
Project-URL: Studio, https://studio.axiometa.io
Keywords: hardware,ai,esp32,rp2040,raspberry-pi,arduino,micropython,iot,cli,maker
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: System :: Hardware
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: pyserial>=3.5
Provides-Extra: micropython
Requires-Dist: mpremote>=1.20; extra == "micropython"

# axiometa-cli

Prompt → hardware, in your terminal. The CLI is a thin client of the same backend Studio's browser
talks to: **codegen stays in the cloud** (Claude + the catalog + your auth/limits), and only the
**local half** — provision the toolchain, deploy, read the serial channel — runs on the machine the
board is plugged into. Same brain as Studio; the terminal (or a Pi) is the body instead of the browser.

It is one experience whether the board speaks Arduino or MicroPython — the board's facts decide the
deploy verb (`deploy` = compile+flash on Arduino; `run`/`install` on MicroPython).

## Install

**Raspberry Pi / Linux / macOS** (from a checkout):
```
./cli/install.sh
axiometa provision        # one-time: arduino-cli + ESP32 core + libs (+ mpremote)
axiometa                  # detect a board and start building
```

**Windows / any OS** (pip):
```
pip install -e cli
axiometa provision
axiometa
```

Config (env, all optional):
```
AXIOMETA_BACKEND=https://studio.axiometa.io   # or your local backend
AXIOMETA_TOKEN=...                            # your auth (carried to the backend)
AXIOMETA_KNOWLEDGE=/path/to/backend/knowledge/boards   # auto-found next to a repo checkout
```

## The experience (`axiometa`)

Typing `axiometa` with no verb runs the guided loop:

1. **Detect** — lists connected boards, naming the silicon from its USB identity (ESP32-S3 vs RP2040).
2. **Target** — confirms the board + language, picks the port, writes `axiometa.json`.
3. **Toolchain** — if `arduino-cli`/`mpremote` is missing, offers `axiometa provision`.
4. **Chat** — describe what to build; Axie streams its reply, shows what it's reading, and writes the
   project files. Refine in follow-ups ("make it blink faster").
5. **Deploy** — when the device program is (re)generated, offers to flash it (Arduino) or
   run/install it (MicroPython), streaming the toolchain output.
6. **Monitor** — after a successful deploy, streams the serial channel so you see the device talk.

Mid-chat commands: `/flash` `/deploy` `/run` `/install` `/monitor` `/serve` `/board` `/help` `/exit`.

## Verbs (scripting / power use)

```
axiometa provision               # install the local toolchain (one-time)
axiometa devices                 # list connected boards (with USB identity)
axiometa board pi-hat            # set the target (writes axiometa.json)
axiometa prompt "blink the RGB LED on port 1 red"   # one-shot: generate + write files
axiometa flash --firmware mp.uf2 # RP2040 over SWD: lay MicroPython on the chip (Pi HAT)
axiometa run                     # MicroPython: test in RAM (ephemeral)
axiometa install                 # MicroPython: persist to flash
axiometa deploy                  # Arduino: compile + flash
axiometa monitor                 # stream serial to the terminal
axiometa serve                   # serve browser/*.html on 127.0.0.1 (ssh -L hint when headless)
```

## The Pi HAT (RP2040 flashed over SWD, talked-to over UART)

The Pi HAT's RP2040 has **no USB** — the Raspberry Pi is both its programmer and its host, over the
40-pin header. So the Pi HAT path differs from a USB board, and the CLI handles it:

- **`axiometa flash --firmware <mp.uf2>`** lays MicroPython onto the chip over **SWD** (OpenOCD
  bit-banging Pi GPIO24=SWDIO / GPIO25=SWCLK / GPIO23=RUN). A `.uf2` is auto-converted to the `.bin`
  OpenOCD needs; `.elf`/`.bin` also work. This is one-time, and the brick-recovery path.
- **`run` / `install` / `monitor`** talk over the Pi's UART at **`/dev/serial0`** (RP2040 GP0/GP1 ↔
  Pi GPIO15/14), not USB. The CLI ships `board_pins.py` + `boot.py` with each deploy; `boot.py` puts
  the REPL on UART0 so `mpremote` can reach the board over `/dev/serial0`.

One-time Pi setup (handled by `axiometa provision`, or do it yourself):
```
sudo apt install openocd                 # SWD flashing
sudo raspi-config  -> Serial Port:  login shell over serial = NO, serial hardware = YES   # frees /dev/serial0
sudo -E axiometa flash --firmware mp.uf2 # SWD needs GPIO/root; -E keeps your env
```
Notes: the flashed firmware must expose the **UART REPL** (freeze `boot.py` into the build, or use a
UART-REPL MicroPython) for first contact. `bcm2835gpio` (the default OpenOCD driver) is Pi 0-4 only;
on a **Pi 5** set `AXIOMETA_OPENOCD_DRIVER=linuxgpiod`. Override the whole OpenOCD interface with
`AXIOMETA_OPENOCD_CFG=/path/to.cfg` if your wiring differs.

## Where things live

A **project is a folder** with an `axiometa.json` manifest (board + substrate + modules), the device
program (`sketch.ino` / `main.py`), any `browser/*.html` surfaces, and `board_pins.py`. `cd` into a
folder and run `axiometa` — it is project-rooted, like `git`.

## Headless vs. desktop

The CLI detects where a visual surface can render and tells the backend (the `capability_profile`):
on a Pi with a display it serves the surface to a local browser; headless-over-SSH it prints an
`ssh -L` line to open it from your own machine; a bare terminal degrades a surface to a serial view.

## Status

The agentic loop is board-agnostic and built: detect → chat (SSE codegen) → flash/deploy → monitor,
plus a cross-platform `provision`. The Pi HAT's **SWD flash (OpenOCD)** and **UART (`/dev/serial0`)**
deploy/monitor path is wired and unit-tested (uf2→bin, config generation, dispatch) but **not yet
validated on real hardware** — exercise it on a connected Pi + RP2040. The one external dependency is
a MicroPython firmware that exposes the UART REPL.

The native **host-linux** runtime (the "whole Pi" brain: code using the host's own camera/files/GPIO)
is **not** wired here — it is approval-gated and waits on the trust model in
`backend/knowledge/runtimes/host-linux/contract.md`.
