# whinee/whiskerframe architecture

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

- Interactive diagram: https://gitdiagram.com/whinee/whiskerframe
- Repository: https://github.com/whinee/whiskerframe

## Overview

WhiskerFrame is a Raspberry Pi cyberdeck with an ESP32 display coprocessor. Its principal workflow accepts CardKB input, authenticates a user, runs shell sessions in PTYs, interprets terminal output into a character grid, and sends display commands over UART to the CYD firmware. Supporting branches provide battery monitoring, storage mounting, health checks, and shared display-command utilities. The README establishes the hardware pairing; source-index references and excerpts support the shown module links. Several subsystem internals were not sampled, so their unverified connections are omitted.

Main entry points: [`pi/terminal/bridge.py`](https://github.com/whinee/whiskerframe/blob/main/pi/terminal/bridge.py) (Terminal Bridge), [`pi/battery_monitor/daemon.py`](https://github.com/whinee/whiskerframe/blob/main/pi/battery_monitor/daemon.py) (Battery Daemon), [`pi/terminal/login_view.py`](https://github.com/whinee/whiskerframe/blob/main/pi/terminal/login_view.py) (Login View), [`pi/terminal/grid.py`](https://github.com/whinee/whiskerframe/blob/main/pi/terminal/grid.py) (Character Grid)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_terminal["Terminal Sessions"]
  node_cardkb["CardKB Input<br/>[reader.py]"]
  node_daemon["Terminal Daemon<br/>[daemon.py]"]
  node_bridge["Terminal Bridge<br/>[bridge.py]"]
  node_login["Login Gate<br/>[login.py]"]
  node_loginview["Login View<br/>[login_view.py]"]
  node_workspaces["Shell Workspaces<br/>[workspaces.py]"]
  node_vt["VT Emulator<br/>[vt.py]"]
  node_grid["Character Grid<br/>[grid.py]"]
  node_statusbar["Terminal Status Bar<br/>[status_bar.py]"]
  node_theme["Terminal Theme<br/>[theme.py]"]
end

subgraph group_display["Display Link"]
  node_transport["Serial Transport<br/>[transport.py]"]
  node_protocol["Wire Protocol<br/>[protocol.py]"]
  node_firmware["CYD Firmware<br/>[main.cpp]"]
  node_frame["Frame Decoder<br/>[frame.h]"]
  node_renderer["Display Renderer<br/>[render.h]"]
end

subgraph group_power["Power Monitoring"]
  node_batterydaemon["Battery Daemon<br/>[daemon.py]"]
  node_ina219["INA219 Driver<br/>[ina219.py]"]
  node_powersupply["Power Supply Reader<br/>[power_supply.py]"]
  node_battery["Battery State<br/>[battery.py]"]
end

subgraph group_platform["Device Services"]
  node_mount["Storage Mounting<br/>[install_mount.py]"]
  node_health["Health Check<br/>[healthcheck.py]"]
  node_config["Configuration<br/>[config.py]"]
end

subgraph group_shared["Display Utilities"]
  node_models["Command Models<br/>[models.py]"]
  node_geometry["Terminal Geometry<br/>[terminal.py]"]
  node_metrics["Font Metrics<br/>[metrics.py]"]
  node_preview["Host Preview<br/>[preview.py]"]
end

node_user(("Cyberdeck User"))
node_shell["Login Shell"]
node_uart(("UART Display"))
node_sensor["Battery Sensor"]
node_powerstore[("Linux Power Supply")]

node_user -->|"enters keys"| node_cardkb
node_daemon -->|"reads input"| node_cardkb
node_daemon -->|"starts bridge"| node_bridge
node_bridge -->|"authenticates"| node_login
node_bridge -->|"renders gate"| node_loginview
node_bridge -->|"manages sessions"| node_workspaces
node_workspaces -->|"spawns PTYs"| node_shell
node_bridge -->|"parses output"| node_vt
node_vt -->|"updates cells"| node_grid
node_bridge -->|"renders grid"| node_grid
node_bridge -->|"updates status"| node_statusbar
node_bridge -->|"uses palette"| node_theme
node_bridge -->|"sends frames"| node_transport
node_transport -->|"serializes commands"| node_protocol
node_transport -.->|"transmits bytes"| node_uart
node_uart -.->|"receives frames"| node_firmware
node_firmware -->|"decodes frames"| node_frame
node_firmware -->|"renders commands"| node_renderer
node_batterydaemon -->|"reads measurements"| node_ina219
node_batterydaemon -->|"reads supply"| node_powersupply
node_batterydaemon -->|"derives state"| node_battery
node_ina219 -.->|"samples"| node_sensor
node_powersupply -.->|"reads kernel data"| node_powerstore
node_batterydaemon -->|"loads settings"| node_config
node_mount -->|"loads settings"| node_config
node_loginview -->|"draws screen"| node_grid
node_loginview -->|"uses login state"| node_login
node_loginview -->|"uses palette"| node_theme
node_statusbar -->|"draws status"| node_grid
node_vt -->|"maps SGR colors"| node_theme
node_protocol -->|"encodes models"| node_models
node_geometry -->|"uses metrics"| node_metrics
node_models -->|"sizes text"| node_metrics
node_preview -->|"renders commands"| node_models
node_preview -->|"renders terminal"| node_geometry

click node_cardkb "https://github.com/whinee/whiskerframe/blob/main/pi/cardkb/reader.py"
click node_daemon "https://github.com/whinee/whiskerframe/blob/main/pi/terminal/daemon.py"
click node_bridge "https://github.com/whinee/whiskerframe/blob/main/pi/terminal/bridge.py"
click node_login "https://github.com/whinee/whiskerframe/blob/main/pi/terminal/login.py"
click node_loginview "https://github.com/whinee/whiskerframe/blob/main/pi/terminal/login_view.py"
click node_workspaces "https://github.com/whinee/whiskerframe/blob/main/pi/terminal/workspaces.py"
click node_vt "https://github.com/whinee/whiskerframe/blob/main/pi/terminal/vt.py"
click node_grid "https://github.com/whinee/whiskerframe/blob/main/pi/terminal/grid.py"
click node_statusbar "https://github.com/whinee/whiskerframe/blob/main/pi/terminal/status_bar.py"
click node_theme "https://github.com/whinee/whiskerframe/blob/main/pi/terminal/theme.py"
click node_transport "https://github.com/whinee/whiskerframe/blob/main/whiskerframe/transport.py"
click node_protocol "https://github.com/whinee/whiskerframe/blob/main/whiskerframe/protocol.py"
click node_firmware "https://github.com/whinee/whiskerframe/blob/main/firmware/cyd_display_link/main.cpp"
click node_frame "https://github.com/whinee/whiskerframe/blob/main/firmware/cyd_display_link/frame.h"
click node_renderer "https://github.com/whinee/whiskerframe/blob/main/firmware/cyd_display_link/render.h"
click node_batterydaemon "https://github.com/whinee/whiskerframe/blob/main/pi/battery_monitor/daemon.py"
click node_ina219 "https://github.com/whinee/whiskerframe/blob/main/pi/battery_monitor/ina219.py"
click node_powersupply "https://github.com/whinee/whiskerframe/blob/main/pi/battery_monitor/power_supply.py"
click node_battery "https://github.com/whinee/whiskerframe/blob/main/pi/battery_monitor/battery.py"
click node_mount "https://github.com/whinee/whiskerframe/blob/main/pi/storage/install_mount.py"
click node_health "https://github.com/whinee/whiskerframe/blob/main/pi/komodo/healthcheck.py"
click node_models "https://github.com/whinee/whiskerframe/blob/main/whiskerframe/models.py"
click node_geometry "https://github.com/whinee/whiskerframe/blob/main/whiskerframe/terminal.py"
click node_metrics "https://github.com/whinee/whiskerframe/blob/main/whiskerframe/metrics.py"
click node_preview "https://github.com/whinee/whiskerframe/blob/main/whiskerframe/preview.py"
click node_config "https://github.com/whinee/whiskerframe/blob/main/scripts/config.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_cardkb,node_daemon,node_bridge,node_login,node_loginview,node_workspaces,node_vt,node_grid,node_statusbar,node_theme,node_user toneBlue
class node_transport,node_protocol,node_firmware,node_frame,node_renderer,node_powerstore toneAmber
class node_batterydaemon,node_ina219,node_powersupply,node_battery toneMint
class node_mount,node_health,node_config toneRose
class node_models,node_geometry,node_metrics,node_preview,node_shell,node_uart,node_sensor toneIndigo
```

## Components

### Terminal Sessions

- [CardKB Input](https://github.com/whinee/whiskerframe/blob/main/pi/cardkb/reader.py): `pi/cardkb/reader.py`
- [Terminal Daemon](https://github.com/whinee/whiskerframe/blob/main/pi/terminal/daemon.py): `pi/terminal/daemon.py`
- [Terminal Bridge](https://github.com/whinee/whiskerframe/blob/main/pi/terminal/bridge.py): `pi/terminal/bridge.py`
- [Login Gate](https://github.com/whinee/whiskerframe/blob/main/pi/terminal/login.py): `pi/terminal/login.py`
- [Login View](https://github.com/whinee/whiskerframe/blob/main/pi/terminal/login_view.py): `pi/terminal/login_view.py`
- [Shell Workspaces](https://github.com/whinee/whiskerframe/blob/main/pi/terminal/workspaces.py): `pi/terminal/workspaces.py`
- [VT Emulator](https://github.com/whinee/whiskerframe/blob/main/pi/terminal/vt.py): `pi/terminal/vt.py`
- [Character Grid](https://github.com/whinee/whiskerframe/blob/main/pi/terminal/grid.py): `pi/terminal/grid.py`
- [Terminal Status Bar](https://github.com/whinee/whiskerframe/blob/main/pi/terminal/status_bar.py): `pi/terminal/status_bar.py`
- [Terminal Theme](https://github.com/whinee/whiskerframe/blob/main/pi/terminal/theme.py): `pi/terminal/theme.py`

### Display Link

- [Serial Transport](https://github.com/whinee/whiskerframe/blob/main/whiskerframe/transport.py): `whiskerframe/transport.py`
- [Wire Protocol](https://github.com/whinee/whiskerframe/blob/main/whiskerframe/protocol.py): `whiskerframe/protocol.py`
- [CYD Firmware](https://github.com/whinee/whiskerframe/blob/main/firmware/cyd_display_link/main.cpp): `firmware/cyd_display_link/main.cpp`
- [Frame Decoder](https://github.com/whinee/whiskerframe/blob/main/firmware/cyd_display_link/frame.h): `firmware/cyd_display_link/frame.h`
- [Display Renderer](https://github.com/whinee/whiskerframe/blob/main/firmware/cyd_display_link/render.h): `firmware/cyd_display_link/render.h`

### Power Monitoring

- [Battery Daemon](https://github.com/whinee/whiskerframe/blob/main/pi/battery_monitor/daemon.py): `pi/battery_monitor/daemon.py`
- [INA219 Driver](https://github.com/whinee/whiskerframe/blob/main/pi/battery_monitor/ina219.py): `pi/battery_monitor/ina219.py`
- [Power Supply Reader](https://github.com/whinee/whiskerframe/blob/main/pi/battery_monitor/power_supply.py): `pi/battery_monitor/power_supply.py`
- [Battery State](https://github.com/whinee/whiskerframe/blob/main/pi/battery_monitor/battery.py): `pi/battery_monitor/battery.py`

### Device Services

- [Storage Mounting](https://github.com/whinee/whiskerframe/blob/main/pi/storage/install_mount.py): `pi/storage/install_mount.py`
- [Health Check](https://github.com/whinee/whiskerframe/blob/main/pi/komodo/healthcheck.py): `pi/komodo/healthcheck.py`
- [Configuration](https://github.com/whinee/whiskerframe/blob/main/scripts/config.py): `scripts/config.py`

### Display Utilities

- [Command Models](https://github.com/whinee/whiskerframe/blob/main/whiskerframe/models.py): `whiskerframe/models.py`
- [Terminal Geometry](https://github.com/whinee/whiskerframe/blob/main/whiskerframe/terminal.py): `whiskerframe/terminal.py`
- [Font Metrics](https://github.com/whinee/whiskerframe/blob/main/whiskerframe/metrics.py): `whiskerframe/metrics.py`
- [Host Preview](https://github.com/whinee/whiskerframe/blob/main/whiskerframe/preview.py): `whiskerframe/preview.py`

### Other components

- **Cyberdeck User**
- **Login Shell**
- **UART Display**
- **Battery Sensor**
- **Linux Power Supply**

## Connections

- Cyberdeck User → CardKB Input: enters keys
- Terminal Daemon → CardKB Input: reads input (evidence: `pi/terminal/daemon.py`)
- Terminal Daemon → Terminal Bridge: starts bridge (evidence: `pi/terminal/daemon.py`)
- Terminal Bridge → Login Gate: authenticates (evidence: `pi/terminal/bridge.py`)
- Terminal Bridge → Login View: renders gate (evidence: `pi/terminal/bridge.py`)
- Terminal Bridge → Shell Workspaces: manages sessions (evidence: `pi/terminal/bridge.py`)
- Shell Workspaces → Login Shell: spawns PTYs (evidence: `pi/terminal/workspaces.py`)
- Terminal Bridge → VT Emulator: parses output (evidence: `pi/terminal/bridge.py`)
- VT Emulator → Character Grid: updates cells (evidence: `pi/terminal/vt.py`)
- Terminal Bridge → Character Grid: renders grid (evidence: `pi/terminal/bridge.py`)
- Terminal Bridge → Terminal Status Bar: updates status (evidence: `pi/terminal/bridge.py`)
- Terminal Bridge → Terminal Theme: uses palette (evidence: `pi/terminal/bridge.py`)
- Terminal Bridge → Serial Transport: sends frames (evidence: `pi/terminal/bridge.py`)
- Serial Transport → Wire Protocol: serializes commands (evidence: `whiskerframe/transport.py`)
- Serial Transport → UART Display: transmits bytes
- UART Display → CYD Firmware: receives frames
- CYD Firmware → Frame Decoder: decodes frames (evidence: `firmware/cyd_display_link/main.cpp`)
- CYD Firmware → Display Renderer: renders commands (evidence: `firmware/cyd_display_link/main.cpp`)
- Battery Daemon → INA219 Driver: reads measurements (evidence: `pi/battery_monitor/daemon.py`)
- Battery Daemon → Power Supply Reader: reads supply (evidence: `pi/battery_monitor/daemon.py`)
- Battery Daemon → Battery State: derives state (evidence: `pi/battery_monitor/daemon.py`)
- INA219 Driver → Battery Sensor: samples
- Power Supply Reader → Linux Power Supply: reads kernel data
- Battery Daemon → Configuration: loads settings (evidence: `pi/battery_monitor/daemon.py`)
- Storage Mounting → Configuration: loads settings (evidence: `pi/storage/install_mount.py`)
- Login View → Character Grid: draws screen (evidence: `pi/terminal/login_view.py`)
- Login View → Login Gate: uses login state (evidence: `pi/terminal/login_view.py`)
- Login View → Terminal Theme: uses palette (evidence: `pi/terminal/login_view.py`)
- Terminal Status Bar → Character Grid: draws status (evidence: `pi/terminal/status_bar.py`)
- VT Emulator → Terminal Theme: maps SGR colors (evidence: `pi/terminal/vt.py`)
- Wire Protocol → Command Models: encodes models (evidence: `whiskerframe/protocol.py`)
- Terminal Geometry → Font Metrics: uses metrics (evidence: `whiskerframe/terminal.py`)
- Command Models → Font Metrics: sizes text (evidence: `whiskerframe/models.py`)
- Host Preview → Command Models: renders commands (evidence: `whiskerframe/preview.py`)
- Host Preview → Terminal Geometry: renders terminal (evidence: `whiskerframe/preview.py`)
