Spike

Spike is my take on the Interaction Company's Poke - a self-hosted personal agent with a personality that lives in one trusted iMessage conversation on your Mac.

Spike runs locally, powered by the Codex App Server. It gives a single configured person a direct line to Codex, and keeps the computer, configuration, journal, and credentials under the owner’s control.

What I built

Spike turns a direct iMessage conversation into a durable interface for a Codex agent.

During onboarding, it lets the owner choose the trusted conversation, working directory, response style, model and reasoning settings, approval policy, sandbox, and optional personal context. Nothing is installed until the final review is confirmed. Applying the setup writes the configuration, installs a user LaunchAgent, runs diagnostics, and waits for a real round trip in the selected conversation.

I run Spike as a daily-driver personal assistant, powered by GPT 5.6 Luna in fast mode. It has access to my whole computer, 706 tools, and is extremely reliable! I can even message it from my Apple Watch!

Once running, Spike:

  • accepts messages only from the configured direct chat;
  • runs Codex locally with access to the owner’s chosen working directory and tools, including CLI tools;
  • stages inbound attachments safely for the agent;
  • persists work, delivery state, approvals, and recovery information in a local SQLite journal;
  • recovers work across daemon and Codex app-server interruptions;
  • supports a compact operator surface: status, doctor, logs, accounts, and approvals; and
  • routes supported permission requests back through the same conversation, one at a time, with exact /yes and /no replies.

The security model is deliberately explicit. The configured peer is trusted input. Spike validates the conversation identity, participant, service, and message direction before scheduling work. It also keeps its Codex configuration and authentication isolated from the user’s normal Codex installation.

How I built it

Spike is an open-source macOS application written in TypeScript with Effect v4 and the Bun runtime. It uses the Codex App Server as its agent harness, the local Messages database for ingestion, macOS automation for replies, launchd for persistent operation, and SQLite for durable state.

I used to have a hacky, grey-market version of Spike built around Claude Code and a forked version of Anthropic's iMessage plugin. I've recently been moving everything to Codex, and Build Week was the perfect excuse to rewrite Spike entirely on top of the Codex App Server. I used GPT-5.6 Sol in fast mode to plan everything, discuss the Effect Schema shapes and TypeScript interfaces, and then spec the whole build. On Saturday, I attended the Build Week hackathon in London, where 5.6 Sol Ultra spent all day crunching through the Linear tickets until it was complete. GPT-5.6 was particularly useful for reasoning through the awkward parts of an always-on local agent: recovery after interrupted turns, conversation isolation, attachment staging, approval state, etc.

What I learned

Simplicity is king. Unlike complex, batteries-included agent harnesses like OpenClaw, Spike does one thing and tries to do it well. The Codex App Server gives us extremely powerful primitives, and there are very few things I needed to reimplement, like task scheduling.

Challenges

macOS privacy permissions are tied to the exact executable, which makes a polished local install surprisingly delicate. Reading Messages, sending replies, and optionally reacting to messages or showing typing indicators each have different permission and session constraints.

The second challenge was reliability. Codex, launchd, Messages, provider authentication, and local tools are separate systems with separate failure modes. Spike uses a local journal and conservative recovery behavior to avoid silently losing work or duplicating delivery, but it also exposes spike doctor, spike status, and bounded logs because recovery should be inspectable.

Finally, I had to make powerful defaults understandable. An unattended agent can be configured with broad local access, but that is a real trust decision. Spike makes the chosen conversation, working directory, sandbox, and approval policy visible during onboarding.

Built With

Share this project:

Updates