v0.30.0Terminal agent · runs on your own machine

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
~/.local/share/horizon no root, no sudo SHA-256 verified Read the script first → Desktop app →
36model providers
37risk patterns checked
6layers of memory
0third-party packages

An illustrative session. Nothing runs until you press a key.

01 · Approval

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.

yRun it, once
aAllow this exact command all session
eEdit it first — risk is re-checked
nSkip — nothing executes
  • 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.
high risk~/projects/site
╭─ 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:

rm -rfsudomkfsdd if= curl … | shgit push --forcegit reset --hard git clean -fchmod 777shutdown Remove-Item -RecurseFormat-Volumereg addbcdedit
02 · Time machine

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
Read the nginx configturn 1 · no files changed
snapshot
Pointed the upstream at :8080turn 2 · 1 file changed
before-deploy
Rewrote the gunicorn unitturn 3 · 2 files changed
snapshot
/rewind before-deployfiles and conversation restored · /undo reverses it
you are here
03 · Memory

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.

L1
Semantic code indexfind code by what it does — TF-IDF over identifiers
L2
Symbol graphreal definitions and call edges, parsed from the AST
L3
Change impactwhich callers live in the files a checkpoint changed
L4
Verified factssmall confirmed memories, injected every turn
L5
Compaction checkpointsexact snapshots of long conversations
L6
Raw local archiveevery chat as JSON — never deleted, never uploaded

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.
04 · Long tasks

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.

05 · Models

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.

AnthropicOpenAIGoogle AI StudioOpenRouter DeepSeekxAIKimi / MoonshotQwen Cloud Z.AI (GLM)MiniMaxFireworks AIDeepInfra NVIDIA NIMHuggingFaceVercel AI GatewayGitHub Copilot Azure FoundryExperiential LabsOllamaLM Studio Upstage SolarXiaomi MiMoStepFunNovitaAI +12+ your own endpoint

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"}
06 · Everywhere

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.

$ horizonTerminalStreaming replies. ←← opens a chat picker; /transcript replays one.
127.0.0.1:7878Web consoleLive browser, keys, components. Password + authenticator sign-in when exposed.
Telegram · BaleMessagingReal bots with menus and buttons, locked to your allowlisted chat.
Discord · SlackTeam chatApprove or skip a proposed command with one button.
tailscale sshAny machinePick a device on your tailnet; commands run there. Same approval, same snapshots.
07 · Reference

The commands you'll actually use.

horizonStart the terminal agent
horizon 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 background
horizon browser navigate <url>Open a page in the real browser
/improveOpt in or out of sharing — off unless you turn it on
08 · Trust

Read 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.

Python 3.10+ No root or sudo SHA-256 verified Updates itself Interface in English and فارسی