sharing my favorite music

· Website

I spend an enormous amount of time listening to music and I think hearing is my strongest sense. After working on PlaylistMint and learning about all the data Apple Music tracks, I was curious to see what the models could produce to share what I listen to. I keep a list of things I want to throw extra tokens at and we’ve been having a lot of Codex resets so I was able to build /Music on this site.

The page pulls two kinds of favorites out of that history: the songs I play most, and the ones I skip the least. You can browse across the whole library or pick a year. You can play individual songs in a mini player or entire sets of songs as published playlists with full support for both Spotify and Apple Music.

More …

turning a decade of saved passages into something I can browse

· Website

For more than a decade, I’ve been saving things I read that motivate me, surprise me, anger me, or just seem beautiful. These went into Apple Notes and later into what became a 200+ page document. I now have a quotes collection on this site where you can actually browse them.

There are over a thousand entries so far: short lines, long passages, poems, and scenes. Some are things I agree with. Others are things I want to think about.

More …

see your open PR count in your Mac’s menu bar

· GitHub

I work across a lot of different GitHub repos, and agents have made it a lot easier to produce code than to verify and merge it. I’ve found one of the best ways to keep things moving is to avoid building up too much of a backlog of PRs. I built prBar to show the open PR counts in my Mac’s menu bar, so I can see how much crud is accumulating and when to focus on clearing it.

More …

city guides generated from a decade of Google Maps stars

· Website

Over the last 10+ years I’ve starred more than 10,000 places on Google Maps. I’ve always wanted to do something with this data but until AI it didn’t feel worth the effort. Since classification and working with new APIs has gotten so much easier, this project now felt within reach but I didn’t just want to make generic guides.

I’ve focused on finding hidden gems in my dataset, pulling the review score and number of reviews for each place and then logarithmically downranking places that have a lot of reviews. This created 58 guides for cities/regions/countries that had enough places to run this on.

More …

personalized daily briefings from newsletters, websites, podcasts, youtube channels, etc you follow

· Website

The newspaper was a pretty great way to stay informed. Read a good one every day and you could have a reasonable understanding of what was happening in the world. An entire editorial team worked on your behalf: deciding what mattered, giving you enough context to understand it, and fitting it into something you could finish. Keeping you informed was their job.

The internet pulled that bundle apart, and a lot of what followed was wonderful. You can get as much detail about something as you’d like. Specialists can now connect directly with their niche audience. Nothing was gatekept but the incentives shifted as well. Newspapers want to increase readership but they were paid by you the reader. Today’s websites sell their readers’ attention and feed their readers junk food content that keeps them reading but struggles to satiate them.

Readers are now their own editors: finding sources, deciding whom to trust, sorting through what they publish, and figuring out what deserves our time. Each newsletter, podcast, and YouTube subscription adds another source to a disjointed publication we put together ourselves, each component attempting to grab our attention and get paid.

I think AI can give us the best of both these things: by wading through the ocean of information and understanding what matters to each reader, we can build a personalized newspaper built around your work, your interests, what you already know, and what you’re trying to learn. I built FireHose to do just this.

More …

using Linear to coordinate swarms of coding agents

· Website

A coding agent can finish its assignment while leaving the project further from shipping. Its change might depend on a branch that hasn’t landed, conflict with another agent’s work, or have been edited since its last review. More agents give you more of these coordination problems.

CrossCheck was my first attempt to put structural constraints around AI development: independent model review, scoped permissions, and repository protections. Switchyard extends that approach across the work itself, from deciding what should run to integrating the result.

The biggest change is moving from a do-work folder of markdown tasks to using Linear as a state machine for the project. I’m writing a bunch of middleware around it to keep agents using that structure consistently and make progress depend on the right evidence.

This has been an internal tool I’m now piloting with a few friends’ startups. The landing page is the best visual explainer; its animation follows work through the whole system.

More …

filter eBay on the clothes that already fit you

· Website

I got into buying clothes on eBay after spending $200 to rent a shitty tuxedo and realizing that the same money could buy one that cost $5,000 new.

eBay is full of beautiful vintage pieces made from fantastic materials and obscure brands. If you know what to look for, you can buy extraordinarily well-made clothes for very little money.

The problem is the looking and figuring out if something will fit. Every brand fits differently, people preferred different sizing in the 70s, and returning things is annoying when it’s possible at all. Meanwhile, you have to check 5-10 measurements for every garment type: the chest of that jacket might fit, but what about the raglan sleeves, and is it too long?

Most sellers take photos of their clothing with tape measures but do you have an intuition for what length of sleeves would be good on a dress shirt vs an overcoat? How about converting between centimeters and inches in your head?

I built thrift.fit to make that process easier. You save measurements from clothes you already like wearing, tell it what you’re looking for, and it compares eBay listings with those reference garments. You get an email with new items that fit you in your price range each morning.

More …

prevent supply chain attacks by waiting

· GitHub

Supply-chain attacks are a growing problem for anyone installing dependencies. An attacker compromises a maintainer account or publishes a malicious package, and an ordinary install brings their code onto your machine. In the Shai-Hulud npm attack, compromised packages used malicious post-install scripts to spread the attack.

The observed activity has grown sharply: Sonatype recorded 3,430 malicious-package advisories in 2025, compared with an annual average of 931 in 2021–2023. That’s one research team’s detection data, but it gives a sense of the change in scale.

I rarely need a dependency update right when it comes out, and researchers, registries, and other users usually spot compromises quite quickly, so waiting to install updates feels like an easy way to prevent most of these attacks.

npm-age-pin enforces this rule: select a release at least 72 hours old, pin its exact version, and install with installation scripts disabled.

More …

work through the alphabet, naming every country that starts with each letter. too easy? try capitals.

· Website

I was at dinner in Uzbekistan with my friend Jordan, who’s spent much of the last few years backpacking around Africa, Central Asia, and everywhere in between. He suggested a game: pick a letter, go around the table, and take turns naming countries that start with it.

More …

compare AI coding usage, estimated API costs, and environmental impact

· GitHub

TokenPrint brings usage from Claude Code, Codex CLI, and Gemini CLI into one local dashboard. It shows token counts over time alongside estimated API costs, energy use, carbon emissions, and water use.

More …

a ruleset for keeping AI coding agents in check

· GitHub

Coding with AI has an entropy problem

A few hours into coding with AI, a pattern shows up. The code looks clean. Abstractions make sense. Tests pass. And yet under concurrency, your rate limiter collapses because the counter isn’t atomic.

Here’s the formula nobody talks about: failure= error rate × variance

Coding with AI massively increases variance. Even if error rate stays constant (big if), failures scale dramatically with output. After a few hours, you have 200 files of mostly okay spaghetti code and an AI who responds to your prompts with things like:

You're absolutely right - I was making up nonsense

More …

the obscure card game my family loves is a very interesting learning problem

· Website

My family loves to play an obscure card game called “forty-fives” (45) popular in northern New England and Atlantic Canada.

We play an even more specific set of rules (the probabilistically most interesting and exciting variant!) where you sit across from a teammate and play another team of two. Each person “bids” for the number of points they expect their team can get in exchange for receiving four hidden cards in the “kitty” and choosing the “trump” suit that defines the hierarchy of cards. Many a game has been turned by our most distinct bid: “30for60” where a player who bids that they can get all 30 points in a hand is rewarded with 60 points if they do so.

Living thousands of miles away from anyone I’m related to is hard sometimes. The long tail of the internet had not produced a way to play online so I built 30for60.com: a fully functional version of the game complete with self-play trained bots that can join a game if we don’t have enough human players.

An actual four-player game of 45 on 30for60, with three bots and the player’s hand

More …

export Chrome tabs to Apple Notes

· GitHub

I don’t like opening my laptop to a wall of tabs from things I was doing the previous day: it slows my computer down and makes it harder to think. I used to use “The Great Suspender”[1], but what I really want is to just put everything away at the end of the day and start the next from a place of agency instead of momentum.

I made the Chrome extension Tab2Notes to do this. Click the extension, export all the tabs in the current window or across all your windows, pipe them to Apple Notes via the Shortcuts app. Bulk open the URLs with a paste when you want them back.

More …

pipe eBay tracking numbers into the Parcel delivery tracking app

· GitHub

I use Parcel to track all of my deliveries. The app has an Amazon integration but I purchase a remarkable number of clothes, tech, and vintage aviation memorabilia on eBay.

I built eBay2Parcel to automatically import eBay tracking numbers into Parcel. Once a day it asks eBay for my recent buyer orders, filters for the ones that have a tracking number and haven’t been delivered, and sends them to Parcel.

More …

playlists built from your listening history

· Website

I use Apple Music in large part because I’ve been rating songs there (and in iTunes before it) for over a decade. I also really dislike making playlists and Apple has a “smart playlists” feature that makes it really easy to programmatically include/remove music based on its rating and other attributes. Apple natively tracks play count, skip count, and genre, but the genre is usually one broad word the label picked, and plays and skips only mean something together: a song I’ve played 200 times and skipped 150 times isn’t a favorite, and one I’ve played 20 times and never skipped probably is. So I built PlaylistMint. PlaylistMint reads my library, classifies every track by energy, mood, genre, listening context, and language, writes the labels back into Music.app, and then builds playlists that combine those labels with my ratings and a calculated skip rate to reflect how much I enjoy the song.

More …

a local transcription app for your Mac

· GitHub

A lot of the longer writing I do starts as a voice memo: I go on a long walk with just my recorder and exhaust all of the angles I can think of over an hour or two. I used to use online sites to do transcription but I didn’t love the idea of sharing these with a third party and the experience was kind of annoying so I built WhisperBatch: a native SwiftUI Mac app that uses WhisperKit to transcribe locally. Pick as many files as you’d like, choose a model, and save a transcript next to each recording. You can preview the waveform and crop audio, include timestamps, or export text, SRT, VTT, and JSON. The default model is large-v3-turbo; models download on first use, and transcription then runs locally using the cached model. There’s also a Swift CLI that shares the app’s transcription engine.

More …

move files in and out of Airtable with Python

· GitHub

I’ve used Airtable as a custom ERP across a few businesses. I’ve always been annoyed by how difficult it is to bulk export/import attachments so I built bulkAirtable.

More …

a drawer of Python scripts for Notion dumps, bloated PDFs, and photos that shouldn't have metadata

· GitHub

Preview on a Mac will merge two PDFs for you. It will also, in my experience, turn a pair of 2MB files into a 22MB one. Notion will export a second brain as a zip of folders named with 32-character hashes. A phone photo posted to a website is likely to carry timestamps and GPS coordinates unless you strip the metadata.

I got tired of solving each of those once and throwing the script away. tidyData is the drawer I keep them in.

More …