push is a tiny personal assistant gateway. You text it, it sends the message to a configured coding-agent runtime, then it sends the answer back.
The product is the gateway: messaging, allowlists, routing, assistant profile, memory, and conversation state. The agent runtime is deliberately disposable. Claude Code and Codex are the first two backends.
iMessage -> push gateway -> Claude Code or Codex -> iMessage reply
- Poll
~/Library/Messages/chat.dbfor new messages. - Keep only messages from yourself or configured allowed senders.
- Map each conversation to the active backend session.
- Load your assistant context from
assistant/User.mdandassistant/Memory.md. - Run the configured backend headlessly.
- Send the final answer back through Messages.
Memory is plain markdown you own. The gateway injects it into each run, so you can read it, edit it, and version it without learning a custom memory database.
Coding agents are becoming commodity runtimes. Claude Code, Codex, Cursor, AMP, Pi-style agents, and independent agents all compete on the same layer: tool use, repo edits, command execution, MCP, plugins, model choice, and coding workflow.
push does not try to win that layer. It treats those agents as workers behind a small contract: given this user message and assistant context, produce the reply or task result that should be sent back.
push owns the personal assistant layer:
- Message ingress and egress.
- Sender allowlists and reply loop prevention.
- User-owned assistant config.
- Durable memory files.
- Conversation to backend-session mapping.
- Routing between channels and runtimes.
The framing is personal assistant first, coding agent second. The backend may be Claude Code today and Codex tomorrow, but the assistant identity, memory, and messaging relationship stay with push.
See docs/strategy.md for the full direction.
Claude Code uses claude -p with --session-id for new conversations and
--resume for existing conversations. Assistant context is passed with
--append-system-prompt, so Claude Code keeps its normal tools, MCP servers,
permissions, login, and CLAUDE.md behavior.
Codex uses codex exec in non-interactive mode. The first run captures the
Codex thread id from JSONL output; later turns resume that session with
codex exec resume. Assistant context is included in the prompt because Codex
does not expose the same --append-system-prompt flag as Claude Code.
- iMessage channel.
- Claude Code backend.
- Codex backend.
- Read-only memory files.
- One configured backend at a time.
- macOS with iMessage signed in.
- Full Disk Access for your terminal so push can read
chat.db. osascript, which ships with macOS.- At least one backend on your
PATH:claudefor Claude Code.codexfor Codex.
- A recent Rust toolchain.
Install the latest release:
curl -fsSL https://raw.githubusercontent.com/owainlewis/push/main/install.sh | shOr build from source:
git clone https://github.com/owainlewis/push.git
cd push
cp config.example.json config.json
# edit config.json: set self_handles and choose "agent": "claude" or "codex"
cargo build --release
./target/release/pushThen text yourself in Messages. The reply comes back in the same thread.
Tagged releases publish binary archives for Linux and macOS on GitHub Releases. Release notes are generated from the merged pull requests and commits for the tag.
To create a release:
git tag v0.1.0
git push origin v0.1.0The release workflow builds with cargo build --locked --release, packages the
binary with README.md, LICENSE, and config.example.json, uploads checksum
files, and publishes generated notes.
The project site is published with GitHub Pages from the static files in
site/. Once Pages is enabled for GitHub Actions in the repository
settings, pushes to main deploy the site automatically.
/clear,/new,/reset: start a fresh backend session./help: list commands.
{
"agent": "codex",
"routes": [
{ "thread": "self:you@icloud.com", "agent": "codex" }
],
"assistant": {
"name": "push",
"tone": "short, direct, and useful",
"business": "Describe your business or work context here.",
"projects": ["push"],
"preferences": ["Prefer concise replies."]
},
"self_handles": ["you@icloud.com", "+15551234567"],
"allow_from": [],
"claude_bin": "claude",
"claude_permission_mode": "bypassPermissions",
"codex_bin": "codex",
"codex_sandbox": "workspace-write",
"codex_approval_policy": "never"
}agent can be claude or codex.
routes can override the backend for exact thread keys like
self:you@icloud.com or dm:+15551234567.
An inbound text is an instruction to an agent with tool access. Keep
allow_from tight.
Claude Code defaults to bypassPermissions for headless use. Codex defaults to
workspace-write plus never approval for non-interactive use. Both settings
should be treated as powerful automation. Use the least access that still makes
the assistant useful, and run broad-access modes only in an environment you
control.