01
Installing
Install Jai with one command. There are builds for Linux on x86_64, macOS on Apple silicon and Windows on x86_64. The installer downloads the build for your machine and checks it against the release before installing it.
Linux and macOS
curl -fsSL https://michael.sinax.be/jai/releases/install.sh | sh
The Linux build runs on any distribution, including WSL. The installer needs curl and sha256sum or shasum, which most systems have.
- Jai goes in
~/.local/bin. The installer tells you if that folder isn't on yourPATH. - If Jai is already installed, it is replaced where it is, and the previous version is kept next to it as
jai.old. A running session switches to the new version and keeps all its windows.
To change what the installer does, set these before sh:
| Setting | Effect |
|---|---|
JAI_INSTALL_DIR=DIR | Install into DIR instead. |
JAI_SWITCH=no | Leave a running session on the version it has. |
curl -fsSL https://michael.sinax.be/jai/releases/install.sh | JAI_INSTALL_DIR=~/bin sh
Windows
Jai runs natively on Windows 10 (version 1809 or later) and Windows 11; it works best in Windows Terminal. Install it from PowerShell:
irm https://michael.sinax.be/jai/releases/install.ps1 | iex
- Jai goes in
%LOCALAPPDATA%\Programs\jai, and the installer adds that folder to yourPATH. Open a new terminal to use it. - If Jai is already installed, it is replaced where it is, and the previous version is kept next to it as
jai.old.exe. - A running session keeps using the old version until you restart it with
jai kill-server, which closes every window. See Updating. - The same settings work as PowerShell variables:
$env:JAI_INSTALL_DIR = 'C:\Tools\jai'before running the installer. Windows PowerShell 5.1 and PowerShell 7 both work. - Windows on Arm runs the x86_64 build.
Each window runs your shell: PowerShell 7 if you have it, otherwise Windows PowerShell, or cmd as a last resort. Set SHELL to a Windows path to choose another. Closing a window ends the console programs in it; programs with their own window keep running. To connect to other machines, Jai uses ssh from Windows' OpenSSH client.
By hand or from source
To install by hand, download jai-x86_64-unknown-linux-musl (Linux) or jai-aarch64-apple-darwin (macOS) or jai-x86_64-pc-windows-msvc.exe (Windows), check its SHA-256 against latest.json, and put it on your PATH as jai (jai.exe on Windows). You can also build from source with cargo install --path .; those builds don't check for updates.
Getting started
Run jai. It attaches to your session, starting one if none is running.
You have one session. Detach with prefix q (ctrl+b then q); your shells and agents keep running, and running jai again brings you back. Press prefix ? at any time for a list of keys.
The session ends when its last window closes, or when you run jai kill-server, which closes every window.
02
Commands
Run these from any shell. Inside a Jai window, jai name and jai send know which window they are run from.
| Command | What it does |
|---|---|
jai | Attach to the session, starting it if needed. |
jai new RUNTIME | Start an agent in a new window. See Starting agents. |
jai agents | List running agents with their window, state, queued messages, project and branch. |
jai name [NAME] | Show or set the name of the current window. |
jai rename OLD NEW | Rename a window. OLD is a name or window number. |
jai send NAME MSG | Message an agent. Use - as the message to read it from stdin. |
jai connect HOST [CMD] | Show another machine's windows here. See Other machines. |
jai disconnect HOST | Stop showing a machine. |
jai hosts | List machines and whether they are connected. |
jai notify [on|off|test] | Turn desktop notifications on or off, or send a test one. See Notifications. |
jai update [check|on|off] | Install the latest release, or only check for one. See Updating. |
jai version | Show the version of jai and of the running session, and whether a newer release is out. |
jai help | Show commands and keys. |
jai kill-server | End the session and every window in it. |
03
Keys & mouse
The prefix is ctrl+b, as in tmux: press it, let go, then press the key. Window keys act on the machine of the window you are viewing.
| Key | Action |
|---|---|
prefix c | New window |
prefix n / prefix p | Next / previous window |
prefix 0–9 | Select window |
prefix a | Go to the next agent that needs you, on any machine: first those waiting for input, then those that are done |
prefix s | Switch to any window on any machine; see Window picker |
prefix r | Rename the current window; an empty name restores the default |
prefix [ | Scroll back through history; see Scrollback |
prefix ? | Show the keys; scroll with the scrollback keys, leave with q, esc or ? |
prefix q | Detach |
prefix ctrl+b | Send ctrl+b to the program |
With the mouse, click an agent or machine in the sidebar, or a window in the status bar, to switch to it. The wheel scrolls back through history. In programs that use the mouse or the full screen, such as an editor, the wheel goes to the program instead.
The sidebar hides itself when the terminal is narrower than 64 columns.
Window picker
prefix s opens a list of every window on every machine, grouped by machine like the sidebar. Type to narrow it down:
- Words match a window's name, machine, project, branch or agent, in any order:
codex review. name@hostonly matches windows on that machine:claude@gpu.- The best match is selected. Move with the arrows or
ctrl+n/ctrl+p, pressenterto go andescto cancel. - The picker opens on the window you were in before, so
prefix sentertakes you back. - Machines without windows are listed too; choosing one opens a shell there.
04
Supported agents
Jai recognises five coding agents. Start them however you like, by typing their command in a window or with jai new; there's nothing to configure.
| Agent | Runtime name | Default window name |
|---|---|---|
| Claude Code | claude | <project>-claude |
| OpenAI Codex | codex | <project>-codex |
| OpenCode | opencode | <project>-opencode |
| Pi | pi | <project>-pi |
| Grok | grok | <project>-grok |
The runtime name is what you pass to jai new and what jai agents shows. Agents installed through npm are recognised too.
- Other programs run fine in a Jai window, but they don't appear in the sidebar and can't receive messages.
- A window shows one agent. If you run several in one window, the one in the foreground is shown.
- If another machine runs a newer Jai that knows an agent this one doesn't, that agent shows as
agent.
Projects
The sidebar groups agents by project: the git repository they work in. Agents in different worktrees of one repository are grouped together. Outside git, the agent's directory is the project.
05
Starting agents
jai new opens a new window running an agent, in the directory you run it from, and prints the agent's name.
jai new claude
jai new codex --name reviewer
jai new pi --on gpu-box
jai new claude -- --model opus
| Option | Meaning |
|---|---|
RUNTIME | One of claude, codex, opencode, pi or grok. |
--name NAME | Name the window instead of using the default name. |
--on HOST | Start it on a connected machine instead. The short name shown in the sidebar is enough, such as sinax-01. |
-- ARGS | Everything after -- is passed to the agent. |
- The agent runs with the same
PATHand settings as your own shell. - When the agent exits, the window stays open as a shell.
- You can
jai sendto the new agent straight away. If it hasn't started after 30 seconds, the messages are dropped and Jai tells you. --onneeds an up-to-date Jai on the other machine.
06
Agent states
The sidebar and jai agents show what each agent is doing.
| State | Meaning |
|---|---|
working (spinner) | Thinking, running tools or writing output. |
needs-input ● | Waiting for you to answer a question, such as a permission prompt. |
done ✓ | Finished while you were in another window. Cleared when you look at it. |
idle ○ | Waiting at its prompt. |
unreachable | On a machine Jai has lost its connection to. |
prefix a takes you to agents that need input first, then to those that are done.
07
Notifications
Jai shows a desktop notification when an agent on any machine needs input or is done. You won't get one for the agent you are looking at while your terminal has focus. When several agents change at once, they share one notification.
Where notifications appear depends on where Jai runs:
| Running in | Notifications |
|---|---|
| Windows or WSL | Windows notifications |
| macOS | Notification Center |
| A Linux desktop | Your desktop's notifications, through notify-send |
| Anywhere else, such as over ssh | Your terminal is asked to show one. Not every terminal supports this. |
Notifications are on by default. jai notify off turns them off and jai notify on back on; the setting is remembered. jai notify test sends one so you can see how they look, and jai notify shows the current setting.
08
Window names
Names are how you and your agents address windows, for example in jai send. A window without a name is addressed by its number.
Default names
A window running an agent is named after its project and agent: jai-claude, public_html-codex. Outside a project it is just the runtime name, such as claude.
- If that name is taken, Jai adds a number:
jai-claude-2,jai-claude-3. - Spaces and other unusual characters in the project's name become
-, and the name is lowercased. - When the agent exits, its default name goes away. If the window starts a different agent or project, the name follows.
- A name you choose yourself is never changed. Clear it with
prefix rand an empty name to get the default back.
Choosing a name
Set a name with jai name, jai rename, prefix r or jai new --name. Names are typed on the command line, so they must be:
- at most 32 characters,
- letters, digits,
-,_and., starting with a letter or digit, - not only digits, since those mean window numbers,
- unique within the session.
09
Messages
jai send NAME MSG sends a message to an agent. You can send from your own terminal, or an agent can send to another agent.
jai send jai-codex "Review the diff on main"
git diff | jai send jai-codex -
If the agent is busy, the message waits until it is idle, and Jai doesn't type it in while you are typing in that window. Several waiting messages arrive together. jai agents shows how many are waiting, and the sidebar shows them once they have waited for two minutes.
What the agent receives
The message arrives as one paste with a header saying who sent it and how to reply:
[jai] Message from agent 'jai-claude' (another agent, not the user). Reply with: jai send jai-claude "<message>"
Review the diff on main
Messages sent from outside Jai say they have no reply address.
Limits
- Messages are at most 64 KiB.
- Control characters are removed, so a message can't press keys such as answering a permission prompt.
- Only agents on the same machine can receive messages for now.
- A window can't message itself.
10
Other machines
jai connect HOST connects to another machine over ssh and shows its windows and agents in your sidebar, each machine in its own colour. Jai needs to be installed on that machine too. Pass a command if it isn't on the PATH there:
jai connect gpu-box
jai connect michael@build.lan ~/bin/jai
HOSTis anything you would pass tossh, such asuser@hostor a name from your ssh config.- Machines are remembered and reconnected when Jai starts, or when a connection drops. They are saved in
~/.config/jai/hosts(%APPDATA%\jai\hostson Windows), one per line, which you can edit by hand. - The sidebar shows machines by short name:
user@sinax-01.vm.sinax.bebecomessinax-01. - Choosing a machine in the sidebar or the window picker opens a shell there if it has no windows yet.
11
Scrollback
Each window keeps its last 10,000 lines. Scroll back with prefix [, shift+pgup or the mouse wheel.
| Key | Action |
|---|---|
k ↑ / j ↓ | Up / down a line |
u / d | Up / down half a page |
pgup b / pgdn f space | Up / down a page |
g home / G end | Top / bottom |
q esc | Stop scrolling |
Any other key stops scrolling and is typed into the window. New output doesn't move the view while you are scrolled back.
12
Updating
Jai checks for a new release when it starts and every six hours. When one is out, the status bar says so, you get a notification once, and jai version shows it.
jai update
jai update downloads and checks the new version like the installer does, keeps the old one as jai.old, and switches your running session over. Your shells, agents, window names, history and waiting messages all carry over; connections to other machines drop for a moment and reconnect.
On Windows the running session can't switch versions. It keeps using the old one until you run jai kill-server, which closes every window; the next jai starts the new version.
| Command | What it does |
|---|---|
jai update | Install the latest release. |
jai update check | Only say whether a newer release is out. |
jai update off / on | Stop or restart the automatic checks. |
Other machines
jai hosts shows which version each connected machine runs and whether it can be updated. Run jai update on that machine too. If the two versions get too far apart to talk to each other, the machine shows as offline until both are updated.