← back

internal tools

2026

the daily drivers, rebuilt to fit

the software i use every day, remade to fit exactly how i work rather than how the average person does: my Mac from my phone, a vector database, dictation, screen recording and demo editing. each one only as general as it needs to be for one user, and all of it running on my own machines.

redeye

your computer, without being at your computer

welcome · mac
welcome · mac

Pair a phone with a Mac and run real coding sessions on it from anywhere. The agent runs as me, in my own repo, with my shell and my auth. Access is limited by the pairing and by the permissions macOS has granted, and there is no path check inside the app for the agent to talk its way past.

A menu-bar Mac app keeps the connection up and shows round trip, uptime, frames, reconnects and spend, and an iOS app drives it: send a prompt, watch tool calls and diffs come in, and see the Mac's screen live when I need to. The full writeup has how it works and where it falls short.

  • swift
  • swiftui
  • electron
  • node
  • python
  • fastapi
  • websockets
  • postgres
  • webcodecs
  • apns
  • permissions · macpermissions · mac
  • pair a phone · macpair a phone · mac
  • writing regression tests · ioswriting regression tests · ios
  • live mac screen · ioslive mac screen · ios
  • session complete · cost · iossession complete · cost · ios

needledb

a self-hostable vector database with Pinecone's API, on FAISS

overview under load · 118,874 vectors, ~500 requests a second
overview under load · 118,874 vectors, ~500 requests a second

I wanted Pinecone's API without Pinecone: one process with a REST API, a dashboard, durable storage and metadata filters, which the official Pinecone client can point at unchanged. Flat search for small collections, HNSW for large ones, and the switch happens in the background at 20k vectors without blocking reads.

The part I care about is that filters keep their recall. A planner looks at how selective a filter is and answers a narrow one with an exact scan of the matches and a wide one with filtered HNSW and a widened beam. Every write lands in a SQLite write-ahead log before it is acknowledged, so a crash replays only what came after the last index snapshot.

For these shots I loaded 100,000 real DBpedia articles with their OpenAI embeddings, a 3,072-d copy and 3,000 articles embedded on the machine by a local model, then drove it with 16 clients: 80,336 requests in 150 seconds, 536 a second, no errors.

  • python
  • faiss
  • hnsw
  • fastapi
  • sqlite wal
  • fp16
  • react
  • pinecone api
  • neighbours of a stored article, filtered · 1.8 msneighbours of a stored article, filtered · 1.8 ms
  • the 100k index laid out by similaritythe 100k index laid out by similarity
  • typed search on a locally embedded indextyped search on a locally embedded index
  • one index · HNSW, half precision, live trafficone index · HNSW, half precision, live traffic
  • benchmarks against Qdrant and pgvectorbenchmarks against Qdrant and pgvector
  • security posture, evaluated per connectionsecurity posture, evaluated per connection
a write, and a filtered read
clientdurabilitymemorydiskupsertPinecone shapedquery + filterwrite-aheadlogcommitted firstfilter plannerhow selective?HNSW graphfp16 vectorsexact scannarrow filtersindex snapshotevery 50k writesthen applynarrowwide
queries per second, 16 clients · 100k × 3,072-d OpenAI vectors at 95% recall, same Docker VM
  • needledb2,818
  • qdrant1,230
  • pgvector900

yapper

local dictation for macOS: hold a key, talk, text appears

the pill: live waveform, the draft transcript above it
the pill: live waveform, the draft transcript above it

Most local dictation records everything and transcribes when you stop, so you pay the whole decode at the worst moment. Yapper decodes while you talk: a voice-activity detector finds phrase boundaries, each finished phrase is decoded in the background, and on release only the last phrase is still outstanding.

Whisper's encoder runs over a fixed 30 second window however short the clip, so a one second phrase costs almost as much as a long one. Sizing that window to the audio took the final pass from 1,410 ms to 600 ms. The model stays loaded in a persistent Metal sidecar, and nothing leaves the machine.

  • electron
  • whisper.cpp
  • metal
  • vad
  • large-v3-turbo
  • macos
one dictation
  1. 1hold the key
  2. 2phrase endsVAD commits it
  3. 3decode nowgreedy draft
  4. 4releaselast phrase only
  5. 5final passbeam search, 5
  6. 6text at cursor
final pass latency, before and after sizing the encoder window to the audio
  • fixed 30 s window1,410 ms
  • adaptive window600 ms

tape

a local-first screen recorder and motion editor

the editor · screen and zoom lanes
the editor · screen and zoom lanes

Record a screen or a window, then turn it into something that looks designed: zooms that follow the cursor into the action, window frames, backgrounds, and a real cut, trim and speed timeline. Auto-zoom regenerates without touching the zooms you placed by hand.

Recordings live in the browser's own database on the machine. Nothing is uploaded, which is the whole reason it exists instead of a subscription.

  • electron
  • typescript
  • react
  • indexeddb
  • macos
  • auto-zoom and a synthetic cursorauto-zoom and a synthetic cursor
  • the librarythe library

demoedit

a demo video studio for app recordings

the editor, framed in an iPhone 13
the editor, framed in an iPhone 13

Drop in a phone screen recording, cut it on a timeline, speed clips up, score it with a song, and wrap it in a real iPhone frame centred on a 16:9 canvas. It renders an mp4 locally with ffmpeg.

A Next.js editor over a FastAPI backend, with a Playwright suite that drives every flow end to end and saves a screenshot at each step, which is where these came from.

  • next.js
  • typescript
  • fastapi
  • sqlite
  • ffmpeg
  • playwright
  • device frames, finishes and coloursdevice frames, finishes and colours
  • an export, rendered with ffmpegan export, rendered with ffmpeg
  • projectsprojects