fusible 0.4.0

Electronic linter: a fuse that blows to block firmware code generation
# Fusible

> **The fuse for your firmware.** An electronic linter and tscircuit project manager in Rust:
> it reads the Circuit JSON generated by [tscircuit]https://tscircuit.com, checks the
> electrical and physical rules of the board — and when a rule fails, **the
> fuse blows**: the process exits with an error and firmware code generation
> never happens.

Fusible unifies hardware and firmware into a single monorepo contract using `fusible.yml`,
wrapping tscircuit development servers, viewers, artifact exports, and hardware compilation.

## Project status

| Phase | Scope | Status |
|---|---|---|
| 1 (MVP) | CLI, Circuit JSON parser, rules engine, diagnostics | ✅ shipped |
| 1.1 | `fusible.yml` manifest, tscircuit CLI wrapper (`dev`, `export`, `build`, `init`) | ✅ shipped |
| 2 | `mcu::` — pin-muxing validation against the silicon target | 🔜 |
| 2 | `codegen::` — `pins.rs` generation for Embassy (fuse intact only) | 🔜 |

## Prerequisites

Fusible requires **`tscircuit`** (`tsci` CLI) to compile `.tsx` circuits, run the live dev previewer (`fusible dev`), and export manufacturing deliverables. Install it globally or locally in your workspace:

```sh
# Using bun (recommended):
bun add -g tscircuit

# Or using npm:
npm install -g tscircuit
```

Inspect toolchain health anytime with `fusible doctor` (or run `fusible doctor --install` to automatically provision it).

## Installation

```sh
cargo install fusible
# or build from source:
# cargo install --path .
```

## Quick Start (Monorepo)

Initialize a new hardware + firmware project:

```sh
fusible init --name sensor-node
```

This creates a minimal `fusible.yml`:

```yaml
name: sensor-node

hardware:
  entry: hardware/index.tsx
  out_dir: dist
  port: 3020

mcu:
  chip: stm32g431

firmware:
  path: firmware
  framework: embassy
  pins_rs: firmware/src/pins.rs
  build_cmd: cargo build
```

## Commands

### 1. Electrical Linter (`check`)

```sh
fusible check                     # uses fusible.yml entry
fusible check hardware/index.tsx  # compiles .tsx on the fly and lints
fusible --input circuit.json      # direct Circuit JSON input
```

Clean circuit (exit code 0):

```
✅ Circuit validated (fuse intact)
```

Rule violated (exit code 1):

```
× the fuse blew: 1 electrical violation(s)
× [unconnected_net] net "I2C_SDA" has only 1 connection(s) (minimum 2): it is floating
  help: every net must connect at least two pads/ports — complete the routing in tscircuit
```

### 2. Live Interactive Viewer (`dev` / `view` / `webview`)

Starts the local tscircuit development server with interactive schematic, PCB layout, and 3D preview:

```sh
fusible dev
fusible view --port 3020
```

### 3. Build (`build`)

Evaluates the board, lints the circuit, and compiles firmware only if the fuse is intact:

```sh
fusible build
```

### 4. Fuse-Gated Deliverables (`export`)

Exports fabrication-ready Gerbers, KiCad projects, SVGs, 3D models (STEP/GLB), or documentation.
All exports are **fuse-gated**: electrical rules are verified first. If a rule fails, the fuse blows and no artifacts are produced.

```sh
# Presets:
fusible export --preset fab       # Gerbers (.zip) + Circuit JSON
fusible export --preset cad       # KiCad project (.zip) + 3D STEP (.step)
fusible export --preset docs      # Schematic SVG + PCB SVG + Schematic PDF
fusible export --preset all       # Generates all export bundles

# Specific format exports:
fusible export -f gerbers -o dist/gerbers.zip
fusible export -f pcb-svg
fusible export -f step
fusible export -f kicad_zip

# Bypass verification (for debugging/drafts):
fusible export --preset fab --skip-lint
```

### 5. Hardware Package Management (`add`, `install`, `search`)

Manage tscircuit packages, community footprints, and components without touching npm or tsci directly:

```sh
# Search footprints and components in the tscircuit registry:
fusible search esp32-s3

# Add a community component or registry footprint to hardware/:
fusible add @tsci/seveibar.smd-resistor

# Install all hardware dependencies:
fusible install
```

### 6. Toolchain Diagnostics (`doctor` / `setup`)

Inspects local toolchain health (bun, node, npm, npx, tsci) and verifies tscircuit runner availability:

```sh
fusible doctor
# Automatically provision tscircuit if missing:
fusible doctor --install
```

## Exit codes

The codes are part of the contract, so CI can tell failures apart:

| Code | Meaning |
|---|---|
| `0` | Fuse intact — circuit validated / command succeeded |
| `1` | Electrical violations — the fuse blew, generation is blocked |
| `2` | Tool or usage error (unreadable/malformed input, bad arguments) |

## Architecture

```
src/
├── main.rs                 # read → parse → lint → verdict, exit codes
├── cli.rs                  # clap commands: check, dev, build, export, init
├── commands/               # subcommand implementations
│   ├── check.rs            # electrical linter + on-the-fly .tsx compilation
│   ├── dev.rs              # live viewer wrapper (tsci dev)
│   ├── export.rs           # artifact export wrapper
│   ├── build.rs            # full build pipeline
│   ├── init.rs             # fusible.yml scaffolding
│   └── target.rs           # manifest & convention path resolution
├── config/                 # fusible.yml / fusible.yaml manifest loader
├── tscircuit/              # runner detection (local/global tsci) & process execution
├── parser/                 # Serde Circuit JSON parser
├── linter/                 # Rule trait + fail-closed electrical engine
└── netlist/                # graph representation of circuit connectivity
```

## Development

```sh
mise install        # installs lefthook (conventional commits)
cargo test          # test suite (50+ unit and integration tests)
cargo clippy --all-targets -- -D warnings
filet check .       # code quality (https://github.com/FacileStudio/filet)
```

## License

[MIT](LICENSE)