Skip to content

CLI reference

Nagi’s CLI talks to the running server over the same local socket API used by integrations and agents.

Most commands print JSON responses. Use them from scripts when you want deterministic automation.

Terminal window
nagi # launch or attach to the default session
nagi --session work # launch or attach to a named session
nagi --remote workbox # attach through SSH, using local keybindings
nagi --remote workbox --remote-keybindings server
nagi --remote workbox --handoff
nagi --no-session # single-process escape hatch
nagi --default-config # print default config
nagi update # download and install from the configured channel
nagi update --handoff # opt into live handoff for supported running servers
nagi completion zsh # generate a zsh completion script
nagi channel show # print stable or preview
nagi channel set preview # opt into preview builds
nagi channel set stable # return Linux/macOS direct installs to stable
nagi --version # print version

Status commands:

Terminal window
nagi status
nagi status server
nagi status client

API schema commands:

Terminal window
nagi api schema
nagi api schema --json
nagi api schema --output nagi-api.schema.json

nagi api schema prints a short summary of the socket protocol schema bundled with the installed binary. Use --json for the full JSON Schema document, or --output PATH to write that document to a file.

Terminal window
nagi completion zsh
nagi completions zsh
nagi completion bash
nagi completion fish
nagi completion powershell
nagi completion elvish

completion prints the script to stdout. completions is an alias. For a temporary zsh session, load the script directly:

Terminal window
source <(nagi completion zsh)

For a persistent zsh setup, write the generated _nagi function somewhere on your fpath before compinit runs:

Terminal window
mkdir -p ~/.zfunc
nagi completion zsh > ~/.zfunc/_nagi

Then make sure your .zshrc contains:

Terminal window
fpath=(~/.zfunc $fpath)
autoload -Uz compinit
compinit
Terminal window
nagi server
nagi server stop
nagi server reload-config
nagi server agent-manifests [--json]
nagi server update-agent-manifests [--json]
nagi server reload-agent-manifests

nagi server runs the headless server explicitly. Use it for supervised or service-style setups. reload-config applies reloadable settings without restarting panes. agent-manifests shows the active agent detection manifest sources, cached remote versions, and last remote update results. update-agent-manifests fetches remote manifest updates immediately, reloads them into the running server, and prints the updated manifest status; pass --json for the raw status response. reload-agent-manifests reloads agent detection manifests into the running server after local override edits.

Terminal window
nagi notification show <title> [--body TEXT] [--position top-left|top-right|bottom-left|bottom-right] [--sound none|done|request]

notification show uses the configured [ui.toast] delivery. --position only affects in-app Nagi toasts. --sound defaults to none; done and request play the existing finished and needs-attention sounds only when the notification is shown.

Terminal window
nagi session list [--json]
nagi session attach <name>
nagi session stop <name> [--json]
nagi session delete <name> [--json]

Use default as the session name when you need to stop the default session explicitly.

Terminal window
nagi workspace list
nagi workspace create [--cwd PATH] [--label TEXT] [--env KEY=VALUE] [--focus] [--no-focus]
nagi workspace get <workspace_id>
nagi workspace focus <workspace_id>
nagi workspace rename <workspace_id> <label>
nagi workspace report-metadata <workspace_id> --source ID [--token NAME=VALUE] [--clear-token NAME] [--seq N] [--ttl-ms N]
nagi workspace close <workspace_id>

Create a workspace without stealing focus:

Terminal window
nagi workspace create --cwd ~/project --label api --no-focus
Terminal window
nagi worktree list [--workspace ID | --cwd PATH] [--json]
nagi worktree create [--workspace ID | --cwd PATH] [--branch NAME] [--base REF] [--path PATH] [--label TEXT] [--focus] [--no-focus] [--json]
nagi worktree open [--workspace ID | --cwd PATH] (--path PATH | --branch NAME) [--label TEXT] [--focus] [--no-focus] [--json]
nagi worktree remove --workspace ID [--force] [--json]

Worktrees are normal Nagi workspaces with Git checkout provenance. worktree create creates a Git worktree checkout, opens it as a workspace, and groups it with the parent repo workspace. If --branch names an existing local branch, Nagi checks it out; otherwise it creates the branch from --base or HEAD. Without --path, Nagi creates the checkout under <worktrees.directory>/<repo>/<branch-slug>.

workspace close closes Nagi state only. worktree remove is the explicit checkout deletion path; it runs git worktree remove, never deletes the branch, and requires --force when Git refuses a dirty checkout.

A repository can declare bounded setup, checks, services, cleanup, and exact ignored-file copying in .nagi/project.toml. Detection and validation never execute repository code. Execution always requires --yes:

Terminal window
nagi project detect [PATH] [--json]
nagi project validate [PATH] [--json]
nagi project setup [PATH] --yes [--json]
nagi project check [PATH] [--id ID] --yes [--json]
nagi project cleanup [PATH] --yes [--json]
nagi project services start [PATH] --mission ID --run ID --yes [--json]
nagi project services status [PATH] --mission ID --run ID [--json]
nagi project services stop [PATH] --mission ID --run ID --yes [--json]
nagi project resources preview [--json]
nagi project resources apply --digest DIGEST --yes [--json]

Services receive collision-free loopback ports, must pass their declared HTTP health check, and keep durable ownership records. A new Nagi process adopts a healthy service for the same mission/run instead of starting a duplicate. Cleanup applies only the exact digest the user previewed. Worktree creation copies only explicit regular files: untracked sources must be ignored by Git, and symlinks, globs, secret-like names, oversized files, and overwrites fail closed.

Terminal window
nagi mission list
nagi mission get <mission_id>
nagi mission proof <mission_id>
nagi mission close <mission_id>
nagi mission handoff <mission_id> --to <codex|claude-code|opencode|acp> --preview
nagi mission handoff <mission_id> --to <provider> --start --artifact-sha256 <sha256> --generated-at-millis <timestamp>

The cockpit is the recommended handoff flow: open a blocked or review mission, press h, inspect the bound workspace snapshot, select the next provider, then confirm write scope. The CLI start form requires the exact digest and timestamp printed by the preview, so automation cannot continue from stale context.

ACP agents are local stdio processes configured without a shell:

[providers.acp]
command = ["my-acp-agent", "--stdio"]
Terminal window
nagi tab list [--workspace <workspace_id>]
nagi tab create [--workspace <workspace_id>] [--cwd PATH] [--label TEXT] [--env KEY=VALUE] [--focus] [--no-focus]
nagi tab get <tab_id>
nagi tab focus <tab_id>
nagi tab rename <tab_id> <label>
nagi tab close <tab_id>
Terminal window
nagi pane list [--workspace <workspace_id>]
nagi pane current [--pane ID|--current]
nagi pane get <pane_id>
nagi pane layout [--pane ID|--current]
nagi pane process-info [--pane ID|--current]
nagi pane neighbor --direction left|right|up|down [--pane ID|--current]
nagi pane edges [--pane ID|--current]
nagi pane focus --direction left|right|up|down [--pane ID|--current]
nagi pane resize --direction left|right|up|down [--amount FLOAT] [--pane ID|--current]
nagi pane zoom [<pane_id>|--pane ID|--current] [--toggle|--on|--off]
nagi pane rename <pane_id> <label>|--clear
nagi pane split [<pane_id>|--pane ID|--current] --direction right|down [--ratio FLOAT] [--cwd PATH] [--env KEY=VALUE] [--focus] [--no-focus]
nagi pane swap --direction left|right|up|down [--pane ID|--current]
nagi pane swap --source-pane ID --target-pane ID
nagi pane move <pane_id> --tab <tab_id> --split right|down [--target-pane ID] [--ratio FLOAT] [--focus|--no-focus]
nagi pane move <pane_id> --new-tab [--workspace ID] [--label TEXT] [--focus|--no-focus]
nagi pane move <pane_id> --new-workspace [--label TEXT] [--tab-label TEXT] [--focus|--no-focus]
nagi pane close <pane_id>

For pane commands that accept --current, Nagi uses the calling pane’s NAGI_PANE_ID when the command runs inside a Nagi pane. For pane split, an explicit pane id or --pane ID splits that pane, --current splits the calling pane, and an omitted target keeps using the UI-focused pane.

Read output:

Terminal window
nagi pane read <pane_id> [--source visible|recent|recent-unwrapped|detection] [--lines N]
nagi pane read <pane_id> --source visible --ansi
nagi pane read <pane_id> --source recent-unwrapped --lines 120

Send input:

Terminal window
nagi pane send-text <pane_id> <text>
nagi pane send-keys <pane_id> <key> [key ...]
nagi pane run <pane_id> <command>

<key> uses Nagi key-combo syntax: plain printable keys such as a, special keys such as enter, tab, esc, backspace, left, right, up, and down, modifier chords such as ctrl+h, control+j, alt+x, and shift+tab, function keys such as f1, and named punctuation such as minus, plus, and backtick. Legacy C-c and c-c are accepted as aliases for ctrl+c.

pane run submits text plus Enter atomically. Prefer it over send-text plus send-keys Enter for commands.

Report agent state from custom hooks:

Terminal window
nagi pane report-agent <pane_id> \
--source ID \
--agent LABEL \
--state idle|working|blocked|unknown \
[--message TEXT] \
[--seq N] \
[--agent-session-id ID] \
[--agent-session-path PATH]

pane get, pane list, agent get, and agent list include a read-only agent_session object when an official integration has reported a native session reference. If no native session reference is stored, the field is omitted.

Those commands include foreground_cwd when Nagi can resolve the cwd of the foreground process controlling the pane. The existing cwd field remains the pane/workspace cwd used for labels and follow-cwd behavior.

pane get and pane list include scroll when terminal scroll metrics are available. scroll.offset_from_bottom == 0 means the pane is at the bottom of its scrollback.

Report display-only pane metadata without taking over semantic state:

Terminal window
nagi pane report-metadata <pane_id> \
--source ID \
[--agent LABEL] \
[--applies-to-source ID] \
[--title TEXT|--clear-title] \
[--display-agent TEXT|--clear-display-agent] \
[--state-label STATUS=TEXT] \
[--clear-state-labels] \
[--token NAME=VALUE] \
[--clear-token NAME] \
[--seq N] \
[--ttl-ms N]

STATUS is one of idle, working, blocked, done, or unknown. --agent and --applies-to-source guard only --title, --display-agent, and --state-label. They do not guard token patches; token reporters own clearing or TTL refresh. Use --display-agent to change the visible name.

Metadata text is normalized before storage. Nagi trims surrounding whitespace, removes control characters, and caps --title, --display-agent, each --state-label, and token values at 80 characters. Empty normalized token values clear that key.

--token patches one named display value; --clear-token removes one. Unmentioned tokens remain unchanged. Pane tokens are available to Agent sidebar rows as $name; workspace tokens are available to Space rows. TTL applies independently to the token keys updated by that call.

--source and --applies-to-source must be 80 characters or fewer and may contain only ASCII letters, digits, colon, dot, underscore, and hyphen. --ttl-ms makes metadata expire automatically and must be between 1 and 86400000 milliseconds. Omit it for metadata that should stay until replaced, cleared, or the pane closes. --seq lets Nagi ignore stale reports from the same --source; stale reports are accepted by the API but ignored by pane state. A pane or workspace accepts sequenced token reports from at most 32 distinct sources during its lifetime; clearing or expiry does not release those source slots.

Terminal window
nagi agent list
nagi agent get <target>
nagi agent read <target> [--source visible|recent|recent-unwrapped|detection] [--lines N] [--format text|ansi] [--ansi]
nagi agent send <target> <text>
nagi agent rename <target> <name>|--clear
nagi agent focus <target>
nagi agent wait <target> --status <idle|working|blocked|unknown> [--timeout MS]
nagi agent attach <target> [--takeover]
nagi agent start <name> [--cwd PATH] [--workspace ID] [--tab ID] [--split right|down] [--env KEY=VALUE] [--focus|--no-focus] -- <argv...>
nagi agent explain <target> [--json|--verbose]
nagi agent explain --file PATH --agent LABEL [--json|--verbose]

Agent targets can be terminal IDs, unique agent names, detected or reported agent labels, or legacy pane IDs. Names and labels are agent identities. Terminal IDs and legacy pane IDs are low-level escape hatches.

agent read reads the resolved terminal stream. agent send writes literal text to that stream. agent get, agent focus, agent wait, and agent attach require the resolved terminal to have agent identity. agent rename can assign that identity.

agent explain asks the running server to classify the same bottom-buffer detection snapshot used by screen detection, so live output reflects the server’s active manifest cache. Because this uses the agent.explain socket method, restart or hand off to an updated server after upgrading Nagi before using live explain. Use --file PATH --agent LABEL to explain a saved fixture locally instead. The default output shows the agent, final state, manifest source and version, matched rule with its region evidence, and any fallback, skip, or warning reasons. Add --verbose for visible evidence flags, cached remote version, local override shadowing, remote update status, and the full evaluated-rules list with matcher and region evidence. Add --json for issue reports or tests.

Use pane send-text, pane send-keys, pane run, and terminal attach for ordinary terminals, servers, tests, shells, or low-level terminal control. Use pane run when you want to submit a command with Enter.

Terminal window
nagi terminal attach <terminal_id> [--takeover]
nagi terminal session control <target> [--takeover] [--cols N] [--rows N]
nagi terminal session observe <target> [--cols N] [--rows N]
nagi terminal title set <title>
nagi terminal title clear

Detach from direct attach with ctrl+b q. Send literal ctrl+b with ctrl+b ctrl+b. terminal session control opens a writable live terminal stream for a pane, terminal, or agent target. It prints the same newline-delimited terminal.frame and terminal.closed records as observe mode. It reads newline-delimited JSON commands on stdin: terminal.input, terminal.resize, terminal.scroll, and terminal.release. One controller can own a terminal at a time; use --takeover to replace it. terminal session observe opens a read-only live terminal stream for a pane, terminal, or agent target. It prints newline-delimited JSON terminal.frame records with base64-encoded ANSI bytes, then a terminal.closed record when the server closes the stream. Multiple observers can watch the same terminal without taking input, resize, scroll, or takeover authority. terminal title clear restores Nagi’s default outer terminal window title.

Wait for output in a pane:

Terminal window
nagi wait output <pane_id> --match <text> [--source visible|recent|recent-unwrapped] [--lines N] [--timeout MS] [--regex] [--raw]

Wait for pane agent state:

Terminal window
nagi wait agent-status <pane_id> --status <idle|working|blocked|done|unknown> [--timeout MS]

Use wait output for normal commands and servers. Use wait agent-status for coding agents.

Terminal window
nagi integration install pi
nagi integration install omp
nagi integration install claude
nagi integration install codex
nagi integration install copilot
nagi integration install devin
nagi integration install droid
nagi integration install kimi
nagi integration install opencode
nagi integration install kilo
nagi integration install hermes
nagi integration install qodercli
nagi integration install cursor
nagi integration install mastracode
nagi integration uninstall pi
nagi integration uninstall omp
nagi integration uninstall claude
nagi integration uninstall codex
nagi integration uninstall copilot
nagi integration uninstall devin
nagi integration uninstall droid
nagi integration uninstall kimi
nagi integration uninstall opencode
nagi integration uninstall kilo
nagi integration uninstall hermes
nagi integration uninstall qodercli
nagi integration uninstall cursor
nagi integration uninstall mastracode
nagi integration status [--outdated-only]

Plugin commands install and run local executable workflow plugins. A plugin is a manifest plus out-of-process commands; Nagi owns the host surface and plugins own their implementation language.

Install, list, and remove plugins:

Terminal window
nagi plugin install <owner>/<repo>[/subdir...] [--ref REF] [--yes] [--trust-native]
nagi plugin list [--plugin ID] [--json]
nagi plugin uninstall <plugin_id|owner/repo[/subdir...]>
nagi plugin enable <plugin_id>
nagi plugin disable <plugin_id>
nagi plugin approve <plugin_id>
nagi plugin revoke <plugin_id>

plugin install accepts GitHub shorthand only, such as owner/nagi-plugin/worktree-bootstrap. It uses git, shows a source preview, runs supported legacy build commands, and stores GitHub installs in a Nagi-managed directory. Interactive confirmation records unrestricted trust only for legacy native plugins. Non-interactive native installs require both --yes and --trust-native; sandboxed v2 components reject --trust-native. A v2 component that requests capabilities installs disabled until plugin approve and plugin enable are run. Reinstalling a GitHub-managed plugin replaces that managed checkout. Installing over a locally linked plugin is refused. Plugin manifests must declare min_nagi_version; install and link fail when the plugin requires a newer Nagi binary. plugin list is human-readable by default; pass --json for the raw API response.

Local development:

Terminal window
nagi plugin new <path> [--id ID] [--name NAME] [--runtime wasi|native]
nagi plugin validate <path> [--json]
nagi plugin test <path> [--action ID] [--context-json JSON] [--stdin FILE] [--workspace PATH] [--json]
nagi plugin pack <path> [--out PATH] [--json]
nagi plugin dev <path> [--once] [--interval-ms N] [--disabled] [--trust-native]
nagi plugin link <path> [--disabled] [--trust-native]
nagi plugin inspect <plugin_id> [--json]
nagi plugin unlink <plugin_id>

plugin new scaffolds a manifest v2 WASI component by default, or an explicitly trusted native plugin. plugin validate checks the manifest, host capability bindings, compatibility, and component binary. plugin test runs the WASI component inside Nagi’s real sandbox with a deterministic mission fixture; inspector actions pass only when their stdout is a bounded, host-compatible UI document. Optional JSON context and stdin files make host-facing behavior reproducible. Pass --workspace PATH to mount a test worktree with only the manifest’s declared read/write capabilities. plugin pack creates a non-overwriting, self-contained bundle with a package-relative component entrypoint, SHA-256 checksums, SPDX 2.3 SBOM, and provenance. plugin dev links once, tails recent logs, watches source and component contents, revalidates before every reload, and keeps capability-bearing plugins disabled until approval. Use --once in CI or editor tasks. plugin inspect shows runtime, provenance, resolved commit, requested capabilities, contributions, trust, warnings, and the approved-to-current security diff for version, manifest, component, commit, and added capabilities.

plugin link accepts a plugin directory containing nagi-plugin.toml or a direct manifest path. Legacy native manifests require --trust-native before enablement. Sandboxed manifest v2 components do not accept that flag and can link enabled when they request no capabilities. Requested capabilities require an exact, revocable grant. plugin unlink unregisters the plugin, removes its stored grant and leaves files alone. plugin uninstall also removes Nagi-managed GitHub checkout files. For GitHub installs, uninstall accepts either the plugin id or the same owner/repo[/subdir...] shorthand used by install.

Config directory:

Terminal window
nagi plugin config-dir <plugin_id>

plugin config-dir prints the plugin’s config directory, creating it (and seeding it from legacy plugin config locations when present) if needed. Use it in setup docs and shell scripts to point users at a stable path for .env files and other user-editable config, separate from the managed plugin checkout.

Actions:

Terminal window
nagi plugin action list [--plugin ID]
nagi plugin action invoke <action_id> [--plugin ID]

plugin action invoke starts the manifest command for an installed, enabled, platform-compatible plugin action and prints the started command log record in the JSON response. Use the qualified action id (plugin.id.action) when more than one plugin uses the same action id. Local action ids cannot contain dots, so qualified ids remain unambiguous even when plugin ids contain dots.

Logs:

Terminal window
nagi plugin log list [--plugin ID] [--limit N]

Managed terminal panes:

Terminal window
nagi plugin pane open --plugin ID --entrypoint ID [--placement overlay|popup|split|tab|zoomed] [--width SIZE] [--height SIZE] [--workspace ID] [--target-pane PANE] [--direction right|down] [--cwd PATH] [--env KEY=VALUE] [--focus|--no-focus]
nagi plugin pane focus <pane_id>
nagi plugin pane close <pane_id>

plugin pane open requires the plugin to be linked, enabled, and compatible with the current platform. It starts a manifest-declared [[panes]] command as a Nagi-managed terminal pane. The manifest default is overlay, which opens a temporary zoomed overlay over the active pane. It can also open as a split, a new tab, a zoomed pane, or a session-modal popup that does not change the tab layout. --width and --height set the outer popup dimensions in terminal cells or percentages such as 80%; omitted dimensions default to half the terminal size, and values smaller than the popup minimum are clamped. A popup is not a Nagi pane, does not export NAGI_PANE_ID, and does not participate in pane or agent APIs. Native non-terminal plugin panes are a later surface.

--env KEY=VALUE can be repeated on process-launching commands. It applies to the newly launched process only. Nagi-managed variables such as NAGI_SOCKET_PATH, NAGI_BIN_PATH, NAGI_ENV, NAGI_WORKSPACE_ID, NAGI_TAB_ID, NAGI_PANE_ID, NAGI_PLUGIN_ID, NAGI_PLUGIN_ROOT, NAGI_PLUGIN_CONFIG_DIR, NAGI_PLUGIN_STATE_DIR, NAGI_PLUGIN_ENTRYPOINT_ID, and NAGI_PLUGIN_CONTEXT_JSON stay authoritative when they conflict with caller-provided env.

SourceMeaning
visibleCurrent rendered screen. Best for UI feedback loops.
recentRecent scrollback with terminal wrapping.
recent-unwrappedRecent scrollback without soft wrapping. Best for logs.
detectionBottom-buffer snapshot used by agent screen detection.
VariablePurpose
NAGI_CONFIG_PATHOverride the config file path.
NAGI_SESSIONSelect a named session for CLI commands.
NAGI_SOCKET_PATHLow-level socket path override.
NAGI_ENVSet to 1 inside Nagi-managed pane processes.
NAGI_PANE_IDPublic pane id for the running pane process.
NAGI_TAB_IDPublic tab id for the running pane process.
NAGI_WORKSPACE_IDPublic workspace id for the running pane process.
NAGI_LOGSet log filter, for example NAGI_LOG=nagi=debug.
NAGI_DISABLE_SOUNDDisable sound playback even when sound notifications are enabled.