Skip to main content

· 4 min read

Claude Code has a hooks system that lets you run scripts after every file edit. The killer use case: run your linter automatically and force Claude to fix issues before moving on. No more "can you run rubocop" after every change — it just happens.

The catch? Getting Claude to actually act on hook output requires a specific JSON format that isn't obvious from the docs. Here's what works.

· 2 min read

Mattermost truncates any post taller than 600 pixels, hiding the rest behind a "Show More" button with a gradient fade. There's no setting to turn this off — it's hardcoded in the webapp. If you're self-hosting and your posts are routinely long (AI bot responses, log dumps, code blocks), this gets old fast.

The fix is a tiny webapp-only plugin that injects CSS to remove the truncation.

· 16 min read

I wanted my email in local Maildir files — searchable, indexable, and accessible from the command line. The goal is a stack where mbsync handles IMAP sync, himalaya provides quick CLI access, and neomutt gives me a full TUI when I need it. Push notifications via IMAP IDLE keep it all near-instant.

I run two accounts through this setup — Fastmail (personal) and Google Workspace (work) — and adding more follows the same pattern.

· One min read

I have a global keyboard shortcut (⌥`) to mute my microphone on Zoom. I've done this several ways in the past but right now my solution is to send the mute keyboard shortcut (⌘⇧A) to the Zoom app via Keyboard Maestro.

Screenshot of Keyboard Maestro

Download Macro

Mute status in macOS Menubar

Using SwiftBar, I have a script which checks the mute status and displays it in my menubar. Screenshot of Swiftbar Zoom mute state icon Download Script

· 4 min read

When serving assets and attachments from Rails and ActiveStorage, a CDN is a great way to reduce load on your web server and speed up content delivery to your users.

Asset CDN

First, even if you're not using ActiveStorage, you'll want to set up a CDN to stand in front of your app. This will proxy requests for images, fonts, javascripts, and stylesheets that live in your app's repository.

The ideal setup here is to serve your assets from your app, set a high cache-expiration, and serve your assets through a CDN.

Setting up your Asset CDN

For a CDN, I recommend Amazon CloudFront. You'll want to create a web distribution which points at the root of your app. Heroku [has a good guide][2] on that.

· One min read

My main computer is my iMac. It seemed like every time I opened my MacBook Pro, it would show this screen:

MacBook Pro showing low battery full screen

So I researched a bit and fixed it. Here's what I did:

· 2 min read

I was looking for an outbound ping tool that I could run continuously on a secondary monitor or in the background so I could quickly troubleshoot internet outages or packet loss.

For example, when I'm in a video call, if the other person starts to have issues with audio/video, I can, with a glance, tell if it's me or not by looking for latency/packet loss amongst the hosts I'm pinging.

[ICMPUtil][1] is the best I've found. It's $6 [on the App Store][2].

Screenshot of ICMPUtil

· 2 min read

I've been searching for a solution to allow me to instantly search Google from anywhere on my Mac. My goal is to access the result I want as fast as possible.

My previous solution was to use the default fallback search in Alfred. I hit Option-Space typed my search and pressed Enter. This was pretty good. It would open Safari with my query's Google results. The page would take two seconds to load and then I'd have to figure out how to select the result I wanted.

Ideally, I'd just press 1, 2, 3, etc on my keyboard to launch the corresponding result. But the closest I could find was a vim-like browser plugin (such as Vimari) which gives all links a letter combination to type to navigate to it. Or Shortcat, which I use for navigating all macOS UI.1

This solution wasn't fast enough for me though. I wanted a more modal experience where I hop into an ephemeral search session.

· 2 min read

I wanted to log my internet's upload and download speeds over time. brew search speed turned up speedtest-cli which uses speedtest.net servers to measure what I was interested in.

Unfortunately it's a one time test and if you want it to repeat, you'll need to automate it. I chose a simple shell while loop to handle this for me1:

while; do
speedtest-cli --json --server $(
speedtest-cli --list |
grep -E "CenturyLink|Sprint|Enid|OneNet|Cox|Suddenlink" |
head -20 |
cut -f 1 -d ')' |
sort -R | head -1
) | tee -a speedtest-log.json
sleep 600
clear
done

This checks a random nearby server every 10 minutes.