Claude Code, Codex, OpenCode and Superset each leave a different trail. Byte 2.2.5 keeps
their identities and capabilities distinct, then brings live activity, history, cost,
decisions and outcomes into one workspace. The numbers drive the pictures, and every
chart keeps its exact records available.
Local-first · Organisation-ready · No background inference
Byte uses one adapter contract for detection, capabilities, collection, history,
configuration, usage and supported execution. Claude Code uses hooks and transcripts;
Codex uses trusted lifecycle hooks and supported App Server methods; OpenCode uses a
Byte-owned plugin and server SDK; Superset uses its supported CLI and underlying agent
adapters. Reconciliation preserves native identity and prevents duplicate sessions.
Native events carry the live path. Reconciliation fills in what that path never saw.
Claude Code's eight hooks
npm run install-hooks writes eight entries into
~/.claude/settings.json. Five take a "*" matcher:
PreToolUse, PostToolUse, Stop,
SubagentStop, Notification. Three take none:
SessionStart, SessionEnd, UserPromptSubmit. The
merge is idempotent: an existing Byte entry is replaced in place, and the file is only
rewritten when the bytes would actually change.
What Claude Code's hooks miss
Some things emit no hook at all: /compact, and the tools a subagent runs
inside itself. Those are recovered by reading the session transcripts under
~/.claude/projects, so the charts are drawn from what happened rather than
from what was reported. Live rows and imported rows are written through the same turn
key, backed by a unique index, so an overlap is a no-op instead of a duplicate. An
Esc cancel is caught separately, by a watchdog that reads the interrupt
marker Claude Code leaves in the transcript.
[ 02 · Start here ]
The screens
Six primary destinations organise the workspace: Home, Work, Sessions, Insights,
Library and Settings. Existing detailed routes and shortcuts remain available. People,
devices and administration appear only for authorised organisation roles.
The session mark
One session, one line. It is the same drawing in a table row, on a card and at full
width, and it is the thing to learn first, because it appears everywhere else.
The five channels of the session mark. A key on screen names every one in a plain
sentence.
Both scales are logarithmic over fixed absolute domains, so the same session draws at
the same size no matter what you have filtered to. Length runs from one second to thirty
days. Thickness runs from a thousand tokens to a hundred billion. Eight decades, chosen
by measurement: across ten real sessions on a 2 to 14 pixel stroke, a linear scale
resolved 2 of 10 distinct weights, square root 5 of 10, and log 9 of 10.
The mark never claims more at a large size than it can support at a small one. In a
table row, where twenty-one strands will not fit in twenty pixels, the stack collapses
into a single stepped envelope rather than drawing eight strands and calling them
twenty-one, and the envelope is stepped, never smoothed, because a curve between two
buckets would draw agent counts that never existed. At full size the stack draws at most
twelve rows and letters the rest (up to 61 agents at once, 12 drawn). Sessions
with no tools and no subagents, most sessions in a real database, all draw as one short
identical tick, because that is what they are.
The time spine
A ribbon pinned under the status bar, on every screen. It shows where your events sit in
time, and dragging it moves the whole app. Arrow keys pan, up and down zoom, Home shows
everything, End goes live. It goes inert, dimmed and unfocusable, on Settings, Agent
Config and Run, where a time window means nothing, but it stays mounted so the page
geometry never jumps.
Its axis is warped on purpose. Most minutes hold nothing: measured against the live
database on 8 August 2026, 2,501 of 11,677 minutes held any event at all, 21%, so a
linear axis would spend four fifths of its travel on dead air. Empty stretches collapse
instead, the way a stock chart skips weekends. Nothing is ever stretched, only capped,
so a dataset with no long gaps gets an exactly linear axis and the warp costs nothing.
Each collapsed stretch is drawn as a dashed rule and lettered with the time it stands
for, and the live density figure sits in the rail beside it.
/
Overview
The home screen is a board you arrange. Tiles are dragged on a twelve-column grid;
the layout is pure CSS, so nothing is measured until you pick a tile up. It ships
already arranged, and the empty canvas that sinks every build-your-own dashboard is
only reachable by deleting every tile, at which point the screen offers the default
back. The fixed arrangement it replaced is still there at /overview,
with twelve lenses covering the fleet and system health.
/kanban
Agent Board
Two views behind a toggle that remembers your choice. Agents has
four columns: working, waiting, completed, error. Sessions has
five, adding abandoned. Each column scrolls on its own and pages ten at a time. The
yellow waiting column is the useful one: it flags what is sitting
on you rather than on the machine. Live refresh is coalesced at 300 ms, because
three quarters of hook events land closer together than that.
/sessions
Sessions
Every recorded session, paginated on the server so each page fetches only its slice.
Free-text search, a searchable multi-select directory filter, sort by time, duration
or price, and status chips. The columns are Session, Shape, Status,
Last active, Duration, Agents, Cost and Directory, Shape being the session mark at
its inline size, so you can read a page of sessions as a page of drawings.
/sessions/:id
Session
Four tabs, and the open one lives in the query string so any view is a link.
Agents leads with the mark at full width, then counts, the agent
tree with subagents expanded or collapsed, and a cost breakdown.
Conversation is the transcript. Timeline is the
paged event list. Replay plays the session back. A banner appears
when the session is waiting on you in the terminal.
/activity
Activity
The event stream as it arrives. Server-driven filters, and a fixed column grid:
time, status, origin, tool, age, link, so a long tool name cannot shift the columns
right of it. Click a row to expand its payload. Pause is real: incoming frames are
buffered and counted rather than repainting under you, and every hold is written to
an attention log you can read later in Settings.
/analytics
Cost & Usage
Five readouts sharing one rail, a 52-week activity heatmap sized so the year fills
its panel exactly, and a 30-day column chart beside it. Below, five tabs: token
analytics, cost analytics (the default: daily trends, cost by model, cost by
weekday, and the priced-feature breakdown), workflow intelligence, productivity, and
operations. While the data loads the chart region shows skeletons shaped like the
charts, so the page never flashes a zeroed axis.
/workflows
Orchestration
Ten charts of what your agents did to each other, six headline figures above them, a
runs panel beside them and a per-session drill-in below. One status filter (active,
completed or all) applies to every chart at once, and the whole set exports as JSON.
Every chart carries an info popover: what it shows, how to read it, why it matters.
The full list is in the table below.
/run
Run
Start or resume a session from the browser and watch it stream. Two modes,
conversation or one-shot. You choose the prompt (with @-file
completion), working directory, model, permission mode and thinking effort. Output
renders as a chat stream with collapsible tool calls, a live context meter, and cost
and duration in the footer. An active-runs switcher attaches to anything already in
flight. Built-in slash commands stay in the terminal: they mutate CLI-only state.
/cc-config
Agent Config
Twelve tabs over what Claude Code has actually got on disk: skills, subagents, slash
commands, memory, plugins, marketplaces, MCP servers, hooks, keybindings, settings
and output styles, filtered by scope. Each entry names the exact file it came from,
and secrets in MCP URLs and headers are redacted. You can edit the low-risk text
artifacts, and every write takes a timestamped backup first. Plugins, MCP servers
and settings stay read-only, because the running CLI writes them concurrently.
/record
The Record
What you asked for, what it cost, what it produced, one user turn at a time. Every
other screen is a control room answering "what is happening now". This one answers
"what did I build", so it is laid out as a document you read: the ask is the
headline, in your own words, and the telemetry is the subtitle under it.
/compare
Compare
Two sessions read as a difference rather than as two sets of totals. The first is
the baseline and the only column showing raw totals; every other column is value,
delta and ratio, because a reader comparing two costs is doing arithmetic the page
should have done. The selection lives in the query string, so any comparison is a
link.
The ten orchestration charts
Chart
What it draws
Orchestration DAG
Which agent spawned which, as a four-column directed graph. Edge width scales
with how many times that spawn happened. The agent-type column is split in two
so recursion draws as a forward edge instead of a loop.
Tool execution flow
A Sankey diagram of tool-to-tool transitions. A tool that appears on both sides
is split into a source node and a target node, because a Sankey collapses
self-loops.
Agent collaboration network
A force-directed graph of agent types that run in sequence. Node radius is the
square root of that type's total runs; edge width and its Nx label
are how often the pair co-occurred.
Model delegation flow
Which model handed work to which, main models on the left and subagent models on
the right, grouped by family. Edges are uniform width on purpose: the only
domain available would be the three counts on screen. One model degrades to four
figures rather than a one-bar bar chart.
Concurrency timeline
A lane per agent type, where the track is the session's own duration and the bar
spans where in it that type typically runs. Fill opacity carries sample size.
Below it, how much real time ran with exactly N subagents alive.
Session complexity scatter
Duration against agent count, both axes logarithmic, bubble area proportional to
tokens, colour by outcome. Log because most sessions have exactly one agent and
a linear axis draws every one of them on the same line. Click a bubble to drill
in.
Subagent effectiveness
A card per subagent type: a success ring, the type's sessions and average
duration, and a seven-column weekday sparkline.
Error propagation map
Where errors cluster by depth in the agent hierarchy, and which agent types are
error-prone. Depth is an ordinal severity ramp, so a session-root error is the
loudest mark and a deeply nested one the quietest. Nothing errored gives you a
green all-clear, not an empty chart.
Compaction impact
A histogram: how many sessions compacted exactly k times. One series,
so one gradient rather than categorical hues.
Workflow patterns
Agent sequences that repeat, ranked by how often. Expanding one gives a
rule-derived description, deterministic, so the page can never state something
the data does not support.
Above them sit six figures: average agent depth, average subagents per session, agent
success rate, most common flow, average compactions and average duration. Beside them, a
runs panel for the fleets spawned by the Workflow tool. Those emit no hooks, so they are
reconstructed from the run journals left on disk.
[ 03 · Start here ]
Settings
Eleven panels behind a sticky "jump to" rail that follows your scroll, at
/settings.
Panel
What it controls
Appearance
Theme (system, light, dark), accent colour, density
Model pricing
Pricing rules matched by glob pattern: input and output rates, cache-write at
five minutes and one hour, fast input and output, and introductory rates with an
end date. Unpriced models are called out. Reset to defaults is one button
Hook configuration
Whether the eight hooks are installed and complete, and a reinstall action
Session data directory
Where transcripts are read from
Import history
Four ways in: rescan ~/.claude/projects, scan any absolute folder,
upload JSONL or an archive, or restore a backup export
Remote data sources
A global data scope (all machines, local only, or a chosen set) and the SSH
sources themselves: add, test, sync, enable, and delete with a choice of purging
the imported data or keeping it
Cody
Show or hide the corner companion
Notifications
Browser permission, a test notification, and per-event toggles for new session,
session complete, session error and subagent spawned
Alerts
Rules, channels (webhook targets with a setup guide per provider) and activity,
plus the attention log the Activity screen writes to
Data management
Database size and counts, session cleanup with abandon-after and purge-after
thresholds, and a danger zone behind an explicit confirmation
Export sits in the page header: it is the counterpart the backup-restore import mode
reads. Every write reports through a toast with a pending state.
Remote data sources
A remote source is another machine you can read over SSH. Byte mirrors that machine's
projects tree into a per-source staging directory with scp,
then runs the same importer it uses for local history, so remote sessions line up with
local ones exactly. Authentication defers entirely to your own SSH stack:
~/.ssh/config, your agent, your keys, your known_hosts. Byte
stores no secrets; a host is an ssh destination and nothing more. External commands run
with an argument array and no shell, and an unknown host key fails the sync.
[ 04 · Run it ]
Quick start
Byte 2.2.5 and upgrading
Download Byte 2.2.5 desktop applications and SHA256 checksums from the
2.2.5 release page
.
Windows has an installer and a portable build, macOS has separate Apple Silicon and Intel
disk images, and Linux has a deb package and an AppImage. Choose the package for your machine.
Windows and AppImage installations check for updates in the application. On macOS, download
the new disk image and replace Byte in Applications. Existing records and enrolment remain in
the application data directory. Keep that directory when uninstalling or replacing the app.
New installations use dark mode and signal orange. Upgrades preserve your saved theme,
density and accent; signal is an additional choice in Settings. Organisation device codes
connect a reporting machine to an organisation. They remain distinct from an application licence.
Byte 2.1 preserves your account, records and preferences. To invite a new account, add its email in Organisation, use the pending
member's Invitation button, and share that private invitation with the named recipient.
They paste it when creating their account or signing in. Invitations expire after 24 hours
and can be accepted once.
Keep progress with Byte 2.2
Open a task from Work and define its observable outcomes. Checks capture the command, code revision and relevant environment. Verified, Failed, Needs judgment and Not checked are distinct states. A relevant code or dependency change makes prior evidence stale.
Review a requirement change before saving. Delivery to an agent is separate, and each attempt shows the instruction revision it has acknowledged. Record an investigation with its current question, observations, rejected approaches and next experiment. Facts and hypotheses remain separate.
Keep a useful fix as a lesson. It becomes verified only when its regression check fails on the original revision and passes on the correction. Reuse requires applicable paths and reviewed context. Sharing a lesson does not share its source conversation.
Prepare selected Git text changes in an isolated workspace. Review dependencies and checks, then apply only if the destination is still the reviewed revision. Unsupported file types, ambiguous ownership and inseparable edits require manual resolution. Byte does not reverse external service or database writes.
Max includes combined-task rehearsal and bounded automatic recovery. Automation starts disabled. Enabling it requires a reviewed project grant, supported native controls and visible attempt and time limits. The defaults allow at most two attempts and fifteen minutes. Cancel or disable without losing the original workspace; applying a candidate remains a separate approval.
Hosted Byte can inspect authorized synchronized evidence and author permitted private notes. Run local checks and prepare candidates on the connected local installation. Deploy compatible server and licence metadata before upgrading collectors. Back up existing data and verify a restore before production migrations.
What 2.1.3 repairs
Collection health now distinguishes recorded live events from history. Child-agent inspection, integration-aware pricing, cost grouping, theme switching, compact density and machine setup are improved. Existing records and preferences are retained. External Codex hook delivery is still under investigation; Byte-managed execution has verified live updates. Native execution also requires the corresponding application's installation, authentication and account permissions.
What 2.1.2 repairs
Integration and machine scope now reach orchestration details and model pricing. Codex history imports in bounded pages. Review live hooks with /hooks after connecting. Settings saves zoom from 75% to 150%; existing themes and data stay in place. Cody's optional panel includes its cat companion.
What 2.1.1 repairs
Integration lists and drill-throughs keep the selected agent, host and data source
together. Task attachments require matching ownership and the actual run/session
link. Existing external sessions, resumed sessions and legacy IDs remain supported
when they belong to the task.
Migration 34 adds missing tasks.source storage, including databases
that already recorded migration 33. Existing source values, task records and
execution grants stay intact. For stored imported tasks, a source is recovered
only when every linked session agrees and matches the task's agent and host.
Missing or conflicting evidence stays unresolved and cannot start local work.
Native cost reports distinguish measured charges, token-based estimates and
missing data. A captured zero remains zero; an absent measurement stays unavailable.
Lifetime totals without a usable measurement date remain undated and do not become
daily chart points or period-budget spend.
Compact navigation and controls use the correct Claude Code, Codex, OpenCode and
Superset logos. Integration names stay visible so the current view is easy to identify.
Connect your coding tools
Open Settings, then Integrations, to connect Codex or OpenCode on the device where it runs.
Review Byte's Codex hooks in the native application. OpenCode uses a Byte-owned plugin;
explicit managed runs use an authenticated local service. Superset exposes its supported
workspace and underlying-agent controls separately from native chat.
Connect and managed runs check the installed CLI's required interfaces before
changing configuration or starting work. A different version can be used when
those interfaces are present. Reading history does not start or resume an agent.
The four workspace switches change what you inspect while connected collectors continue
recording. Existing Claude Code collection stays available. Native run ownership never changes
merely because you switch views, and active conversations are not transferred between agents.
Library items start private. Preview the audience and content before sharing. Budget alerts
warn without stopping independent agents. Back up data before upgrading a hosted cell and
deploy the compatible server before enabling new collectors.
Requires Node.js 20 or newer.
Step 1
Install
npm run setup installs the server, client and extension dependencies
and links the byte CLI
Step 2
Connect
Open Settings → Integrations and connect the agents installed on this machine.
Claude Code hooks can also be installed with npm run install-hooks
Step 3
Start
npm run dev brings up the server on 4820 and the client on 5173
Step 4
Start work
Run a connected agent: supported live events and history appear in its workspace
bash
npm run setup # dependencies, and link the byte CLI
npm run install-hooks # forward Claude Code events to Byte
npm run dev # server on :4820, client on :5173
# production: one process serving everything on :4820
npm run build && npm start
# something on screen straight away
npm run seed # three demo sessions
The server installs Claude Code hooks itself when you run it directly on the host. Codex
and OpenCode are connected explicitly from Settings so their native trust and profile
boundaries stay visible. History reconciliation runs in the background for each
supported adapter.
Did it work?
Screen
What you should see
Sessions
Your session, at
Waiting
while the CLI sits at the prompt, flipping to
Active
the moment the selected agent starts a turn
Agent Board
A main-agent card in Waiting, moving to
Working on your first message and back after each turn
Activity
Events arriving; click a row to expand its payload
[ 05 · Run it ]
Configuration
Everything has a working default. These are the ones worth knowing; the full annotated
set is in .env.example.
Variable
Default
What it does
DASHBOARD_PORT
4820
Port the server listens on
DASHBOARD_HOST
127.0.0.1
Interface it binds. Loopback, so not network-reachable
DASHBOARD_TOKEN
unset
Required on every API call and on the WebSocket when set
DASHBOARD_ALLOWED_HOSTS
empty
Extra Host header names to accept beyond loopback, comma-separated
CLAUDE_HOME
~/.claude
Where transcripts and settings are read from
DASHBOARD_DATA_DIR
$CLAUDE_HOME/byte-agent-monitor
Where the database lives
DASHBOARD_DB_PATH
$DASHBOARD_DATA_DIR/dashboard.db
The SQLite file itself
DASHBOARD_STALE_MINUTES
180
Idle minutes before a session is marked abandoned
DASHBOARD_SESSION_SYNC_MS
30000
How often the transcript tree is re-swept. 0 disables it
RUN_MAX_CONCURRENT
10
Live claude subprocesses the Run screen will start. Over the cap it
refuses
[ 06 · Talk to it ]
API reference
Everything the screens do, they do over this API. It is 112 paths and 136 operations,
and the generated OpenAPI 3.0 document is the complete reference: parameters, schemas,
field descriptions and examples. It is served live at /api/openapi.json, as
Swagger UI at /api/docs, and as ReDoc at /api/redoc. The ReDoc
bundle is self-hosted, so it works offline.
Responses are JSON. Errors are always
{ "error": { "code", "message" } }. Collections take limit and
offset, and the values are clamped rather than rejected: SQLite reads a
negative LIMIT as "no limit". The envelope is flat and named for its
collection: { sessions, limit, offset, total }.
Route groups
Prefix
Covers
/api/sessions
Sessions, their transcripts, marks, replay and lifelines
/api/agents, /api/events
Agents and the event feed
/api/stats, /api/analytics, /api/timeline
Counters, chart aggregates, the activity ribbon
/api/workflows, /api/record
Orchestration data and the per-turn record
/api/hooks, /api/import
Event ingestion and history import
/api/pricing, /api/settings
Pricing rules, server info, export and import
/api/alerts, /api/webhooks, /api/push
Alert rules, webhook targets and deliveries, web push
/api/cc-config
What Claude Code has on disk. The largest group, at 19 operations
/api/run, /api/remote-sources
Spawning sessions, and other machines read over SSH
/api/metrics, /api/updates
Prometheus exposition, and the update check
The ones you will actually call
GET/api/healthLiveness. Returns { status, version, timestamp }. Never needs a
token
GET/api/sessionsSessions with agent counts and computed cost. Params status,
q, limit (default 50), offset
GET/api/sessions/:idOne session with its agents and events. The event array is bounded and says so, so
a long session cannot return an unbounded payload
GET/api/eventsThe event feed. Filter by event_type, tool_name,
q, from, to
GET/api/statsThe header counters: events today, live socket count, agents and sessions by
status
POST/api/hooks/eventIngestion. Body is { hook_type, data }. This is the one the hook
handler calls
GET/api/settings/infoDatabase path, size and counts, hook install status, server version and
uptime
GET/api/settings/exportStreams the whole dataset as NDJSON
POST/api/runSpawns claude as a subprocess and streams it back over the
WebSocket
GET/api/metricsPrometheus exposition: byte_sessions, byte_agents,
byte_events_total, byte_tokens_total and process
gauges
Authentication
Set DASHBOARD_TOKEN and every /api/* call and the WebSocket
upgrade need it. It is read from Authorization: Bearer …, an
x-dashboard-token header, or a ?token= query parameter, and
compared in constant time. Four paths stay open even then: /api/health,
/api/openapi.json, /api/docs and /api/hooks/*,
because the local hook handler carries no token and the loopback bind is what protects
it. Browsers cannot set headers on a WebSocket, so the socket accepts only the query
parameter or the custom header.
WebSocket
One socket at /ws. Every frame is { type, data, timestamp }.
The types are:
A client that says nothing receives everything. To narrow, send
{ "action": "subscribe", "topics": [ … ] } where each topic is a frame type
and optionally a session_id; the server answers with a
subscribed frame. Subscriptions replace rather than merge, and cap at 200
topics. The server pings every 30 seconds and drops a socket that misses a pong. If a
client stops reading, frames are dropped past a 1 MB send buffer and the socket is
closed at 8 MB: a slow reader cannot become a memory leak.
[ 07 · Talk to it ]
Beyond the browser
Six other ways into the same database.
Surface
What it gives you
Desktop app
macOS, Windows and Linux. Bundles and supervises the server, adds a tray icon
and start-at-login. No terminal
VS Code extension
Live health, tokens and cost in the sidebar; the dashboard as a tab
byte CLI
Every surface from a terminal, with box-drawn tables and inline bar charts.
Eleven commands work offline against the database
MCP server
30 typed tools over stdio, HTTP+SSE or a REPL, so an agent can query its own
history
Plugins
Ten Claude Code plugins reading the same data model
Statusline
Model, context bar, tokens and session cost in your prompt
MCP server
Thirty tools: sixteen read-only, thirteen that mutate, and one that is destructive.
Mutating tools are refused unless MCP_DASHBOARD_ALLOW_MUTATIONS=true. The
destructive one, dashboard_clear_all_data, additionally needs
MCP_DASHBOARD_ALLOW_DESTRUCTIVE=true and a confirmation token that must
read exactly CLEAR_ALL_DATA. Read-only tools never touch either gate. The
remote source listing scrubs hostnames, key paths and addresses before returning,
because tool results are copied into a model's context.
bash
npm run mcp:install
npm run mcp:build
npm run mcp:start # stdio, for MCP hosts
npm run mcp:start:http # HTTP + SSE on 127.0.0.1:8819
npm run mcp:start:repl # interactive, with tab completion
# register it with Claude Code
claude mcp add byte \
--env MCP_DASHBOARD_BASE_URL=http://127.0.0.1:4820 \
-- node /path/to/Byte/mcp/build/index.js
The HTTP transport serves streamable HTTP at /mcp, legacy SSE at
/sse and /messages, and a liveness probe at
/health. The dashboard URL it talks to must be a local host: the allowlist
covers loopback and the container gateway names, and rejects anything else.
The byte CLI
npm run setup links it. It finds the server from
CLAUDE_DASHBOARD_PORT or DASHBOARD_PORT, then
~/.claude/.byte-agent-monitor.json, then 127.0.0.1:4820.
Colour turns itself off when you pipe it.
bash
byte status # is the server up, and where
byte stats # the header counters
byte kanban # the board, in the terminal
byte sessions --limit 20 # box-drawn table
byte session <id> # one session in full
byte tail --session <id> # follow events as they arrive
byte analytics # tokens, cost, tools, with inline bars
byte cost # what it has cost you
byte doctor # check the install
byte repl # interactive shell with completion
Eleven commands work with no server at all, reading the SQLite file directly:
stats, sessions, agents, events,
kanban, session, pricing, alerts,
rules, export and doctor. Offline runs still
correct a stale active session for display, using the same process-liveness
probe the server uses, and footnote that they did, without writing to the database.
Desktop app
Electron. It ships as a DMG on macOS, an NSIS installer and a portable executable on
Windows, and a .deb and AppImage on Linux. The .deb is the one
to prefer, because the hook command written into your settings embeds an absolute path
and an AppImage remounts somewhere new every run.
The server runs in a dedicated child process, not in the window's own event loop:
SQLite's API is synchronous, and a free-text search that takes most of a second froze
the interface when the two shared a thread. If a healthy server is already answering on
4820 the app adopts it and leaves it running on quit; otherwise it picks a free port and
writes it where the hook handler will look. The tray menu carries the port, active
sessions, working agents and events today, plus open, restart, logs and an
Open at Login switch, macOS and Windows only, since Electron has no
supported mechanism on Linux.
VS Code extension
One activity-bar view, Monitor Control Center, polling every five seconds: four
stat tiles with sparklines over the last twenty samples (sessions, agents, tokens,
cost), an agent-health bar, recent sessions you can click through, and quick navigation.
Four commands: open the dashboard, refresh, open in a browser, clear history. There are
no settings to configure; it reads the port from the environment and falls back to 4820.
Statusline
A Python script, standard library only, that reads the JSON Claude Code pipes to it and
prints seven segments: model, user, working directory, git branch, a ten-cell context
bar with its percentage, tokens in and out with cache reads, and session cost to four
decimal places. The context bar and the cost both change colour as they climb. It reads
nothing else, no server, no database, no config, and exits zero whatever it is given, so
it can never block Claude Code.
Plugins
Ten Claude Code plugins (byte-analytics, byte-cost-guard,
byte-productivity, byte-devtools, byte-insights,
byte-sessions, byte-workflows, byte-quality,
byte-config and byte-dashboard), each bundling some mix of
agents, commands, skills and hooks. They live under plugins/, alongside the
marketplace manifest that lists them, and load straight from the checkout:
bash
claude --plugin-dir plugins/byte-analytics
[ 08 · Operate it ]
Deployment
One SQLite file means one writer. Byte is not a stateless pool you scale sideways; it is
a cell you run more of. The Helm chart enforces that itself: it refuses to render above
one replica, and CI asserts the refusal on every change.
Target
What ships
Your machine
npm run build && npm start, or the desktop app. The usual
case
Docker or Podman
A three-stage Dockerfile on node:22-alpine, plus
compose files for the app alone, the app with Prometheus and Grafana, and the
hosted stack
Kubernetes
A Helm chart (StatefulSet, service, ingress, PVC, pod-disruption budget, network
policy and a ServiceMonitor) with dev, staging and production value sets
Azure
Bicep: one main.bicep over ten modules (network, key vault,
storage, Front Door, data plane, observability, alerts, access, registry access
and edge config) with per-environment parameter files
bash
# Docker Compose, publishes on loopback only
docker compose up -d --build
# with Prometheus and Grafana alongside
docker compose -f docker-compose.full.yml up -d --build
# Podman
CLAUDE_HOME="$HOME/.claude" podman compose up -d --build
The image's health check opens the database rather than calling
/api/health: that endpoint answers ok without touching
storage, which is exactly the failure you want the check to catch. Hooks must be
installed from the host, not from inside the container: the installer refuses there, so
it can never write a container-internal path into a bind-mounted ~/.claude.
Monitoring
GET /api/metrics is Prometheus exposition: byte_up,
byte_build_info, process uptime and resident memory,
byte_sessions and byte_agents by status,
byte_events_total, byte_websocket_clients,
byte_remote_sources, and byte_tokens_total split by input,
output, cache read and cache write. Scrape configs and Grafana dashboards ship under
monitoring/; npm run monitoring:verify checks the wiring.
Security
The trust boundary is the loopback bind. Everything else is a layer on top of it.
Loopback by default. The server binds 127.0.0.1 and is
not reachable from the network.
It refuses to start on a wider bind with no token and no explicit
acknowledgement.
Token auth over every API route and the WebSocket, compared in
constant time, when DASHBOARD_TOKEN is set.
A Host header allowlist, loopback plus whatever you name
in DASHBOARD_ALLOWED_HOSTS, which is what stops DNS rebinding. CORS is
restricted to the same set. Both are browser defences, not authentication: neither
stops curl.
Every query is a prepared statement with bound parameters, and query
parameters go through one coercion module that fails closed. It exists because
?limit=-1 used to mean "no limit" to SQLite, and an int64 overflow used
to mean a 500.
Spawning is same-origin guarded. Every /api/run route
rejects a browser request whose origin is not loopback, so a web page you happen to
have open cannot start processes on your machine.
Check Settings → Integrations for the selected platform's detection, trust and
collector state. Claude Code hooks require a new session after repair; Codex and
OpenCode show their own reconnect instructions. Superset also reports the
underlying agent binding
Nothing on screen on a fresh install
History import runs once, in the background, on first start. Give it a moment,
or force it from Settings → Import history. npm run seed puts three
demo sessions in
Sessions stuck as Active
A session that exits without firing SessionEnd is swept after
DASHBOARD_STALE_MINUTES (180 by default), and a liveness probe
catches dead processes sooner
Server will not start on a chosen host
That is the wide-bind refusal. Set DASHBOARD_TOKEN, or set
DASHBOARD_ALLOW_INSECURE_BIND if you genuinely mean it
403 on every request
The Host header is not on the allowlist. Add the name you are
browsing to, to DASHBOARD_ALLOWED_HOSTS
Docker: hooks never install
By design. Run npm run install-hooks on the host after the
container is up, then restart Claude Code
/api/docs returns 501
The Swagger and ReDoc packages are optional and the desktop build omits them.
The spec itself is still at /api/openapi.json