CLI State & Codex Support
CLI State & Codex Support
Info
The cli state provides real-time monitoring of Claude Code and Codex CLI sessions directly within the island. It uses a compact island notification (500ร88 px) for quick status and a full panel (860ร400 px) in maxExpand for detailed session management. This document covers the dual-provider architecture, session lifecycle, event streaming, and permission handling.
Architecture Overview
The CLI subsystem has two layers:
| Layer | State | Dimensions | Purpose |
|---|---|---|---|
| Island compact view | cli | 500ร88 px | Quick session status, permission buttons, provider toggle |
| Full panel | maxExpand (tab: cli) | 860ร400 px | Session sidebar, event stream, activity heatmap, monitor controls |
Both layers support two providers via the CliProvider type:
type CliProvider = 'claude' | 'codex';The active provider is stored in the Zustand store (cliProvider) and persisted to localStorage. A CliProviderSwitch component allows toggling between providers in both the island view and the full panel.
Tips
The provider state persists across sessions. When a new session is detected for the inactive provider, the system automatically switches to it and shows a notification.
Provider Comparison
| Feature | Claude Code | Codex |
|---|---|---|
| Session detection | Hook-based (onClaudeCodeStatusUpdated) | Hook-based (onCodexStatusUpdated) |
| Permission flow | Deny / Allow / Always Allow | Not supported (auto-approves) |
| Island icon | Animated GIF (phase-dependent) | Static SVG with inverted filter |
| Monitor control | Install / Uninstall hook | Enable / Disable monitor |
| Event clearing | claudeCodeEventsClear | codexEventsClear |
| Session deletion | claudeCodeSessionsDelete | codexSessionsDelete |
Session Lifecycle
A CLI session progresses through four phases:
stateDiagram-v2
[*] --> idle : Session created
idle --> running : First event received
running --> waiting_permission : Tool requires approval
waiting_permission --> running : Permission granted
running --> completed : Session ends
idle --> completed : Session ends| Phase | Description | Island Icon |
|---|---|---|
idle | Session created, no activity yet | CLAWD_IDLE GIF |
running | Actively processing events | CLAWD_WAITING GIF |
waiting_permission | Blocked on user approval for a tool call | CLAWD_REVIEW GIF |
completed | Session finished (filtered out of active list) | โ |
Note
The waiting_permission phase triggers an automatic state transition to cli (if not already viewing) with a notification sound and glow overlay effect.
Entry & Exit Conditions
Island Compact View (cli state)
Entry Conditions:
- New CLI session detected (auto-transition from any state via notification)
- Permission request received (auto-transition with sound + glow)
- Click on CLI tab with active session (from
expanded,maxExpand, orannouncement)
Exit Conditions:
- Close button โ
idle - Click on body โ
maxExpand(opens full CLI panel) - Escape key โ previous state
Full Panel (maxExpand with cli tab)
Entry Conditions:
- Click on CLI island body
- Navigate to CLI tab from any
maxExpandtab
Exit Conditions:
- Click on island โ
hover - Escape key โ
expanded - Close button โ
expanded
Session Detection Flow
The useClaudeCliSessionStatus hook runs in the coordinator and monitors both providers simultaneously. It uses per-provider trackers to detect new sessions and permission requests without triggering re-renders.
sequenceDiagram
participant H as useClaudeCliSessionStatus
participant M as Main Process
participant S as Store
M->>H: onClaudeCodeStatusUpdated / onCodexStatusUpdated
H->>H: Compare session IDs vs tracker
alt New session or permission request
H->>H: Play notification sound
H->>H: Show CLI glow overlay
H->>S: setCliProvider(provider)
H->>S: setCli() or setNotification()
end
H->>H: Update tracker stateWarning
The hook filters out completed sessions when determining if there are active sessions. A provider is considered "active" if at least one session has phase !== 'completed'.
Event System
Each provider streams events through IPC. The useCliStatus hook subscribes to real-time updates and exposes a unified snapshot:
interface CliStatusSnapshot {
enabled: boolean;
receiverRunning: boolean;
receiverUrl: string | null;
settingsPath: string;
hookScriptPath: string;
sessions: CliSessionSnapshot[];
events: CliHookEvent[];
heatmap: Record<string, { session: number; tool: number; prompt: number }>;
updatedAt: number;
}Event Types
Events are categorized by kind and eventName. The island compact view displays the latest event summary; the full panel shows a paginated, filterable event stream.
| Field | Description |
|---|---|
sessionId | Which session this event belongs to |
kind | Event category (e.g., tool, prompt, system) |
eventName | Human-readable event name |
summary | Short description for display |
timestamp | When the event occurred |
Activity Heatmap
The full panel includes a GitHub-style activity heatmap that visualizes session, tool, and prompt activity over time. Data is keyed by date (YYYY-MM-DD) and supports three metrics: session, tool, and prompt.
Tips
The heatmap scrolls horizontally and auto-scrolls to today's date when the panel becomes visible.
Permission Handling
When a Claude Code session enters waiting_permission, the island compact view displays three action buttons:
| Button | Action | IPC Call |
|---|---|---|
| Deny | Reject the tool call | claudeCodePermissionResolve(sessionId, 'deny') |
| Allow | Approve once | claudeCodePermissionResolve(sessionId, 'allow') |
| Always Allow | Approve this tool permanently | claudeCodePermissionResolve(sessionId, 'always') |
The pending tool's name, command, and description are extracted from the event's tool_input field and displayed alongside the permission buttons.
Important
Permission buttons are only shown for the claude provider. Codex sessions do not require explicit permission approval.
Pill Mode Behavior
In pill shape mode, the CLI island compact view has a reduced content height:
.island-shell.shape-pill .cli-state-content {
height: 80px;
}The shell background remains at 100px (shared with notification, agent, and stt states). The content container is centered within the shell via flexbox alignment.
Module Structure
CLI module file tree
states/cli/
โโโ CliContent.tsx # Island compact view component
states/maxExpand/components/cli/
โโโ index.ts # Module entry point
โโโ types/types.ts # Shared type definitions
โโโ config/
โ โโโ cliConstants.ts # Constants and defaults
โ โโโ cliFilters.ts # Event filter definitions
โโโ hooks/
โ โโโ useCliStatus.ts # Provider status subscription
โ โโโ useCliEvents.ts # Event filtering and session selection
โ โโโ useBulkSelect.ts # Bulk session selection
โ โโโ useEventPagination.ts # Event list pagination
โ โโโ usePendingPermissions.ts # Permission event tracking
โ โโโ useHeatmapGrid.ts # Heatmap grid calculation
โ โโโ useHeatmapScroll.ts # Heatmap scroll management
โโโ components/
โ โโโ CliTab.tsx # Full panel main component
โ โโโ CliProviderSwitch.tsx # Claude/Codex toggle
โ โโโ SessionSidebar.tsx # Session list sidebar
โ โโโ EventStreamPanel.tsx # Event stream display
โ โโโ EventRow.tsx # Single event row
โ โโโ ActivityHeatmap.tsx # GitHub-style heatmap
โโโ utils/
โโโ cliFormatters.ts # Phase labels, date formatting
โโโ heatmapGrid.ts # Heatmap layout calculationKey Hooks
| Hook | Location | Purpose |
|---|---|---|
useClaudeCliSessionStatus | components/hooks/ | Coordinator-level dual-provider session detection |
useCliStatus | cli/hooks/ | Per-provider status snapshot and control actions |
useCliEvents | cli/hooks/ | Event filtering, session selection, active session tracking |
usePendingPermissions | cli/hooks/ | Tracks events with waiting_permission phase |
useBulkSelect | cli/hooks/ | Multi-session selection for batch deletion |
useEventPagination | cli/hooks/ | Paginated event list with configurable page size |
Note
useClaudeCliSessionStatus is a ref-based hook that does not trigger re-renders. It reads the Zustand store directly via getState() to determine whether to fire notifications or state transitions.
IPC Channels
| Channel | Direction | Description |
|---|---|---|
claudeCodeStatusGet | Renderer โ Main | Fetch current Claude Code status snapshot |
codexStatusGet | Renderer โ Main | Fetch current Codex status snapshot |
onClaudeCodeStatusUpdated | Main โ Renderer | Subscribe to Claude Code status changes |
onCodexStatusUpdated | Main โ Renderer | Subscribe to Codex status changes |
claudeCodePermissionResolve | Renderer โ Main | Resolve a pending permission request |
claudeCodeHookInstall | Renderer โ Main | Install Claude Code hook script |
claudeCodeHookUninstall | Renderer โ Main | Uninstall Claude Code hook script |
codexMonitorEnable | Renderer โ Main | Enable Codex monitoring |
codexMonitorDisable | Renderer โ Main | Disable Codex monitoring |
cliGlowShow | Renderer โ Main | Show fullscreen CLI glow overlay |
Caution
Never call claudeCodePermissionResolve without a valid session ID and action. An invalid call may leave the session in a stuck waiting_permission state.
Changelog
bb5b2-on

