Agent status

Spaces tracks a coding agent's state in your sidebar, so you always know which one needs you next.

Supported agents

Spaces tracks Claude Code, Codex, opencode, GitHub Copilot CLI, pi (1.1.0 or later), and Amp. Start any of them in a Spaces terminal and it shows up as its own row, listed under Coding Agents in that terminal's workspace.

Status hooks

Spaces reports agent state through a small hook it installs into each agent's own configuration. Spaces offers to install these the first time it detects an agent, in the skippable coding-agents step at first launch, and any time after that from Settings → Coding Agents. It touches ~/.claude/settings.json for Claude Code, ~/.codex/hooks.json for Codex (which also turns on Codex's hooks feature), and a plugin file under ~/.config/opencode/plugin/ for opencode. For Copilot it writes its own file, ~/.copilot/hooks/spaces.json, and leaves your other Copilot hook files alone. For pi it writes its own extension, ~/.pi/agent/extensions/spaces.ts, and leaves your other pi extensions alone. For Amp it writes its own plugin, ~/.config/amp/plugins/spaces.ts, and leaves your other Amp plugins alone.

Settings → Coding Agents shows, per agent, one of five states: not installed, out of date, switched off in the agent, not yet trusted in Codex, or installed. A row shows a button only when there is something to do: Install, Update, or, for Codex hooks waiting for trust, Trust in Codex. Hooks switched off in the agent are turned back on in the agent itself; for Copilot that means the disableAllHooks setting in ~/.copilot/settings.json (copilot config disableAllHooks false), and for pi it means checking spaces.ts again in pi config.

Copilot reports nothing until you send its first prompt, so a Copilot you just launched shows as a row once Spaces sees it running, and its status follows from the first prompt on. Copilot shows as blocked only while a permission prompt or a question from the agent is waiting for you. Pressing Esc on a permission prompt ends the turn without a hook, so that row stays blocked until your next prompt.

pi has no permission prompts, so a pi row shows as blocked only while a dialog opened by one of your pi extensions (a confirmation, a choice, or an input) is waiting for you during a turn. pi's own startup trust prompt and its /login picker don't show as blocked. A pi row shows done when the turn has fully settled, after any retries, and it follows the conversation when you start another with /new or resume one. pi older than 1.1.0 isn't tracked, and Spaces reports only from pi's interactive terminal, not from pi -p or the json and rpc modes.

Amp reports from your first prompt on: a freshly launched Amp shows as a row once Spaces sees it running, and its status follows once you send a prompt. An Amp row follows the thread you are looking at, so starting a new thread or continuing another keeps it in step. Amp asks for no tool approvals by default, so an Amp row shows as blocked only when a tool approval is waiting; a question from the agent or a dialog from one of your Amp plugins does not show as blocked. Spaces does not report from Amp's execute mode (amp -x). Removing spaces.ts from the plugins folder is how you switch the integration off.

Copilot asks whether you trust a folder each time you start it in one it has not remembered, and runs nothing until you answer. The first time it asks in a project, choose Yes, and remember this folder, or trust ~/spaces (where Spaces keeps its workspaces) and your project folders in Copilot; trusting a folder covers the folders under it. Otherwise an agent Spaces spawns or an automation answers the question with its prompt and does nothing, so trust the folders first and spawned agents and automations can start without a person at the keyboard.

Codex runs no hook until you trust it. Trust in Codex first lists the exact commands Codex will run, then records the trust through Codex for those Spaces hooks only. Hooks from other tools, and hooks you switched off in Codex, stay as they are. Codex sessions already running pick up the hooks when they restart. If Codex can't record the trust, the row shows Codex's reason: update Codex, or open it in a terminal and trust the hooks there. Installing again keeps the trust as long as the hooks come out the same; a Spaces update that changes them asks for trust again, and hooks you switched off in Codex stay off through it.

A hook or an MCP call counts for a terminal only when it comes from a process running inside that terminal. A process carried out of its terminal still carries that terminal's identity, so Spaces ignores it rather than show its status on the wrong row. Agents running inside tmux or screen therefore don't report status to Spaces.

Agents that report their own status to the terminal (Claude Code and Codex do, through the terminal Program Status Protocol) take over the working, blocked, and done states of their row from the hooks, and raise the same alerts. Hooks still provide the conversation Spaces resumes, the brief, and when the agent starts and exits. This needs no setup, and it applies only to terminals where Spaces has identified a coding agent.

Codex's background server

Codex 0.157 and later can run its sessions on one shared background server, started by the first Codex you open. Every session on that server runs with the first terminal's environment, so Spaces can't tell which terminal it belongs to. In Spaces terminals, Spaces starts Codex with --no-daemon, so each session runs in its own process with its own terminal's environment and reports to its own row. which codex shows a small Spaces wrapper that runs your own Codex with that flag. codex agents, codex queue, and --remote run exactly as you typed them. This needs Codex 0.156 or later: an older Codex stops with "unexpected argument '--no-daemon'" in Spaces terminals until you update it.

A Codex session started some other way can still land on the background server, and Spaces ignores its hooks. While that server is running, the Codex row in Settings → Coding Agents says so and offers Stop Server. Stopping ends the Codex sessions running on it. Their conversations are kept, and you can resume them in a Spaces terminal.

Spaces keeps its wrapper first on PATH in zsh, bash, and fish, even when your startup files add their own folders. The exception is macOS's built-in /bin/bash, which doesn't load Spaces' startup file: if your bash startup files put another codex ahead of the wrapper, that Codex can still use the background server.

States

  • • Working (green): the agent is running a turn.
  • • Blocked (amber): the agent is waiting on a permission prompt or your answer. Counts toward Alerts and the Dock badge until it clears on its own.
  • • Done (blue): the agent finished a turn. Stays in Alerts and the Dock badge until you dismiss it or visit its terminal.
  • • Idle (gray): not doing anything at the moment, whether it is sitting at its prompt or has not started a turn yet.

When the agent's process exits, its row reads "Exited" while the terminal stays open, and disappears once its terminal session ends; closing its pane only detaches the terminal and leaves the exited row in place. An agent that asks a question in plain text, without going through a permission prompt, shows as done rather than blocked, since Spaces has no hook for a plain-text question.

Status shows on the sidebar row, in Alerts, in the command palette, in the All agents cycling mode, and on the iPhone Agents tab.

Agent briefs

A coding agent can keep one short brief: a status page it writes about itself, covering what it is doing, when a long step should finish, questions for you, and its task list. Spaces shows it read-only beside the agent's terminal, and it is the agent's own writing, never something Spaces adds for it. Any terminal where Spaces has detected a supported coding agent can keep one.

A brief belongs to the agent's conversation. Resume that conversation later in the same workspace, by hand or through Bringing agents back, and the brief comes back with it; a resumed Codex shows it after your first prompt. A new conversation in the same terminal, such as after /clear, starts without one. A brief is deleted when the agent clears it or when you delete its workspace.

On the Mac it renders as a column at the trailing edge of the agent's pane. Show or hide it with ⌥⌘B (configurable in Settings → Shortcuts), the footer's brief glyph, the pane's "⋯" menu ("Hide Brief" or "Show Brief"), or a global panel window's title strip. On iPhone and iPad, a brief button in the terminal's top bar opens a sheet, which also opens on its own for an agent whose brief you have not dismissed. The sidebar and the iPhone agent rows show a small glyph when the agent has a brief.

A brief's first line is its one-line summary, shown wherever there is no room for the whole document: spaces agent list, spaces agent status, and subscribe notifications. For the commands that read and write a brief, see briefs. For your own notes on a workspace, see workspace notes.

Stopping an agent

End an agent and its terminal from its sidebar row, from the iPhone Agents tab, or with spaces agent kill.

Driving several agents

Once agents report their state, one agent, or you from a single terminal, can watch and drive the others across your workspaces and devices. See Orchestrate agents.

See also

  • • Orchestrate agents, for spawning, watching, and stopping agents from another agent.
  • • Automations, for running an agent on a schedule.
  • • CLI, for every spaces agent command.