Working with AI agents
Let coding agents delegate work and coordinate across Zshell panes while you stay focused and in control.
Zshell's automation is primarily for AI coding agents. It gives them a safe way to work with Zshell's panes and coordinate other agents; it is not another command language you need to learn.
AI integration is enabled by default. Talk to your coding agent normally. It can create a background pane, start a delegated worker, run a command, wait for the result, and bring the answer back without taking focus from the pane you are using.
Wait for command results
For finite commands such as tests or a build, your agent can wait for the command’s own exit status and duration, then read saved recent terminal output. If a wait times out, the command keeps running and the same task can be waited on again. Waiting does not take focus. This requires an empty prompt in the original local zsh that Zshell launched; nested shells, SSH, and custom startup programs do not support command results. Recent terminal output can include earlier commands or prompts and is bounded, so ask the agent to save complete output to a file when needed.
Direct exit, logout, and exec are rejected because they end or replace the original shell; use /bin/sh -c for those commands in a subprocess.
Setup
Check Settings → Automation → AI. It is on by default; if you previously disabled it, enable it again, then start a new terminal or restart an agent that was already running.
Zshell supports Codex, Claude Code, Gemini CLI, Grok Build, OpenCode, Cursor Agent, Aider, Amp, and Pi. If Zshell finds an existing agent setup that conflicts with this feature, it leaves that setup unchanged, returns the toggle to its previous state, and shows the error in Settings.
Ask in plain language
Tell your agent the outcome you want. For example:
Run the focused tests in a background pane and tell me what fails.
Delegate this bug to another Codex agent, then review its result.
Ask the agent working on the API whether the schema is ready, then pass the answer to the agent running the tests.
Start the dev server beside us, wait until it is ready, and give me the URL.
Check whether the background agent is finished. If it is blocked, tell me what it needs.
The agent handles Zshell's automation interface on your behalf. You do not need to type or memorize any Zshell automation commands.
Let agents coordinate across panes
You can split related work across several Zshell panes and ask your main agent to coordinate it. For example, one agent can work on an API while another updates tests. The coordinating agent can ask a specific worker for its findings, send a follow-up, pass the useful result to another worker, and bring the combined answer back to you. The workers can use different supported coding tools.
This removes the copy-and-paste step from parallel work. Each agent keeps its own conversation in its own pane, while the coordinating agent passes along only the question, update, or result the other worker needs.
Sending a follow-up does not mean the work is finished. The coordinating agent still waits for the worker, reads its result, and checks the outcome. A message from another agent is also never treated as your approval. Permissions, credentials, trust decisions, and destructive actions still come back to you.
Keep working while it runs
Delegated panes stay in the background unless you ask to see them. When a provider-native lifecycle integration reports state, Zshell shows it on the agent's pane and tab:
| State | What it means for you |
|---|---|
| Working | The agent is actively handling the task. |
| Blocked | It needs input, approval, or another decision from you. |
| Done | It finished in the background and you have not viewed the pane yet. |
Zshell prefers native lifecycle events from Codex, Claude Code, Pi, OpenCode, and Grok, followed by explicit program reports. Hover the status badge or open Agents to see the source, waiting reason, percentage, and child tasks. Codex hooks must first be reviewed and trusted in its /hooks menu; Zshell does not bypass that review.
For recognized agent processes without a native report, Zshell can inspect a bounded live screen footer. Screen inference is labelled, never reports completion, never sends a notification, and cannot satisfy zshell +agent wait. It never grants an approval. Read the pane and verify the actual result before treating work as complete.
Programs can report progress with zshell +agent report and clear their own report with zshell +agent clear. Reports expire after 120 seconds without an update or when the owning process exits. See program reports.
When an integration reports that an agent finished or needs input, Zshell can also send a notification. Press Cmd+Shift+A to jump to the next reported agent that needs your attention.
Program reports
A script or tool running inside a Zshell terminal can publish its own status:
zshell +agent report working --name Build --progress 25 --reason 'Compiling sources'
zshell +agent report blocked --name Build --attention approval --reason 'Review the release before publishing'
zshell +agent clearrunning is an alias for working. approval, input, login, and error
are shortcuts for blocked with that attention reason. Other states are
done, idle, and unknown. done is an explicit status report, not a verified
command result. Zshell never answers a prompt or grants approval based on a report.
Completion in the focused pane is already seen, so done appears as idle
with its progress and task details retained. Reading through the API does not
mark a background completion seen; focusing that pane does.
For several child tasks, pass --tasks with a JSON array or send one JSON object
to zshell +agent report --json on standard input:
{
"name": "Build",
"state": "working",
"progress": 50,
"tasks": [
{ "id": "compile", "title": "Compile", "state": "done", "progress": 100 },
{ "id": "tests", "title": "Tests", "state": "working", "progress": 20 }
]
}Each report replaces the previous program report and child-task list. Task IDs
must be unique. A blocked child brings the parent to attention; an active child
keeps a reported idle or completed parent working. Percentages must be integers from 0 to 100. A report supports
at most 32 tasks; the badge tooltip previews eight and reports the total, while
zshell +agent get --current returns every task. Names are limited to 128 UTF-8
bytes, reasons to 1 KiB, task IDs to 128 bytes, task titles to 256 bytes, and
standard-input JSON to 32 KiB. Text must fit on one line and contain no terminal
control characters. Reports are limited to 10 updates per second per terminal.
The CLI binds the report to its parent process by default. --pid PID (or
process_id in JSON) may select a live ancestor of the CLI within the same
terminal. Its PID and process start time must still match. Refresh long-running
reports at least once every 120 seconds. Closing the terminal, exiting the owner,
or letting the report expire removes its status. clear removes only the
program report; it cannot clear a provider's native lifecycle state.
This interface uses Zshell's private, authenticated Unix socket and works with both Ghostty and Alacritty. It has no pane or project target option. Printing terminal text or an OSC sequence cannot impersonate a native lifecycle report. Native state takes priority over program reports; inferred screen state is lower priority and never counts as a result or approval.
Account usage and limits
Settings → Automation → Account Usage shows available account limits for Claude Code and Codex, including the used percentage, reset time when reported, and the time of the last update. Use Refresh Usage to reload the latest available data.
Codex needs an installed, signed-in CLI that can report account limits. Claude Code usage appears when Zshell has received a status-line usage report from the provider. The section only appears when usage data is available; supported windows depend on the provider and account. These are account limits, not a token total for the focused session.
A typical workflow
- Start your usual coding agent in a Zshell terminal.
- Ask it to delegate a bounded task, run something in the background, or coordinate another agent.
- Continue working in your current pane while Zshell keeps the delegated work visible in the project layout.
- Follow a provider-reported Working, Blocked, or Done badge when available. If the tool does not report lifecycle, open the pane to inspect its conversation or terminal output instead.
- Review the resulting files in the Git panel, inspect the diff, and decide what to keep.
You stay in control
- Agent automation stays inside the current Zshell project and cannot reach panes in another project or window.
- Background work does not take focus unless you explicitly ask for it.
- Zshell never answers permission, credential, trust, or destructive-action prompts for you. A provider-reported blocked agent hands that decision back to you.
- Reported completion is a signal to review the result, not an automatic approval of the agent's changes.
If an agent does not use Zshell
- Confirm that Settings → Automation → AI is enabled.
- Open a new Zshell terminal if the current one existed before you enabled the setting.
- Restart an agent that was already running when you enabled it.
- Check Settings for an inline setup error.
- Ask explicitly for a "background Zshell pane" or a "delegated Zshell agent" if you want the agent to use this workflow for a task.
Resume the original conversation
With Resume agent conversations enabled, reopening a terminal pane resumes its recorded Claude Code, Codex, Pi, or OpenCode conversation when the original PTY is unavailable. The conversation belongs to that pane, even when several panes use the same directory.
Zshell installs SessionStart hooks for Claude Code and Codex, a Pi extension, and an OpenCode TUI plugin in existing provider configuration. Your other hooks, plugins, settings, and JSONC comments are preserved. Enable the hooks in Claude Code’s trust prompt and approve new Codex hooks in /hooks when the provider asks. Restart an agent that was running before installation.
Only verified root conversations reported by these integrations can be resumed. Shared Codex app-server sessions are supported when a verified conversation ID matches the pane; ambiguous matches remain unbound. See shared remote sessions for conversations on remote hosts. OpenCode requires the TUI plugin API; older versions, headless server sessions, and opencode attach are unsupported. A child agent cannot replace the parent pane’s conversation. Pi requires its saved session file.
No verified identity, a missing working directory, or an unavailable Pi file opens a new shell. An unavailable CLI also returns to a shell. Zshell does not replay an arbitrary startup command or pick a recent conversation. Provider errors such as a deleted conversation are displayed by the CLI.
Find and resume saved conversations
Open Agents → Agent Conversation History, click the clock button at the top of the project sidebar. Search across projects by title, provider, project, conversation ID, working directory, or configuration directory. Zshell keeps the newest 200 verified local conversations after agents and panes exit and across app restarts. Recent shows 20 unarchived matches; All includes archived records; Archived shows only archived records.
Select Show Conversation for an open conversation or Resume Conversation for a saved one. Zshell reuses an open pane, reconnects a surviving PTY, or starts the provider's exact conversation with its original directory and configuration. Manual resume requires AI integration, even when automatic conversation restoration is off. Missing working or configuration directories and missing or mismatched Pi files show an error before a new pane is created.
Archive hides a record from Recent; Unarchive brings it back. Delete… removes only the Zshell history record and keeps the provider's conversation files.
Inside a Zshell pane, use zshell +agent history --all and zshell +agent resume --id HISTORY_UUID for that pane's project. From an ordinary external terminal, keep Zshell running, discover a project UUID, and select it explicitly:
zshell +agent history projects
zshell +agent history --project PROJECT_UUID --all
zshell +agent resume --project PROJECT_UUID --id HISTORY_UUID --focusCLI resume stays in the background unless you add --focus. For a project open in several windows, choose --window WINDOW_UUID from history projects. If several app instances are running, use --connection PATH with the absolute private descriptor path shown by the CLI. These target options are for external terminals; pane processes retain their original project scope.
Follow live project events
Run zshell +events inside a Zshell terminal to subscribe to future changes in
that terminal's project and window. It streams one JSON object per line over the
same authenticated private socket as pane automation; it does not poll. There
is no external-control fallback, and --project is not supported. Removing the
terminal environment does not grant broader access.
zshell +events
zshell +events --pane PANE_UUID --event agent.attention --once --timeout 30000
zshell +events --event command.task.finished--pane accepts an existing pane UUID in the caller's project. Repeat --event
to combine names from the table below. --once stops after the first matching
change, excluding stream.ready. --timeout is milliseconds, from 0 to 86400000;
0 waits indefinitely. A timeout exits 0, or 124 with --once when no change
matched. Interrupting the command cancels the subscription.
| Event | Data |
|---|---|
session.created, session.closed | Terminal session added to or removed from the project. |
pane.created, pane.closed | Pane added to or removed from the project, including nonterminal panes. |
pane.updated | The same pane moved to another tab or changed content. from contains its prior tab/terminal/content IDs; replacing a terminal also emits session.closed and session.created. |
focus.changed | from and to selection; window_key also reflects application/window activation. |
agent.status, agent.progress, agent.attention, agent.finished | Current agent snapshot from Zshell's existing status model. Screen inference is labelled and never emits agent.finished. |
command.finished | Shell integration's exit_code, duration_ms, and completion_sequence. Backend support follows the existing shell integration; an absent status is JSON null. |
command.task.finished | Automation task_id, state, exit_code, duration_ms, and error_code. Read the retained result with +pane wait --task UUID; terminal output is not copied into this stream. |
Every output line uses this versioned NDJSON envelope:
{"version":1,"event":"pane.created","stream_id":"UUID","sequence":1,"time":1793000000000,"project_id":"UUID","data":{"tab_id":"UUID","pane_id":"UUID","terminal_id":"UUID","content":"terminal"}}time is Unix milliseconds. data contains event-specific fields; pane events
include tab_id, pane_id, terminal_id (null for nonterminals), content_id, and content.
The first line is stream.ready with sequence 0 and queue limits. Subsequent
matching changes increase the sequence by one within that stream_id. The
subscription starts atomically at stream.ready: earlier events are not
replayed. Use pane/agent reads to inspect current state when reconnecting.
The app allows at most 32 subscriptions. Each has a limit of 256 queued frames,
1 MiB total, and 64 KiB per frame. A slow consumer receives stream.lagged when
possible, followed by disconnect; its sequence jumps forward when queued changes
are discarded and always exceeds previously delivered sequence numbers. A peer that cannot accept writes for 2 seconds is
closed. Lag, unexpected EOF, authentication failure, or a sequence error makes
the CLI exit nonzero. Reconnect and inspect current state; there is no replay or
exactly-once delivery across connections.
Closing the owning terminal, rotating its capability, or moving it to another project/window ends its existing subscriptions and discards queued events. Other projects/windows are never included, even if a caller supplies their pane UUID. A move of another terminal appears as removal in the source project and creation in the destination project.