Notes from the trenches.
Field notes on PHP, Symfony, PrestaShop, CI/CD, and the unglamorous engineering that keeps production quiet. No fluff — just what actually worked, and why.
-
Three Strings and Two Fallbacks: Wiring the Native Share Sheet Into Forgemage.net
The share button on Forgemage.net's request detail page opens the OS share sheet wherever the operating system has one — Android, iOS, Windows, macOS — copies the link where it doesn't, and stays quiet when you simply change your mind. Here's the whole implementation: navigator.share with three strings, an AbortError guard that falls through instead of catching, a clipboard fallback with an execCommand fallback under it, and the one-letter Symfony detail that decides whether the shared link works at all.
Read article ↗ -
Every New Smithmagus Made Search Slower: Killing the N+1 Behind Forgemage.net
Forgemage.net's smithmagus directory ran roughly seven queries per card — reviews, response time, online status, three lazy relations — plus facet counts recomputed on every filter tweak. Here's how I got a page of 24 cards from ~168 queries down to a handful, with a request-scoped batch cache and a paginate-then-hydrate pass, without touching the single-profile pages.
Read article ↗ -
Markdown for Agents, Self-Hosted: One Symfony Subscriber Instead of a Cloudflare Plan
Cloudflare converts pages to markdown for AI agents via Accept: text/markdown — on paid plans. The same HTTP contract fits in a 144-line Symfony event subscriber. My homepage went from 59 KB of HTML to 7.7 KB of markdown, same URL.
Read article ↗ -
Claude Code From My Phone: Tailscale, Termius, and the Whole Machine in My Pocket
Claude Code's /remote-control mirrors one session to your phone. SSH over Tailscale hands you the whole workstation: resume sessions, start new ones in any repo, tail logs, restart containers — with nothing exposed to the internet.
Read article ↗ -
RepoWrapped: Spotify Wrapped for a GitHub Repo, and the API That Fought Me
A weekend idea — a shareable stats page and README badge for any GitHub repo and contributor — turned into a fight with GitHub's stats API: 202s that never resolve, a top-100 wall, and a first-commit lookup you have to trick out of a header.
Read article ↗ -
Letting Non-Technical PMs Query the Codebase in Plain Language
Why I built a read-only AI analyst that lets project managers ask questions about a codebase and have a Jira ticket filed for them automatically — and why the whole thing only works because the AI can read but never write.
Read article ↗ -
Adding AI Code Review to a Self-Hosted GitLab — Without Handing It the Keys
How I wired Claude into the merge-request pipeline of an old, self-hosted GitLab, and why the whole design hangs on never letting the AI both read an untrusted diff and hold a token at the same time.
Read article ↗