Lab

The lab

Experiments, prototypes and internal tooling. Rougher on purpose.

Internal tool

Portfolio QA pipeline

Automated review passes check claims, responsive layouts, accessibility regressions, broken links, and content consistency before deployment.

Internal tool

AI video to sprite pipeline

The generation-to-game-asset workflow sprite-chroma-key ships from: generate animation frames with video AI over green, key per frame, pack sheets. The keyer is the public piece; the pipeline is the reason it exists.

Developer tools the write-ups behind two repos
Developer toolLive

sprite-chroma-key

Removes green screens from AI-generated sprite sheets where the background color drifts between frames.

Case study

The problemMy sprite pipeline generates animation frames with video AI. The green background is never quite the same green twice. Normal chroma keying assumes one color: it either left green fringes or ate the sprite's edges.

Why I built itI needed clean sprites for my own games and got tired of hand-fixing edges frame by frame.

The buildSamples the border pixels of each frame independently, takes the circular mean of the saturated hues to find that frame's actual background color, removes pixels near that hue, despills the green rim glow, then erodes the alpha edge.

Real tool output: a raw AI-generated sprite frame on a green background beside the same frame after keying, background removed cleanly Edge close-up: a fixed-color key leaves green fringe and dropout holes along the sprite's outline; the measured key from this tool cuts a clean edge
Real output, from the tool's listing images: raw frame vs keyed, and the edge detail a fixed-color key gets wrong.

What didn't workKeying against a fixed green value. The generated frames varied enough in hue that edge cleanup was inconsistent across a single sheet. Per-frame sampling replaced it.

Technical decisionsTests run on synthetic frames instead of image fixtures, so the repo stays small and the tests stay deterministic.

Built withPython, NumPy, Pillow. MIT.

Developer toolLive

vaultlint

A structure linter for Obsidian vaults: broken wikilinks, missing anchors, orphan notes, frontmatter rules.

Case study

The problemMy second brain is a few hundred markdown notes. Links rot quietly: a renamed note, a deleted heading, an alias that stopped matching. Obsidian shows you one broken link when you trip over it. I wanted all of them in one pass.

The buildImplements Obsidian's actual link-resolution rules (full path, path suffix, basename, aliases, case-insensitive, heading and block anchors), then lints every note. Exit codes and a --json mode so it runs in CI.

Technical decisionsCode fences, inline code, and comments are masked before link scanning, so example links in documentation don't count as real ones. That one choice removed most false positives.

Built withTypeScript on Node's native type stripping. No dependencies, no build step. MIT.

Log

Ship log

Milestones, not commit noise. All dates 2026.

Contact

Have something in mind?

Tell me what you're trying to build. Rough notes are fine. If I'm not the right fit, my first reply will say so.

Most interested in internal tools, agentic workflows, business automation, and odd software problems.