Bodega

Skills › Tecnología

m5-onboard

End-to-end onboarding for a freshly-plugged-in M5Stack ESP32 device (Cardputer, Cardputer-Adv, Core, CoreS3, Stick) — detect on USB, flash UIFlow 2.0 firmware, and install the Claude Buddy MicroPython app bundle. Use whenever the user plugs in or wants to flash/provision/reset an M5Stack or ESP32 board, or says "m5-onboard go".

Descargar .zipVer en GitHub
Departamento
Tecnología
Fuente
Oficial · anthropics/claude-plugins-official › cwc-makers
Autor
Anthropic
Licencia
Apache-2.0
Idioma
Inglés
Riesgo
Medio

Señales de riesgo

Cómo instalarla en Claude

  1. Descargue el .zip sin descomprimirlo.
  2. En Claude active Configuración › Capacidades › Crear y editar archivos.
  3. Vaya a Personalizar › Skills › Crear skill › Subir una skill y elija el archivo.

Instrucciones completas (SKILL.md)

M5Stack Onboarding

This skill automates the full cold-start workflow for an M5Stack ESP32 device: detect on USB, identify model, flash UIFlow 2.0, and push a MicroPython app bundle onto /flash/ so the device boots into user software. The apps we ship (Claude Buddy, Snake, Hello) talk over BLE or USB. The workflow runs on macOS, Linux, and Windows; the skill was developed against an M5Stack Basic v2.6 (CH9102 bridge, ESP32-D0WDQ6-V3, 16 MB flash) and generalized to cover the rest of the Core family, with the Cardputer-Adv (ESP32-S3, native USB) as the current default target.

Where the scripts live

This skill ships as part of the cwc-makers plugin for reference, but the executable scripts and the buddy/ app bundle live in a local clone of https://github.com/moremas/build-with-claude (the /maker-setup command creates this clone). Run every scripts/*.py invocation below from inside that clone's onboard/ directory so --apps buddy resolves to the sibling buddy/device/ payload.

When to use

Use this when a user plugs in an M5Stack device and wants it provisioned. The decision tree:

If multiple devices are plugged in, ask which port to target — don't guess. If the user is provisioning a device they previously worked with (e.g. "same thing as last time" or "another Buddy"), default to --apps buddy unless they say otherwise.

Which variant to assume

The rig this skill lives on provisions Cardputer-Adv boards overwhelmingly, so onboard.py now defaults to --variant cardputer-adv. In practice that means:

The workflow

The main orchestrator is scripts/onboard.py. It drives the sub-scripts in order and handles the handoffs between them (waiting for reboots, capturing MAC, reporting progress). Prefer calling it directly over stitching the sub-scripts yourself unless the user asks for a partial run.

The default provisioning command (fresh Cardputer-Adv, install the buddy bundle):

python3 scripts/onboard.py --apps buddy

How to invoke this from Claude Code's Bash tool. Do NOT call onboard.py as a foreground Bash command. The Bash tool captures output and does not stream it back to the assistant until the command exits — and this command runs 2–3 minutes. That silence looks identical to a hang, and the assistant will usually give up before the button-dance prompt ever reaches the user. Instead, always run with run_in_background: true, tee to a log file, and then use the Monitor tool (or periodic tail via Read) to surface stage banners, heartbeats, and prompts to the user in real time. 2>&1 is not the fix — all progress already writes to stderr, which a terminal shows fine. The fix is streaming semantics, not redirection. The pattern that works:

# Launch (background, tee log):
python3 scripts/onboard.py --apps buddy 2>&1 | tee /tmp/m5-onboard.log

# Monitor (surfaces key events without drowning in byte-progress spam):
tail -f /tmp/m5-onboard.log | grep -E --line-buffered \
  "^====|heartbeat|Heads up|Enter download mode|download mode!|rebooted into UIFlow|Manual reset|DONE|ERROR|Error|Traceback|FAIL|failed|No USB|not detected|Attempt [0-9]|Device already in download|Download mode port|Post-flash port|Waiting for device"

Relaying physical steps to the user (REQUIRED)

The flash stage cannot proceed without a manual button press on native-USB boards — there is no software path. When the monitored log shows Enter download mode (or the script appears to wait at the FLASH stage), you MUST stop and tell the user to do the following on the back of the Cardputer, in your own words, before continuing:

If the device reboots into UIFlow instead of going dark, tell the user G0 was released too early and to try again holding it longer. Do not move on, retry the script, or attempt a software workaround until the user confirms the screen is dark — the flash will not start otherwise. The same applies to any later Manual reset prompt: relay the physical step and wait for the user.

Users running onboard.py directly in their own terminal (not via Claude Code) will see all output live — no changes needed there.

If --port is omitted, detect.py picks the most likely candidate across all three OSes: native-USB ESP32-S3 (/dev/cu.usbmodem* on macOS, /dev/ttyACM* on Linux, COMx on Windows), or a CH9102/CP210x UART bridge on older boards. Bluetooth-serial ports are filtered out. If multiple candidates are present, it asks.

The known apps name buddy resolves to the buddy/device/ directory in this repo (custom launcher + Hello + Claude Buddy BLE client + Snake). Any other --apps value is treated as a filesystem path.

To skip re-flashing and just push (or refresh) the apps onto an already-provisioned device:

python3 scripts/install_apps.py --port <PORT> --src buddy

Where <PORT> is whatever detect.py printed on the last full run — for example /dev/cu.usbmodem1101, /dev/ttyACM0, or COM3.

Stages

Critical gotchas (baked into the scripts — do not second-guess)

These are things the scripts already handle correctly but which you should not override if the user asks you to "just run esptool manually" or similar:

After provisioning (what the user sees on the device)

Once m5-onboard go finishes at the DONE banner, the device is ready to use on its own:

Files

Dependencies

onboard.py runs a preflight check at startup: if esptool (or, in the rare prune-vendor case, pyserial) is missing, it lists what's needed and asks the user whether to install now. On Y (or Enter) it runs python -m pip install --user <missing> in the current interpreter, then verifies. Inside a venv the --user flag is dropped so the install lands in the venv's site-packages. Non-interactive callers (piped stdin) get a manual-install hint instead of a prompt.

Python itself has to exist before this skill can do anything — you can't bootstrap an interpreter from inside one. git is not required — the /maker-setup command falls back to downloading the GitHub tarball with curl+tar (both pre-installed on macOS, Linux, and Windows 10+) when git --version fails. Claude's responsible for detecting Python and installing it if missing *before* running any scripts/*.py invocation. Detection is just running python3 --version / python --version — if it fails, Claude fetches Python with the host's native package manager before anything else.

Per-OS Python bootstrap (Claude's responsibility if missing):

pyserial — bundled with the skill:

A pinned pyserial 3.5 ships under scripts/vendor/ (BSD-3-Clause, Apache-compatible). Every script that imports serial calls vendor_path.ensure_on_syspath() before the first third-party import, which prepends scripts/vendor/ to sys.path, so the vendored copy resolves regardless of whatever the user has system-wide. Net effect: port enumeration and REPL I/O work on a fresh clone with zero pip step. ~500 KB, pure-Python, same tree on macOS / Linux / Windows.

esptool — pip dependency, auto-installed on first run:

esptool is GPLv2+ and is intentionally not vendored — keeping the repository cleanly Apache-2.0 means the GPL bits live in the user's pip-managed environment, not in the tree. The skill's preflight checks for an importable esptool and, if missing, prompts to install it (python -m pip install --user esptool — --user dropped inside a venv so it lands in site-packages). For subprocess calls we use [sys.executable, "-m", "esptool", ...]; the subprocess inherits user-site so the pip-installed module imports cleanly. requirements.txt declares this for explicit setup; the prompt path is the default for first-time attendees who haven't run pip yet.

Non-interactive callers (piped stdin, CI) skip the prompt and get a python -m pip install --user esptool hint instead.

Fallback if someone prunes scripts/vendor/:

The same preflight path also re-installs pyserial via pip if the vendor copy is gone. This handles the case where someone downloaded a source-only zip that excluded vendor, or manually trimmed the repo to save space.

USB driver — Windows-specific, only for older boards:

The CH9102 USB-UART driver is still a manual install on Windows — WCH doesn't publish a winget manifest. Only needed for UART-bridge boards (Basic, Fire, Core2, StickC). Native-USB ESP32-S3 boards (Cardputer, Cardputer-Adv, CoreS3) enumerate as composite USB-CDC devices using Windows' in-box drivers and need no extra install.

Platform notes

The skill runs on macOS, Linux, and Windows. Non-obvious bits:

  sudo usermod -aG dialout $USER
  # log out / log back in — group change only takes effect for new sessions

sudo python3 scripts/onboard.py ... works as a one-off but adding the group membership is strictly better because pyserial's port-open in user mode succeeds cleanly from then on.

Most installs hit (2). Set M5_BUDDY_DIR only for the unusual case of pointing at a bundle outside this clone: export M5_BUDDY_DIR=/path/to/buddy/device (Unix) or $env:M5_BUDDY_DIR="C:\path\to\buddy\device" (PowerShell).