The agent inside
One key opens it beside your work. The other half was telling it what only the editor knows.
Ctrl+Shift+A opens the agent drawer: a panel down the right of the window, in whatever you were already doing. Empty, it is the launcher — claude, codex, opencode and gemini written large, arrows and Enter to start one, the ones you do not have shown anyway and dimmed, so the empty drawer is also where you find out what CleeCode runs. Pinned it is a column of the layout and everything makes room for it; set to autocollapse it paints itself over the frames and withdraws the moment the keyboard goes back to your work. Dismissing it is not killing it: the agent goes on running and the conversation is where you left it. There is nothing to install and nothing to configure: this is a real pty, and all four are terminal programs. The agent is the TUI you already have, not a chat window rebuilt inside an editor.
With one running, that same Ctrl+Shift+A hands it whatever you are looking at — the selection, the diagnostic under the cursor, or the line the cursor is on — written at its prompt as path:line. And then it stops. Nothing is ever submitted: the text sits at the prompt and Enter is yours to press once you have read what you are about to ask. The way back was always there, since an agent prints file:line all day and a double-click opens it.
The files it rewrites reload on their own, the arrived lines lit green in the gutter until you type again or press Esc. A buffer with your unsaved edits never reloads itself: your work wins over the agent's, always. Follow mode — off until you ask for it — opens the files it touched beside your work without ever taking the keyboard; it watches the difference between two git status sweeps, so an agent and a sed in a shell trip it identically.
And the editor can answer back. clee --mcp makes CleeCode an MCP server with four read-only tools: open_files, selection, diagnostics, and open_file, which shows a file beside your work without touching your keyboard. One line of configuration per agent:
claude mcp add clee -- clee --mcp
codex, opencode and gemini take one line each in their own config file — the shapes are in the tour. The Claude Code line is the one verified against a running agent; the other three are written from those projects' documented shapes. Nothing writes to a buffer: reading has no risk and is offered generously, writing needs your consent, and the way to ask for it is not built yet.
Pictures, PDFs, Markdown
A terminal editor that shows you the file, not a description of it.
A .png gets a tab that draws it — real pixels, not a blank read-only buffer and not a wall of coloured blocks. An animated .gif plays there too, at the speed the file itself asks for, looping for as long as the tab is on screen. A PDF opens as pages you turn with the arrow keys. A Markdown file opens as a document beside its source.
chafa putting it into a terminal pane below, with the Run button beside it. The difference is the point — and it is not the terminal's fault.A program running inside a pane never talks to your terminal directly: it talks to the emulator in between, which turns everything into a grid of cells before repainting it, and graphics sequences do not survive that trip. CleeCode's pixels take the other road — out on the same channel as the rest of the interface, arriving at the host terminal intact. Which is also why the same picture keeps showing over an ssh session: what travels on the wire is the editor's output, not that of a program buried in a shell.
.tex, press Run, and the page beside it is the one you just typeset — it re-renders in place. On a preview tab the button says Refresh instead, because there the file is generated and can come out different.Every preview carries a navigation bar along its bottom edge: the page arrows, go to jump to a page by number, - and + for zoom, fit or wide to size the page to the pane or to its width. Each control is labelled with its own key, so the bar is also the reminder of how to work without the mouse. Documents get one control pictures do not — dark, which inverts the page for reading at night: inverting a photograph is not a reading aid, it is just a wrong photograph.
Best in a terminal that can draw pictures — Ghostty, kitty, WezTerm or iTerm2 — which is where it looks like these screenshots. Elsewhere pictures fall back to coloured half-blocks and Markdown to styled terminal text: less to look at, nothing missing. Previews reach for a few outside tools (poppler for PDF pages, pandoc or typst for Markdown as a real document); none is required, and without them CleeCode says so in the tab rather than leaving it blank.
Octave & Python
A live numeric session, with the panel beside it that no terminal gives you.
clee -w octave or clee -w pylab starts the interpreter you already have — in a terminal you can type into — and puts a second window beside it showing what that session holds: every variable with its size, class and range, filling in by itself whenever a command finishes.
figure(1) arriving as the fig1.png tab, the Octave prompt below it and the workspace panel beside — x and y with their size, class and range, listed without asking.Nothing CleeCode wants to know is typed at your prompt. Your transcript stays a record of what you did, and a busy interpreter is never interrupted mid-computation to answer a question about itself. Ctrl+Shift+X sends a cell to the running session, plots arrive as tabs beside the script that drew them, Ctrl+Shift+I looks inside a variable, and Ctrl+Shift+P sets a breakpoint — where the panel shows the frame's variables rather than the session's.
▶ Run on plot.py did not start a fresh interpreter: it typed exec(open(...).read()) at the prompt that was already there, so the session kept everything the file made — which is what the panel on the right is listing, and what lets the next line you type carry on from where the script left off.Everything works in both languages and almost none of it works the same way underneath. The full walkthrough says what is different between the two, and what is not built yet.
The day's work
Tabs, a split, git, and search that knows the whole project.
syntect highlighting over two-face's grammars — 200-odd languages, the ones written this decade included — multi-file tabs, a split editor sharing one pool of buffers, find and replace with regular expressions, project-wide search, code folding, and a column selection that writes: with a rectangle up, a printable key puts its character on every line of the block.
Words already in your buffers are offered as you type, along with what a language server suggests where one is installed — after a dot, in magenta, the names no amount of reading the file could have found — and its errors underlined where they are, with the message for the line you are on at the right of the status bar. When the line is clean, that spot says what the thing under the cursor is instead: the type, or one line of the signature. Nothing is pressed for it.
The commands you reach for every hour are all there. Ctrl+Shift+J goes to a definition and Ctrl+Shift+L comes back, a stack deep; Ctrl+Shift+Y lists every use of the name under the cursor and Ctrl+Shift+V the symbols of the file, both as filterable pickers. Ctrl+Shift+Q formats the buffer as a single edit and a single undo.
The two commands that write follow the git panel's discipline rather than the language server's enthusiasm. Ctrl+Shift+C renames the symbol under the cursor: the server's answer touches nothing until it has been shown to you as a diff, and then applies atomically, one undo step per buffer. Replace-in-project is the same shape widened to files nobody has opened — a second field in the search box, a preview grouped by file, open buffers taking one Ctrl+Z each and files on disk rewritten through a temporary file and a rename. There is no undo for that half, so the count is said out loud. Six refusals have a sentence each, because a rename that quietly skips a file is worse than one that will not run.
Ctrl+Shift+D opens a git panel that stages, commits, switches branch and draws the history as a graph — all of it through git on PATH rather than a library, so what the panel does is what the terminal beside it would do: hooks run, commits are signed, credential helpers are asked. Fetch, pull and push are typed into one of your shells rather than run behind the panel, and that is the point rather than a shortcut: they can stop to ask for a passphrase, a two-factor code or a host key, and a modal panel has nowhere to put such a question. A terminal is exactly the thing that can ask it.
It does not close on you
A broken terminal costs you that terminal, at most.
CleeCode hosts long-running shells, so a crash costing you an ssh session or a build would be the worst thing it could do. An internal failure is contained and reported in the status line rather than ending the process, and the details go to ~/.config/cleecode/panic.log. Files changed underneath you are reloaded only when they are not dirty; a binary or non-UTF-8 file opens read-only rather than being corrupted on save; and every write goes out through a temporary file and a rename.
The shield keeps the process alive; it cannot help against a SIGKILL or a stack overflow, so those are covered separately. Every few seconds the buffers you have changed since the last tick are copied into a recovery folder under ~/.config/cleecode — the config directory and not the temp one, because this data exists precisely to outlive the process. At the next start a picker offers back anything newer than the file on disk, including the unnamed buffer that no session file could have remembered. Enter restores it dirty: saving stays a decision, and one Ctrl+Z is the version on disk.
That promise is tested the only way it can be: a driver kills the editor with kill -9 and watches the text come back. Not a unit test — the real binary, really killed.
Nine themes, and the far end of an ssh
The IDE that works over ssh with nothing to install on the far end.
Five dark themes and four light ones. The button beside the background toggle on the menu bar opens the list, or View → Theme… if your hands are on the keyboard. The choice is written out at once, because the reason to reach for it is usually that the screen has become hard to read, and having to make it again next session would be its own small misery.
That is the ground CleeCode stands on. Not VS Code's, and not Zed's: one binary, batteries included, the mouse working, the compiler's output clickable — on a server you reached over ssh, with nothing installed at the far end and nothing to configure before the first hour is useful. The git panel deliberately speaks the old spellings (reset HEAD --, stash save) because a long-lived server reached over ssh is exactly where the newer commands are missing. Drop a file onto a terminal inside an ssh session and it goes up with scp.
English and Italian throughout, menus and built-in manual included. The ◐ at the right-hand end of the menu bar fills in the background, for a translucent terminal with something bright behind it — which is worth knowing the other way round too: by default CleeCode paints no background of its own, so a translucent terminal shows your desktop through the editor.
Install
Three lines on macOS and Linux.
brew tap msavox/clee
brew trust msavox/clee
brew install clee
brew trust exists from Homebrew 6 onwards, and there it is required rather than a formality: a formula is Ruby code Homebrew executes locally, so it refuses to load one from a third-party tap until you trust the source. On older Homebrew the command does not exist and is not needed — skip it and install. The formula builds from source: well under a minute on macOS, longer on Linux, where it also pulls libxcb.
Prebuilt binaries
Attached to every release, each built on the architecture it names.
-
macOS arm64
Apple silicon. The supported platform: where CleeCode is developed, tested and released.
-
macOS x86_64
Intel Macs.
-
Linux x86_64
Needs glibc and libxcb —
libxcb1on Debian/Ubuntu,libxcbon Fedora/Arch. For Alpine or musl, build from source. -
Linux arm64
An Ampere or Graviton server, and a 64-bit Raspberry Pi OS. Same libxcb note.
-
Windows x86_64
Compiles and starts in CI. Not yet driven daily by anybody — treat it as experimental, and bug reports are welcome.
Outside macOS the binaries are experimental: Linux and Windows are written for throughout — paths, clipboard, shell, fonts, venvs — and compile in CI, where the binary is also started to confirm it links and launches. Beyond that nobody has used the editor there.
From source
Needs a Rust toolchain 1.85 or newer (edition 2024). On Linux the clipboard also wants the X11/xcb headers; on Windows, the MSVC toolchain plus Desktop development with C++.
cargo install --locked --git https://github.com/msavox/cleecode
That puts clee in ~/.cargo/bin, so make sure it is on your PATH. Then clee --install-font installs the bundled Nerd Font for the file tree's icons, and on macOS clee --install-app builds CleeCode.app so the editor can live in the Dock like any other.
What this page describes. Everything above is built and tested — nothing here is a plan. Some of it landed after the last tag and ships in the next release: the refactoring commands, replace-in-project and crash recovery are on master now, so cargo install --locked --git has them today, while Homebrew and the attached binaries follow the last tagged version. The release notes say which is which, release by release.