writing

a control surface in the notch

· 2 min read

building latch, and why the hook forwarder is the most important part of it.

i run several coding agents at once, and each one asks for permission in its own window. the one that's blocked is always the one i'm not looking at. latch puts all of those asks in one place: the macbook notch.

one queue, ordered by what's waiting on you

approvals, questions, failures, and completions from codex, claude code, cursor, copilot, and kimi land in one queue. blocking items sit first; completions wait quietly. each resolves in one action, without switching windows.

the forwarder

each tool already supports hooks. latch installs a tiny signed binary as the hook, which relays the event over a local unix socket to the app and waits for the answer.

swift
guard let socket = try? UnixSocket.connect(path: latchSocket, timeout: .milliseconds(150)) else {
    // latch isn't running: step aside and let the tool ask as it always has
    exit(passthrough)
}
try socket.send(event)
exit(try socket.awaitDecision())

the important line is the guard. if the app is down, the forwarder exits straight away and the tool falls back to its own prompt. latch can make supervising agents nicer. it must never be the reason one stalls.

a tool that sits in the critical path has to be able to disappear.

local-first

everything stays on the machine: no account, no server, no telemetry. it's in closed beta now with people who run agents all day.