# openhands/openhands-cli architecture

> Architecture diagram of the GitHub repository openhands/openhands-cli, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-09). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/openhands/openhands-cli
- Repository: https://github.com/openhands/openhands-cli

## Overview

OpenHands V1 CLI is a terminal and IDE-facing interface for running coding-agent conversations, with headless, browser/web, GUI-server, and OpenHands Cloud modes. The primary workflow starts at the CLI entry point, accepts a task, runs or resumes an agent conversation, and presents or persists its progress. TUI conversation management, confirmation and critic refinement form a distinct internal layer; authentication, MCP configuration, and cloud conversations are additional capabilities. Some mode implementations are unsampled, so their nodes are retained from the README and tree without guessed internal links.

Main entry points: [`openhands_cli/entrypoint.py`](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/entrypoint.py) (CLI entry point), [`openhands_cli/tui/core/conversation_manager.py`](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/tui/core/conversation_manager.py) (Conversation manager), [`openhands_cli/tui/core/state.py`](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/tui/core/state.py) (Conversation state), [`openhands_cli/locations.py`](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/locations.py) (Persistence locations)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_cli["CLI entry and modes"]
  node_entry["CLI entry point<br/>[entrypoint.py]"]
  node_tui_app["Terminal UI<br/>[textual_app.py]"]
  node_web["Web mode<br/>[web_parser.py]"]
  node_gui["GUI server<br/>[gui_launcher.py]"]
  node_headless["Headless mode<br/>[main_parser.py]"]
end

subgraph group_tui["TUI conversations"]
  node_manager["Conversation manager"]
  node_state["Conversation state<br/>[state.py]"]
  node_registry["Runner registry<br/>[runner_registry.py]"]
  node_runner["Conversation runner"]
  node_switch["Switch controller"]
  node_refine["Critic refinement"]
  node_local_store[("Local conversations<br/>[local.py]")]
end

subgraph group_agent["Agent interfaces"]
  node_acp["IDE ACP agent<br/>[base_agent.py]"]
end

subgraph group_account["Accounts and cloud"]
  node_auth["Cloud authentication<br/>[login_command.py]"]
  node_api["Cloud API client<br/>[api_client.py]"]
  node_tokens[("Token storage<br/>[token_storage.py]")]
  node_cloud_convo["Cloud conversations<br/>[conversation.py]"]
end

subgraph group_integrations["Settings and integrations"]
  node_mcp["MCP management<br/>[mcp_commands.py]"]
  node_mcp_config[("MCP configuration<br/>[mcp_utils.py]")]
  node_agent_store[("Agent settings<br/>[agent_store.py]")]
  node_cli_settings[("CLI preferences<br/>[cli_settings.py]")]
  node_locations["Persistence locations<br/>[locations.py]"]
end

node_user(("CLI user"))

node_user -->|"starts"| node_entry
node_entry -->|"launches"| node_tui_app
node_entry -->|"dispatches"| node_acp
node_entry -->|"dispatches"| node_headless
node_entry -->|"dispatches"| node_web
node_entry -->|"dispatches"| node_gui
node_entry -->|"dispatches"| node_auth
node_entry -->|"dispatches"| node_cloud_convo
node_entry -->|"dispatches"| node_mcp
node_manager -->|"delegates to"| node_registry
node_manager -->|"delegates to"| node_switch
node_manager -->|"delegates to"| node_refine
node_manager -->|"updates"| node_state
node_registry -->|"creates"| node_runner
node_switch -->|"selects runner"| node_registry
node_switch -->|"updates"| node_state
node_refine -->|"reads settings"| node_state
node_runner -->|"uses state"| node_state
node_manager -.->|"manages conversations"| node_local_store
node_auth -->|"calls"| node_api
node_auth -->|"stores credentials"| node_tokens
node_cloud_convo -->|"uses client"| node_api
node_mcp -->|"uses configuration"| node_mcp_config
node_agent_store -->|"reads configuration"| node_mcp_config
node_agent_store -->|"resolves storage"| node_locations
node_tokens -->|"resolves storage"| node_locations
node_local_store -->|"resolves storage"| node_locations
node_cli_settings -.->|"resolves storage"| node_locations

click node_entry "https://github.com/openhands/openhands-cli/blob/main/openhands_cli/entrypoint.py"
click node_tui_app "https://github.com/openhands/openhands-cli/blob/main/openhands_cli/tui/textual_app.py"
click node_web "https://github.com/openhands/openhands-cli/blob/main/openhands_cli/argparsers/web_parser.py"
click node_gui "https://github.com/openhands/openhands-cli/blob/main/openhands_cli/gui_launcher.py"
click node_acp "https://github.com/openhands/openhands-cli/blob/main/openhands_cli/acp_impl/agent/base_agent.py"
click node_headless "https://github.com/openhands/openhands-cli/blob/main/openhands_cli/argparsers/main_parser.py"
click node_manager "https://github.com/openhands/openhands-cli/blob/main/openhands_cli/tui/core/conversation_manager.py"
click node_state "https://github.com/openhands/openhands-cli/blob/main/openhands_cli/tui/core/state.py"
click node_registry "https://github.com/openhands/openhands-cli/blob/main/openhands_cli/tui/core/runner_registry.py"
click node_runner "https://github.com/openhands/openhands-cli/blob/main/openhands_cli/tui/core/conversation_runner.py"
click node_switch "https://github.com/openhands/openhands-cli/blob/main/openhands_cli/tui/core/conversation_switch_controller.py"
click node_refine "https://github.com/openhands/openhands-cli/blob/main/openhands_cli/tui/core/refinement_controller.py"
click node_local_store "https://github.com/openhands/openhands-cli/blob/main/openhands_cli/conversations/store/local.py"
click node_auth "https://github.com/openhands/openhands-cli/blob/main/openhands_cli/auth/login_command.py"
click node_api "https://github.com/openhands/openhands-cli/blob/main/openhands_cli/auth/api_client.py"
click node_tokens "https://github.com/openhands/openhands-cli/blob/main/openhands_cli/auth/token_storage.py"
click node_cloud_convo "https://github.com/openhands/openhands-cli/blob/main/openhands_cli/cloud/conversation.py"
click node_mcp "https://github.com/openhands/openhands-cli/blob/main/openhands_cli/mcp/mcp_commands.py"
click node_mcp_config "https://github.com/openhands/openhands-cli/blob/main/openhands_cli/mcp/mcp_utils.py"
click node_agent_store "https://github.com/openhands/openhands-cli/blob/main/openhands_cli/stores/agent_store.py"
click node_cli_settings "https://github.com/openhands/openhands-cli/blob/main/openhands_cli/stores/cli_settings.py"
click node_locations "https://github.com/openhands/openhands-cli/blob/main/openhands_cli/locations.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_entry,node_tui_app,node_web,node_gui,node_headless,node_user toneBlue
class node_manager,node_state,node_registry,node_runner,node_switch,node_refine,node_local_store toneAmber
class node_acp toneMint
class node_auth,node_api,node_tokens,node_cloud_convo toneRose
class node_mcp,node_mcp_config,node_agent_store,node_cli_settings,node_locations toneIndigo
```

## Components

### CLI entry and modes

- [CLI entry point](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/entrypoint.py): `openhands_cli/entrypoint.py`
- [Terminal UI](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/tui/textual_app.py): `openhands_cli/tui/textual_app.py`
- [Web mode](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/argparsers/web_parser.py): `openhands_cli/argparsers/web_parser.py`
- [GUI server](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/gui_launcher.py): `openhands_cli/gui_launcher.py`
- [Headless mode](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/argparsers/main_parser.py): `openhands_cli/argparsers/main_parser.py`

### TUI conversations

- [Conversation manager](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/tui/core/conversation_manager.py): `openhands_cli/tui/core/conversation_manager.py`
- [Conversation state](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/tui/core/state.py): `openhands_cli/tui/core/state.py`
- [Runner registry](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/tui/core/runner_registry.py): `openhands_cli/tui/core/runner_registry.py`
- [Conversation runner](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/tui/core/conversation_runner.py): `openhands_cli/tui/core/conversation_runner.py`
- [Switch controller](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/tui/core/conversation_switch_controller.py): `openhands_cli/tui/core/conversation_switch_controller.py`
- [Critic refinement](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/tui/core/refinement_controller.py): `openhands_cli/tui/core/refinement_controller.py`
- [Local conversations](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/conversations/store/local.py): `openhands_cli/conversations/store/local.py`

### Agent interfaces

- [IDE ACP agent](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/acp_impl/agent/base_agent.py): `openhands_cli/acp_impl/agent/base_agent.py`

### Accounts and cloud

- [Cloud authentication](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/auth/login_command.py): `openhands_cli/auth/login_command.py`
- [Cloud API client](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/auth/api_client.py): `openhands_cli/auth/api_client.py`
- [Token storage](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/auth/token_storage.py): `openhands_cli/auth/token_storage.py`
- [Cloud conversations](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/cloud/conversation.py): `openhands_cli/cloud/conversation.py`

### Settings and integrations

- [MCP management](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/mcp/mcp_commands.py): `openhands_cli/mcp/mcp_commands.py`
- [MCP configuration](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/mcp/mcp_utils.py): `openhands_cli/mcp/mcp_utils.py`
- [Agent settings](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/stores/agent_store.py): `openhands_cli/stores/agent_store.py`
- [CLI preferences](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/stores/cli_settings.py): `openhands_cli/stores/cli_settings.py`
- [Persistence locations](https://github.com/openhands/openhands-cli/blob/main/openhands_cli/locations.py): `openhands_cli/locations.py`

### Other components

- **CLI user**

## Connections

- CLI user → CLI entry point: starts (evidence: `README.md`)
- CLI entry point → Terminal UI: launches (evidence: `openhands_cli/entrypoint.py`)
- CLI entry point → IDE ACP agent: dispatches (evidence: `openhands_cli/entrypoint.py`)
- CLI entry point → Headless mode: dispatches (evidence: `openhands_cli/argparsers/main_parser.py`)
- CLI entry point → Web mode: dispatches (evidence: `openhands_cli/entrypoint.py`)
- CLI entry point → GUI server: dispatches (evidence: `openhands_cli/entrypoint.py`)
- CLI entry point → Cloud authentication: dispatches (evidence: `openhands_cli/entrypoint.py`)
- CLI entry point → Cloud conversations: dispatches (evidence: `openhands_cli/entrypoint.py`)
- CLI entry point → MCP management: dispatches (evidence: `openhands_cli/entrypoint.py`)
- Conversation manager → Runner registry: delegates to (evidence: `openhands_cli/tui/core/conversation_manager.py`)
- Conversation manager → Switch controller: delegates to (evidence: `openhands_cli/tui/core/conversation_manager.py`)
- Conversation manager → Critic refinement: delegates to (evidence: `openhands_cli/tui/core/conversation_manager.py`)
- Conversation manager → Conversation state: updates (evidence: `openhands_cli/tui/core/conversation_manager.py`)
- Runner registry → Conversation runner: creates (evidence: `openhands_cli/tui/core/runner_registry.py`)
- Switch controller → Runner registry: selects runner (evidence: `openhands_cli/tui/core/conversation_switch_controller.py`)
- Switch controller → Conversation state: updates (evidence: `openhands_cli/tui/core/conversation_switch_controller.py`)
- Critic refinement → Conversation state: reads settings (evidence: `openhands_cli/tui/core/refinement_controller.py`)
- Conversation runner → Conversation state: uses state (evidence: `openhands_cli/tui/core/conversation_runner.py`)
- Conversation manager → Local conversations: manages conversations
- Cloud authentication → Cloud API client: calls (evidence: `openhands_cli/auth/login_command.py`)
- Cloud authentication → Token storage: stores credentials (evidence: `openhands_cli/auth/login_command.py`)
- Cloud conversations → Cloud API client: uses client (evidence: `openhands_cli/cloud/conversation.py`)
- MCP management → MCP configuration: uses configuration (evidence: `openhands_cli/mcp/mcp_commands.py`)
- Agent settings → MCP configuration: reads configuration (evidence: `openhands_cli/stores/agent_store.py`)
- Agent settings → Persistence locations: resolves storage (evidence: `openhands_cli/stores/agent_store.py`)
- Token storage → Persistence locations: resolves storage (evidence: `openhands_cli/auth/token_storage.py`)
- Local conversations → Persistence locations: resolves storage (evidence: `openhands_cli/conversations/store/local.py`)
- CLI preferences → Persistence locations: resolves storage
