Things I've built

Croquis logoAI-directed
01

A circuit simulator, running entirely on your own machine.

croquis

A desktop app for building and running Arduino circuits without an Arduino. You drag components onto a canvas, wire them up, write a sketch and press Run. The sketch is compiled locally with avr-gcc and executed on a simulated AVR chip.

Why I built it

I wanted a circuit simulator that was local, offline, free, and polished. That gap didn't exist, so I built one.

What it does

  • 15 preset circuits to start from — Blink, Button, Potentiometer, Photoresistor, Thermometer, Slide potentiometer, RGB LED, Joystick, Digital sensors, Seven segment, Four digit, LED bar, Buzzer & relay, Button + serial and Fade.
  • Parts include the Uno, LEDs including RGB, resistors, pushbuttons, rotary and slide potentiometers, photoresistor, NTC temperature sensor, analog joystick, tilt switch, PIR, flame and sound sensors, a buzzer, relay, 7-segment and 4-digit displays, an LED bar, and half or full breadboards.
  • The canvas does drag, rotate and snap, orthogonal wiring, multi-select, undo/redo and copy/paste. Wokwi diagrams.json imports and exports, sketch included.
  • The editor is CodeMirror with Arduino API completions, and the serial monitor docks beside the circuit.
  • No server, no account, no telemetry, no network calls.

How it works

  1. Your sketch is compiled by avr-gcc into a real AVR program — it is not interpreted.
  2. simavr runs that program instruction by instruction, paced to real time.
  3. When a pin goes high, the netlist works out what is wired to it and how much current will actually flow, so the canvas draws the LED lit — or burnt, if you left the resistor out.
  4. Input travels the other way: holding a button or turning a knob feeds set_input and set_analog back into simavr, with analogue values held as a voltage so analogRead re-reads them every loop.

What it doesn't do yet

  • No servo or LCD yet.
  • A second Uno gets its own circuit but shares the single sketch.
  • The electrical model is deliberately small, not a circuit solver: a resistor does something real and a missing one is reported, but there are no arbitrary parallel networks.
  • Wokwi files open with one caveat — a wire using Wokwi's `*` route separator draws a different path here, though to the same pins.

At a glance

Written in
Tauri, Svelte 5, TypeScript and Rust
Released
v0.1 took about 3 days
License
AGPL v3.0
Install
AppImage, .deb, .rpm, or build from source
Built with
Tauri, Svelte 5, TypeScript, Rust, simavr / avr-gcc
lnetx logo
02

A CLI for all your file transfer troubles.

lnetx

Sends a file from one machine to another on the same network. The receiving side shows the file name, size and hash, and waits for your y before anything gets written.

Why I built it

I used LocalSend for a while, but its UI and discovery were finicky. I wanted something minimal that did the same job.

What it does

  • The receiver confirms before anything is written: you see the name, size and BLAKE3 hash first, and n stops the transfer before a single byte lands.
  • Integrity is checked end to end — the received file is hashed and compared against the sender's before it is renamed into ~/Downloads.
  • Transfers run in 64 KiB chunks written as <name>.part, so a half-finished file never looks like a finished one.
  • Aliases save a name for an IP, so you stop typing addresses.
  • Plain TCP sockets in C — the receiver listens on port 56389.

How it works

  1. The sender hashes the file and sends its name, size and BLAKE3 hash.
  2. The receiver answers N to decline or G to go; on N the sender stops without sending the file.
  3. On G the file arrives in 64 KiB chunks, written as <name>.part.
  4. The received file is hashed: on a match, and with no name clash, it is renamed into ~/Downloads and the receiver replies K — the sender only reports success once it sees that K.

What it doesn't do yet

  • Same network only — there is no relay or remote-host path.
  • A name clash at the destination is treated as a failed transfer rather than overwriting.

At a glance

Written in
C, on plain TCP sockets with BLAKE3
Released
About 2 weeks
License
GPL v3.0
Install
Build with make (Clang, Git, Make) or take the binary from releases
Built with
C, TCP sockets, BLAKE3
webp-purger logo
03

A CLI to deal with all your WebP troubles.

webp-purger

Walks through a path you give it and converts every valid .webp file it finds.

Why I built it

Downloading WebP files for slide shows was a recurring pain, so I built a small CLI to batch-convert them.

What it does

  • Recursive by design: give it a directory and it walks into every subdirectory looking for WebP files.
  • Nothing is destroyed — converted originals are moved to ~/.webptrashed rather than deleted.
  • Flags for real batches: --force skips the prompt on failed files, --include-hidden reaches dotfiles and dot-directories, and --verbose prints the full error behind a failure.
  • Built in C against libwebp and libpng.

How it works

  1. The directory you pass is opened and its entries are looped through.
  2. Any entry that is another directory sends walk() back around.
  3. A file entry is checked to see whether it is really a WebP image.
  4. If it is, it is converted to PNG, and on success the original is moved to .webptrashed in your home directory.

What it doesn't do yet

  • One file at a time, in place — there is no dry-run mode or conversion log.
  • Failed conversions need --force to skip unattended.

At a glance

Written in
C, against libwebp and libpng
Released
About 5 days
License
GPL v3.0
Install
Build with make (Clang, Git, Make, libwebp, libpng) or take the binary from releases
Built with
C, libwebp, libpng