# yyzybb537/remote_claude architecture

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

- Interactive diagram: https://gitdiagram.com/yyzybb537/remote_claude
- Repository: https://github.com/yyzybb537/remote_claude

## Overview

#### Purpose and execution surface
Remote Claude bridges locally running Claude Code or Codex CLI sessions to Feishu/Lark, while retaining terminal-based interaction through tmux. User-facing launchers are `cla`, `cl`, `cx`, and `cdx`; the management CLI supports session lifecycle and attach operations. Primary entry points: `remote_claude.py`, `bin/remote-claude`, `bin/cla`.

#### Session and terminal orchestration
The core host-side control plane creates, lists, attaches to, and kills named tmux-backed AI CLI sessions. It supports multiple terminal and Lark clients sharing one process without embedding into Claude/Codex itself. Session identity, attachment coordination, and protocol-level state live in `utils/session.py`, `utils/protocol.py`, and `server/shared_state.py`.

#### Local server: PTY stream to structured UI
The server receives terminal output/input around managed sessions, parses CLI-specific terminal regions, and exposes structured components suitable for remote rendering and interaction. `server/server.py` coordinates the service; `server/component_parser.py` selects parsers, with CLI-specific behavior in `server/parsers/claude_parser.py` and `server/parsers/codex_parser.py`. This is the key boundary between opaque ANSI terminal streams and application-level output, option, and approval controls.

#### Lark client and bidirectional bridge
The Lark process connects to Feishu as a bot client, manages conversation/session selection, and relays user messages or card actions back to the active terminal session. `lark_client/main.py` is its process entry point; `lark_client/lark_handler.py` handles inbound Lark events; `lark_client/session_bridge.py` connects those events to local session state. `lark_client/shared_memory_poller.py` streams local updates to the client.

#### Output rendering and interactive cards
Terminal data is buffered, cleaned, ANSI-rendered, and transformed into Feishu rich-text/cards, including streamed output and clickable choices or permission confirmations. The rendering pipeline is represented by `lark_client/terminal_buffer.py`, `lark_client/output_cleaner.py`, and `lark_client/terminal_renderer.py`; card construction/update behavior is in `lark_client/card_builder.py` and `lark_client/card_service.py`. Server-side rich text conversion is in `server/rich_text_renderer.py`.

#### State, concurrency, and transport boundaries
Shared state separates session/process control from Lark presentation, allowing terminal and remote clients to attach concurrently. The local service communicates through project protocol/session abstractions rather than directly modifying the managed Claude/Codex process. Important boundaries are `utils/protocol.py`, `utils/components.py`, and `server/shared_state.py`; terminal capture is isolated in `lark_client/capture_output.py`.

#### Runtime and external dependencies
The system targets macOS/Linux and relies materially on tmux, uv/Python, and installed Claude CLI or Codex CLI. Feishu/Lark is optional but requires an enterprise self-built application, credentials, event callbacks, and app publication. Environment/configuration and bot setup are managed by `lark_client/config.py` and `lark_client/setup_wizard.py`; install/bootstrap behavior begins at `init.sh`.

#### Packaging and operational modes
The project is distributed through npm while its application runtime is primarily Python, reflected by `package.json`, `pyproject.toml`, and `requirements.txt`. Docker support is oriented toward package/test validation rather than the primary deployment model: `docker/Dockerfile.test` and `docker/docker-compose.test.yml`. Lightweight statistics collection/query capabilities are isolated under `stats/collector.py` and `stats/query.py`.

Main entry points: [`server/component_parser.py`](https://github.com/yyzybb537/remote_claude/blob/main/server/component_parser.py) (Component parser), [`utils/session.py`](https://github.com/yyzybb537/remote_claude/blob/main/utils/session.py) (Session manager), [`utils/protocol.py`](https://github.com/yyzybb537/remote_claude/blob/main/utils/protocol.py) (Session protocol), [`server/shared_state.py`](https://github.com/yyzybb537/remote_claude/blob/main/server/shared_state.py) (Shared state)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_host["Host Control Plane"]
  node_launchers["CLI launchers<br/>shell entrypoints"]
  node_management_cli["Management CLI<br/>Python entrypoint<br/>[remote_claude.py]"]
  node_session_manager["Session manager<br/>session control<br/>[session.py]"]
  node_protocol["Session protocol<br/>transport abstraction<br/>[protocol.py]"]
  node_tmux{{"tmux sessions<br/>external terminal runtime"}}
  node_ai_clis{{"Claude / Codex CLI<br/>external AI runtime"}}
end

subgraph group_server["Local Stream Server"]
  node_shared_state[("Shared state<br/>concurrency state<br/>[shared_state.py]")]
  node_local_server["Local server<br/>service coordinator<br/>[server.py]"]
  node_component_parser["Component parser<br/>parser selector"]
  node_claude_parser["Claude parser<br/>terminal parser<br/>[claude_parser.py]"]
  node_codex_parser["Codex parser<br/>terminal parser<br/>[codex_parser.py]"]
  node_components["Structured components<br/>UI protocol model<br/>[components.py]"]
  node_rich_text["Rich text renderer<br/>text conversion"]
end

subgraph group_lark["Lark Bridge"]
  node_lark_main["Lark client<br/>process entrypoint<br/>[main.py]"]
  node_lark_handler["Lark event handler<br/>bot event handler<br/>[lark_handler.py]"]
  node_session_bridge["Session bridge<br/>bidirectional relay<br/>[session_bridge.py]"]
  node_capture_output["Terminal capture<br/>PTY capture<br/>[capture_output.py]"]
  node_state_poller["State poller<br/>update stream"]
  node_render_pipeline["Terminal render pipeline<br/>buffer and ANSI rendering"]
  node_card_service["Card service<br/>Feishu card updates<br/>[card_service.py]"]
  node_feishu{{"Feishu / Lark<br/>external bot platform"}}
  node_setup["Bot setup<br/>configuration wizard<br/>[setup_wizard.py]"]
end

node_launchers -->|"launches"| node_management_cli
node_management_cli -->|"manages"| node_session_manager
node_session_manager -->|"coordinates through"| node_protocol
node_session_manager -->|"creates and attaches"| node_tmux
node_tmux -->|"hosts"| node_ai_clis
node_protocol -->|"shares state"| node_shared_state
node_local_server -->|"reads and updates"| node_shared_state
node_local_server -->|"parses terminal stream"| node_component_parser
node_component_parser -->|"Claude mode"| node_claude_parser
node_component_parser -->|"Codex mode"| node_codex_parser
node_component_parser -->|"emits"| node_components
node_components -->|"renders"| node_rich_text
node_lark_main -->|"receives events"| node_lark_handler
node_lark_handler -->|"forwards actions"| node_session_bridge
node_session_bridge -->|"sends input"| node_protocol
node_capture_output -->|"publishes updates"| node_state_poller
node_shared_state -->|"exposes session state"| node_state_poller
node_state_poller -->|"streams output"| node_render_pipeline
node_render_pipeline -->|"produces rendered content"| node_card_service
node_card_service -->|"updates cards"| node_feishu
node_feishu -->|"messages and actions"| node_lark_handler
node_setup -.->|"configures bot"| node_feishu

click node_launchers "https://github.com/yyzybb537/remote_claude/blob/main/bin/cla"
click node_management_cli "https://github.com/yyzybb537/remote_claude/blob/main/remote_claude.py"
click node_session_manager "https://github.com/yyzybb537/remote_claude/blob/main/utils/session.py"
click node_protocol "https://github.com/yyzybb537/remote_claude/blob/main/utils/protocol.py"
click node_shared_state "https://github.com/yyzybb537/remote_claude/blob/main/server/shared_state.py"
click node_local_server "https://github.com/yyzybb537/remote_claude/blob/main/server/server.py"
click node_component_parser "https://github.com/yyzybb537/remote_claude/blob/main/server/component_parser.py"
click node_claude_parser "https://github.com/yyzybb537/remote_claude/blob/main/server/parsers/claude_parser.py"
click node_codex_parser "https://github.com/yyzybb537/remote_claude/blob/main/server/parsers/codex_parser.py"
click node_components "https://github.com/yyzybb537/remote_claude/blob/main/utils/components.py"
click node_rich_text "https://github.com/yyzybb537/remote_claude/blob/main/server/rich_text_renderer.py"
click node_lark_main "https://github.com/yyzybb537/remote_claude/blob/main/lark_client/main.py"
click node_lark_handler "https://github.com/yyzybb537/remote_claude/blob/main/lark_client/lark_handler.py"
click node_session_bridge "https://github.com/yyzybb537/remote_claude/blob/main/lark_client/session_bridge.py"
click node_capture_output "https://github.com/yyzybb537/remote_claude/blob/main/lark_client/capture_output.py"
click node_state_poller "https://github.com/yyzybb537/remote_claude/blob/main/lark_client/shared_memory_poller.py"
click node_render_pipeline "https://github.com/yyzybb537/remote_claude/blob/main/lark_client/terminal_renderer.py"
click node_card_service "https://github.com/yyzybb537/remote_claude/blob/main/lark_client/card_service.py"
click node_setup "https://github.com/yyzybb537/remote_claude/blob/main/lark_client/setup_wizard.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_launchers,node_management_cli,node_session_manager,node_protocol,node_tmux,node_ai_clis toneBlue
class node_shared_state,node_local_server,node_component_parser,node_claude_parser,node_codex_parser,node_components,node_rich_text toneAmber
class node_lark_main,node_lark_handler,node_session_bridge,node_capture_output,node_state_poller,node_render_pipeline,node_card_service,node_feishu,node_setup toneMint
```

## Components

### Host Control Plane

Manages named local AI CLI sessions and terminal attachment.

- [CLI launchers](https://github.com/yyzybb537/remote_claude/blob/main/bin/cla): shell entrypoints · User-facing cla, cl, cx, and cdx commands. · `bin/cla`
- [Management CLI](https://github.com/yyzybb537/remote_claude/blob/main/remote_claude.py): Python entrypoint · Starts and manages remote Claude sessions. · `remote_claude.py`
- [Session manager](https://github.com/yyzybb537/remote_claude/blob/main/utils/session.py): session control · Creates, lists, attaches to, and kills named sessions. · `utils/session.py`
- [Session protocol](https://github.com/yyzybb537/remote_claude/blob/main/utils/protocol.py): transport abstraction · Coordinates session identity and protocol state. · `utils/protocol.py`
- **tmux sessions**: external terminal runtime · Hosts shareable Claude Code or Codex CLI processes.
- **Claude / Codex CLI**: external AI runtime · Opaque managed terminal applications.

### Local Stream Server

Converts PTY terminal streams into structured controls.

- [Shared state](https://github.com/yyzybb537/remote_claude/blob/main/server/shared_state.py): concurrency state · Separates process control from remote presentation state. · `server/shared_state.py`
- [Local server](https://github.com/yyzybb537/remote_claude/blob/main/server/server.py): service coordinator · Coordinates terminal input, output, and structured UI. · `server/server.py`
- [Component parser](https://github.com/yyzybb537/remote_claude/blob/main/server/component_parser.py): parser selector · Selects CLI-specific terminal parsers. · `server/component_parser.py`
- [Claude parser](https://github.com/yyzybb537/remote_claude/blob/main/server/parsers/claude_parser.py): terminal parser · `server/parsers/claude_parser.py`
- [Codex parser](https://github.com/yyzybb537/remote_claude/blob/main/server/parsers/codex_parser.py): terminal parser · `server/parsers/codex_parser.py`
- [Structured components](https://github.com/yyzybb537/remote_claude/blob/main/utils/components.py): UI protocol model · Represents output, choices, and approval controls. · `utils/components.py`
- [Rich text renderer](https://github.com/yyzybb537/remote_claude/blob/main/server/rich_text_renderer.py): text conversion · Converts server-side content for rich presentation. · `server/rich_text_renderer.py`

### Lark Bridge

Relays Feishu events and renders terminal output as cards.

- [Lark client](https://github.com/yyzybb537/remote_claude/blob/main/lark_client/main.py): process entrypoint · Runs the Feishu bot bridge process. · `lark_client/main.py`
- [Lark event handler](https://github.com/yyzybb537/remote_claude/blob/main/lark_client/lark_handler.py): bot event handler · Handles inbound messages and card actions. · `lark_client/lark_handler.py`
- [Session bridge](https://github.com/yyzybb537/remote_claude/blob/main/lark_client/session_bridge.py): bidirectional relay · Maps Lark interactions to active local sessions. · `lark_client/session_bridge.py`
- [Terminal capture](https://github.com/yyzybb537/remote_claude/blob/main/lark_client/capture_output.py): PTY capture · Isolates terminal output capture. · `lark_client/capture_output.py`
- [State poller](https://github.com/yyzybb537/remote_claude/blob/main/lark_client/shared_memory_poller.py): update stream · Streams local session updates to the Lark client. · `lark_client/shared_memory_poller.py`
- [Terminal render pipeline](https://github.com/yyzybb537/remote_claude/blob/main/lark_client/terminal_renderer.py): buffer and ANSI rendering · Buffers, cleans, and renders streamed terminal output. · `lark_client/terminal_renderer.py`
- [Card service](https://github.com/yyzybb537/remote_claude/blob/main/lark_client/card_service.py): Feishu card updates · Builds and updates interactive output cards. · `lark_client/card_service.py`
- **Feishu / Lark**: external bot platform · Optional remote messaging and interactive-card surface.
- [Bot setup](https://github.com/yyzybb537/remote_claude/blob/main/lark_client/setup_wizard.py): configuration wizard · Configures Lark credentials and bot setup. · `lark_client/setup_wizard.py`

## Connections

- CLI launchers → Management CLI: launches
- Management CLI → Session manager: manages
- Session manager → Session protocol: coordinates through
- Session manager → tmux sessions: creates and attaches
- tmux sessions → Claude / Codex CLI: hosts
- Session protocol → Shared state: shares state
- Local server → Shared state: reads and updates
- Local server → Component parser: parses terminal stream
- Component parser → Claude parser: Claude mode
- Component parser → Codex parser: Codex mode
- Component parser → Structured components: emits
- Structured components → Rich text renderer: renders
- Lark client → Lark event handler: receives events
- Lark event handler → Session bridge: forwards actions
- Session bridge → Session protocol: sends input
- Terminal capture → State poller: publishes updates
- Shared state → State poller: exposes session state
- State poller → Terminal render pipeline: streams output
- Terminal render pipeline → Card service: produces rendered content
- Card service → Feishu / Lark: updates cards
- Feishu / Lark → Lark event handler: messages and actions
- Bot setup → Feishu / Lark: configures bot
