The investigator is the only part of the gate that goes off and reads a repository by itself, so most of its design is a list of things it cannot do — including fail.
#pr-compliance-gate · part 3/3
A blog is a place where one goes to tell the world about something interesting. Usually it comes down to complaints or achievements — and I choose the latter.
The investigator is the only part of the gate that goes off and reads a repository by itself, so most of its design is a list of things it cannot do — including fail.
#pr-compliance-gate · part 3/3
Routing in the gate is a pure-Python rule ladder, not an LLM call — but the list reducer underneath it meant an investigation could never actually resolve anything.
#pr-compliance-gate · part 2/3
A portfolio piece, plainly — a LangGraph and Agent SDK pipeline that reviews PRs against policy, built around two cost gates that keep most traffic away from the expensive models.
#pr-compliance-gate · part 1/3
An echo tool grew a callback_url and lint had nothing to say about it — which is why the cassette gate has a second step that only asks whether the server's surface moved.
#mcp-cassette · part 6/6
A cassette is a verbatim transcript of what a third-party server said, committed to your repository and fed to a model — so lint reads it for injection smells, and its rule packs are TOML on purpose.
#mcp-cassette · part 5/6
Adding remote transport meant framing SSE myself to keep the dependency list short — and then a recording fixture hung because the server was talking on a stream nobody was listening to.
#mcp-cassette · part 4/6
The clean POSIX shutdown path had never run anywhere. CI ran it on four machines at once and found two bugs the blunt Windows path had already solved.
#mcp-cassette · part 3/6
Three things about stdio nearly stopped the recording proxy from working at all — and shutting it down cleanly on Windows ended in os._exit(130) after I gave up on the correct design.
#mcp-cassette · part 2/6
I wanted to start a project with MCP and found there was no easy way to test the interaction without calling the agent over and over — so I built the vcrpy equivalent for it.
#mcp-cassette · part 1/6
The smallest tool in my Claude Code monorepo — a wrapper that auto-names every unnamed session with its folder and a timestamp, so the session history is actually browsable.
#claude-code-command-center · part 10/10
file-sync keeps my Claude config in step across two folders, newer wins either way — until a raw copy clobbered a machine-specific statusLine.command and taught me why settings.json needs a merge, not a copy.
#claude-code-command-center · part 9/10
Claude sessions are disposable, so I harvest their lessons into a weekly master file on a schedule — plus a hand-run skill I built for a separate credit pot Anthropic announced but never shipped.
#claude-code-command-center · part 8/10
I'd copied the same CLAUDE.md and configs across a dozen repos and let them drift — Vantage is a single HTML file that surveys every repo, diffs any two files, and copies the good version across.
#claude-code-command-center · part 7/10
Planning got cheap enough to do from my phone, so plans piled up across ten repos — docket is the single board I run them all from, one at a time or batched by project.
#claude-code-command-center · part 6/10
Two skills, same name, no way to tell which one Claude Code fires — so I built a browser that lists every skill, agent, and hook on the machine, shows which one wins, and lets me read what each actually does.
#claude-code-command-center · part 5/10
I already had a usage dashboard; I built the terminal version out of pure "can I" curiosity — and it's what finally justified extracting the shared parsing into a library.
#claude-code-command-center · part 4/10
The Claude Code status line shows the moment; I wanted the story — so I built a dashboard that breaks token usage down by project, tool, and model, with a rate-limit trajectory that tells me when I'll hit the wall.
#claude-code-command-center · part 3/10
My Claude Code status line started as a context gauge back in the 200k days, grew rate limits and a cost figure — and why I trust two of those three and squint at the third.
#claude-code-command-center · part 2/10
Why I pulled a dozen standalone Claude Code tools into one monorepo called C4 — and why that would have been a maintenance trap before Claude Code could read the whole thing.
#claude-code-command-center · part 1/10
I built figureflow to answer two questions — can you wrap React Flow in Python, and can an LLM author interactive diagrams with it. Both got answered. The second answer is why I archived it.
#figureflow
The generic recipe underneath my Claude Code wrapper — a WebSocket-to-PTY bridge into a container, written down with the five things that actually cost me time.
#claude-code-html-wrapper · part 3/3
A self-hosted web front end for Claude Code — one Docker container per user, sessions you can resume from a browser tab, and no cloud in the loop.
#claude-code-html-wrapper · part 1/3
My Claude Code wrapper has no database, no Docker SDK, and no permission prompts — each absence was a decision made in the spec, and each one is why the server fits in seven files.
#claude-code-html-wrapper · part 2/3
The redesign looked AI-generated and I couldn't say why — so I asked the model that designed it to critique it. It listed its own tells, and iteration 19 became a subtraction pass.
#claude-code-plugin-toggler · part 6/6
Reskinning my Claude Code plugin manager around teal and terracotta — a palette that stays related to Claude without looking like an Anthropic product, and a VSCode panel that does the same trick against the editor.
#claude-code-plugin-toggler · part 5/6
Going from a two-tier local/global plugin model to three scopes — Local, Project, User — because the missing one lets a repo carry its own opinions to whoever works in it.
#claude-code-plugin-toggler · part 4/6
Every line of my Claude Code plugin manager was written by Claude Code. What I actually did all those days — specs, sequencing, and being the first user — and where the model out-debugged me.
#claude-code-plugin-toggler · part 3/6
I promised to write up the path problems once I understood them. It took three releases, a 29-line band-aid, and Claude Code finding the one character I couldn't see.
#claude-code-plugin-toggler · part 2/6
Setting up yet another project with my usual Claude Code plugins, I got annoyed enough to build a toggler — a browser UI and a VSCode panel over one JSON file.
#claude-code-plugin-toggler · part 1/6
Resetting the blog. Expect short, occasional notes on building AI coding agents and the tooling around them.