The feature I wanted is the one that sounds like a malfunction: my mouse moving on its own, to the right button, while I sit there not touching it.
You cannot build that in a browser tab. A chatbot in a tab reads what you paste into it and writes back; it cannot see the web app you are actually working in, and it certainly cannot click anything. To get what I wanted — something that lived on my OS, could see what I was doing on web apps, and could literally take over my mouse to automate tasks for me — I needed three things a tab will never hand you: low-level OS hooks to control the mouse and capture audio, local AI inference so I wasn’t beaming my private screen data to the cloud, and a way to securely inject UI overlays into web apps. Each of those wants to live somewhere different, which is the whole reason the system has the shape it does.
Three layers, because nothing wanted to share
To make this work without freezing up the user’s computer, I had to separate the heavy lifting from the UI. I ended up splitting the system into three main layers:
- The Native Core (Rust): I needed something insanely fast, so I went with Rust. This layer talks directly to the OS. It handles hardware-accelerated local AI inference (running Speech-to-Text and a Small Language Model right on the GPU). It also manages a constant audio ring-buffer so it’s always listening, and it calculates the Bezier curves needed to make the synthetic mouse movements look like a real human is moving the cursor.
- The IPC Bridge: This is the nervous system. It’s a secure message bus that shuttles events (like microphone state or AI text tokens) between my Rust backend and the web frontend.
- The Web Overlay (Injected DOM): A JavaScript payload that gets injected right into whatever web app the user is looking at. It renders the floating command palette and the “ghost cursor”. More importantly, it scans the web page’s accessibility tree and slaps numerical markers on everything you can click. I call this the “Set-of-Marks” (SoM). It’s how the AI actually “sees” the screen to know exactly what X/Y coordinates to click.
The two problems that earned the native core
- The “Clipping” Problem: Ever use a voice assistant that misses the first word you say? I fixed that by building a continuous 750ms audio pre-roll buffer. It’s constantly recording a tiny loop, so the second you hit the hotkey, it already has the start of your sentence.
- Keeping it Private: By forcing all the AI processing (the Whisper transcription and the SLM reasoning) onto the local Metal GPU, the app can look at highly sensitive web apps without sending a single byte to an external API.
Neither survives a round trip to a server, which is why there is a Rust layer at all.
Who wrote it
A multi-threaded Rust backend, an IPC layer, and an injected TypeScript frontend is months of work for a solo dev. I did not have months, so I built it agentically.
Instead of writing every line myself I acted as the system architect: I wrote the blueprints and spun up a team of AI coding agents to do the heavy lifting in parallel. A Systems Agent lived in the Rust codebase, wiring up the OS hooks. A Frontend Agent built out the isolated DOM injection scripts. And a QA Agent did nothing but enforce the IPC contracts between the two.
That third one is the agent I would not have thought to staff with humans. Whenever the Systems Agent changed how a Rust struct was serialized, the QA agent caught the breaking change over the IPC bridge and told the Frontend Agent to update the TypeScript interfaces. The seam between two specialists is where work rots, and neither of them owns it. Giving that seam its own agent was the closest I got to an engineering team rather than three fast strangers.
Building an agent out of other agents was a strange few weeks, and on the evidence so far it is how I intend to ship complex software from here on.