$ kolu — the terminal, done right
The terminal
built for many.
Not a chat-UI wrapper.
Not an editor fork.
A real terminal — just better at scale.
Real xterm.js tiles on an infinite 2D canvas, with a dock that surfaces every terminal's live state at a glance — and a code browser where you comment on any file and hand it straight to the agent. claude, codex, opencode — anything you can run in a shell, runs in kolu.
quickstart
From zero to running.
kolu is packaged with Nix. Install Nix with flakes enabled, then run a single command. The same command runs kolu
and updates it — --refresh busts Nix's flake cache so
you always pull the latest commit.
# run (or update) kolu — serves on 127.0.0.1:7681
$ nix --refresh run github:juspay/kolu
# expose on LAN with a custom host / port
$ nix --refresh run github:juspay/kolu -- --host 0.0.0.0 --port 8080 Open http://127.0.0.1:7681 (or the address you chose). You should see kolu open with an empty canvas.
first 5 minutes
Open a repo, launch an agent.
The whole point lands in one move: open a repository and start an agent in its own tile. kolu watches what you do, so you barely configure anything.
- 1
Open the command palette
Press Cmd/Ctrl + K. This is kolu's canonical search surface — terminals, themes, actions, repos, all from one box.
- 2
Drill into New terminal → your repo
Recent repos appear automatically — kolu tracks the directories you
cdinto. Pick one and the worktree-naming leaf opens with a name pre-filled (a random adj-noun) and an agent picker below. - 3
Pick an agent — or just hit Enter
Any agent CLI you've run before (
claude,codex,opencode, …) shows as a launch option. Choose one and kolu creates a fresh worktree and launches the agent in one step. Or hit Enter to land in a plain shell. - 4
Watch the dock
The new tile's dock row pulses while the agent is working and breathes when it's waiting on you — so a glance tells you who needs attention, even across many tiles.
core concepts
The vocabulary.
Eight ideas cover almost everything. Learn these and the rest of kolu reads like plain language.
- Canvas
- An infinite, mode-less 2D plane. Pan with two-finger scroll, zoom with pinch or Ctrl + scroll, snap to a 24px grid. No boundaries — spread terminals out like Figma or Excalidraw.
- Tiles
- Every terminal is a draggable, resizable tile — a real xterm.js instance: WebGL rendering, clickable URLs, inline images (sixel / iTerm2 / kitty), splits, 200+ themes, and a mobile key bar. Double-click the title bar to maximize.
- Dock
- The left-edge navigator — the canonical at-a-glance list of every live terminal. Repo-tinted rows show branch, agent state, and PR/CI status; the state pip's shape tells you who's working vs. awaiting you.
- Worktrees
- Creating a terminal in a repo branches a fresh git worktree under the hood. The name you type becomes the branch and shows verbatim on the dock row, so parallel work stays identifiable.
- Command & sub-palette
- Cmd/Ctrl + K opens the unified palette; drilling into a row opens a sub-palette (e.g. repo → worktree name → agent). Cmd/Ctrl + Shift + K jumps straight to the workspace grid.
- Auto-detection
-
kolu populates itself by watching you — recent repos from
cdevents, recent agents from shell command marks, branch / PR / CI from each terminal's working directory. If kolu knows it, the shell told it. - Git & GitHub
- Each terminal knows its repo: branch, PR number, and CI status are read from its working directory and shown right on the dock row — no token pasting, no config. Creating a worktree and launching the agent in it is a single palette step.
- Comment on any file
- Select text in the Code tab — source, a branch diff, or a rendered artifact — and pin a quoted note to it. The per-terminal tray flushes to Markdown you paste straight back into the agent, which re-locates each comment by quote-matching even after the file changes.
how-to Using the code browser
The right-hand panel carries an Inspector tab and a Code tab. The Code tab is a full file browser scoped to the active terminal's repo: a Pierre file tree with git-status tinting (modified / added / untracked, with every changed subtree's ancestors tinted too) over a syntax-highlighted source view.
-
Click a
path/to/file.ts:42reference in terminal output to jump straight to that line. - Markdown renders as a reading document with a Source ⇄ Rendered toggle; repo-relative links open the target file right in the tab.
-
Agent-generated
.html/.svg/.pdfartifacts preview inline in a sandboxed iframe, live-reloading on change. - Select text in any file — source, branch diff, or rendered artifact — and leave a quoted comment; the tray flushes to Markdown you paste back into the agent.
how-to Working the canvas view
The desktop workspace is mode-less — there's no separate "edit" mode. Terminals are tiles you arrange freely.
- Pan with two-finger scroll; hold Shift to force pan even when the cursor is over a tile (hand-tool style).
- Zoom with pinch or Ctrl + scroll; tiles snap to a 24px grid on drag and resize.
- Maximize a tile by double-clicking its title bar; the posture persists across reload.
- Arrange canvas by repo (from the palette) clusters each repo's tiles into an island — a one-shot action that leaves new tiles where they open.
- The minimap heatmap dots any tile whose agent is waiting or thinking, so you can scan a 20-tile workspace for "who needs me".
pin it as an app
Install kolu as a PWA.
Pinning kolu gives it its own window, a dock / home-screen icon, and — on a secure context — a live badge plus desktop notifications for finished agents. But there's one rule that trips everyone up, so read this first.
Install per browser — the one-click paths need HTTPS or
localhost; the manual paths work over plain
http:// too:
Chromium desktop / Android
Chrome, Edge, Brave, Arc. On HTTPS/localhost: the Install
icon in the address bar, or ⋮ menu → Install app (the
one-click path). Over plain http://: ⋮ → Save and
share → Create shortcut… and tick Open as window
for the same app window.
iOS — Safari / Chrome / Edge / Firefox
Tap Share ⬆ → Add to Home Screen. iOS has no install API, so this is the only path — and since iOS 16.4 it works from any of these browsers, not just Safari.
Safari desktop (macOS Sonoma+)
Safari 17 on macOS Sonoma or newer: File → Add to Dock. Works on any page; no install event needed.
Firefox desktop
No native PWA install yet (Taskbar Tabs is still experimental). Use Chrome or Edge to install, then keep using Firefox for browsing if you like.
reach it anywhere
Tailscale: HTTPS + your phone, one command.
Here's the payoff that ties the last two sections together: the same Tailscale command that makes kolu reachable from your phone is what gives it the HTTPS secure context that unlocks one-click install and the app badge. One move unlocks both.
- 1
Install Tailscale on both devices
Put Tailscale on the dev box and the phone / laptop, signed into the same account. They join one private tailnet.
- 2
Enable MagicDNS + HTTPS Certificates
In the admin console → DNS, turn on MagicDNS, then HTTPS Certificates (a one-time toggle). This lets Tailscale issue a real Let's Encrypt cert for your machine.
- 3
Serve the port
On the dev box, point Serve at kolu's port (
--bgkeeps it running across reboots):$ tailscale serve --bg 7681 → Available within your tailnet: https://your-box.your-tailnet.ts.net/ - 4
Open the printed URL on your phone — and install
Visit the full
https://<machine>.<tailnet>.ts.netaddress. It's a genuine HTTPS secure context, so the Install / Add to Home Screen affordance now appears. Pin it from there.
One more honesty note: your …ts.net hostname lands in public
Certificate Transparency logs (that's how the public web verifies certs), so
don't bake secrets into machine names. Manage everything with tailscale serve status, tailscale serve reset, and tailscale serve off.
Which tunnel? A decision aid.
Serve covers "just my devices." If you need something else, match the intent:
tailnet-only, real HTTPS, zero config once MagicDNS is on. The default.
expose to the world, but force a login (SSO / email) before anyone reaches it.
a quick share link for a demo. No auth — tear it down after.
how-to Worktrees — the parallel-work model
Each terminal you create in a repo is backed by its own git worktree, so several branches check out side by side without stashing or re-cloning.
- Press Cmd/Ctrl + Shift + Enter to open the New terminal menu, then pick a recent repo and name the worktree — kolu branches it and (optionally) launches the agent in one step. (The command palette → New terminal is the same flow.)
- The worktree name you type in the palette becomes the branch name and shows verbatim on the dock row.
- Branch, PR number, and CI status are derived from each terminal's working directory — no manual wiring.
- Run five agents on five branches at once; the dock keeps every one distinct, suffixing a stable id when two share a repo + branch.
power features
Run many, lose none.
kolu is built for the moment you're running five agents at once. These are the tools that keep that legible.
- Multi-agent at scale
-
The dock pulses for working agents and breathes for awaiting ones; a
finished background agent fires a loud violet ping plus a toast with a
Switch action that pans the canvas straight to it —
and, on an HTTPS/
localhostkolu with notifications granted, a native OS notification you can click to jump to that terminal, even when kolu is in the background. - Keybindings
- Cmd + T new terminal, Cmd + Shift + Enter opens the New terminal menu (worktree creation), Cmd + 1…9 jump, Ctrl + Tab cycles in MRU order, Cmd + / shows the full shortcut help. Splits: Ctrl + `.
- Sessions
- Layout, themes, and maximized posture persist across reloads via localStorage, so you land back exactly where you left off. The activity-window filter hides stale rows without killing them.
how-to Sessions — save, restore, and tidy
kolu remembers your workspace without a save button — but you stay in control of what's on screen.
- Reopening kolu restores your tiles, their themes, and the maximized tile if you had one.
- The activity window (All / 4h / 12h / 24h / 48h, default 24h) hides rows older than the cutoff from the dock; "show all" brings them back. Hidden tiles stop counting toward the dock badge.
- A fresh agent transition automatically resurfaces a hidden terminal, so nothing important stays buried.
how-to Export & record what your agent did
Two ways to share a session beyond the live workspace:
- Transcript export — save any Claude Code, Codex, or
OpenCode session as a single self-contained
.html: shiki code, real diff views for every edit, dark/light toggle, no external assets. Opens offline anywhere. - Workspace recording — one click in the chrome bar
captures the whole kolu tab with mic and optional webcam PiP, streamed
to a local
.webm. Pause / resume with ⌘⇧..
faq / troubleshooting
Common snags.
#1 I see no one-click Install button
You're almost certainly on plain http:// — a LAN IP or a
Tailscale 100.x address. The automatic Install
prompt needs an HTTPS secure context, so it's hidden there — but you can
still pin manually: Chrome ⋮ → Save and share → Create shortcut →
Open as window, or iOS Share → Add to Home Screen.
For the one-click prompt plus the live app badge, open the
https://…ts.net URL from Reach it anywhere.
#2 I'm not getting desktop notifications when an agent finishes
kolu fires a native OS notification when an agent finishes in a terminal you're not actively watching — a background terminal, or any time kolu isn't the focused window. If you're looking right at that terminal as it finishes, the on-canvas dock surfaces it instead and no banner fires (by design). Past that, work these in order:
- Secure context. Notifications ride a service
worker, which only registers over HTTPS or
localhost— the same rule as the app badge. Over plainhttp://(a LAN IP or Tailscale100.x) there's no worker, so no banner. Give kolu anhttps://…ts.netURL — Reach it anywhere ↑. - Grant permission. The browser asks once; if it was dismissed, re-enable it via the address-bar lock icon → Notifications.
- Let the OS through — the step that trips everyone. The site toggle being on is not enough: your browser must itself be allowed to post notifications at the OS level. On macOS: System Settings → Notifications → Google Chrome (or the pinned kolu app — it gets its own entry, separate from Chrome) → Allow, style Banners or Alerts, and turn off Focus / Do Not Disturb. Relaunching the browser after toggling helps it take effect.
Quick check: open DevTools console on kolu and run
navigator.serviceWorker.getRegistration().then(r =>
r.showNotification('test')). If that banner shows, the OS layer is fine and it's the
"not watching" rule above; if it doesn't, it's the OS-level setting.
q Can I use it without Tailscale?
Yes — locally over localhost everything works, including
one-click install (loopback is an HTTPS exemption). Tailscale only
matters when you want to reach kolu from another device — and want the
frictionless one-click install plus app badge there (manual pinning
works over plain HTTP regardless).
q Which agents does kolu support?
Run any agent. The terminal is the interface, so
aider, gemini, or whatever ships next week
works the moment you run it — and any CLI you've run joins the
palette's recent-agents list with no adapter and no config file.
Three get first-class integration today —
claude (Claude Code), codex, and opencode. For these, kolu reads live agent state into the dock
(working ▸ / awaiting ⏵ / idle ☾) and can export the session as a
self-contained HTML transcript. Any other agent still runs in its
tile — it just doesn't light up the dock.
q How do I update kolu?
Re-run the same command: nix --refresh run github:juspay/kolu.
The --refresh flag busts Nix's flake cache so you always pull
the latest commit. For a long-lived service, wire it into a home-manager
module (see the
deployment guide).
q I closed the welcome — how do I get it back?
Open the palette (Cmd/Ctrl + K) and run Tutorial (alias "Welcome"). It re-summons the welcome overlay anytime, even while you're working.
Still stuck? The source, issues, and full README live on GitHub.
juspay/kolufrom the blog
all posts →odu: a CI runner for agents and humans
odu runs your project's CI across real machines over ssh, holds the run as live typed state instead of a pile of log files, and exposes that one state as three frontends — a terminal dashboard, an MCP server your agent drives, and a web dashboard on the way. Here's what it is, and how the @kolu/surface stack makes it cheap.
read →