Blog
Notes from building software: experiments, debugging trails, product decisions, and the tools that make the work easier to understand.
88 posts, newest first
November 2026 5
Hill-climbing Draftably's layout speed without making the drawings worseOne Claude session climbed layout() speed one measured change at a time, while Codex and Sonnet sessions tried ideas in parallel. A drawing digest and a quality gate decided what stayed. A fresh 100-node DAG went from 663 ms to about 20 ms, and dense graphs kept their old drawings.
Analytics and Search Console for six sites, in one Codex thread and one Claude threadCodex did the Google console work in 25 minutes. Claude turned it into six merged PRs, working sitemaps, a read-only metrics script, and a retired Umami server in about 45. Then the daily review started reading the numbers.- Chat titles that show what still needs meA small naming convention lets an agent turn a crowded chat sidebar into a useful view of questions, approvals, and unfinished work.
The prettiest layout lost: ranking diagram layouts with draftably varyDraftably's vary command and the editor's Compare sheet try the layouts that suit a diagram, measure each one, and recommend a change only when it is no worse on warnings, crossings and area. The layout that looks best often loses, and that is on purpose.
Voice memos that turn into searchable notesVisual Notes now transcribes every recording on a note into a title, summary, timed sections, and tasks that search, embeddings, and agents can all read. Groq Whisper keeps it at about $0.04 an hour.
October 2026 17
HN Offline's service worker never registered, so I replaced itThe offline Hacker News reader had a service worker that never registered in production. The fix was a short plain worker, a redirect trick for offline story reloads, and an update flow that waits until you stop reading.- Moving Visual Notes to SolidStart 2, and what broke along the wayDropping vinxi for Vite 8 cut the Visual Notes build from 292s to 49s on a 2-CPU box. The port itself was small. The breakage was at the boundaries: auth, server function IDs, WebSockets, and the dev server port.
Cleaning up 6,300 notes, from decision models to a working review queueHow my own labels changed Visual Notes cleanup from deletion to distillation, what Jev suggested across the collection, and what production verification caught.
- One TypeScript server per agent session, and moving Claude to the TypeScript 7 oneA second memory jam on an 18 GB Mac: runaway engine scripts, 194 unarchived sessions each holding a TypeScript server, a local Claude Code plugin for the TypeScript 7 native language server, six tsconfig PRs, and a session-start hook that flags configs TypeScript 7 rejects.
From a 12-minute narrated review to 16 stacked PRsI talked through thirteen Draftably diagrams with Context Recorder running, handed the session folder to Claude Code, and got back a stack of sixteen pull requests, each with screenshots as proof.- Out of memory with too many agent sessions, and why Panda 2 didn't fix itFreeing memory on an 18 GB Mac running many Claude Code sessions, turning the cleanup into a skill, then measuring where the TypeScript memory goes and testing whether a Panda CSS 2 upgrade reduces it. It did not.
- From a PHP vulnerability report to a verified Coolify updateUsing the ChatGPT desktop app to research PHP2Shell, inspect my Coolify exposure, stop the affected service, and verify the eventual update.
Context Recorder: marking bugs while I talk through an appA macOS screen recorder for reviewing my own apps. I talk, press a hotkey when something is wrong, and get back a session with the video, each marked moment, what was on screen, what the page was doing, and what I said.
Draftably: a diagram file that an agent and I both editDiagram Studio went from a sandboxed GPT Pro prototype to a published npm CLI: a plain-text .draft file an agent writes, a viewer that follows it live and saves my drags back into it, and a compiler that draws the same picture every time.
Five diagram themes for DraftablyDraftably's default diagrams looked like every other diagram tool. Five themes now change the palette, the padding and the type, including an editorial theme with serif titles, and they all live in the diagram file.
Making Srcly's dependency graph readableSix rounds of before-and-after screenshots that took Srcly's dependency graph from an unreadable layered hairball to boxes that carry the information, grouped neighbors, and hubs that stop flooding the screen.
Showing the lines behind Srcly's metricsSrcly's code viewer now marks every line that contributes to a metric. The first thing the overlay did was expose a nesting bug that had been inflating hotspot scores for every long else-if chain.
Srcly compare: what did this PR do to the codebase?A before/after mode for Srcly that scans two commits and draws both treemaps and both dependency graphs on one shared layout, so a 12-file PR in a 2,000-file repo reads like a 12-file PR.
Turning a screen recording into a canvasContext Recorder now has a Canvas mode. It turns time into space: a scrolled page becomes one tall column, and everything else becomes a timed card. Clicking any part of the canvas jumps back to the frame that supplied it.
ComicBam: a before-and-after UI refreshThe comic book creator got a new name, one consistent comic-pop look, sticker art, kid-friendly copy, and a dev mode that opens straight into sample books.
Product Grid now ships its viewer with the CLIA denser workspace, a local viewer inside pgm, Changesets releases, and the Codex and Claude work behind the update.
Reading initiative docs inside tk viewThe Initiatives tab in my ticket viewer is now a reader for intent briefs, shape briefs, and plans, with a prompt for sending comments back to the planning skill.
September 2026 14
Making project icons with Logo Dodo and CodexThe explorEDA icon worked. A second run for my resume site exposed where Logo Dodo still falls short.
How I triage small explorEDA UX issues with Product GridI grouped 13 explorEDA UX issues with screenshots in Product Grid, then used them to guide a set of focused fixes.
Understanding fields before building another chartField distributions, filter comparisons, a searchable field list, and direct chart actions make data inspection easier in explorEDA.- Moving Resume Studio model calls to MastraHow Resume Studio moved from direct AI SDK calls to Mastra, with bounded validation repair, durable traces, and a proof-first ticket plan.
- Connecting exploreda.dev with an OpenAI desktop agentA desktop agent connected Namecheap DNS, GitHub Pages, and the demo build, then checked the live result.
Reworking the explorEDA landing pageThe explorEDA landing page now leads with a live example and the React integration. Parallel threads in a Claude Code project did the work.
Making the explorEDA summary table read as a tableThe explorEDA summary table replaced stacked stat badges with aligned columns, inline distributions, and a Missing column.
Keeping the original when cropping a hand-drawn comic pageA four-corner crop makes photographed drawings printable, while saved source photos and corner positions keep the edit reversible.
Seeing the ticket graph, planning at the frontierA live view of my ticket dependency graph and a two-pass fan-out process that waits to write implementation detail until work can start.Turning an old repo audit into 86 focused commitsI reopened a two-week sprint project, found 54 concrete problems, and used an agent orchestration loop to repair the library and demo without supervising every change.
From a flow tool to an all-in-one diagram workbenchHow User Flow Workbench combined flows, overviews, wireframes, and application maps—and why improving the DSL meant removing exceptions instead of replacing it.
Reviving an old site with a known Docker stackHow I moved fawnix.rocks from a broken platform-generated build to a repository-owned Docker Compose setup with SQLite on a persistent volume.- Backlog gave my agents a graph, but weakened the planBacklog.md gave coding agents a useful dependency graph, but its tickets became a lossy summary of the detailed implementation plan they were supposed to execute.
From wireframe sketches to observed screensUser Flow Workbench grew from a rough semantic proof into a wireframe viewer that checks proposed screens against real site references.
August 2026 14
Improving a CLI and skill by reviewing the agent's workI reviewed nine agent-authored soccer flows, then turned the useful findings into better CLI rendering, validation, and authoring guidance.Building a flow tool that agents can editHow a single-file diagram prototype became a schema-first workbench by separating graph meaning, layout, variants, and visible flow.
Turning a blank print page into a sideline field guideA quick Coach Companion update used a reference image to turn the blank back of a printed schedule into an editable soccer field guide.
A small playback speed picker for ChromeA small Chrome extension that lets me select embedded media and set its playback speed up to 3×.
ChatGPT Pro delivered one wrong Base64 character, broke six HTML prototypes, and spent 124 minutes fixing themChatGPT Pro published one wrong Base64 character, broke six table variants, and spent another 124 minutes recovering its compressed payload.
Repolishing fawnix.rocks with OX Alpha workersA screenshot-led redesign of fawnix.rocks, followed by an honest test of what free OX Alpha workers could and could not carry through implementation.
What 57.7 million free tokens taught me about Ox Alpha and ompI turned a tweet about free Ox Alpha coding agents into a Codex-driven omp worker pool, burned through 57.7 million tokens, reviewed the evidence, and simplified the final skill.
Making Gunk Patrol from my son's game ideaHow a four-minute idea about cleaning a swamp became a small touch-first game with a forgiving goal and a staged route.- Building a date table that stays editable until printA dependency-free date table for editing recurring schedules in place and printing the same table without moving the work elsewhere.
- Does Serena make Codex code navigation better?A repeatable Serena-versus-bare Codex evaluation found useful semantic retrieval, but no overall quality or token-efficiency win from the tested integration.
The click that became a background clickHow pointer capture turned a Route totality node click into a background deselection, why the early tests looked green, and what finally exposed the real event path.Improving a diagram with a diagram-review skillI ran one Vaultwarden update diagram through a structured review skill, fixed its reading path in three passes, and kept the full skill with the article.
Building a dev feedback loop directly into my portfolioA dev-only overlay for leaving page-specific notes, targeting elements, and handing a durable local queue to coding agents.Updating Vaultwarden with Codex and a verified rollback pathHow Codex inspected an old Vaultwarden deployment, proved the backups were real, completed a guarded update, and got the iOS app working again.
July 2026 32
From an empty dashboard to useful product analyticsHow I added a private usage desk to Find My AI Fit, found the production analytics pipeline was empty, and connected traffic and events to the generated results that actually matter.
Building Find My AI Fit from a 50-minute dictationHow a long voice memo became a resume-to-AI opportunity map, then got simpler through repeated design, product, and branding passes in Codex.
Building an AI project intake with ChatGPT SitesA prompt-to-production experiment with ChatGPT Sites, including the design pass, the missing-data mistake, durable submissions, and a private admin view.- Give Codex the tweet and let it run the claim to groundA post-work audit of giving Codex an alarming SSD-wear tweet, letting it choose and run the diagnostics, and checking whether the conclusion was actually earned.
Building a force-directed graph one desire at a timeBuild a readable graph by turning springs, flow, collision, and fringe behavior into small desires you can inspect one tick at a time.
Learning to zoom out a data-flow visualizationA visual log of the TSX Data Flow views that were too detailed, too flat, or too noisy—and the design rules emerging from a route-scoped topology view.
When static analysis invents a recursive component graphA Suspense cycle exposed a component-identity problem in TSX Data Flow: merging render occurrences by name can manufacture paths that do not exist.
Tuning a force-directed graph with visible controlsA visual debugging log of turning a graph layout from a black box into a system I could step, inspect, reverse, and tune on screen.
Photographing hand-drawn comics for booklet printingHow I added photographed page layers, grayscale and black-and-white controls, and disk-backed image storage to a printable comic-book editor.
Introducing Coach CompanionA soccer rotation planner built around the actual coaching job: get a fair first draft, make the judgment calls visible, and carry one clear plan to the field.
What Coach Companion changed about my development workflowHow a dictated product plan, a long browser QA pass, and repeated development friction turned into better scripts, repository rules, domain invariants, and verification defaults.- Letting a starter repo learn from the projects cloned from itA practical workflow for reviewing agent threads, finding reusable improvements in projects derived from a common starter, and feeding the useful parts back into the next project.
The invisible backdrop filter that blanked my code blocksA one-line backdrop blur on an invisible copy button made Chrome intermittently stop painting code-heavy MDX articles. The DOM stayed correct; the compositor did not.
Making slow static analysis explain itselfHow tsx-dataflow moved analysis into a worker thread and added real per-file progress over SSE, turning an apparently locked page into an inspectable workflow.
When a 5 MB Git push times out after the upload finishesA GitHub HTTPS push returned HTTP 408 after every byte arrived. The useful clues were in the curl trace, and the practical fix was to push the image objects in smaller batches.- Review the product assumptions before the architectureA practical way to review technical plans by asking product questions first, then letting the answers determine the architecture—especially when agents will write much of the implementation.
Testing OpenGraph images with a contact sheetI built a small contact-sheet workflow for comparing real OpenGraph route renders and catching visual failures that were easy to miss one image at a time.
Rebuilding TSX Data Flow around TypeScript and SolidJSHow I used a concrete Codex goal, a written migration plan, typed API contracts, and visual comparison to replace a mixed JavaScript and generated-HTML architecture with a smaller TypeScript and SolidJS application.- Canvas interactivity basicsAn interactive guide to scene models, hit testing, hover overlays, and drag-pan camera math for canvas-based interfaces.
- Using Codex as a bridge between browser appsA lightweight workflow for turning information from one browser app into calendar entries and reference notes in another, using Codex and appshots as the coordination layer.
Encoding time on the canvas to debug Pluck inventory panningA Pluck debugging note about turning pan-and-zoom viewport history into a visual overlay: the canvas stays spatial, while time becomes a trace.
Forcing Suspense boundaries from a tiny debug overlayA Pluck debugging note about wrapping Solid Suspense boundaries with dev-only controls so loading states can be inspected on demand.
Iterating a comic-book app icon with contact sheetsA short walkthrough of turning a generated PNG into SVG app icons by using a contact sheet to compare every iteration.- OpenAI prompt caching with prompt_cache_key and cached_tokensHow Video to Context structures repeated OpenAI Responses API calls so long transcript context can hit the prompt cache, report cached tokens, and make cost visible.
Breaking top-level Suspense into component-level SuspenseHow a SolidJS loading state got smoother by keeping the page shell mounted and moving resource reads behind local Suspense boundaries.- Understanding SolidJS resourcesAn interactive guide to how SolidJS resources interact with Suspense, resource.latest, derived accessors, and memoized reads.
Building a review UI for LLM-processed voice memosHow Video to Context grew from a transcription CLI into a local review workspace with sectioned transcripts, inline extracted evidence, and cost-aware LLM processing.
Packaging llmly for PyPI with a publish scriptWhat it took to turn a local Flask usage viewer into a PyPI package, and why a small publish script makes versioning and token-based uploads much less error-prone.- Making Pluck capture faster by making the timings harder to ignoreI optimized Pluck's Chrome extension capture loop by adding detailed timing traces and a repeatable diagnostic batch that made every speed experiment measurable.
Turning voice memos into Codex-ready analysisHow I pushed Video to Context from transcription toward a Codex-backed analysis pipeline while keeping the CLI aimed at one command that just works.
Adding voice memo support to Video to ContextHow I expanded a local screen-recording transcription CLI so one flag can process Apple Voice Memos into a reusable context folder.
Debugging background removal on a carpet-colored stuffed animalA practical walkthrough of tuning rembg for a stuffed-animal zoo: threshold sweeps, mask repair, visual contact sheets, and a regeneration path for production images.
June 2026 3
Expanding webpage tables when copy is the real featureI added an Alt-click table viewer to my Chrome extension after needing exact DNS record values from a page that made table text hard to copy.
A small shared expense splitter for family tripsA quick static browser tool for importing shared expenses, tracking payments, and turning the final balance into a simple settlement plan.- Speeding up Pluck's full-page Chrome extension capture loopNotes from optimizing Pluck's real Chrome extension full-page capture path from slow scroll-settle loops to sub-four-second captures on recent sites.

