The agent that asks first — and can always go back.
Horizon proposes every shell command for your approval, snapshots your files before each one runs, and rewinds your work and the conversation together. Python 3.10+ standard library only — there is nothing to pip install.
curl -fsSL https://horizon.mahanmirzaee.com/install.sh | sh
● horizon:claude-sonnet-5 ❯ the api has returned 502s since this morning — find out why ✦ Horizon (claude-sonnet-5) │ Checking whether the upstream is still listening where nginx expects it. ╭─ proposed command ────────────────────────────────────────────╮ │ ss -ltnp | grep -E ':(8000|8080)' │ cwd ~/srv/api · risk low · snapshot before run ╰─ [y] run [a] always [e] edit [n] skip ──────────────────────────╯ y ┌─ running ss -ltnp | grep -E ':(8000|8080)' │ LISTEN 0 4096 127.0.0.1:8080 users:(("gunicorn",pid=2214)) └─ exit 0 · 0.04s ✦ Horizon · step 2 │ Gunicorn moved to 8080; nginx still proxies to 8000. One line in │ sites-enabled/api fixes it. Files are snapshotted — /rewind undoes it. 2,214 in · 96 out · 2,310 this task ● horizon:claude-sonnet-5 ❯
An illustrative session. Nothing runs until you press a key.
Nothing reaches your shell until you press a key.
When the model wants to run something, you see the exact command, the directory it will run in, and a verdict from 37 risk patterns covering bash and PowerShell. Then it waits.
Four keys decide every command.
- Only a ```bash fence is executable. A ```python or untagged block is read-only.
- /auto runs everything else unattended — and still stops for anything destructive.
╭─ proposed command · HIGH RISK ────────────────╮ │ rm -rf build/ dist/ node_modules/ │ │ ! recursive/forced delete │ cannot be allowlisted for this session ╰─ type run to execute — anything else skips ❯
Always red, never allowlistable, needs run typed in full:
Every change can be undone — the conversation included.
Before each approved command, Horizon commits your working directory to a shadow git repository under ~/.horizon/sessions. It never touches your own .git.
Rewind a turn, and the agent forgets the detour too.
Files and chat go back together, so the model doesn't keep reasoning from a change you just undid. Snapshots survive restarts.
- /checkpoint before-deploy — name the current files and conversation
- /rewind before-deploy or /rewind -1 — back to a name, or one turn
- /undo — reverse the last rewind
- /timeline — every turn, checkpoint and branch
It understands the code, not just the chat.
Six layers, all on your disk, no embedding model. Ask who calls a function and get the real callers from Python's AST — not a guess from text search.
Teach it once. It keeps it.
- /remember <fact> — kept for every future session
- /add_to_memory_start … /add_to_memory_end — record a stretch of conversation as one memory
- add action <name> — save how something was just done as a skill, loaded only when it's relevant
- Chats are named by the model after their subject. A name you type is never overwritten.
Built for work that takes more than one prompt.
Long tasks fail in boring ways: a key runs out, a server never exits, a page needs a real browser. Each one has a specific answer.
Servers don't hang it
A command that stays alive but goes quiet — 3 s for a known server, 10 s for anything else — moves to the background with its output so far. horizon jobs stop <id> ends it.
Keys that don't stop you
Several keys per provider. A 429 or a rejected key rotates to the next one mid-run. If every key fails, the answer is finished on another provider — and it tells you which.
A real browser, not curl
Headless Chromium on port 2727 runs JavaScript and keeps cookies. horizon browser navigate <url>, then text. You watch it live; CAPTCHAs are handed to you, never bypassed.
Steer while it works
Type mid-run. Your note is read at the next step, without interrupting the one in progress — no need to stop and start over.
Six thinking levels
Minimal · Low · Medium · High · Extra High · Ultra — mapped onto whichever provider is active, with /think.
One button for the rest
Node, Playwright, Chromium and an audio recorder are built per platform, so they are fetched for your machine. Settings › Components installs whatever is missing.
36 providers. Or your own endpoint.
/model switches everywhere at once — terminal, console and chat bots. Any OpenAI-compatible endpoint can be added with a name, a base URL and an optional key.
Paste keys the way you already have them.
Commas, one per line, a JSON array, or a JSON object naming several providers at once — by provider id or by environment variable.
sk-one, sk-two, sk-three
["sk-one", "sk-two"]
{"openrouter": ["sk-one", "sk-two"], "ANTHROPIC_API_KEY": "sk-three"}
One conversation on every surface.
Start in the terminal, continue in the browser, approve from your phone. The same chat, the same model, one history in ~/.horizon/chats.
The commands you'll actually use.
horizonStart the terminal agenthorizon serveOpen the web console on 127.0.0.1:7878/modelSwitch model — applies to terminal, console and bots/autoAll-accept mode; still stops for destructive commands/checkpoint <name>Bookmark the files and the conversation/rewind <name|-1>Go back to a checkpoint or a turn/undoReverse the last rewind/transcriptReplay the whole conversation/remember <fact>Keep a fact for every future session/jobsServers and log follows left running in the backgroundhorizon browser navigate <url>Open a page in the real browser/improveOpt in or out of sharing — off unless you turn it onRead it before you run it.
A one-line curl | sh asks you to trust a stranger's script — and Horizon's own risk checker flags exactly that pattern. Here is the careful version:
curl -fsSL https://horizon.mahanmirzaee.com/install.sh -o install.sh && less install.sh && sh install.sh
- Chats stay on your disk as JSON. Nothing is uploaded unless you opt in with /improve.
- If you do, secrets are stripped on your machine first, usernames and passwords are never sent, and reports are deleted after 30 days.
- The installer verifies a SHA-256 checksum before unpacking and never asks for sudo.
- The console listens on loopback only. Expose it through a tunnel and it asks for a password and an authenticator code.
Horizon began as an instrument for one question: does an agent that can find its own mistake and roll back to before it finish long tasks more often than one that simply starts over?
Install Horizon in one line.
Then type horizon and tell it what you need.
curl -fsSL https://horizon.mahanmirzaee.com/install.sh | sh
Or download the desktop app
On a Mac, open the .dmg and drag Horizon into Applications. The first time, right-click Horizon and choose Open, since it isn't from the App Store yet; it installs everything it needs on first launch. On Windows, run the installer; Horizon then appears in the Start menu.