Activity Detection
Kangentic monitors each agent’s activity in real-time, so you always know what your agents are doing without opening their terminals. All seven supported agents (Claude Code, Codex CLI, Gemini CLI, Cursor CLI, GitHub Copilot CLI, Aider, and Warp/Oz CLI) feed into a single activity state machine that drives the card indicators, but each uses a different underlying strategy because each CLI exposes activity differently.
Agent States
Section titled “Agent States”The Kanban board shows each agent’s current state with visual indicators. These update in real-time, giving you an at-a-glance view of your entire agent fleet.
| State | Description |
|---|---|
| Thinking (pulsing animation) | Agent is processing, running tools, or generating a response |
| Idle (static icon) | Agent has stopped, hit a permission prompt, or is asking a question |
| Queued (label) | Waiting for a concurrent session slot to open |
Event Types
Section titled “Event Types”Kangentic tracks these events from each agent session. They feed into both the card indicators and the Activity Tab in the bottom panel.
User-Facing Events
Section titled “User-Facing Events”| Event | Key | Effect on Indicator | Description |
|---|---|---|---|
| Tool start | tool_start | Thinking | Agent began using a tool (Read, Edit, Bash, etc.) |
| Tool end | tool_end | (no change) | Tool execution completed |
| Prompt | prompt | Thinking | User submitted a message or the agent resumed after approval |
| Idle | idle | Idle | Agent stopped, hit a permission wall, or asked a question |
| Interrupted | interrupted | Idle | User interrupted the agent (Escape or interrupt signal) |
Internal Events
Section titled “Internal Events”These events are logged but don’t directly change the card indicator — they support subagent tracking, context management, and system-level operations. Not every agent emits every event (see per-agent strategies below).
| Event | Key | Effect on Indicator | Emitted by | Description |
|---|---|---|---|---|
| Session start | session_start | (no change) | All | Session was created or resumed |
| Session end | session_end | (no change) | All | Session exited |
| Notification | notification | (no change) | Claude, Gemini | Informational message from the agent (e.g., “context getting full”) |
| Compact | compact | Thinking | Claude, Gemini | Context compaction occurred |
| Subagent start | subagent_start | Thinking | Claude | A subagent was spawned (increases depth counter) |
| Subagent stop | subagent_stop | (no change) | Claude | A subagent finished (decreases depth counter) |
| Teammate idle | teammate_idle | (no change) | Kangentic | Another agent in the same project went idle |
| Task completed | task_completed | (no change) | Kangentic | A task was marked complete |
| Config change | config_change | (no change) | Kangentic | A configuration setting was modified |
| Worktree create | worktree_create | Thinking | Kangentic | A git worktree was created |
| Worktree remove | worktree_remove | (no change) | Kangentic | A git worktree was removed |
| Background shell start | background_shell_start | Thinking | Claude | Agent launched a backgrounded Bash tool. Kangentic tracks the detached child so the session isn’t falsely flagged idle while it’s still running. |
| Background shell end | background_shell_end | (no change) | Claude | A tracked background shell exited. Releases a deferred idle when the last background child finishes. |
Per-Agent Detection Strategy
Section titled “Per-Agent Detection Strategy”Kangentic uses a different detection strategy for each agent because each CLI exposes activity differently. All seven strategies feed into the same unified state machine, so card indicators behave identically regardless of which agent is running.
| Agent | Strategy |
|---|---|
| Claude Code | Hooks only |
| Codex CLI | PTY silence timer |
| Gemini CLI | Hooks primary, PTY fallback |
| Cursor CLI | PTY silence timer + stream-JSON init event for session ID |
| GitHub Copilot CLI | Hooks primary, PTY fallback |
| Aider | PTY prompt regex |
| Warp (Oz CLI) | PTY silence timer |
Claude Code, hooks only
Section titled “Claude Code, hooks only”Claude Code’s native hooks system is the sole source of truth. Kangentic injects an event-bridge.js shim into the session that fires on Claude Code hook events and writes them to a structured log file that Kangentic watches incrementally.
| Claude Code hook | Effect |
|---|---|
| PreToolUse | Agent is about to use a tool → thinking state |
| PostToolUse | Tool finished (no state change) |
| UserPromptSubmit | User sent a message → thinking state |
| Stop | Agent stopped naturally → idle state |
| PermissionRequest | Agent needs approval → idle state |
| SubagentStart / SubagentStop | Track subagent nesting depth |
| Notification / PreCompact | Logged as internal events |
| SessionStart / SessionEnd | Logged as internal events |
Hook injection is automatic — no manual setup. All Kangentic artifacts stay in the .kangentic/ directory; nothing is written to your .claude/settings.local.json. Claude is the only agent Kangentic parses a status.json file for (context window percentage, token counts, cost, rate limits).
Codex CLI, PTY silence timer
Section titled “Codex CLI, PTY silence timer”Codex’s Rust CLI (0.118+) does not read .codex/hooks.json at runtime, so Kangentic falls back to a pure PTY strategy: after each burst of terminal output, a 3-second silence timer marks the session idle. Content deduplication filters repeated TUI frames automatically so resize redraws don’t look like activity.
Codex’s › prompt character stays visible even during tool execution, so a prompt regex can’t be used — the silence timer is the only reliable signal. Kangentic writes hook files anyway for structural compatibility, but the user-facing idle detection is the PTY timer.
Gemini CLI, hooks primary with PTY fallback
Section titled “Gemini CLI, hooks primary with PTY fallback”Gemini supports hook injection via .gemini/settings.json (reference-counted so concurrent sessions don’t clobber each other). Hooks fire on BeforeAgent, AfterAgent, BeforeTool, AfterTool, SessionStart, SessionEnd, Notification, and PreCompress events.
If hooks don’t fire (e.g., early in startup or during a hang), a PTY-based fallback kicks in: Kangentic watches for Gemini’s closed-box TUI border (╰────╯) or the “I’m ready.” message to detect idle, backed by the same 3-second silence timer as Codex. Once hooks start firing, the PTY fallback defers to them.
Cursor CLI, PTY silence timer
Section titled “Cursor CLI, PTY silence timer”Cursor’s terminal agent (agent) has no hooks and no status file. Activity detection is a PTY silence timer, same 3-second threshold as Codex and Warp. Kangentic spawns Cursor in non-interactive mode (agent -p ... --output-format stream-json) by default so the first line of NDJSON output is an init event containing the model and session ID. That event lets ContextBar resolve the model pill immediately and lets --resume=<id> work reliably across restarts. There is no subagent tracking and no compaction event.
GitHub Copilot CLI, hooks primary with PTY fallback
Section titled “GitHub Copilot CLI, hooks primary with PTY fallback”Copilot (v1.0+) supports inline hooks written to a per-session config.json in the copilot-config/ directory beside the Kangentic events file. Kangentic wires preToolUse, postToolUse, agentStop, and preCompact hooks; these are the primary activity signal. A PTY silence timer backs them up because Copilot’s statusLine is best-effort (empirically it doesn’t always fire in ConPTY). Stream-output parsing picks up the model label either from the NDJSON stream when invoked with --output-format json or from the interactive TUI’s status bar.
Aider, prompt regex
Section titled “Aider, prompt regex”Aider doesn’t support hook injection, so detection is pure PTY. Kangentic strips ANSI escapes from the output stream and matches a prompt regex at the end of the buffer:
/(?:^|\n)\s*(?:aider|architect)?>\s*$/Any terminal output flips the session to thinking; a prompt match flips it back to idle. There is no subagent tracking, no status.json, and no compaction event. This is consistent with Aider’s edit-first, fire-and-forget design.
Warp (Oz CLI), PTY silence timer
Section titled “Warp (Oz CLI), PTY silence timer”Warp’s oz CLI is the simplest adapter: no hooks, no status file, no structured event output, no trust mechanism, and no caller-specified session IDs. Activity detection is a PTY silence timer only. Unlike Codex and Cursor, there is no prompt regex, so the silence timer is the sole idle signal.
Thinking vs. Idle Indicators
Section titled “Thinking vs. Idle Indicators”The card indicators are designed to avoid false signals:
- Tool end doesn’t set idle. Between consecutive tool calls there’s a brief gap — showing idle here would cause the spinner to flicker. For agents that emit explicit events (Claude, Gemini), only
StoporPermissionRequestsets idle. - Tool failure doesn’t set idle. The agent continues processing after a failure and may retry.
- Notifications don’t change state. Informational notifications (like “context getting full”) fire unpredictably and shouldn’t flip the indicator.
- Frame redraws don’t wake a session. For PTY-based agents, content-deduplication filters resize redraws so they don’t look like real activity.
Subagent Awareness (Claude Code only)
Section titled “Subagent Awareness (Claude Code only)”Claude Code’s Agent tool lets a main agent spawn subagents to delegate work. Kangentic tracks the subagent depth from Claude’s SubagentStart / SubagentStop hook events so the card indicator stays accurate during nested operations:
- If the main agent is idle but a subagent is still running tools, the card correctly stays idle — subagent tool events don’t override the main agent’s state
- When all subagents finish and the main agent resumes, the card correctly shows thinking
- Main-agent
Stopis deferred until any running subagent finishes, so a pending user decision isn’t hidden - User prompts and interrupts always take effect immediately regardless of subagent state
The other six agents (Codex, Gemini, Cursor, Copilot, Aider, Warp) don’t expose subagents, so this logic is inactive for those sessions.
Native Session History
Section titled “Native Session History”Added in v0.15.0. For Claude Code, Codex, and Gemini, Kangentic reads each agent’s own native session history file (in addition to the hook/PTY activity stream) to produce higher-fidelity telemetry: token-accurate context percentages, tool call transcripts, and the full conversation record used as the handoff context payload when a task moves between agents. Kangentic watches these files incrementally so the Activity Tab and context bar stay in sync without polling the CLI:
| Agent | Native history path |
|---|---|
| Claude Code | ~/.claude/projects/<sanitized-cwd>/<session-id>.jsonl |
| Codex CLI | ~/.codex/sessions/.../rollout-*.jsonl |
| Gemini CLI | ~/.gemini/tmp/<cwd>/chats/session-*.json |
Cursor, Copilot, Aider, and Warp don’t expose a file Kangentic can parse, so their context bar falls back to PTY-derived heuristics and handoff context is unavailable.
Board Overview
Section titled “Board Overview”The combination of activity detection and the Kanban layout gives you a dashboard view of all agent work:
- See which agents are actively working vs. waiting for input
- Identify stuck or idle agents that may need intervention
- Monitor overall project progress at a glance
- Know when agents finish without watching their terminals
When an agent goes idle, Kangentic can also notify you via desktop notifications and idle badges. See Notifications for details.