Skip to content

0.48.0 — the page wears the Claude Design System, and the dashboard operates - #109

Merged
lroolle merged 2 commits into
mainfrom
feat/cds-ui
Sep 2, 2026
Merged

0.48.0 — the page wears the Claude Design System, and the dashboard operates#109
lroolle merged 2 commits into
mainfrom
feat/cds-ui

Conversation

@lroolle

@lroolle lroolle commented Sep 2, 2026

Copy link
Copy Markdown
Member

What

Two shipped things, one release.

The UI adopts the Claude Design System. cctrace traces Claude Code, so it should read as part of the same product — and an official system is a governed context, so nothing was invented: the palette, geometry and type ramp were measured off claude.ai on 2026-09-02 (769 --cds-* custom properties resolved in the live page, both themes) and adopted whole. docs/design/proposals/ carries the two directions the team chose between (A "the recorder", designed here; B the CDS adoption) with their cold audits; the token block at the top of src/ui.ts names the CDS token behind every value.

We took B, and kept the two details from A that make the requests view stop being a DevTools panel: the pen and the named wait.

  • The frame: tabs → a destination rail carrying the mark, the run card (client · trace · session · live/snapshot), the destinations with their counts, and the page chrome in its foot. The work header names this destination. Under 1000px it narrows; under 760px it becomes a labelled bottom bar with 44px targets.
  • Two faces: the reading face for prose, labels and controls; mono for the wire (urls, ids, status codes, byte counts, payloads). The conversation reads at 14px, 46rem measure.
  • Clay is identity, blue is interaction — the mark and the one primary action per screen wear the brand ink, nothing else.
  • The list is a recording: rules not cards (26px on a 27px pitch vs the card's 41px — 37 rows per 1000px vs 24, measured), each row opening with its pen (30s full-scale deflection, faint head = ttft, solid tail = the streaming after it, inked by category), and a hatched band naming every wait over two minutes.
  • Data colors are the six hues CDS already ships for git status, so a cctrace lane and a Claude Code diff badge are the same inks.
  • The dashboard is the same material, and the mark was redrawn in CDS geometry and moved to src/icons.ts (one source: rail, dashboard, favicon).

The dashboard operates (the other half of this release): a two-step stop on every live row — a capture run ends the way Ctrl-C ends it, so the trace is still sealed — and a store section with the archive plan and one archive now button, which spawns cctrace compress --all --yes as a child and streams its output into the page.

Evidence

  • bun test911 pass, 0 fail (5 new: the rail's active mark + page title follow the route, the destination counts, the pen, the named wait, and no band between consecutive requests).
  • kit/render-check.mjs on /trace and /dashboard0 fail, at 390 and 1440, both themes. Contrast was the real finding: CDS ships success and warning as FILL hues, and as text on their own soft grounds they read 3.95:1 and 4.08:1 (clay as text on paper: 3.12:1), so each gets its own darker step in light. The one warning kept is CDS's own three measured radii — collapsing them would be our taste overruling the system we said we adopted.
  • Density measured, not remembered: 41px pitch before, 27px after, both at 1440 on the same trace.
  • make build compiles.

Docs

docs/design/ui.md (the shipped rules: material, faces, the accent/clay split, the rail, the row), docs/design/web-ui.md (behaviour spec), docs/web-ui.md (the user-facing tour), README.md, CLAUDE.md, skills/cctrace/SKILL.md.

🤖 Generated with Claude Code

lroolle and others added 2 commits September 2, 2026 08:19
Every live row grows a two-step stop button (the first click arms, the
second sends), worded for what it ends: "end session?" for a capture run,
"close?" for a viewer. A capture run stops the way Ctrl-C stops it — the
traced client takes SIGTERM and its exit runs the whole close-out (flush,
receipt, seal, tombstone) — so stopping from the page never costs a
trace; force escalates to SIGKILL.

The stop is addressed the way liveness is probed, and for the same
reason: the page posts to its own origin (POST /api/instances/stop {id}),
the server that served it relays to the target's own port (POST
/api/shutdown), and the receiver compares the run id against its own
before acting. A pid is neither addressable nor trustworthy across the
pid namespaces that share a data dir.

The store section reports bytes, traces, projects and the exact archive
plan, with one "archive now" behind it. The job is `cctrace compress
--all --yes` spawned as a CHILD (src/maintenance.ts) with its output
streamed into the page: one implementation of archiving, and a multi-GB
walk must never sit on the event loop of a capture run whose proxy the
traced session depends on.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
cctrace traces Claude Code, so it should read as part of the same
product. An official system is a governed context, so nothing here is
invented: the palette, the geometry and the type ramp were MEASURED off
claude.ai on 2026-09-02 (769 --cds-* custom properties resolved in the
live page, both themes) and adopted whole. The token block at the top of
src/ui.ts names the CDS token behind every value; docs/design/proposals/
carries the two directions the team chose between and their audits.

The frame: the tabs became a destination RAIL. The left edge carries the
mark, the run card (client, trace, session id, live or snapshot — the
card that answers "what am I looking at"), the destinations with their
counts, and the page's own chrome in its foot. The work column's header
then names THIS destination. Identity belongs to the navigation, not to a
strip above the content. Under 760px the rail becomes a labelled bottom
bar with 44px targets — four glyphs beside four numbers is a rebus, not
navigation.

Two faces, one job each: the reading face for prose, labels and controls;
mono for the wire — urls, ids, status codes, byte counts, payloads. Clay
is identity (the mark, the one primary action), blue is interaction.

The request list is a recording. Rows are rules, not cards: 26px on a
27px pitch against the card's 41px — 37 requests per 1000px of list
against 24, measured — and every row opens with its PEN, its own stroke
on a shared 30s scale whose faint head is time-to-first-token and whose
solid tail is the streaming that followed, inked by category. A wait over
two minutes between rows becomes a hatched band naming it: a list that
silently closes the gap makes an hour of nothing look like the next line.
(Both are direction A's, kept in direction B's frame.)

Data colors are the six hues CDS ships for git status, so a cctrace lane
and a Claude Code diff badge are the same inks. Contrast is measured, not
asserted: CDS ships success and warning as FILL hues, and as text on
their own soft grounds they read 3.95:1 and 4.08:1, so each gets its own
darker step in light — render-check reports 0 fail on both pages, at 390
and 1440, in both themes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@lroolle
lroolle merged commit 5d9742d into main Sep 2, 2026
1 check passed
@lroolle
lroolle deleted the feat/cds-ui branch September 2, 2026 15:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant