Skip to content

Status tracking

Copy page

Workrex shows agent status in the dashboard, sidebar, and managed Rex window labels. Agents can report status through Rex’s program status protocol or the hooks installed by workrex setup.

AgentStatus
Claude Code✅ Supported
OpenCode✅ Supported
Codex✅ Supported
Copilot CLI✅ Supported*
Pi✅ Supported*
Oh My Pi✅ Supported
Gemini CLI✅ Supported
Grok✅ Supported
Muse Code✅ Supported*
Antigravity CLI (agy)✅ Supported*
KiroTracking issue
Mistral VibeTracking issue

Notes:

  • Copilot CLI: No 💬 waiting state
  • Pi: No 💬 waiting state
  • Codex: Registration occurs when the first turn begins because its session hook is turn-bound
  • Antigravity CLI (agy): No 💬 waiting state; registration occurs when agent execution begins
  • Muse Code: Registration occurs when the first prompt is sent, because Muse starts its session then
  • Kiro: Hooks support is messy: requires a custom agent since the default can’t be edited
  • 🤖 = agent is working
  • 💬 = agent is waiting for user input
  • ✅ = agent finished (changes on the next status update)

Under the Rex backend, workrex also reads the status that programs report to Rex through the Program Status Protocol (OSC 7501). Claude Code reports it without any setup, so its status shows up in workrex status, the dashboard and the sidebar with no hooks installed.

Rex stateworkrex status
working🤖 working
blocked💬 waiting
done✅ done
error✅ done
idlenone
  • When a pane reports program status, that status wins over the hook status. Hooks still track agents that do not report it.
  • A pane that reports status but has no hook state counts as an agent only when its working directory is a linked worktree of the repository you run workrex in.
  • A record left behind by a program that is no longer in the foreground is ignored, so an agent that exits drops out of the list.
  • Hook-reported status puts its icon in front of the Rex window label. Rex draws its own indicator on tabs for program status. The icon does not clear on window focus; it changes with the next status.

Run workrex setup to automatically detect your agent CLIs and install status tracking hooks:

Terminal window
workrex setup

This detects Claude Code, Codex, Copilot CLI, Gemini CLI, Grok, Muse Code, Antigravity CLI, OpenCode, Pi, and Oh My Pi by checking for their executable or configuration directories, then offers to install the appropriate hooks. Agent-specific configuration directory overrides are respected. workrex also offers updates when an installed integration differs from its bundled version.

The sections below describe manual installation. The repository’s native workrex-status integrations already call workrex. Merge the relevant entries with existing user configuration so unrelated hooks remain intact.

workrex setup --hooks adds the hooks to ~/.claude/settings.json, or to $CLAUDE_CONFIG_DIR/settings.json when that is set.

To add them by hand, copy the hooks from .claude-plugin/plugin.json into ~/.claude/settings.json, preserving unrelated hooks.

workrex setup also recognizes an enabled Workrex Claude Code plugin whose enabledPlugins key begins with workrex-status@.

If you prefer manual setup, copy the workrex status extension to your global pi extensions directory:

Terminal window
mkdir -p ~/.pi/agent/extensions
curl -o ~/.pi/agent/extensions/workrex-status.ts \
https://raw.githubusercontent.com/kong109/workrex/main/resources/pi/extensions/workrex-status.ts

Restart pi for the extension to take effect.

With a pi-suba release that publishes activity snapshots, the parent stays working while either the parent or any delegated child is active. Waiting children do not count as active. When both the parent and all children are inactive, workrex reports done. Resuming a child marks the parent working again, even without a new parent turn.

The extensions communicate through pi.events: pi-suba publishes suba:activity with { activeCount: number }, and workrex requests an initial snapshot with suba:activity:request. workrex does not read child session files or poll child processes.

Without an activity publisher, Pi status behavior is unchanged, including keeping aborted turns working for continuation. With a publisher, a settled aborted parent is inactive, but active children still keep it working.

If you prefer manual setup, copy the workrex status extension to your global OMP extensions directory:

Terminal window
mkdir -p ~/.omp/agent/extensions
curl -o ~/.omp/agent/extensions/workrex-status.ts \
https://raw.githubusercontent.com/kong109/workrex/main/resources/omp/extensions/workrex-status.ts

Restart omp for the extension to take effect.

OpenCode V2 status tracking requires the terminal UI; headless opencode run is not tracked.

For manual setup:

Terminal window
mkdir -p ~/.config/opencode/plugins/workrex-status
for file in index.ts tui.ts status.ts; do
curl -fsSL -o "$HOME/.config/opencode/plugins/workrex-status/$file" \
"https://raw.githubusercontent.com/kong109/workrex/main/resources/opencode/v2/workrex-status/$file"
done

When switching versions manually, back up any local edits and remove the other version’s workrex plugin: plugins/workrex-status.ts (or plugin/workrex-status.ts) for V1, plugins/workrex-status/ for V2.

Restart OpenCode for the plugin to take effect.

If you prefer manual setup, first ensure hooks are enabled in your Codex config:

# ${CODEX_HOME:-$HOME/.codex}/config.toml
[features]
hooks = true

Then download the hooks configuration:

Terminal window
codex_home="${CODEX_HOME:-$HOME/.codex}"
mkdir -p "$codex_home"
curl -o "$codex_home/hooks.json" \
https://raw.githubusercontent.com/kong109/workrex/main/resources/codex/hooks/workrex-status.json

If you already have a hooks.json in your Codex home, merge the hook entries from the downloaded file into your existing configuration.

Codex permission prompts use the 💬 waiting state.

If you prefer manual setup, download the hooks configuration and merge it into your Gemini settings:

Terminal window
gemini_dir="${GEMINI_CLI_HOME:-$HOME}/.gemini"
curl -s https://raw.githubusercontent.com/kong109/workrex/main/resources/gemini/settings.json \
| jq -s '.[0] * .[1]' "$gemini_dir/settings.json" - > /tmp/gemini-settings.json \
&& mv /tmp/gemini-settings.json "$gemini_dir/settings.json"

If you don’t have an existing Gemini settings file, you can download the hooks configuration directly:

Terminal window
gemini_dir="${GEMINI_CLI_HOME:-$HOME}/.gemini"
mkdir -p "$gemini_dir"
curl -o "$gemini_dir/settings.json" \
https://raw.githubusercontent.com/kong109/workrex/main/resources/gemini/settings.json

workrex setup installs Grok lifecycle hooks under $GROK_HOME/hooks/, or ~/.grok/hooks/ when GROK_HOME is unset. Start a new Grok session after setup so it discovers the hook.

For manual setup, download the hooks configuration:

Terminal window
grok_home="${GROK_HOME:-$HOME/.grok}"
mkdir -p "$grok_home/hooks"
curl -o "$grok_home/hooks/workrex-status.json" \
https://raw.githubusercontent.com/kong109/workrex/main/.grok/hooks/workrex-status.json

UserPromptSubmit and PostToolUse mark the pane working, Notification marks it waiting, and Stop or SessionEnd marks it done. Grok permission prompts do not all emit Notification, so some prompts may remain marked as working while waiting for input.

Muse runs hooks from its settings.json with most environment variables removed, including the ones workrex uses to find the agent’s pane. Hooks in a managed hooks file keep the variables that managed_hooks_env_vars names. workrex setup therefore writes the hooks to workrex-status.json in Muse’s config directory, $XDG_CONFIG_HOME/muse/ or ~/.config/muse/. It also adds two keys to settings.json in that directory:

  • managed_hooks_path names the hooks file.
  • managed_hooks_env_vars lists the multiplexer, WORKREX_* and XDG variables that the hooks need.

Setup records the variable names it adds in workrex-env-vars.json in the same directory. workrex uninstall removes the hooks file, managed_hooks_path, and only the names in that record, so names you listed before setup stay.

If settings.json already sets managed_hooks_path to another file, setup changes nothing and reports the conflict. Add the hooks from resources/muse/workrex-status.json to that file, using the workrex commands shown in that file.

UserPromptSubmit, ToolUseStart, PostToolUse and PostToolUseFailure mark the pane working, Notification marks it waiting, and Stop, Interrupt or SessionEnd marks it done. Muse sends Notification only while a permission prompt or a question is still unanswered a few seconds after it opens. A shell command you run with ! does not change the status, and neither does an event that Muse marks as sent after the turn ended.

Muse loads hooks when it starts, so restart running muse sessions after setup.

workrex setup installs Antigravity lifecycle hooks in ~/.gemini/config/hooks.json. The first PreInvocation handler registers the pane when agent execution begins, the second marks it working, and the terminal Stop event marks it done.

Antigravity loads hook configuration when a session starts, so restart existing agy sessions after setup.

For manual setup, merge this named hook group into ~/.gemini/config/hooks.json:

{
"workrex-status": {
"PreInvocation": [
{
"type": "command",
"command": "workrex register-agent >/dev/null 2>&1 || true; printf '{}\\n'"
},
{
"type": "command",
"command": "workrex set-window-status working >/dev/null 2>&1 || true; printf '{}\\n'"
}
],
"Stop": [
{
"type": "command",
"command": "workrex set-window-status done >/dev/null 2>&1 || true; printf '{}\\n'"
}
]
}
}

Copilot CLI 0.0.422 or later supports personal hooks. If you prefer manual setup, install the workrex hook under $COPILOT_HOME/hooks/, or ~/.copilot/hooks/ when COPILOT_HOME is unset:

Terminal window
copilot_home="${COPILOT_HOME:-$HOME/.copilot}"
mkdir -p "$copilot_home/hooks"
curl -o "$copilot_home/hooks/workrex-status.json" \
https://raw.githubusercontent.com/kong109/workrex/main/resources/copilot/hooks/workrex-status/hooks.json

Copilot loads personal hooks in every repository. If the repository contains a .github/hooks/workrex-status installation, remove that directory to avoid running both copies of the hook. The Copilot CLI hooks API does not support detecting permission prompts, so only working/done states are tracked (no waiting state).

You can customize the icons in your config. Use the Workrex configuration paths and WORKREX_* variables. See Configuration.

~/.config/workrex/config.yaml
status_icons:
working: "🔄"
waiting: "⏸️"
done: "✔️"

Style-tag codes are supported for colored icons, and render in the dashboard and sidebar:

status_icons:
done: "#[fg=#a6e3a1]󰄴#[fg=default]"

When an agent is in “working” status but its pane output hasn’t changed for 10 seconds, workrex automatically detects it as interrupted. This typically happens when a user presses Ctrl+C to stop an agent.

The detection runs in the sidebar daemon. If the agent resumes producing output, the interrupted indicator clears automatically. The dashboard reads the detection results from a shared runtime file, so both views stay in sync.

Use workrex last-done to quickly switch to the agent that most recently finished its task or is waiting for user input. Repeated invocations cycle through all completed and waiting agents in reverse chronological order (most recent first).

Under Rex, last-done and last-agent switch Rex.app to the agent, which needs Remote Control. See Rex.

Use workrex last-agent to toggle between your current agent and the last one you visited. It remembers which agent you came from and switches back to it. Pressing it again returns you to where you were.

This is available both as a CLI command and as the Tab key in the dashboard.

Use the command from a Rex terminal or a Rex action that runs Workrex. The bundled dashboard action provides navigation without inventing another app’s keybinding syntax. See Rex dashboard.

If you launch another agent from inside an agent, that nested agent may run its own configured workrex status hooks and report activity from the same pane. Set WORKREX_DISABLE_SET_WINDOW_STATUS=1 on the nested command to make workrex set-window-status exit successfully without updating Rex or agent state:

Terminal window
WORKREX_DISABLE_SET_WINDOW_STATUS=1 codex

Use this when you want only the parent agent pane to drive the workrex status indicator.