Skip to content

Activity reporting for coding CLIs

A coding CLI running inside a PiCode terminal can identify itself and report its lifecycle, so the sidebar shows which CLI is present, when it is working, and when it needs you.

  • Where: Agent CLIsActivity reporting, from the last icon in the desktop sidebar header or from mobile More.
  • Not this: PiCode does not read the terminal's pixels, and it does not write your ~/.claude, ~/.codex, ~/.grok, ~/.hermes/config.yaml, ~/.config/opencode, or ~/.pi.

You type claude, codex, grok, hermes, opencode, or pi as usual. Inside a PiCode terminal only, a wrapper on that session's PATH launches the real binary with the flags, extension, or overlay that CLI accepts. Hermes may still record PiCode's hook command in its own shell-hooks-allowlist.json when it auto-accepts session hooks.

The old Preferences address redirects here. Configured terminals use the switch on their next launch. Existing plain shells may need a new terminal to pick up the wrapper PATH; changing a switch does not interrupt them. See Agent CLIs for launch settings.

States

Pi agents opened in a terminal use the same activity reporting as other coding CLIs. Launch settings keeps the Pi agent's model and packages; Terminal settings opens its executable, environment and activity options after its first terminal launch. Chat mode continues to report its own activity.

An older Pi terminal that was already open keeps running during an upgrade. Use Restart agent when you are ready to load the shared integration; this interrupts the current turn and resumes the agent's conversation. Changing activity settings never restarts a conversation automatically.

Presence / stateMeaningWhere you see it
Terminal opentmux is open, but no supported CLI was confirmedquiet terminal row
<CLI> · OpenClaude Code, Codex, Grok, Hermes Agent, OpenCode, or Pi owns the pane; activity is not known yetCLI mark + open label
<CLI> · Workingthe CLI started a turn and has not finishedspinner and CLI mark
Needs youthe CLI is waiting on you (permission prompt, question)accent chip
<CLI> · Readythe CLI finished its turn and remains openquiet CLI label
Stoppedthe terminal's tmux session is goneterminal row

The CLI identity comes from a session-only wrapper lease. Older terminals may be reconciled from an exact pane command and PID, but that fallback reports presence only. A working report expires after 30 minutes of silence. Escape or Ctrl+C also clears an active state immediately; arrow and Alt-key escape sequences do not. No identity or activity means "no signal" — never a guess.

What each CLI gets

CLIHow PiCode injects (session only)Coverage
Claude Codeclaude --settings <picode json>maps prompt, tool activity, notification and completion hooks
Codexinvocation-only lifecycle hooks, trusted by their exact command hashesmaps native prompt, tool and completion hooks when available; notify fallback reports completion only
Groknative hooks installed in ~/.grok/hooks behind a receipt; your settings are preservedmaps session, prompt, permission, question, tool activity and completion hooks
Hermes Agentsession Python path injection; follows the official launcher; no HERMES_HOME overlaymaps session start/end, LLM call, and approval hooks. setup / model / auth skip the patch
OpenCodesession plugin in PiCode terminals only; does not write ~/.config/opencode or move session datamaps session busy/idle, permission prompts and questions. session / auth / run skip the plugin
Pipi -e <picode extension>maps native TUI lifecycle events, including settled

Hook coverage depends on the installed CLI version. Check setup verifies the executable and reporter prerequisites, not login or every lifecycle event. An enabled switch is not evidence that the CLI has reported activity.

Outside PiCode, which claude and which pi still resolve to your real binaries. Codex hooks are passed with -c for that invocation and trusted one by one; PiCode never enables Codex's blanket --dangerously-bypass-hook-trust switch.

CLI identity and lifecycle lease

The wrapper sends start and end to POST /api/terminals/{id}/runtime with a canonical CLI, process id, and a run id. Hook reports include that run id, so an old process cannot clear the state of a newer process in the same terminal. The lease is memory-only and is revalidated against the live pane; a daemon restart therefore waits for a new wrapper report or an exact tmux command/PID fallback.

Pi TUI isolation

The Pi extension listens to native lifecycle events. It reports only when the process has a PiCode terminal id and is running in TUI mode. A Pi TUI you launch manually gets terminal status; managed Pi agents (RPC), pi -p, JSON output, and non-TUI child agents do not emit a duplicate. Completion uses agent_settled, after retries, compaction, and queued follow-ups are finished.

For agent runs, the wrapper adds one -e argument before yours. Your own -e extensions and all other agent arguments still reach Pi in their original order. Commands such as pi auth, pi install, and pi --version bypass injection so Pi still sees the command or flag first.

If a CLI has no launch injection

PiCode does not fall back to editing your home files. The row stays a plain terminal (honest). A later fallback may use the terminal bell; pixels are not scraped.