Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"$schema": "https://anthropic.com/claude-code/plugin.schema.json",
"name": "caliper",
"version": "0.27.0",
"description": "Run /caliper to launch. Caliper \u2014 precision for your AI spend: a local dashboard showing exactly where your Claude Code money goes (sessions, workflows, subagents, machine-wide analytics; cache-aware cost reconstruction), plus /optimize-spend to turn your usage into cost discipline. 100% local, no telemetry.",
"version": "0.28.0",
"description": "Run /caliper to launch. Caliper precision for your AI spend: a local dashboard showing exactly where your Claude Code money goes (sessions, workflows, subagents, machine-wide analytics; cache-aware cost reconstruction), plus /optimize-spend to turn your usage into cost discipline. 100% local, no telemetry.",
"author": {
"name": "Dennison Bertram"
},
Expand Down
49 changes: 49 additions & 0 deletions .claude/skills/tour-sync/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
name: tour-sync
description: >
Keep the Caliper dashboard's guided tour in sync with the product. Use whenever changing
the dashboard UI — adding, removing, renaming, or reordering panels, views, routes, KPI
cards, or interactive features in the dashboard prototype (.context/caliper-dashboard-demo.template.html)
or, once the tour ships there, in packages/control-tower. Any change to what a user sees
on a page means the tour may now skip, mis-describe, or point at something that moved.
---

# Tour Sync

The dashboard has a guided tour (`TOUR_STEPS` + spotlight engine) whose steps target
`data-tour="…"` anchors and describe specific panels with specific numbers and behaviors.
UI changes silently break it in three ways: a step's target disappears (tour dead-ends),
a new surface ships with no step (tour is incomplete), or a step's *description* no longer
matches what the panel shows (tour lies).

## When you change the dashboard UI

1. **Run the mechanical check** before finishing any UI change:

```bash
node .context/check-tour-sync.mjs
```

It fails if a tour step targets a missing anchor, if a `data-tour` anchor (or `kpiHtml`
`tour:` option) has no step and no allow-list entry, or if the tour's baked demo routes
(folder/session) vanish from the data. Treat a failure like a failing test — fix the
tour or consciously add the anchor to `EXCLUDED` with a reason, never ignore it.

2. **Check what the machine can't**: re-read the affected step's `title`/`body` text.
Does it still describe what the user actually sees (panel names, colors, interactions,
numbers)? Renamed "Fable fallbacks" → the step must say the new name. Changed the
fallback marker from blue to red → the step body that says "blue dot" must change too.

3. **New user-visible feature?** Add a `data-tour` anchor + a tour step (or an `EXCLUDED`
entry with a reason). The check enforces this; the judgment call is yours.

4. **Verify in-browser when steps changed**: `node .context/build-demo.mjs`, open the demo,
click ✦ Tour, and walk the changed steps end to end (including Done → localStorage flag).

## CI

The check is CI-shaped (exit 0/1, no dependencies). Today it lives beside the prototype.
When the tour ships in `packages/control-tower`, port `check-tour-sync.mjs` into that
package's `test/` (node --test) so `npm test` — and therefore CI — blocks product changes
that orphan the tour. Until then, this skill is the enforcement point: run the script as
part of any dashboard-UI change.
84 changes: 84 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Changelog

All notable changes to Caliper. Versions map to `.claude-plugin/plugin.json`; the
in-app update pill compares against this repo. (Entries before 0.27.0 are
backfilled from commit history.)

## 0.28.0 — 2026-07-03

The redesign release: the dashboard is now the caliper.run design system, end to end.

### New UI (default)

- **caliper.run look & feel** — white/ink tokens, Geist + Geist Mono, hairline panels,
one dark "anchor" KPI card per page; tier data-ink: opus=ink, fable=blue, sonnet/haiku=grays.
- **Drill-down IA** — Home → folder → session with a real breadcrumb (`›`), hash deep links,
and browser back/forward. Session titles render as quoted **first prompts** (that's what they are).
- **All-folders page** (`#/folders`) — full list with filter box and five sorts
(Spend / Sessions / $-per-session / Recent / Fallbacks); linked from Home's folder panel.
- **Session forensics** — waterfall of main + subagents on the real time axis (tier legend,
hover tooltips), subagents ranked by cost, a plain-language "biggest single cost" insight line,
and **per-run workflow timelines**: expand any run to reconstruct each agent call split into
inference vs tool segments (lazy, on demand).
- **Guided tour** — ✦ Tour walks every panel across all three views with a spotlight and
explanations; targets are chosen from your own data; first-visit hint; keyboard navigation.
Enforced by a `tour-sync` test so UI changes can't silently orphan it.
- **Dark mode** — ☾/☀ toggle, persisted, respects `prefers-color-scheme`; charts re-render
with theme-aware palettes.
- **"Nerfed" tracking** — Fable refusal/switch days marked with red dots on the daily chart
(legend + tooltips); fallback panel with **⧉ Analyze reasons** and **⧉ Disable auto-fallback**
copy-prompts, plus scope-aware **⧉ Optimize spend** buttons (machine / folder / session).
- **Live-data states** — boot progress, incremental machine scan ("scanning N/M"),
per-session "Reconstructing…" panels, honest empty states.
- The previous UI is preserved at **`/legacy/`** for one release cycle.

### Server

- New session-scoped endpoints for the v2 UI: `GET /v1/session-scope/subagents`,
`GET /v1/session-scope/observed`, and `GET /v1/session-scope/observed/:runId`
(`?slug=&id=`), so any session — not just the active one — can be drilled into.

### Tooling

- `scripts/demo-data.mjs`: subagents now have staggered starts, multiple turns, and real
durations so waterfalls render in demos and screenshots.
- New test: `test/tour-sync.test.mjs` (tour ↔ UI surface consistency).
- `docs/DEPLOYING.md`: the release checklist.

## 0.27.0 — 2026-07-03

- "Nerfed by Fable" rebrand in the previous UI, honest date range, refreshed README screenshots.
- Demo data can synthesize Fable refusals and fallback switches (main chat + workflow agents).
- CI: dev→prod gating (smoke on dev, full matrix as the prod gate on main).

## 0.26.2 — 2026-07-03

- Fix refusal undercount (100 was a bug; real = 104) + honest formatting.

## 0.26.1 — 2026-07-02

- Mobbin-driven Home dashboard upgrade.

## 0.26.0 — 2026-07-02

- Fable-fallback: machine-wide subagent counts, banner, palette + design cleanup.

## 0.25.0 — 2026-07-01

- Fable refusal-fallback tracking + per-model cost attribution.

## 0.24.5 — 2026-07-01

- Pin dependencies exactly for supply-chain safety.

## 0.24.4 — 2026-07-01

- Security hardening: loopback-only server + local-origin guard.

## 0.24.3 — 2026-07-01

- Alpha tag, Auto-Router teaser, run-/caliper install hint.

## 0.24.2 — 2026-07-01

- Brand the dashboard with caliper.run identity (rename from workflow-lens).
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,12 @@
|---|---|
| ![Folder view](docs/screenshots/folder.png) | ![Session overview](docs/screenshots/session.png) |

- **Machine-wide analytics** — total spend, daily charts stacked by model, spend by repo, cache economics.
- **"Nerfed by Fable" tracking** — counts every time Fable 5's safety classifier declined a request and Claude Code re-served it on the fallback model (refusals + switches), split by where it happened (mostly inside parallel Workflow subagents), down to the exact step and the prompt that triggered it.
- **Everything** — plain chats, Workflow runs, subagents (nested too), full conversations, per-step timelines.
- **The loop** — one click copies your real numbers, file paths, and live API pointers into a prompt; Claude analyzes the spend, edits the workflow that caused it, or writes you a cost skill.
- **Self-updating** — checks this repo and offers one-click updates.
- **Machine-wide analytics** — all-time spend, daily charts stacked by model, every folder ranked (with filter + sorts), cache economics.
- **Session forensics** — waterfall of the main chat + every subagent on the real time axis, subagents ranked by cost, and per-run workflow timelines split into inference vs tool time.
- **"Nerfed by Fable" tracking** — counts every time Fable 5's safety classifier declined a request or Claude Code re-served it on the fallback model, split main chat vs subagents, with red markers on the daily chart and one-click prompts to analyze the reasons or disable auto-fallback. (Per-step prompt drill-down: `/legacy/` for now.)
- **The loop** — scope-aware **⧉ Optimize spend** buttons (machine / folder / session) copy your real numbers and live API pointers into a prompt; Claude analyzes the spend or writes you a cost skill.
- **Guided tour & dark mode** — ✦ Tour explains every panel on your own data; ☾ toggles a full dark theme.
- **Self-updating** — checks this repo and offers one-click updates. (Previous UI preserved at `/legacy/` for one release.)

*Screenshots are bundled demo data (`node scripts/demo-data.mjs`). Your dashboard shows your own transcripts, locally.*

Expand Down
50 changes: 50 additions & 0 deletions docs/DEPLOYING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Deploying a Caliper release

The plugin ships from this repo's `main` branch: users install via the Claude Code plugin
marketplace and the in-app update pill compares the local version against GitHub, so
**merging to `main` with a version bump IS the deployment.**

Work through this checklist in order — every step, every release.

## 1. Check everything works — manually

- `npm test` in `packages/control-tower` AND `packages/workflow-lens` (keyless, no API calls).
This includes `tour-sync.test.mjs` — if you changed the UI, the tour must still match it.
- Launch against **demo data** (never verify releases on your real transcripts):

```sh
node scripts/demo-data.mjs
WFLENS_PROJECTS_ROOT=/tmp/caliper-demo/projects PORT=48899 node packages/control-tower/server.mjs
```

- Walk the real paths in a browser (agent-browser or by hand): Home KPIs + daily chart
hover, folder drill-in, a session with subagents (waterfall renders, per-run expanders
reconstruct), `#/folders` filter + sorts, the ✦ Tour end-to-end (finish with Done),
an ⧉ Optimize modal + copy, dark ⇄ light toggle, and the browser console for errors.
- For UI changes, run the ux-walker story catalog against the demo server and read the
report before shipping (report-only; fix what it finds first).

## 2. Update the changelog

- Add a `## <version> — <date>` section to `CHANGELOG.md` describing user-visible changes.
Plain and accurate; no marketing inflation.

## 3. Update the screenshots

- **Demo data only — always.** Real transcripts contain private prompts, paths, and spend.
- With the demo server from step 1 running, capture in **light theme** at ~1440×900,
tour hint dismissed, and overwrite `docs/screenshots/{home,folder,session}.png`.
Keep the set tight — three images, same filenames, so README links never break.

## 4. Update the README

- Re-read `README.md` against what actually shipped: feature bullets, install steps,
repo layout, cost formula. Fix drift; keep it tight.

## 5. Version, commit, publish

- Bump `version` in `.claude-plugin/plugin.json` (semver: UI/feature releases bump minor).
- One release commit titled like the changelog entry, ending with the version:
`New caliper.run design system UI (v0.28.0)`.
- PR to `main`, merge when green. Users get the update pill on their next dashboard load;
`self-update` runs `git pull --ff-only` against `main`.
Binary file modified docs/screenshots/folder.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/home.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/optimize-prompt.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/screenshots/session.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading