From a natural-language requirement to code, build, flash, runtime evidence, diagnosis, and repair.
GaryCLI is not just an AI code generator. It is an embedded engineering agent designed to execute as much of the real development loop as the connected toolchain and hardware can verify.
GaryProbe is the companion instrument for the hardware end of that loop. It connects host tools over USB or BLE to target-facing debug and signal operations, so supported actions and measurements can inform the next engineering step.
Quick Start · Why GaryCLI · Execution Loop · GaryProbe · Supported Platforms · Commands · Skills · Contributing
AI coding tools are very good at producing source code. Embedded development has a different definition of “done.” A plausible main.c is only the beginning.
A real embedded task often looks like this:
Requirement
↓
Understand board / chip / pins / peripherals
↓
Generate or modify project files
↓
Compile with the real toolchain
↓
Flash / deploy to the target
↓
Observe serial logs / registers / runtime state
↓
Diagnose failures
↓
Patch → rebuild → reflash → re-check
GaryCLI is built around that loop.
Instead of treating the model as a shell script generator, GaryCLI separates responsibilities:
- The model reasons about intent, failures, tradeoffs, and next actions.
- Tools execute deterministic engineering operations such as compilation, flashing, serial monitoring, register access, project inspection, and deployment.
- Evidence drives the next step whenever the connected environment can provide it.
The goal is simple:
Move from “AI wrote some embedded code” toward “AI completed a verifiable engineering task.”
A typical hardware-connected workflow is:
Natural-language task
│
▼
Project / code generation
│
▼
Compile ───────────────┐
│ success │ failure
▼ │
Flash / deploy └──► Diagnose compiler error ─► Patch
│
▼
Runtime observation
(serial / logs / registers / traceback)
│
├── expected evidence ─► Done
│
└── mismatch / failure ─► Diagnose ─► Patch ─► Rebuild
GaryCLI distinguishes several levels of evidence:
- Code-level — files were generated or modified as intended.
- Build-level — the real compiler/toolchain accepted the project.
- Deployment-level — firmware or files were successfully written to the target.
- Runtime-level — serial output, traceback, register state, or other observable software evidence matches expectations.
- Physical-behavior-level — a real external effect was measured or observed by connected instrumentation, including GaryProbe when the signal and test setup are supported.
A successful compile or flash does not automatically prove that the physical task is correct. Physical verification requires an observable signal, sensor, probe, test fixture, or explicit user confirmation. A measured pin waveform proves what happened at that pin during that test; it does not by itself prove that an LED lit or a motor moved.
GaryCLI plans, builds, deploys, and diagnoses through explicit engineering tools. GaryProbe supplies a target-facing hardware path: a compatible host can request supported operations over USB or BLE and receive device status or captured measurements. This is how board-level observations can become evidence for the next AI-guided action.
- Target execution: SWD target access/flashing and PWM or digital signal output, where supported, depend on the target, device firmware, host software, and wiring.
- Target observation: UART data, ADC voltage/waveform samples, and digital-level observations can help distinguish a running program from its actual electrical output where those functions are available.
- Evidence boundary: a capture supports a specific claim under a specific test setup. Unmeasured physical effects still need a sensor, fixture, or direct observation.
The public gary commands in this repository document the current SWD/UART/REPL workflows. GaryProbe-to-GaryCLI host integration and repeatable, automated physical checks are still in development; the presence of a GaryProbe does not imply that every command, target, or measurement path is available from this repository.
For a first-observation checklist, connection precautions, and evidence limits, see GaryProbe getting started.
gary do "PA0 has an LED. Make a 1 kHz PWM breathing-light demo"
gary do "Read MPU6050 acceleration through I2C and print it over UART"
gary --connect --do "Flash the current project and diagnose why there is no serial output"Typical task classes include:
- GPIO, PWM, ADC, EXTI, UART, I2C, SPI, timers
- OLEDs, sensors, buzzers, displays, encoders, motors
- Project generation and incremental modification
- Cross-compilation and build diagnosis
- Firmware flashing / target deployment
- Serial monitoring and runtime-log analysis
- Register-assisted fault analysis on supported STM32 workflows
- MicroPython deployment and traceback repair on supported boards
GaryCLI can continue after failure instead of stopping at a suggestion:
Build fails
→ read compiler diagnostics
→ locate likely source/configuration issue
→ patch project
→ rebuild
Program boots but device does not respond
→ inspect available runtime evidence
→ check address / init order / pin assumptions / peripheral state
→ patch
→ reflash
→ observe again
The project includes tools and workflows for tasks such as:
- compiler and project inspection
- SWD / UART ISP deployment for supported STM32 targets
- serial-port discovery and monitoring
- register and fault-state inspection where available
- MicroPython raw-REPL synchronization and runtime-log collection
- I2C scanning and peripheral smoke tests
- pin-conflict checks
- PWM parameter calculation
- Flash / RAM analysis
- PID-related analysis tools
- font / bitmap generation
- extensible Skills
GaryCLI requires Python 3.10+.
Linux / macOS / WSL:
curl -fsSL https://www.garycli.com/install.sh | bashWindows PowerShell:
irm https://www.garycli.com/install.ps1 | iexgit clone https://github.com/garycli/garycli.git
cd garycli
python3 setup.py --auto
python3 stm32_agent.py --doctorgary configGaryCLI supports multiple backend styles, including OpenAI-compatible APIs, Anthropic Messages-style interfaces, Gemini integrations, and local/model-provider configurations supported by the repository.
gary doctorThis checks the configured AI endpoint, compiler resources, Python dependencies, serial/debug tooling, and detected hardware where applicable.
gary do "Write a WS2812 rainbow demo for 8 LEDs"gary --connect --do "Blink the LED every 500 ms and verify startup over serial"gary --chip STM32F407VET6 --connect --do "Read ADC voltage and print it over UART"gary
gary --connect
gary --chip STM32F103C8T6Then iterate naturally:
Gary > Build an SSD1306 clock on I2C1.
Gary > The display is blank. Diagnose it using the connected hardware evidence.
Gary > Change the I2C address to 0x3D and try again.
Gary > Add an AHT20 and show temperature on the second line.
GaryCLI tries to preserve project context and make incremental changes rather than regenerate everything unnecessarily.
| Command | Purpose |
|---|---|
gary |
Start interactive mode |
gary do "task" |
Run a one-shot task |
gary --connect --do "task" |
Run a task with hardware connection enabled |
gary --chip <model> |
Select a target chip |
gary --connect |
Start with hardware connection enabled |
gary config |
Configure the AI backend |
gary doctor |
Diagnose the environment |
| Command | Purpose |
|---|---|
/connect [chip] |
Connect a debugger / initialize target context |
/disconnect |
Disconnect hardware |
/serial [port] [baudrate] |
Connect serial monitoring |
/serial list |
List serial ports |
/chip [model] |
Show or switch the target chip |
/flash [bin] |
Deploy the latest or specified artifact |
/probes |
List debug probes |
/status |
Show hardware/runtime status |
/config |
Reconfigure the AI backend |
/projects |
Show project history |
/member [path|reload] |
Inspect or reload project memory |
/language [en|zh] |
Switch CLI language |
/skill list |
List installed Skills |
/skill install <source> |
Install a Skill |
/skill create <name> |
Create a Skill template |
/clear |
Clear conversation history |
/exit / /quit |
Exit |
The public repository currently contains these major workflows:
| Platform | Typical targets | Workflow |
|---|---|---|
| STM32F0 / F1 / F3 / F4 | F030F4, F103C8T6, F303RCT6, F407VET6, F411CEU6 | HAL C generation, GCC build, pyOCD/SWD flashing, UART ISP option, register-assisted debugging |
| RP2040 | RP2040, Pico, Pico W | MicroPython validation, USB serial/raw REPL sync, boot-log and traceback debugging |
| ESP32 family | ESP32, S2, S3, C3, C6 and common boards | MicroPython validation, raw REPL sync, boot-log and traceback debugging |
| ESP8266 family | ESP8266, NodeMCU, D1 Mini, ESP-01 | MicroPython validation, raw REPL sync, boot-log and traceback debugging |
| CanMV K230 family | CanMV K230, K230D | MicroPython validation, /sdcard deployment, file inspection, runtime-log debugging |
Support depth is platform-dependent. A workflow listed here does not imply that every SDK, framework, board revision, debugger, peripheral, or physical verification scenario is supported.
For STM32 closed-loop debugging, the most useful setup is usually SWD + UART:
ST-Link / J-Link STM32
SWDIO ─────────── SWDIO
SWCLK ─────────── SWCLK
GND ─────────── GND
VTref ─────────── 3.3V
USB-UART STM32
TX ──────────→ MCU RX
RX ←────────── MCU TX
GND ─────────── GND
- SWD provides flashing, target control, register access, and fault analysis.
- UART provides runtime logs and application-level evidence.
UART ISP can be used on supported STM32 targets when a debugger is unavailable, but it provides less diagnostic visibility than SWD.
The wiring above describes the current public CLI workflow. GaryProbe is an additional instrument for compatible target setups; its USB/BLE host path and available operations depend on the matching firmware and host integration described above.
Skills extend GaryCLI with additional deterministic tools and instructions.
/skill list
/skill install ~/Downloads/skill.zip
/skill install https://github.com/example/gary-skill.git
/skill create motor_driver "Motor control helpers"
/skill reload
/skill export motor_driverA Skill can contain:
skill.json
├── tools.py # executable tool functions
├── schemas.json # function schemas
├── prompt.md # task-specific instructions
└── requirements.txt # optional dependencies
The design principle is the same as the core project: keep physical/engineering operations in explicit tools and let the model decide when and why to use them.
┌────────────────────────────────────────────────────────────┐
│ GaryCLI │
│ CLI / interactive TUI │
├────────────────────────────────────────────────────────────┤
│ Agent reasoning layer │
│ task planning · diagnosis · tool selection │
├───────────────────────┬────────────────────────────────────┤
│ Project / build layer │ Hardware / runtime layer │
│ code · compiler │ SWD · UART ISP · serial · REPL │
│ workspace · repair │ registers · logs · deployment │
├───────────────────────┴────────────────────────────────────┤
│ Skills │
│ deterministic engineering tools + schemas │
└────────────────────────────────────────────────────────────┘
Repository layout:
garycli/
├── ai/ # AI provider clients and tool registry
├── compiler/ # build/compiler logic
├── core/ # agent runtime, projects, platform state
├── hardware/ # SWD, serial, ISP, MicroPython transport
├── prompts/ # system/platform prompts
├── tui/ # interactive terminal UI and commands
├── skills/ # bundled Skill sources
├── tests/ # automated tests
├── stm32_agent.py # CLI entry point
├── gary_skills.py # Skill manager
├── setup.py # setup and resource bootstrap
└── config.py # runtime paths and defaults
Gary > PA0 is connected to an LED. Make it breathe using PWM.
Gary > Read an AHT20 over I2C1 and print temperature/humidity over UART.
Gary > The firmware flashes successfully but the serial port is silent. Diagnose it.
Gary > Scan the I2C bus and tell me which addresses respond.
Gary > Build a PID motor-speed demo using PWM output and encoder feedback.
Gary > Deploy this MicroPython project to the connected ESP32 and fix any boot traceback.
GaryCLI can execute real commands against connected hardware. Treat generated code and automated actions as engineering output that still requires appropriate review.
Before using it on power electronics, motors, heaters, batteries, actuators, high-current loads, safety-critical equipment, or valuable prototypes:
- set conservative current/voltage/speed limits;
- use independent hardware protection where appropriate;
- verify pin mappings and power domains;
- keep a safe recovery / flashing path;
- do not equate “build succeeded” or “flash succeeded” with physical correctness.
Completed in the public repository:
- STM32F0/F1/F3/F4 base workflow
- SWD flashing and register-assisted debugging
- UART ISP option
- Skill system
- RP2040 / Pico MicroPython workflow
- ESP32 / ESP8266 MicroPython workflow
- CanMV K230 / K230D MicroPython workflow
- Modular AI / compiler / core / hardware / prompt / TUI packages
Directions under continued development:
- broader native-SDK and chip-family coverage
- GaryProbe USB/BLE host integration with GaryCLI tools and repeatable measurement-backed validation
- richer serial / signal visualization
- improved project import and migration workflows
- community Skill discovery and distribution
- IDE / GUI integrations
Issues and pull requests are welcome. Useful contribution areas include:
- reproducible hardware/toolchain bugs;
- new target and board support;
- deterministic engineering tools and Skills;
- compiler/deployment diagnostics;
- tests and CI improvements;
- documentation, examples, and translations.
Please read CONTRIBUTING.md, CODE_OF_CONDUCT.md, and SECURITY.md before contributing.
For security-sensitive reports, follow the security policy instead of opening a public issue.
GaryCLI is released under the Apache-2.0 License.
🗡️ Just Gary Do It.
Website · Issues · Contributing · Changelog