Orchestrate multiple AI agents across multiple projects from a single terminal.
Claude Code, Codex, Kilo, OpenCode, Antigravity, Grok, Qwen Code, Kimi Code and plain terminals side by side, organized into sessions.
A single native binary with no runtime, for Windows, Linux and macOS.
Installation · Getting started · Keys · Command line · Configuration · Security
English · Português (Brasil)
orkai-demo-v3.mp4
The overview: sessions in the sidebar, counters and plan usage at the top, and every agent live, grouped by project.
- Every agent on one screen. Claude Code, Codex, Kilo, OpenCode, Antigravity, Grok, Qwen Code, Kimi Code and terminals grouped by folder, with status, time, type, a line saying what each one is doing and the subagents that Claude Code and Codex spawn.
- Exact status, instantly. Hooks, plugins and each agent's own protocols tell when it is working, waiting for you or done, without relying on the screen text (see Supported agents).
- You know when you're needed. Bell, terminal notification, window title and
alt+nto jump straight to the agent that is waiting; or send the alert to your phone. - One worktree per agent. Several agents in the same repository, each on its own branch, with
/diffand/mergewithout leaving orkai. - Plan usage in plain sight. 5-hour, weekly and monthly windows (or the balance) of every agent you're logged into, with a countdown to the reset; agents without a login don't show up.
- Nothing gets lost. Closing, crashing or updating the interface takes down no agent; after a reboot,
ctrl+rresumes every conversation where it left off. - Skills in
/, from any agent. Each agent's skills show up in the autocomplete and start an agent already invoking the skill, and every agent can use the skills of the others: a Claude Code skill in Codex, a Codex one in Antigravity. - orkai on your phone, from anywhere.
ctrl+pshows a QR code; the phone opens the overview, each agent's terminal and creates new agents, end-to-end encrypted (see orkai on your phone). - A single binary that updates itself. Every new build is checked by size and SHA-256 before it replaces the executable.
who |
Agent | Program | Exact status | Usage in overview | Resume after reboot |
|---|---|---|---|---|---|
claude |
Claude Code | claude |
hooks (--settings) |
5h and weekly | --resume <id> |
codex |
Codex | codex |
notify |
5h and weekly | codex resume <id> |
kilo |
Kilo CLI | kilo |
event plugin | balance (funds) and Kilo Pass |
--session <id> |
opencode |
OpenCode | opencode |
event plugin | OpenCode Go (5h and weekly) | --session <id> |
agy |
Antigravity CLI (successor to Gemini CLI) | agy |
OSC 7501 | 5h and weekly | --conversation=<id> |
grok |
Grok Build | grok |
window title | weekly or monthly | --resume=<id> |
qwen |
Qwen Code | qwen |
hooks (system defaults) | no usage API | --resume <id> |
kimi |
Kimi Code | kimi |
screen | 5h, weekly or monthly | --session <id> |
terminal |
PowerShell, bash… | shell |
output activity | — | reruns the command |
-
Launch. The task goes into the agent as soon as it is ready. In OpenCode and Kilo it goes through
--prompt, which they send themselves once they finish loading; in the others, orkai types the task and pressesenter. Claude Code, Grok and Qwen Code start with a session id chosen by orkai. For the others, orkai finds the session when it is time to resume: through thesession listof OpenCode/Kilo, thesession_index.jsonlof Kimi Code (~/.kimi-code) or thelast_conversations.jsonof Antigravity. In each case, it is the session of that folder created after the agent and not already used by any other agent. -
Exact status. On top of reading the screen, which applies to all of them:
- OpenCode and Kilo load an orkai plugin (
OPENCODE_CONFIG_CONTENT/KILO_CONFIG_CONTENT, only in that process) that reports when the session is working, asks for permission or asks a question, and when it goes idle; - Qwen Code gets hooks in the Claude Code format through a system defaults file of the agent's own
(
QWEN_CODE_SYSTEM_DEFAULTS_PATH), which adds to its hooks; - Antigravity is started with
AGY_CLI_OSC7501=onand reports working, blocked and done through the OSC 7501 protocol; - Grok Build shows its status in the window title (spinner and
⚠ Action Required), and so does Qwen Code (◐and✳).
orkai doesn't touch any of your config files. If you already set one of these variables, it doesn't replace it. Grok Build and Kimi Code only accept hooks in the user's global config, so they rely on reading the screen and the title.
- OpenCode and Kilo load an orkai plugin (
-
Skills in
/. Each agent suggests the skills and commands from the folders it reads itself, and also the ones of the other agents (see below).
On Windows, run the installer from PowerShell. On Linux and macOS, download the binary for your platform
from the newest release, rename it to
orkai and put it in a folder on your PATH:
| Platform | File |
|---|---|
| Windows x64 (installer) | orkai-setup.exe |
| Linux x64 (static, any distro) | orkai-x86_64-unknown-linux-musl |
| macOS Apple Silicon | orkai-aarch64-apple-darwin |
| macOS Intel | orkai-x86_64-apple-darwin |
Linux and macOS (replace target with the file for your platform):
target=orkai-x86_64-unknown-linux-musl
mkdir -p ~/.local/bin
curl -fL -o ~/.local/bin/orkai "https://github.com/lucasmarujo/orkai-cli/releases/latest/download/$target"
chmod +x ~/.local/bin/orkaiIf ~/.local/bin isn't on your PATH yet, add export PATH="$HOME/.local/bin:$PATH" to
~/.bashrc or ~/.zshrc.
Windows, in PowerShell:
$setup = "$env:TEMP\orkai-setup.exe"
Invoke-WebRequest "https://github.com/lucasmarujo/orkai-cli/releases/latest/download/orkai-setup.exe" -OutFile $setup
Start-Process $setup -WaitIt installs orkai for your user in %LOCALAPPDATA%\Programs\orkai, without admin rights, and offers to add it to
your PATH so orkai works in any terminal. Running it again upgrades orkai in place, even while it's open,
and Settings › Apps uninstalls it.
The installer isn't code signed yet (see Code signing policy). Downloaded from
PowerShell, it runs without a SmartScreen prompt. If you download
orkai-setup.exe with a
browser instead, SmartScreen may show "Windows protected your PC": click More info › Run anyway. Both
links get the installer of the newest version, whose file never changes; orkai then updates itself whenever
a new version comes out (auto-update).
For an unattended install, pass /VERYSILENT to the installer (/MERGETASKS=!addtopath leaves the PATH
alone). The release also carries orkai-x86_64-pc-windows-msvc, the bare binary that
auto-update downloads; rename it to orkai.exe to use orkai without installing it.
Open a new terminal and type orkai in PowerShell, Bash or zsh.
Important
To use an AI agent, its program must be on the PATH: claude, codex, kilo, opencode,
agy, grok, qwen or kimi (or point to its path in Configuration).
Tip
Keep orkai in a folder your user can write to, like the ones in the examples above: the
auto-update replaces the executable itself.
From source, with Rust 1.88+ (goes to ~/.cargo/bin):
git clone https://github.com/lucasmarujo/orkai-cli.git
cd orkai-cli
cargo install --path .Local builds show up as dev and don't auto-update; orkai update turns one of them into an official build.
- Open orkai in any terminal:
orkai. - Pick the project folder with
ctrl+l(or/where <folder>). - Pick who runs it with
tab: one of the installed agents (claude, codex, opencode…) or terminal;/who <name>picks one directly. - Type the task in "write a task" and press
enter: the agent starts already working on it. enter(or a click) opens the agent in a tab;ctrl+]goes back to the overview.
You can quit whenever you want (ctrl+q): the agents keep running and orkai reconnects to all of them when you open it again.
| Area | What it shows |
|---|---|
| Sidebar | machine, sessions with the number of active agents in each one, + new session |
| Top | the little pixel-art man, the session's agents, working, paused and done counters and, on the right, the usage of the agents you're logged into (see below) |
| List | agents grouped by folder (with the count of each one), the folder and the agent you used last on top: number, status, name, time in the current status, lifetime, type (claude, codex, kilo, opencode, agy, grok, qwen, kimi, terminal) and a line saying what the agent is doing; right below each agent, the subagents it spawned that are still running (↳, type, how long ago, description and the tool in use) |
| Footer | write a task, pc, who, worktree, bypass and where to launch new agents |
| Symbol | State |
|---|---|
⠋ |
working |
‖ |
in yellow, waiting for your answer (approval, question or choice inside the agent) |
✔ |
done (not seen yet) |
● |
idle |
$ |
terminal |
↻ |
interrupted (crash/reboot) |
✗ |
ended |
A terminal where you run an agent (claude, codex, kilo, opencode, agy, grok, qwen or
kimi) becomes that agent on its own: within 2 seconds the overview shows its type, status
(working, waiting for you, done), subagents and counters just like an agent launched by
orkai. When you exit the agent, it goes back to being a terminal. Qwen Code runs on Node and is recognized by
its session registry (~/.qwen/sessions), like Claude Code.
When it launches Claude Code (2.1.78 or newer), orkai passes a --settings with async hooks, which don't
slow the agent down. They tell orkai when you send a task, when the agent uses a tool, asks for
permission or asks a question, and when the turn ends. So the status changes instantly, without relying on the
screen text; for example, a final answer that ends with "Would you like to…?" no longer turns into ‖. In Codex,
orkai uses notify to know when the turn ends. The other agents are in
Supported agents.
- The hooks add to yours (user, project and plugins) without replacing them. If you already pass
--settingsinclaude_args, or already have anotifyin the Codexconfig.toml, orkai leaves it alone. - Each hook only writes the event type and the time to a file inside the agent's folder; the prompt, the commands and the answers are never written to disk.
- Reading the screen stays as a fallback: for agents started before this version, older versions of
Claude Code, interruptions with
esc, dialogs without a hook (like the one to trust the folder) and, on Windows, when there is no Git Bash (Claude Code hooks run in it).
When an agent you're not looking at starts waiting for you (‖) or finishes (✔):
- the orkai chime plays, in two tones: falling when an agent is waiting for you, rising when it finishes, with
the timbre of the bell from the launch video, synthesized by orkai itself (on Windows by the system, on macOS by
afplayand on Linux bypaplay,pw-playoraplay). Over SSH, or without any of these players, the terminal rings the default bell (in Windows Terminal, the taskbar flashes); - the terminal gets a desktop notification (OSC 9, shown by iTerm2, WezTerm, Ghostty, kitty and others);
- the footer shows
<agent> is waiting for you · alt+n opens it; - the window title shows how many are waiting and how many are done, across all sessions
(
‖2 ✔1 · Orkai), visible in the taskbar even with orkai in the background.
alt+n (in the overview or inside any tab) opens the agent that has been waiting the longest; the ones that
are done come next. Inside a tab, the bottom bar shows how many others need you.
Opening the agent marks it as seen. The same agent doesn't chime again for the same reason within 15 s.
To get the alert somewhere else (phone, native system notification), set
notify_command (see Configuration). The command runs on every alert, without a shell, with
these environment variables: ORKAI_MESSAGE, ORKAI_AGENT_ID, ORKAI_AGENT_NAME, ORKAI_AGENT_KIND,
ORKAI_AGENT_STATE (paused or done), ORKAI_SESSION, ORKAI_AGENT_CWD and ORKAI_AGENT_ACTIVITY
(the line saying what the agent is doing). It is killed if it runs longer than 30 s.
To the right of the counters, the overview shows the usage only of the agents you're logged into, whether
you're using the agent right now or not; agents without a login don't show up, to keep the screen clean. Each one
gets two lines: the 5-hour window (5h) and the weekly one (week), or the monthly one (month) when the plan has
no week, or the balance (funds). Each window has a bar (green, yellow from 70%, red from 90%) and the
countdown to the reset. Up to three agents fit in a column next to the little man; with more, they
split into columns, and only on a narrow screen does the top grow. The values are fetched every 2 minutes, in
the background, with the login the agent itself already keeps on the machine:
- Claude Code:
~/.claude/.credentials.json(orCLAUDE_CONFIG_DIR; on macOS, the Keychain); - Codex:
~/.codex/auth.json(orCODEX_HOME), with a ChatGPT login; - Kilo CLI: the Kilo account in
~/.local/share/kilo/auth.json, with the balance in dollars and the Kilo Pass of the month; - OpenCode: the OpenCode Go key in
~/.local/share/opencode/auth.json(5h, week and month). Only the Zen key shows up asapi key · no plan limits; other OpenCode providers don't count; - Antigravity:
agy -p /usage --output-format json, the queryagyitself makes without spending quota (its login lives in the system vault and orkai doesn't read it); - Grok Build:
~/.grok/auth.json(orGROK_HOME/GROK_AUTH_PATH), with the weekly or monthly period of the subscription; - Kimi Code:
~/.kimi-code/credentials(orKIMI_CODE_HOME), on the endpoint from itsconfig.toml.
Qwen Code has no usage API (the free OAuth plan ended in April 2026, and the Coding Plan only shows usage in the Alibaba Cloud console), so it doesn't show up at the top.
With an expired login it shows login expired (opening the agent renews it); if the query fails, the last value
stays on screen with unavailable.
Tasks and launching
| Key | Action |
|---|---|
type + enter |
starts an agent with the typed task |
!command + enter |
runs the command in a new terminal, without changing who (e.g. !npm run dev) |
shift+enter (or alt+enter) |
line break in the task, without sending; pasting text with several lines also keeps the line breaks |
ctrl+↑ (and ctrl+↓) |
recalls the tasks you already sent in this session; the history is forgotten when orkai closes |
tab / shift+tab |
picks who runs it among the installed agents and the terminal; /who <name> picks any of them |
/where <folder> or ctrl+l |
picks the session folder (see below); clicking a project name does too |
ctrl+t |
turns its own worktree on/off for the next agents (see below) |
/bypass |
turns the permission bypass mode on/off for the next agents (see below) |
/ |
commands (tab completes the name): /where, /cd, /who, /session, /new-session, /rename-session, /delete-session, /rename, /kill, /restart, /recover, /open, /worktree, /bypass, /diff, /merge, /cross-review, /tests, /trust, /race, /compare, /pick, /help, /quit, plus the skills of the current who and of the other agents (see below) |
Agents
| Key | Action |
|---|---|
↑ ↓ / mouse |
selects; enter or a click opens the agent in a tab |
ctrl+] |
leaves the agent's tab and goes back to the overview |
shift+pgup / mouse wheel |
agent history |
alt+1..9 |
jumps to an open tab |
alt+n |
opens the next agent waiting for you (or that is done), from any screen |
ctrl+e / f2 |
renames the agent |
delete |
stops and removes the selected agent (with empty text), after confirming in the popup |
ctrl+x |
stops a running agent / removes an ended one (also asks for confirmation in the popup) |
ctrl+r |
recovers the interrupted agents of the session |
ctrl+p · /pwa |
turns on the orkai PWA and shows the QR code to pair your phone (/pwa off turns it off, /pwa new changes the code) |
Sessions and general
| Key | Action |
|---|---|
ctrl+n · alt+↑↓ |
new session · switch session |
f1 (or ? with empty text) |
shows/hides help |
ctrl+c / ctrl+q |
quits orkai; the agents keep running |
Inside an agent's tab every key goes to it (Claude Code, OpenCode, PowerShell, bash…),
including esc, arrows, paste and the mouse when the program uses the mouse.
Type /where (or /cd ) in "write a task". The line below shows, live, the folders
of where you are (current where) and filters them as you type. Relative paths start
from the current where; ~ is your user folder.
tabwith a single possible folder enters it and lists its subfolders right away;tabwith several completes the common prefix and, pressed again, cycles through the options (shift+tabgoes back);entersets the folder. Each session remembers its own: when you switch sessions,wheregoes back to that session's folder.
ctrl+l (or clicking where) opens the same picker already filled in with the current folder.
With worktree on in the footer (ctrl+t, /worktree or a click), each new AI agent starts in its own
git worktree, on an orkai/<agent-name> branch created from
the latest commit of the where folder. That way several agents work on the same repository without stepping on
each other, and your checkout stays intact. Terminals (!command) keep running straight in the folder.
- The worktree lives in
orkai home/worktrees/<agent number>, in the same repository subfolder you were in. Uncommitted changes and files outside git (like.env) don't go into it. The agent may ask whether you trust the new folder. - In the list, the agent stays in the project group and shows
⎇ 4 files +12 −3: what changed since it started, counting commits, edits and new files (updated every 10 s). Inside the tab, the bar shows the branch. - When two agents of the session change the same file of a repository, each one shows
⚠ #<other agent>next to its changes and orkai warns you once (docker-install and physics-merge both change src/app.rs), before the second merge turns into a conflict./difflists the files they share. /diffshows the changes of the selected agent, including new files (esccloses, arrows andpgup/pgdnscroll)./merge(with the agent stopped or done) commits whatever is pending on its branch and merges it into the current branch of the repository. If there is a conflict, the merge is undone, the repository stays as it was and orkai tells you the command to resolve it by hand. After the merge, the count starts over from zero./cross-reviewstarts another agent in the selected agent's worktree to review its work: it gets the branch and the commit to compare against, lists bugs, risks and missing tests, and is told not to change any file. By default it is an installed agent other than the one that did the work (codex reviews claude, claude reviews codex);/cross-review <agent>picks one. It shows up in the same project group, asreview-<name>.- Deleting the agent (
deleteorctrl+x) also deletes the worktree and theorkai/…branch; the popup warns you first. - On the command line:
orkai new --worktree …;orkai rmalso deletes the worktree.
/race claude,codex,opencode fix the login redirect hands the same task to 2 to 4 agents (a kind can repeat),
each in its own worktree and branch of the where repository, so you keep the best result:
/compare, with one of them selected, shows each agent of the race with its state, its tests (see Project settings) and the files it changed, with their+/−;/pickmerges the selected agent like/mergeand then deletes the other agents of the race with their worktrees and branches; the popup says how many go, and if the merge conflicts nothing is deleted.
The agents are named after their kind and the task (claude-fix-login, codex-fix-login…), sit in the
project's group like any other worktree agent, and the conflict radar (⚠) shows where they touch the same
files.
A .orkai.json at the root of a repository tells orkai two things about the agents that work on it in
worktrees:
{
"copy": [".env", "config/local.toml"],
"test": "cargo test"
}copy: files copied from your checkout into each new worktree, like a.envthat git doesn't bring along. Only files that git ignores are copied, so they never show up in the changes or in a/merge; paths outside the repository are refused.test: a command orkai runs in the agent's worktree each time the agent finishes a turn (withcmdon Windows andshelsewhere, for up to 30 minutes; a new turn replaces a run still going). The list shows⠋ testwhile it runs, then✓ testor✗ test; a failure shows up in the footer,/testsshows the output of the last run and/mergewarns when it failed. The command has to finish on its own, without a watch mode.
Because test runs a command that came with the repository, orkai only runs it after you trust that exact
file: /trust (for the repository of the selected agent or of where) shows the command and asks first, and
orkai trust does the same from the command line. Any change to .orkai.json needs a new /trust; until
then the list shows ? test. The trust is saved in trusted.json, in the data folder. The agent's holder runs
the tests, so they run even with orkai closed, and only once with several orkai windows open.
With bypass on in the footer (/bypass, /bypass on|off or a click), each new AI agent starts already in the
agent's own full permission bypass mode: it runs tools, commands and edits without asking for
approval. Only use it in folders and on machines where you trust that. Terminals (!command) don't change.
| Agent | Flag added |
|---|---|
| Claude Code | --dangerously-skip-permissions |
| Codex | --dangerously-bypass-approvals-and-sandbox (also without a sandbox) |
| Kilo CLI | --auto, with KILO_NO_DAEMON=1 (with a daemon running, Kilo ignores --auto) |
| OpenCode | --auto |
| Antigravity | --dangerously-skip-permissions |
| Grok Build | --always-approve |
| Qwen Code | --yolo |
| Kimi Code | --auto (Kimi's --yolo still asks on risky actions) |
- The mode is saved with the agent:
ctrl+r,/restartandorkai recoverresume the conversation still bypassed. - If the agent args in
config.jsonalready pick a permission mode (like-a on-requestin Codex or--approval-modein Qwen Code), orkai doesn't add the flag, because the agent would refuse both together. - The first time, Claude Code asks you to accept bypass mode; the task is only typed after that. Each agent's "trust this folder" screens still show up.
With an AI agent in who, / also suggests the skills and commands that agent has, read from
disk and updated on their own (install a skill and it shows up within seconds). The project folders go from
the where folder up to the repository root:
- Claude Code:
~/.claude/skills,~/.claude/commands,.claude/skillsand.claude/commands, and the skills of enabled plugins (/plugin:skill); - Codex:
.agents/skills,~/.agents/skillsand~/.codex/skills(including the system skills); - OpenCode and Kilo CLI:
skill(s)andcommand(s)from~/.config/opencode(or~/.config/kilo),~/.opencode(~/.kilo) and.opencode(.kilo,.kilocode), plus.claude/skillsand.agents/skills; commands in subfolders become/folder/command; - Antigravity:
~/.gemini/antigravity-cli/skillsand.agents/skills(or the older.agent/skills); - Grok Build:
skillsandcommandsfrom~/.grok,.grok,.agents,.claudeand.cursor; - Qwen Code:
~/.qwen/skills,~/.qwen/commands,.qwen/skills,.qwen/commandsand.agents/skills; - Kimi Code:
~/.kimi-code/skills,.kimi-code/skillsand.agents/skills.
tab completes (or extends the common prefix), and /skill arguments + enter starts an agent already
invoking the skill. In Codex orkai sends it in its format ($skill arguments) and in Kimi Code as
/skill:skill arguments. orkai's own commands take precedence when the name is the same.
/ also suggests the skills and commands of every other agent, in the color of the agent they come from, so
a Claude Code skill works in Codex, a Codex one in Antigravity, and so on. orkai starts the who agent telling
it to read the skill's file (its SKILL.md, or the command's .md) and follow it, with the arguments you
typed. Nothing is copied or installed, and no agent's folders or settings change. The path goes with / on
every system, and the files the skill mentions are read from its folder.
When who has a skill with the same name, its own wins; among the other agents, the first in the order of the
table wins. A skill outside the project may make the agent ask before reading it, like
any other file of yours.
orkai ls [-s session] [--json] lists agents with their live status
orkai new -k <agent> -C <folder> [--worktree] <task...> (claude, codex, kilo, opencode, agy, grok, qwen, kimi, terminal)
orkai send <id> <text...> types into the agent and presses enter
orkai wait <id> [--timeout s] waits until the agent finishes its turn, needs you or ends
orkai attach <id> uses the current terminal straight in the agent (ctrl+] detaches)
orkai logs <id> [-n lines] recorded transcript of the agent
orkai kill <id> · orkai rm <id>
orkai recover [-s session] relaunches interrupted agents, resuming the conversation
orkai sessions · orkai home
orkai trust [-C folder] lets agents in the repository's worktrees run its .orkai.json test
orkai update downloads and installs the newest build
orkai mcp serves orkai to an agent over MCP (see below)
orkai pwa [--tunnel cloudflare|tailscale] turns on the orkai PWA and prints the QR code
orkai pwa --stop · orkai pwa --new-code turns it off · forgets the paired phones
orkai mcp serves orkai to an agent over MCP, so one agent can lead:
hand parts of the work to other agents, of any kind, and follow them.
| Tool | What it does |
|---|---|
start_agent |
starts another agent on a task (claude, codex, opencode… or a terminal), in the lead's folder or another one, optionally in its own worktree |
wait_for_agent |
waits until that agent finishes its turn, needs an answer or ends, and returns the last lines of its screen |
read_agent |
reads the last lines of its terminal |
send_to_agent |
types a message into it and presses enter, optionally waiting for the turn it starts |
stop_agent |
stops it |
list_agents |
lists the agents of the session with their state, folder, branch and tests |
Add it once to the agents that should be able to lead:
claude mcp add --scope user orkai -- orkai mcp# ~/.codex/config.toml
[mcp_servers.orkai]
command = "orkai"
args = ["mcp"]The agents a lead starts go into its session and show up right under it in the overview (↳), where you can
open, answer or stop them like any other. A lead only messages or stops the agents it started; they only get
the bypass mode when the lead has it, and only a lead in bypass mode can start a terminal, which runs its task
without asking; a lead runs at most 8 of them at a time; and agents started by agents go at most 3 levels deep.
Outside an orkai agent, new agents go into the default session and the tools can message or stop any agent.
For scripts, orkai ls --json lists the agents and orkai wait <id> blocks until the agent finishes its turn,
needs you or ends (--timeout gives up with an error). An orkai new run inside an orkai agent records that
agent as the parent of the new one.
The orkai PWA is your orkai on your phone, from anywhere: the overview with the sessions, the usage and the
live agents; each agent's terminal with its colors; messages, keys (esc, tab, arrows, 1/2/3 for
permissions, ^c); new agents with who, where and worktree; stopping, removing, renaming, recovering
interrupted ones, seeing the diff and merging a worktree. The desktop and the phone show the same thing at
the same time.
- In orkai, press
ctrl+p(or click ▣ orkai pwa in the sidebar, or type/pwa). It stays on until you turn it off, even after closing and reopening orkai. - Point your phone's camera at the QR code. The browser opens orkai already paired. Without the camera,
click copy under the
linkshown next to the code (or pressc), send it to the phone and open it there, or paste it into the page the address opens. - Optional: share › add to home screen puts orkai one tap away, like an app.
The sidebar shows off, on or how many phones are connected (● 2). On the PWA screen, d turns it off
and n generates a new code and a new address, which disconnects and forgets the phones already paired.
Turning it off in one orkai window turns it off in all of them, and it stays off until you turn it on.
The bridge writes what happens to the tunnel and the phones in pwa.log, in the data folder.
From the terminal:
orkai pwa # turns it on and prints the QR code
orkai pwa --tunnel tailscale # uses your tailnet instead of cloudflare
orkai pwa --new-code # forgets the paired phones
orkai pwa --stop # turns it offorkai starts a light bridge in a separate process, which listens only on 127.0.0.1 and serves the app
itself. It doesn't weigh on orkai: it only exists while the PWA is on and, with no phone connected, it sits
idle. The bridge only connects to the agents while a phone is open, and only sends the phone what changed:
the overview when a state changes and, in the terminal, only the screen rows that changed.
To work away from home without opening ports on your router, orkai uses a tunnel that only carries bytes:
- cloudflare (default, no account): a Cloudflare quick tunnel. The first time, orkai downloads the
official
cloudflaredfromgithub.com/cloudflare/cloudflaredinto thebin/folder and checks the published SHA-256 before using it. Ifcloudflaredis already on thePATH, it uses that one. The tunnel is saved inpwa-tunnel.json, so the address stays the same when the internet drops and comes back, whencloudflaredor the bridge restarts and when the PWA is turned off and on again within a few minutes: the phone reconnects by itself, even away from home. Cloudflare deletes a quick tunnel that has been offline for longer (somewhere between 5 and 20 minutes), for example while the computer is off or asleep; orkai then opens a new one and the new QR code shows up on its own, as it does aftern/--new-code. For an address that never changes, use tailscale. - tailscale: the phone talks to the computer peer to peer over your tailnet (
tailscale serve), with a fixed address. The phone needs to be on the same tailnet.
No server of yours or of orkai sits in the middle.
- The QR code carries a 256-bit secret in the URL fragment (
#k=…). The browser never sends the fragment over the network, so the tunnel doesn't see the secret. The app removes the fragment from the address bar and keeps the secret only on that phone. - Each connection does a fresh ECDH P-256 exchange and derives, with HKDF-SHA256 salted by the secret and bound to both public keys, one AES-256-GCM key for each direction. Whoever doesn't have the secret can't derive the keys, and the bridge closes the connection on the first frame that doesn't authenticate.
- The nonce of each frame is a counter. A repeated, lost or out-of-order frame doesn't open, so the tunnel can't resend a command already typed.
- The bridge accepts at most 8 connections, gives pairing 10 s and responds with a strict CSP, without
unsafe-inline. - A paired phone controls your agents (and the terminals) just like you at the keyboard.
non the PWA screen ororkai pwa --new-codeforgets every phone at once.
Every push to main goes through the tests on the three systems and publishes nothing. When a push raises
the version in Cargo.toml, CI also builds orkai for every platform and publishes the v<version>
release, whose files never change, with the installer and a manifest.json holding the version, the commit
and the SHA-256 of each binary.
Every time you open orkai, it checks the manifest of the newest version (short timeout; without internet,
it opens right away). If that version is newer than yours, it downloads the binary for your platform, checks
size and SHA-256, replaces its own executable and opens already updated. Running
agents aren't affected, because they run from their own copies of the binary.
orkai updates from one version to the next, not on every push: each version is the same file on every machine, so Windows Defender and SmartScreen judge one binary per version instead of a new unsigned one every few hours.
orkai updateupdates right away (it also turns a local build into an official build);orkai --versionshows the version and the commit (devfor local builds, which don't auto-update);ORKAI_NO_UPDATE=1turns the check off;ORKAI_UPDATE_URLpoints to another build server.
Each agent runs inside its own detached holder process, which owns the pseudo-terminal
(ConPTY on Windows, PTY on Unix). The interface only connects to them.
flowchart LR
ui["orkai · interface"]
subgraph holders["one holder per agent, detached from the interface"]
h1["holder"] -- "ConPTY / PTY" --> a1["claude"]
h2["holder"] -- "ConPTY / PTY" --> a2["codex"]
h3["holder"] -- "ConPTY / PTY" --> a3["pwsh / bash"]
end
ui -- "127.0.0.1 + token" --> h1
ui --> h2
ui --> h3
That's why:
- Closing, restarting or updating orkai takes down no agent. When you open it again, it
reconnects to all of them. The holder runs from a copy of the binary in
bin/, so you can rebuild and reinstallorkaiwith agents running. - If the interface freezes, the agents keep going untouched.
- If a holder dies or the machine reboots, the agent shows up as
↻ interrupted.ctrl+r(ororkai recover) relaunches all the interrupted agents of the session, each one in its folder: Claude Code comes back with--resume <conversation id>(orkai starts every Claude with a known--session-id), Codex withcodex resume <id>, the other agents as in Supported agents, and the terminals rerun the original command. - All the output of each agent is recorded (with rotation) in
agents/<id>/output.log. Opening an ended or interrupted agent shows the last screen, andorkai logs <id>prints the transcript.
The data lives in orkai home:
| System | Folder |
|---|---|
| Windows | %LOCALAPPDATA%\orkai |
| Linux | ~/.local/share/orkai |
| macOS | ~/Library/Application Support/orkai |
The ORKAI_HOME variable changes this location.
config.json inside the data folder (created on the first run):
{
"shell": null,
"shell_args": [],
"claude_command": "claude",
"claude_args": [],
"codex_command": "codex",
"codex_args": [],
"kilo_command": "kilo",
"kilo_args": [],
"opencode_command": "opencode",
"opencode_args": [],
"agy_command": "agy",
"agy_args": [],
"grok_command": "grok",
"grok_args": [],
"qwen_command": "qwen",
"qwen_args": [],
"kimi_command": "kimi",
"kimi_args": [],
"notify": true,
"notify_sound": true,
"notify_command": null,
"notify_args": [],
"pwa_tunnel": "cloudflare",
"pwa_port": 7470
}A null shell uses pwsh/powershell on Windows and $SHELL on Unix.
Examples: "claude_args": ["--model", "opus"], "opencode_args": ["-m", "opencode/big-pickle"]. Fields
missing from the file use the default, so an old config.json still works.
pwa_tunnel picks the orkai PWA tunnel (cloudflare or tailscale) and pwa_port the bridge's local
port, which only listens on 127.0.0.1.
notify: false turns off the chime, the bell and the terminal notification; notify_sound: false swaps the orkai
chime for the terminal's default bell. notify_command works independently of them;
for example, to send it to your phone through ntfy:
"notify_command": "sh",
"notify_args": ["-c", "curl -s -d \"$ORKAI_MESSAGE\" ntfy.sh/my-topic"]Every Claude Code started or resumed by orkai opens with Remote Control on
(--remote-control), so any session can be continued in the Claude app or at
claude.ai/code. Codex has no equivalent for the interactive session in the terminal.
No terminal lets a program change the icon of a tab that is already open, so orkai uses what each terminal offers. When orkai opens:
- Windows Terminal: the
orkaiprofile, with the sailor icon, shows up in the+menu (a fragment in%LOCALAPPDATA%\Microsoft\Windows Terminal\Fragments\orkai). Open orkai through it, or make it your default profile, and the tab shows the icon.orkai.execarries the icon too (Explorer, taskbar, Alt+Tab). - iTerm2: a dynamic profile
orkai · <your profile>inherits everything from the tab's profile and only swaps the icon; the tab uses that profile while orkai is open and goes back to yours when you quit. The first time, the icon shows up after iTerm2 loads the new profile (about a second). - Linux: the
orkaishortcut goes into the applications menu (~/.local/share/applications/orkai.desktop); Linux terminals don't show an icon per tab.
These are new files in the folders each terminal sets aside for extensions; the Windows Terminal settings.json
and your iTerm2 profiles aren't changed. Local builds (dev) don't create anything, and
ORKAI_NO_TERMINAL_PROFILE=1 turns it off.
- Holders listen only on
127.0.0.1, on a random port, and require a 256-bit token per agent, which lives only in the user's data folder (0700/0600permissions on Unix). - To show usage, orkai reads each agent's login token in memory only and sends it only, over
HTTPS, to the service that issued it (
api.anthropic.com,chatgpt.com,api.kilo.ai,opencode.ai,cli-chat-proxy.grok.comand the HTTPSbase_urlof Kimi Code); it is never written, logged or renewed by orkai. The Antigravity login isn't read:agyitself makes the query. .cmd/.batcommands on Windows only get arguments without cmd special characters; a task with any of them is typed into the agent's terminal. npm shims that only forward to an.exe(like the OpenCode one) run the.exedirectly, without cmd.exe.- The Claude Code and Qwen Code hooks, the Codex
notifyand the OpenCode and Kilo plugin call the orkai copy inbin/and only write the event type (working, waiting for you, done) to the agent's folder; the content received from the agent is discarded in memory. The hook files and the plugin live in the agent's folder and only apply to the process orkai launched; none of your config files is changed. - The
testof a repository's.orkai.jsononly runs after you trust that exact content (/trustororkai trust); an edited file runs nothing until it is trusted again (see Project settings). - The profile with the icon (see Terminal icons) only points to the orkai executable and to the icon image, saved in the data folder.
- The orkai PWA bridge listens only on
127.0.0.1and only accepts the phone that has the QR code's secret (see orkai on your phone). The tunnel never gets the secret, which travels in the URL fragment, and only carries AES-256-GCM frames with a counter nonce.
orkai.exe and orkai-setup.exe are not code signed yet. Until they are, Windows SmartScreen may warn about
an orkai-setup.exe downloaded with a browser; the PowerShell command in Installation doesn't
get the prompt.
The CI is ready to sign both files through SignPath once the SignPath Foundation accepts orkai: only builds of this repository are signed, and every signing request is approved by hand.
- Committers and reviewers: Lucas Marujo
- Approvers: Lucas Marujo
Privacy. orkai has no telemetry and sends nothing about you or your projects. It only uses the network for:
- updates: each time it opens, it reads the
manifest.jsonof this repository's newest version release on GitHub and downloads the new version when there is one (ORKAI_NO_UPDATE=1turns it off, see Auto-update); - plan usage: each agent's login token goes only to the service that issued it (see Security, above);
- the orkai PWA, only after you turn it on: the Cloudflare quick tunnel, with
cloudflareddownloaded from Cloudflare's GitHub release, and a query tocloudflare-dns.comthat waits for the tunnel's address to exist before showing the QR code; ortailscale serve; - the Windows Terminal profile, whose icon Windows Terminal loads from
https://orkai.marujo.dev/orkai.ico.
cargo test # unit + e2e with a real PTY (holder and the TUI itself)
cargo clippy --all-targets -- -D warnings
cargo fmt --checkCI runs all three on Windows, Linux and macOS on every push to main and on every pull request. A push to
main that raises the version in Cargo.toml and passes becomes the
v<version> release; other pushes publish nothing.
The Windows installer is built from installer/orkai.iss (see
installer/README.md).
MIT.
