Latest Posts

The Layers of Abstraction Will Kill You

Two hours to debug "command not found."

The actual problem was buried four dependencies deep: an image library couldn't build native bindings for my specific Node + ARM combo. When it failed, npm silently rolled back the entire install while reporting success. Every abstraction layer you add is another place errors get swallowed. The fix took 30 seconds once I found it. The lesson: the developers who move fastest aren't the ones who know the most tools—they're the ones who can drop down a layer when something breaks.

Know what's under your abstractions. Have a plan for when they fail.

I Made a Lightweight Git Worktree Manager (Because I Couldn't Find One)

I built a git worktree manager because I couldn't find a simple one.

The problem hit me when running multiple AI coding agents at once—one was refactoring accessibility code while I needed to review the current implementation for a bug. Same files, different contexts. I couldn't commit the half-done work, couldn't stash and lose the agent's state, couldn't review without a clean checkout.

Git worktrees solved this, but the syntax was awkward. Branchyard exists and is great if you want VS Code integration and git hooks, but I wanted something I could drop in my dotfiles and understand in 20 minutes.

So I built gwt (git-worktree-utils): • ~1K lines of bash, zero dependencies • Source-based, lives in ~/.config • One branch = one directory (keeps the mental model simple) • Built-in cleanup for orphaned directories

Use cases beyond AI agents: • Code review without losing your place • Emergency hotfixes without stashing • Running tests in one branch while coding in another

The pattern works: multiple branches in separate directories beats constant switching. No stashing, IDE state persists, contexts stay separate.

Project: https://github.com/jamesfishwick/git-worktree-utils

Let the System Remember: Multiple Git Accounts

Spent an hour reverse-engineering my own Git multi-account setup. 🙃 It turns out that the "hacky" approach—using SSH host aliases with fake hostnames—works better than the "correct" one. Why? Loud failure beats silent failure, and state beats process. Every "just remember to..." is a bug waiting to happen.

Extracteract

I kept needing to copy text from screenshots—JIRA tickets, PDFs, and images. Cameras have had OCR for years. Why doesn't everything else? On Mac the situation is worse—Apple controls everything. Here's a minimal script using Tesseract OCR. I use it for JIRA tickets and other places where I need quick text extraction. You can run this program anywhere you have Python and Tesseract installed (installer included!).

Syntax, Struggle, and Expertise

For decades, the path to programming expertise ran through syntax struggle—writing, breaking, debugging, repeat. LLMs just eliminated that grind. Junior devs now learn by reviewing AI-generated code instead of writing from scratch.

Can this work?

View more posts in the archive →

Recent Links