# isaluki/tailview architecture

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

- Interactive diagram: https://gitdiagram.com/isaluki/tailview
- Repository: https://github.com/isaluki/tailview

## Overview

tailview is a local Tailscale observability dashboard. Its main workflow polls the local CLI, parses and retains metric samples, serves a live API and dashboard, then presents traffic, relay, peer, health, node, and raw-series views. The README documents the broader CLI data sources and dashboard capabilities; sampled code confirms the collector, parser, HTTP server, client, and chart primitives, but not every collector/API wiring detail.

Main entry points: [`src/tailview/web/app.js`](https://github.com/isaluki/tailview/blob/main/src/tailview/web/app.js) (Dashboard views), [`src/tailview/collector.py`](https://github.com/isaluki/tailview/blob/main/src/tailview/collector.py) (Collector), [`src/tailview/server.py`](https://github.com/isaluki/tailview/blob/main/src/tailview/server.py) (HTTP API and events), [`src/tailview/cli.py`](https://github.com/isaluki/tailview/blob/main/src/tailview/cli.py) (CLI startup)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_startup["Startup"]
  node_cli["CLI startup<br/>[cli.py]"]
end

subgraph group_collection["Collection"]
  node_collector["Collector<br/>[collector.py]"]
  node_client["Tailscale client<br/>[tsclient.py]"]
  node_parser["Metrics parser<br/>[promparse.py]"]
  node_window[("Rolling history<br/>[collector.py]")]
  node_demo["Demo data source<br/>[demo.py]"]
end

subgraph group_serving["Serving"]
  node_http["HTTP API and events<br/>[server.py]"]
end

subgraph group_dashboard["Dashboard"]
  node_page["Dashboard page<br/>[index.html]"]
  node_app["Dashboard views<br/>[app.js]"]
  node_charts["Chart primitives<br/>[charts.js]"]
  node_traffic["Traffic and drops<br/>[app.js]"]
  node_relay["DERP latency<br/>[app.js]"]
  node_peers["Peer explorer<br/>[app.js]"]
  node_health["Health panel<br/>[app.js]"]
  node_nodeview["Node details<br/>[app.js]"]
  node_metrics["Metrics explorer<br/>[app.js]"]
  node_styles["Dashboard styling<br/>[style.css]"]
end

node_operator(("Operator"))
node_tailscale["Tailscale CLI"]
node_browser(("Browser"))

node_operator -->|"starts"| node_cli
node_cli -->|"starts polling"| node_collector
node_cli -->|"starts server"| node_http
node_cli -->|"selects"| node_client
node_cli -.->|"selects demo"| node_demo
node_collector -->|"requests sources"| node_client
node_client -->|"runs commands"| node_tailscale
node_collector -->|"parses metrics"| node_parser
node_collector -->|"records samples"| node_window
node_collector -->|"derives rates"| node_window
node_http -->|"reads state"| node_collector
node_browser -->|"requests dashboard"| node_http
node_http -->|"serves page and data"| node_browser
node_http -->|"serves static files"| node_page
node_page -->|"loads"| node_app
node_app -->|"fetches and subscribes"| node_http
node_app -->|"renders"| node_traffic
node_app -->|"renders"| node_relay
node_app -->|"renders"| node_peers
node_app -->|"renders"| node_health
node_app -->|"renders"| node_nodeview
node_app -->|"renders"| node_metrics
node_traffic -->|"draws charts"| node_charts
node_relay -->|"draws bars"| node_charts
node_peers -->|"draws sparklines"| node_charts
node_metrics -->|"displays series"| node_window
node_page -->|"loads stylesheet"| node_styles
node_collector -.->|"uses synthetic source"| node_demo

click node_cli "https://github.com/isaluki/tailview/blob/main/src/tailview/cli.py"
click node_collector "https://github.com/isaluki/tailview/blob/main/src/tailview/collector.py"
click node_client "https://github.com/isaluki/tailview/blob/main/src/tailview/tsclient.py"
click node_parser "https://github.com/isaluki/tailview/blob/main/src/tailview/promparse.py"
click node_window "https://github.com/isaluki/tailview/blob/main/src/tailview/collector.py"
click node_demo "https://github.com/isaluki/tailview/blob/main/src/tailview/demo.py"
click node_http "https://github.com/isaluki/tailview/blob/main/src/tailview/server.py"
click node_page "https://github.com/isaluki/tailview/blob/main/src/tailview/web/index.html"
click node_app "https://github.com/isaluki/tailview/blob/main/src/tailview/web/app.js"
click node_charts "https://github.com/isaluki/tailview/blob/main/src/tailview/web/charts.js"
click node_traffic "https://github.com/isaluki/tailview/blob/main/src/tailview/web/app.js"
click node_relay "https://github.com/isaluki/tailview/blob/main/src/tailview/web/app.js"
click node_peers "https://github.com/isaluki/tailview/blob/main/src/tailview/web/app.js"
click node_health "https://github.com/isaluki/tailview/blob/main/src/tailview/web/app.js"
click node_nodeview "https://github.com/isaluki/tailview/blob/main/src/tailview/web/app.js"
click node_metrics "https://github.com/isaluki/tailview/blob/main/src/tailview/web/app.js"
click node_styles "https://github.com/isaluki/tailview/blob/main/src/tailview/web/style.css"

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_cli,node_browser toneBlue
class node_collector,node_client,node_parser,node_window,node_demo toneAmber
class node_http toneMint
class node_page,node_app,node_charts,node_traffic,node_relay,node_peers,node_health,node_nodeview,node_metrics,node_styles toneRose
class node_operator,node_tailscale toneIndigo
```

## Components

### Startup

- [CLI startup](https://github.com/isaluki/tailview/blob/main/src/tailview/cli.py): `src/tailview/cli.py`

### Collection

- [Collector](https://github.com/isaluki/tailview/blob/main/src/tailview/collector.py): `src/tailview/collector.py`
- [Tailscale client](https://github.com/isaluki/tailview/blob/main/src/tailview/tsclient.py): `src/tailview/tsclient.py`
- [Metrics parser](https://github.com/isaluki/tailview/blob/main/src/tailview/promparse.py): `src/tailview/promparse.py`
- [Rolling history](https://github.com/isaluki/tailview/blob/main/src/tailview/collector.py): `src/tailview/collector.py`
- [Demo data source](https://github.com/isaluki/tailview/blob/main/src/tailview/demo.py): `src/tailview/demo.py`

### Serving

- [HTTP API and events](https://github.com/isaluki/tailview/blob/main/src/tailview/server.py): `src/tailview/server.py`

### Dashboard

- [Dashboard page](https://github.com/isaluki/tailview/blob/main/src/tailview/web/index.html): `src/tailview/web/index.html`
- [Dashboard views](https://github.com/isaluki/tailview/blob/main/src/tailview/web/app.js): `src/tailview/web/app.js`
- [Chart primitives](https://github.com/isaluki/tailview/blob/main/src/tailview/web/charts.js): `src/tailview/web/charts.js`
- [Traffic and drops](https://github.com/isaluki/tailview/blob/main/src/tailview/web/app.js): `src/tailview/web/app.js`
- [DERP latency](https://github.com/isaluki/tailview/blob/main/src/tailview/web/app.js): `src/tailview/web/app.js`
- [Peer explorer](https://github.com/isaluki/tailview/blob/main/src/tailview/web/app.js): `src/tailview/web/app.js`
- [Health panel](https://github.com/isaluki/tailview/blob/main/src/tailview/web/app.js): `src/tailview/web/app.js`
- [Node details](https://github.com/isaluki/tailview/blob/main/src/tailview/web/app.js): `src/tailview/web/app.js`
- [Metrics explorer](https://github.com/isaluki/tailview/blob/main/src/tailview/web/app.js): `src/tailview/web/app.js`
- [Dashboard styling](https://github.com/isaluki/tailview/blob/main/src/tailview/web/style.css): `src/tailview/web/style.css`

### Other components

- **Operator**
- **Tailscale CLI**
- **Browser**

## Connections

- Operator → CLI startup: starts
- CLI startup → Collector: starts polling
- CLI startup → HTTP API and events: starts server
- CLI startup → Tailscale client: selects
- CLI startup → Demo data source: selects demo
- Collector → Tailscale client: requests sources
- Tailscale client → Tailscale CLI: runs commands
- Collector → Metrics parser: parses metrics
- Collector → Rolling history: records samples
- Collector → Rolling history: derives rates
- HTTP API and events → Collector: reads state
- Browser → HTTP API and events: requests dashboard
- HTTP API and events → Browser: serves page and data
- HTTP API and events → Dashboard page: serves static files
- Dashboard page → Dashboard views: loads
- Dashboard views → HTTP API and events: fetches and subscribes
- Dashboard views → Traffic and drops: renders
- Dashboard views → DERP latency: renders
- Dashboard views → Peer explorer: renders
- Dashboard views → Health panel: renders
- Dashboard views → Node details: renders
- Dashboard views → Metrics explorer: renders
- Traffic and drops → Chart primitives: draws charts
- DERP latency → Chart primitives: draws bars
- Peer explorer → Chart primitives: draws sparklines
- Metrics explorer → Rolling history: displays series
- Dashboard page → Dashboard styling: loads stylesheet
- Collector → Demo data source: uses synthetic source
