Skip to main content

Agent-driven IoT device design tool that produces ESPHome YAML.

Project description

wirestudio

Agent-driven IoT device design tool. Describe a goal (or pick parts); get ESPHome YAML, an ASCII wiring diagram, and a BOM that compile under upstream ESPHome.

Produces ESPHome configs but is not affiliated with the ESPHome project — see weirded/fleet-for-esphome for the OTA-deploy companion this studio's Push to fleet flow talks to.

Status

v0.9.0 — first tagged release. The studio has wide surface area (YAML, schematic, enclosure, agent, fleet handoff, web UI) and a narrow set of things actually verified against upstream tools. This section is honest about which is which, ordered by how much it matters that it works.

Tiers, in priority order:

Tier Area What it does Verified by
Verified ESPHome YAML production render design.json → ESPHome YAML esphome config passes on every bundled example, every PR (gate); nightly esphome compile smoke against a representative example (compile)
Verified CSP pin solver + compat checker assign legal pins, surface boot-strap / ADC2-WiFi / voltage / locked-pin issues unit tests + property checks in tests/test_pin_solver.py + tests/test_compatibility.py
Verified Fleet handoff push YAML to fleet-for-esphome ha-addon, optional compile + log relay round-trip tests in tests/test_fleet.py
Works (lighter checks) KiCad schematic emit a SKiDL Python script the user runs locally unit tests assert the script is well-formed Python with expected nets; not verified by opening in KiCad
Works (lighter checks) Parametric enclosure OpenSCAD .scad from board mount-hole metadata unit tests + manual-print iteration; not verified by an OpenSCAD parser in CI
Experimental Thingiverse search relay rank community models for a board smoke-tested; depends on a third-party search API that ranks unevenly
Experimental Agent (Claude tool-using) natural-language design driving works in practice; tool surface is small; no auto-eval against task list yet
Deferred KiCad PCB layout Freerouting + Gerber + JLCPCB CPL/BOM 1.0+, not started

The Verified tier is the bar the project is asking to be judged on. Everything else is offered with the caveat that's spelled out in the table.

See CONTRIBUTING.md for the bar a change has to clear before merging, CHANGELOG.md for per-release deltas, and START.md for the longer-form design notes.

Tested against ESPHome ==2025.12.7 (pinned in .github/workflows/esphome-config.yml + bumped deliberately). When that pin moves, this line moves with it.

What it does

  • Design. Web UI inspector (board, fleet metadata, components, buses, connections, requirements, warnings). Add components by picking a capability (Add by function) — the recommender ranks library matches against use cases. Drag-and-drop pinout for component-to-board pin assignment. Pin locks per role. Bus editor with rename propagation + inline compatibility warnings. USB bootstrap from a plugged-in ESP via WebSerial + esptool-js. Saved designs at designs/<id>.json with a Saved tab + New design dialog.
  • Validate. CSP pin solver assigns every unbound connection with capability-aware fallback (boot strap pins de-prioritised; ADC1 preferred over ADC2 on classic ESP32). Port-compatibility checker flags input-only-as-output errors, boot-strap risks, serial console reuse, voltage limits, ADC2/WiFi conflicts, locked-pin mismatches. Strict mode (header toggle) promotes warn/error compat to render errors as a pre-deploy gate.
  • Generate. Pure functions over design.json + the static library produce ESPHome YAML, ASCII wiring diagrams + BOM, a parametric OpenSCAD enclosure (.scad), and a SKiDL Python script the user runs locally to produce a .kicad_sch. Bundled examples pinned as goldens.
  • Deploy. Push to fleet ships the YAML to a running weirded/fleet-for-esphome ha-addon over Bearer-token HTTP; optional compile: true enqueues an OTA build with live log streaming (Server-Sent Events). Strict mode refuses the push when warn/error compat issues remain.
  • Discover enclosures. Generate a parametric .scad shell from the board's mount-hole + USB-port metadata, or search community models on Thingiverse (THINGIVERSE_API_KEY).
  • Self-host. Single multi-arch Docker image (linux/amd64 + linux/arm64). FastAPI serves API + SPA from one process. Kubernetes manifest, docker-compose recipe, and an nginx production layout in deploy/.

Quickstart

Docker (single-image deployment)

docker run --rm -p 8765:8765 \
  -e ANTHROPIC_API_KEY=sk-ant-... \
  -v wirestudio-data:/data \
  ghcr.io/moellere/wirestudio:v0.9.0

Open http://localhost:8765. The image bundles the FastAPI server + the built web UI in one process; /api/* is the JSON API, / is the SPA. /data holds the agent's session log + saved designs across upgrades.

Available tags:

Tag What it tracks
:v0.9.0 / :0.9.0 / :0.9 / :latest the v0.9.0 release
:main latest commit on main (rolling)
:sha-<short> a specific commit

All four feature-gating env vars are optional — the studio runs without any of them, just with the corresponding feature turned off:

Env var What it gates
ANTHROPIC_API_KEY the agent (/agent/* endpoints + the chat sidebar)
FLEET_URL + FLEET_TOKEN fleet-for-esphome push (/fleet/*)
THINGIVERSE_API_KEY enclosure search (/enclosure/search)

For Kubernetes, see deploy/k8s.yaml. For an nginx-front compose recipe, see deploy/README.md.

CLI

pip install -e .[dev]
python -m wirestudio.generate examples/garage-motion.json

Prints rendered YAML and the ASCII wiring block to stdout. To write to files:

python -m wirestudio.generate examples/garage-motion.json \
    --out-yaml build/garage-motion.yaml \
    --out-ascii build/garage-motion.txt

HTTP API

python -m wirestudio.api                    # localhost:8765
python -m wirestudio.api --reload           # dev mode (auto-reload on edits)

Browse the auto-generated OpenAPI docs at http://127.0.0.1:8765/docs.

To enable the agent endpoints (/agent/turn, /agent/sessions/{id}), export an Anthropic API key before starting the server:

export ANTHROPIC_API_KEY=sk-ant-...
python -m wirestudio.api

Without a key, /agent/status reports available: false and the agent sidebar in the UI shows a friendly notice instead of trying to talk.

To enable the fleet handoff (/fleet/push and the Push to fleet header button), point the API at a running fleet-for-esphome ha-addon:

export FLEET_URL=http://homeassistant.local:8765
export FLEET_TOKEN=$(grep -oP '(?<=token: )\S+' .../addon/secrets.yaml)
python -m wirestudio.api

GET /fleet/status reports available: true when both env vars are set and the addon answers a probe; otherwise the UI surfaces the specific reason (URL missing, unauthorized, unreachable).

MCP server

The studio's design-editing tools are also exposed over the Model Context Protocol at /mcp. Point Claude Code or Claude Desktop at the daemon and the model drives the studio on your Claude subscription — no Anthropic key, no studio-side token spend. See docs/MCP.md for the end-to-end setup.

Web UI (dev)

# In one terminal:
python -m wirestudio.api

# In another:
cd web && npm install && npm run dev

Open http://localhost:5173. Vite proxies /api/* to the studio API, so no CORS plumbing in dev. The same web UI is served at / from the production Docker image; the dev server is only useful when you're editing UI code yourself.

Inspector surfaces:

  • Design pane — board picker, fleet metadata (device_name, tags, secrets refs), requirements, warnings, components list (add / remove with auto-wiring), buses (add / rename / edit pin slots / remove), per-bus + design-level compatibility warnings.
  • Component-instance pane — params (form generated from each library entry's params_schema), connections (per-row editor with rail / gpio / bus / expander_pin / component target kinds), Form ⇄ Pinout view toggle for drag-and-drop pin assignment, 🔓/🔒 per-row pin lock.

Header buttons: New design, Reset, Save, Download JSON, Solve pins, strict (toggle), Connect device (USB bootstrap), Add by function (capability picker), Schematic (KiCad export), Enclosure (parametric .scad + Thingiverse search), Push to fleet.

Useful endpoints:

Method Path What it does
GET /library/boards summaries of every board in the library
GET /library/boards/{id} full board, including pinout
GET /library/components?category=&use_case=&bus= filtered component summaries
GET /library/components/{id} full component, including ESPHome template
GET /library/use_cases distinct capabilities across the library, with counts; powers the Add by function picker
POST /library/recommend rank library components against a free-text or capability query
POST /design/validate parse a design.json, return summary or 422
POST /design/render parse + render a design.json to {yaml, ascii}
POST /design/enclosure/openscad generate a parametric .scad shell for the design's board
POST /design/kicad/schematic generate a SKiDL Python script the user runs locally to produce a .kicad_sch
GET /enclosure/search?library_id=...&query=... search community-uploaded enclosure models (Thingiverse)
GET /enclosure/search/status per-source availability + configure hints
GET /examples list bundled examples
GET /examples/{id} fetch an example as raw design.json
GET /fleet/status check whether FLEET_URL + FLEET_TOKEN reach a fleet-for-esphome ha-addon
POST /fleet/push render design.json and push it as <device_name>.yaml (optionally compile: true)
GET /fleet/jobs/{run_id}/log?offset=N poll the addon's build log for a compile run; returns {log, offset, finished}
GET /fleet/jobs/{run_id}/log/stream Server-Sent Events relay over the same log endpoint; ~300ms cadence, exits with event: done when the build finishes

The HTTP API is a thin layer over the studio's pure-function modules (wirestudio.generate, wirestudio.csp, wirestudio.recommend, wirestudio.fleet, wirestudio.enclosure, wirestudio.kicad). Server state is limited to the agent session log + the saved-design store — both file-backed under /data (via SESSIONS_DIR / DESIGNS_DIR). Permissive CORS for localhost:5173 / localhost:3000 so the dev Vite server can hit it without a proxy.

Examples

Example Board What it is
garage-motion.json ESP32-DevKitC-V4 PIR + BME280 (temp/humidity/pressure) over I2C
awning-control.json WeMos D1 Mini Cover controller — 4 limit switches + buttons via MCP23008 expander, 2 GPIO relays, dual-PWM motor drive
wasserpir.json WeMos D1 Mini Single PIR with a scheduled nightly reboot
oled.json WeMos D1 Mini SSD1306 status display rendering time, date, IP
bluemotion.json WeMos D1 Mini PIR + WS2812B NeoPixel; motion lights the LED
distance-sensor.json NodeMCU v2 HC-SR04 ultrasonic + WS2812B NeoPixel; LED color tracks distance
securitypanel.json WeMos D1 Mini 12 door/window/motion sensors via MCP23017 expander, RTTTL piezo, GPIO siren
rc522.json WeMos D1 Mini MFRC522 RFID reader (SPI), NeoPixel status LED, RTTTL piezo, manual button
esp32-audio.json NodeMCU-32S I2S audio (MAX98357A DAC) + ST7789V SPI dashboard display, Arduino framework
bluesonoff.json ESP-01S 1MB Sonoff Basic relay; front button (boot strap pin) toggles a single GPIO relay
wemosgps.json WeMos D1 Mini UART GPS module — lat/lon/altitude/speed/satellites + runtime baud-rate selector
ttgo-lora32.json TTGO LoRa32 V1 ESP32 + onboard SX1276 LoRa radio + onboard SSD1306 OLED + battery ADC, ESP-IDF
multi-temp.json WeMos D1 Mini Two DS18B20 temp sensors sharing a single 1-wire bus + an RCWL-0516 microwave motion sensor
room-climate.json WeMos D1 Mini BH1750 ambient-light + AHT20 temp/humidity on one I2C bus
desk-climate.json ESP32-C3-DevKitM-1 Sensirion SHT3x precision temp/humidity over I2C
parking-distance.json NodeMCU v2 VL53L0X laser ToF distance (indoor parking-spot indicator)
keypad.json WeMos D1 Mini 8 buttons read through a PCF8574 GPIO expander over I2C
smart-plug.json ESP8285 1MB Athom-style smart plug — relay + button + CSE7766 AC power metering over UART 4800 8E1
smart-plug-v1.json ESP8285 1MB Older Athom v1 / Sonoff POW R1 plug — same topology with the HLW8012 / BL0937 3-pin pulse meter
desk-matrix.json ESP32-DevKitC 8x8 WS2812 matrix driven by the ESP32 RMT peripheral (no bit-banging)
rs485-energy.json ESP32-DevKitC-V4 Eastron SDM230 single-phase energy meter via Modbus RTU (UART2 + MAX485 transceiver, GPIO5 drives DE+RE)
bl0906-mainmeter.json ESP32-DevKitC-V4 BL0906 6-channel CT-clamp energy monitor over UART2 (Athom EM6-style whole-home sub-metering)
nextion-thermostat.json ESP32-DevKitC-V4 Nextion HMI thermostat panel — display on UART2 + SHT3xD temp/humidity on default I2C
tuya-smart-plug.json ESP8285 1MB Tuya-MCU smart plug — relay (DP 1) + power (DP 17) + energy (DP 18) over UART 9600; logger off UART0
weather-station.json ESP32-DevKitC-V4 BMP280 barometer + HTU21D temp/humidity + TSL2561 lux on one shared I2C bus
attic-logger.json WeMos D1 Mini DHT22 single-wire temp/humidity + legacy BMP180 I2C barometer

Generated artifacts for each are pinned as goldens in tests/golden/. For a per-component / per-board view of which library entries are exercised by these examples, see docs/library-coverage.md (regenerate with python scripts/coverage_matrix.py).

Architecture

   design.json  ── single source of truth (JSON-Schema-validated)
        │
        ▼
  ┌─ wirestudio.model         pydantic models mirroring the schema
  ├─ wirestudio.library       loads boards/ + components/ YAML
  ├─ wirestudio.generate      design + library → ESPHome YAML + ASCII
  ├─ wirestudio.csp           pin solver + port-compatibility checker
  ├─ wirestudio.recommend     deterministic capability ranking
  ├─ wirestudio.agent         Claude tool-using agent + session store
  ├─ wirestudio.designs       file-backed designs/<id>.json store
  ├─ wirestudio.fleet         fleet-for-esphome HTTP client
  ├─ wirestudio.enclosure     parametric OpenSCAD + Thingiverse search
  ├─ wirestudio.kicad         SKiDL Python script emitter
  └─ wirestudio.api           FastAPI HTTP layer (mounts everything above)
                          serve.py adds the production wrapper:
                          API at /api/*, web bundle at /

Generators are pure functions of design.json + the static library — no artifact-to-document round-trips. Library files in library/components/ carry the electrical metadata ESPHome doesn't (pin roles, voltage ranges, current draw, decoupling caps, pull-up requirements) plus a Jinja2 template that renders the ESPHome YAML for that component, an enclosure: block the OpenSCAD generator reads, and a kicad: block the schematic exporter reads.

Library

Currently shipped:

Boards (library/boards/)

  • esp32-devkitc-v4 — ESP32 DevKitC V4 (ESP32-WROOM-32, 4MB flash)
  • nodemcu-32s — NodeMCU-32S (ESP32-WROOM-32, marks I2S-capable pins)
  • ttgo-lora32-v1 — LilyGO TTGO LoRa32 V1 (ESP32 + onboard SX1276 + onboard SSD1306)
  • ttgo-t-beam — LilyGO TTGO T-Beam v1.x (ESP32 + onboard SX1276 + NEO-6M GPS + AXP192 PMIC + 18650)
  • esp32-c3-devkitm-1 — ESP32-C3-DevKitM-1 (single-core RISC-V, USB-Serial-JTAG, onboard WS2812)
  • esp32-s3-devkitc-1 — ESP32-S3-DevKitC-1 (dual-core Xtensa, native USB, onboard WS2812)
  • esp32cam-ai-thinker — AI-Thinker ESP32-CAM (ESP32-WROVER-B + OV2640 + microSD)
  • esp32-wrover-cam — ESP32-WROVER-CAM (Freenove-style, OV2640 with the WROVER pinout)
  • m5stack-atom — M5Stack Atom Lite / Echo (ESP32-PICO-D4, 24mm cube, onboard SK6812)
  • m5stack-atoms3 — M5Stack AtomS3 (ESP32-S3 + onboard 0.85" 128×128 ST7789 + IMU)
  • wemos-d1-mini — WeMos D1 Mini (ESP-12F module, ESP8266)
  • nodemcu-v2 — NodeMCU v2 (ESP-12E/F module, ESP8266, breaks out RX/TX/MISO/MOSI as D9-D12)
  • esp01_1m — ESP-01S 1MB module / Sonoff Basic-class devices
  • esp8285-1m — Generic ESP8285 1MB SoC (Athom / Sonoff Basic R3+ / Tuya smart plugs)

Components (library/components/)

Environmental sensors:

  • bme280 — Bosch temperature/humidity/pressure sensor (I2C)
  • bmp180 — Bosch BMP180/BMP085 barometric pressure + temperature (I2C)
  • bmp280 — Bosch temperature/pressure sensor (I2C, no humidity)
  • dht — DHT11 / DHT22 / AM2302 temperature + humidity (single-wire)
  • htu21d — TE Connectivity HTU21D temperature + humidity (I2C; covers Si7021 / SHT2x)
  • sht3xd — Sensirion SHT3x / SHT4x precision temp + humidity (I2C; modern default)
  • aht10 — Aosong AHT10 / AHT20 cheap temp + humidity (I2C; AliExpress weather modules)
  • ds18b20 — Dallas DS18B20 1-Wire temperature sensor (single-pin bus + 4.7kΩ pull-up)
  • bh1750 — BH1750FVI ambient light sensor in lux (I2C; GY-30 / GY-302 modules)

Specialty sensors:

  • max31855 — Maxim K-type thermocouple amplifier (SPI; -270..+1372°C)
  • hx711 — AVIA 24-bit load-cell ADC (custom 2-wire serial)
  • tsl2561 — AMS ambient light sensor (lux, I2C)
  • mpu6050 — InvenSense 6-axis IMU (3-axis accel + 3-axis gyro + die temp, I2C)

Presence / distance:

  • hc-sr04 — ultrasonic distance sensor (4-pin: VCC, GND, TRIGGER, ECHO)
  • hc-sr501 — PIR motion sensor (used as a generic PIR)
  • rcwl-0516 — microwave doppler motion sensor (low-power PIR alternative)
  • ld2420 — Hi-Link LD2420 24GHz mmWave presence sensor (UART)
  • vl53l0x — STMicro VL53L0X laser time-of-flight distance (I2C; indoor up to ~1.2m)

RFID / radios:

  • rc522 — MFRC522 RFID reader (SPI, singleton)
  • rdm6300 — RDM6300 125kHz EM4100 RFID reader (UART, singleton)
  • sx127x — Semtech SX1276/SX1278 LoRa radio (SPI, singleton)
  • cc1101 — TI CC1101 sub-GHz transceiver (SPI, singleton)
  • rf_bridge — Sonoff RF Bridge 433MHz EFM8 module (UART, singleton)

Displays:

  • ssd1306 — 128×64 OLED (I2C)
  • st7789 — Sitronix ST7789V color TFT (SPI write-only)
  • ili9xxx — ILI9341 / ILI9486 / ILI9488 SPI TFT
  • lcd_pcf8574 — HD44780 16x2 / 20x4 LCD via PCF8574 I2C backpack
  • tm1638 — TM1638 8-digit 7-segment + 8 LEDs + 8 buttons combo
  • max7219 — MAX7219 7-segment / 8x8 LED matrix driver (SPI)

Touch / input:

  • xpt2046 — XPT2046 resistive touchscreen controller (SPI)
  • rotary_encoder — Quadrature rotary encoder (KY-040 style)

IO expanders + ADC hubs:

  • mcp23008 — 8-bit I2C GPIO expander (Microchip)
  • mcp23017 — 16-bit I2C GPIO expander (Microchip)
  • pcf8574 — NXP PCF8574 / PCF8575 8-/16-bit I2C GPIO expander (cheap, weak open-drain)
  • ads1115 — TI 4-channel 16-bit ADC (I2C) hub; rescues ESP32 designs from the ADC2/WiFi conflict
  • ads1115_channel — one logical reading on an ADS1115 hub (multiplexer + gain + update_interval per channel)

Generic IO:

  • gpio_input — generic binary_sensor on a GPIO or expander pin (buttons, limit switches, door/window/motion sensors)
  • gpio_output — generic switch on a GPIO or expander pin (relays, indicators)
  • adc — generic analog input (battery monitoring, potentiometers, LDRs)
  • pulse_counter — pulse counter / tachometer (RPM, flow, energy meters)

Light / audio / camera:

  • ws2812b — WS2812B / SK6812 addressable RGB LED (1-wire NeoPixel; bit-banged or ESP8266-DMA)
  • esp32_rmt_led_strip — same WS2812 / SK6812 silicon, ESP32 RMT-driven (preferred on ESP32 / S2 / S3 / C3)
  • apa102 — APA102 / SK9822 addressable RGB strip (DotStar, SPI-style)
  • max98357a — Maxim Class-D mono I2S amp + DAC
  • rtttl — piezo buzzer + RTTTL melody player (PWM output)
  • esp32_camera — ESP32 OV2640 / OV7670 / OV5640 camera

Power metering:

  • cse7766 — Chipsea AC voltage / current / power / energy over UART 4800 8E1 (Athom v2/c3 + Sonoff plugs)
  • hlw8012 — HLW8012 / BL0937 / CSE7759 AC power meter via 3-pin pulse interface (older Athom v1 + Sonoff POW R1)
  • bl0906 — Belling 6-channel AC energy meter over UART 19200 (Athom EM6 / whole-home sub-metering)
  • modbus + sdm_meter — Modbus RTU bus (RS485 via MAX485 transceiver) + Eastron SDM120/220/230/630 single/three-phase DIN-rail meter

Vendor bridges:

  • tuya + tuya_switch + tuya_sensor — Tuya MCU UART bridge plus per-datapoint switch and sensor platforms (smart plugs / switches / climate gadgets that ship with an ESP8266-class radio talking to a separate Tuya MCU)

Displays (HMI):

  • nextion — Nextion HMI smart display over UART 9600 (T/K/P series; .tft uploaded separately via Nextion Editor)

Location:

  • uart_gps — generic UART GPS module (NEO-6M / NEO-8M)

The gpio_input / gpio_output components and the kind: expander_pin connection target together let downstream platforms hang off any expander without bloating esphome_extras. See examples/securitypanel.json for a 12-sensor MCP23017 wiring or examples/awning-control.json for a mix of expander inputs and outputs.

The library now spans the device classes used across the moellere/esphome device configurations (camera boards, mmWave presence, sub-GHz radios, character LCDs, touchscreens, generic ADC and pulse counters, addressable LEDs, RTTTL piezo, RFID variants, and the M5Stack / ESP32-C3 / ESP32-S3 board family). It will keep growing as new device configs land. See START.md § Library sourcing strategy for the hybrid plan.

Layout

schema/                  JSON Schema for design.json (source of truth)
library/boards/          board manifests (pinout, rails, framework, enclosure, kicad)
library/components/      component manifests (electrical + ESPHome + enclosure + kicad)
wirestudio/                  python package — see Architecture above for the module map
web/                     React 19 + Vite + Tailwind v4 SPA
examples/                bundled design.json files (every one pinned by goldens)
tests/                   pytest + golden artifacts; vitest tests under web/src
deploy/                  k8s.yaml, docker-compose.yml, nginx.conf for self-hosting
Dockerfile               multi-stage build for the published GHCR image
.github/workflows/       GHA workflow that publishes ghcr.io/.../wirestudio
scripts/                 dev helpers (currently: examples → `esphome config` gate)
CHANGELOG.md             per-release feature deltas
START.md                 vision, decisions, phase plan
CLAUDE.md                working conventions for both Claude and humans
CONTRIBUTING.md          substantive bar a change has to clear (the YAML gate, etc.)

Tests

python -m pytest                          # ~297 cases, ~10s
python -m ruff check .                    # lint
cd web && npx vitest run                  # ~125 cases, ~5s (vitest + jsdom)
pip install 'esphome==2025.12.7'
python scripts/check_examples.py          # the YAML gate -- every example through `esphome config`
python scripts/check_examples.py --compile garage-motion    # the compile-smoke; slow (~10min cold)

The esphome config gate is the headline test: it renders every bundled example through the studio and runs upstream ESPHome's own validator against the output. Anything the studio emits has to round-trip through that gate, and the GitHub Actions workflow (.github/workflows/esphome-config.yml) runs it on every PR. A nightly compile-smoke (.github/workflows/esphome-compile.yml) goes one level deeper -- it runs esphome compile against a representative example so we catch upstream toolchain / codegen regressions even when no code has changed.

To run the same gate before every push, install the pre-commit hooks once:

pip install pre-commit
pre-commit install --hook-type pre-push

After that, git push runs the gate locally and aborts on failure.

Golden tests pin the generator output for every bundled example. Regenerate goldens with the CLI when output legitimately changes; commit the new files in the same diff as the code change. The web suite covers lib/design.ts plus React components (BusList, ConnectionForm, EnclosureDialog, Inspector, CapabilityPickerDialog, PinoutView, PushToFleetDialog, SchematicDialog) via React Testing Library + jsdom; network surfaces are mocked at the api/client boundary so the suite stays offline.

The GitHub Actions workflow runs the YAML gate + the full suite + multi-arch image build on every PR + merge to main.

Roadmap

Reorganised by priority — what's worth working on next, ordered by how much it raises the floor on whether the studio is actually useful. The previous "ship more surface area" roadmap is preserved in CHANGELOG.md (per-release deltas) and START.md (decisions + phase scope).

Priority 1 — YAML production correctness. Active. The single non-negotiable bar: every artifact the studio emits round-trips through upstream esphome config. Done so far: esphome config CI gate over every bundled example; pinned ESPHome version called out in this README + workflow; CONTRIBUTING.md establishes the gate as the merge bar. Next: real esphome compile smoke for one example; component-coverage matrix (which components have an example that validates) so additions are forced through the gate.

Priority 2 — Wiring schema correctness. Verified-light. SKiDL emitter + 100% library kicad: coverage shipped. Honest gap: the output is unit-tested as Python text, not opened in KiCad. Next: container-side KiCad CLI in CI to actually open + render the generated schematic; pin-solver property tests on randomized designs; compatibility-checker fuzzing.

Priority 3 — Enclosures. Lower priority. Parametric OpenSCAD generator + Thingiverse search relay shipped. Open question: keep investing here, or outsource to e.g. YAPP_Box and integrate instead of reimplementing? Decision deferred until P1 + P2 are tighter.

Priority 4 — PCB layout. Deferred to 1.0+. No work in flight; not adding surface here until P1 is rock solid.

Plumbing — already shipped. API (0.2), web UI (0.3 + 0.6+), USB bootstrap (0.4), agent (0.5 + streaming), CSP solver (0.6), fleet handoff (0.7), enclosure (0.8), KiCad schematic (0.9), Docker single-image deploy + K8s manifest. See CHANGELOG.md for the per-release feature deltas.

Future — multi-writer state backend so the studio can run as a HA replica; agent eval harness against a task list; ESPHome version matrix in CI (last 2 stables) so we can call out which components work where.

Contributing

CONTRIBUTING.md is the substantive bar — what "working" means for the artifacts the studio produces, including the esphome config gate every PR has to clear. CLAUDE.md covers the prose / commit / comment conventions (concise, no emojis, default-to-no-comments, boundary-only validation, no premature abstraction).

License

MIT. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wirestudio-0.10.0.tar.gz (206.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wirestudio-0.10.0-py3-none-any.whl (224.1 kB view details)

Uploaded Python 3

File details

Details for the file wirestudio-0.10.0.tar.gz.

File metadata

  • Download URL: wirestudio-0.10.0.tar.gz
  • Upload date:
  • Size: 206.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for wirestudio-0.10.0.tar.gz
Algorithm Hash digest
SHA256 878aec7a08aa7f7deab84de57e373df9496f65baf1431e8d2f039e4e2b86d1df
MD5 4a2f8bf41340fedfa1fddc66674f2dce
BLAKE2b-256 a458b6f62eabc1868e864fda97f6b83507b149ca82ab516407a739e0e65f8349

See more details on using hashes here.

Provenance

The following attestation bundles were made for wirestudio-0.10.0.tar.gz:

Publisher: release.yml on moellere/WireStudio

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file wirestudio-0.10.0-py3-none-any.whl.

File metadata

  • Download URL: wirestudio-0.10.0-py3-none-any.whl
  • Upload date:
  • Size: 224.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for wirestudio-0.10.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0244447847f6a853df124084ef19aacb44ef9f0a59ad67b193bb5fb75905f1ed
MD5 cf0fb51e773b75d0608ce697bc28d884
BLAKE2b-256 e1f19dfe1c3f75deb3e45de83b5edaaa9147c39d553080d48fea0ec8a05ac76f

See more details on using hashes here.

Provenance

The following attestation bundles were made for wirestudio-0.10.0-py3-none-any.whl:

Publisher: release.yml on moellere/WireStudio

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page