Contents
How Data Flows Into the Dashboard
Where every number comes from — end to end.
Every time you use Claude Code (in VS Code or terminal), it silently writes a log file called a transcript. These logs are the primary data source for the dashboard.
with Claude Code
~/.claude/projects/
*.jsonlLog files on your PC
parse_transcripts.pyReads & extracts data
export_data.pyProcesses & builds JSON
metrics_data.jsonLocal summary file
sync_to_supabase.pyPushes to cloud DB
dashboard.htmlShows charts
Step 1 · ~/.claude/projects/*.jsonl — The raw log files
Claude Code automatically creates one .jsonl file per conversation. Every message is appended to that file in real-time as the conversation happens — not daily, not batched. When you send a message it is written immediately; when Claude responds it is written immediately.
One file = one session (conversation)
Three types of lines inside each file
| Line type | When it appears | Key fields |
|---|---|---|
type: "human" |
Every message you send to Claude | sessionId, timestamp, cwd (your project folder) |
type: "assistant" |
Every reply Claude sends back | usage.input_tokens, usage.output_tokens, model, content[] (tool calls inside) |
type: "tool_result" |
Result returned to Claude after a tool ran | Output text of the tool — not used by the dashboard |
Example assistant line (simplified)
From this one line the parser extracts: 5,413 tokens consumed, 1 tool call (Edit), 1 code change to login.html.
Step 2 · parse_transcripts.py — The reader
Reads every .jsonl file in ~/.claude/projects/ and extracts structured metrics from the raw messages. This is the only step that touches the raw log files.
Incremental cache — fast re-runs
It never re-reads a file that hasn't changed. It stores results in .parse_state.json and checks each file's mtime (last-modified time). If unchanged → skip. This makes repeated runs fast even with 60+ sessions.
What it extracts per session
| Field | How it is counted |
|---|---|
| turns | Count every role: "human" line — one per message you send |
| input_tokens | Sum usage.input_tokens from all assistant lines |
| output_tokens | Sum usage.output_tokens from all assistant lines |
| tool_calls | Every content block with type: "tool_use" across all assistant lines |
| code_changes | Tool calls where name = Write / Edit / NotebookEdit — lines counted from new_string / content field |
| daily | Tokens + turns broken down by day (timestamp[:10]) within the session |
Output: In-memory Python dicts — no file written. Data is passed directly to export_data.py.
Step 3 · export_data.py — The calculator
Calls parse_transcripts.py, then aggregates the raw session data into every number the dashboard needs. Two time windows are used depending on the metric:
| What it calculates | Window | How |
|---|---|---|
| KPI cards (sessions, lines, tool calls, avg iterations) | Last 30 days | Simple sums and averages across sessions in the 30-day window |
| KPI tokens & turns | All time | Summed from the weekly summary so the KPI board always matches the weekly table total |
| Daily data | Last 30 days | Merges the per-day breakdown from every session — if a session spans 5 days, all 5 days get contributions |
| Weekly summary | All time | Groups all sessions (from install date to today) into ISO weeks (2026-W24) — so older weeks never disappear as the 30-day window rolls forward |
| Tool usage | Last 30 days | Counts how many times each tool was called; top 20 returned |
| Language breakdown | Last 30 days | Groups code_changes by file extension (.py → Python, .html → HTML) and sums lines |
| Iterations distribution | Last 30 days | Buckets sessions by turn count: 1, 2, 3, 4, 5, 6–10, 11–20, 20+ |
Output: Writes metrics_data.json to the project folder. This file is overwritten on every refresh run.
Step 4 · metrics_data.json — The local summary file
The output of export_data.py. Contains only computed numbers — no raw conversation text. This is the file that gets uploaded to Supabase.
| Top-level key | Type | Contents |
|---|---|---|
generated_at | string | ISO timestamp of when this file was built |
days_analyzed | number | Analysis window (default 30) |
kpis | object | Total sessions, tokens, turns, lines generated, tool calls, avg iterations |
daily_data | array | One object per active day: { day, sessions, tokens, turns, lines } |
weekly_summary | array | One object per ISO week: { week, sessions, tokens, turns, lines } |
tool_usage | array | Top 20 tools: { tool_name, cnt } sorted by count |
language_breakdown | array | Lines written per language: { language, lines } |
iterations_dist | array | Session count per turns bucket: { bucket, sessions } |
mcp_usage | array | MCP server call counts (if you use MCP tools) |
ai_tools_comparison | array | Usage summary across Claude Code, ChatGPT, Copilot (reserved fields) |
Step 5 · sync_to_supabase.py — The uploader
Reads metrics_data.json and pushes it to the shared Supabase database so your data appears on the team dashboard for everyone to see.
| What it does | Detail |
|---|---|
| Identify you | Looks up your UUID — first checks SUPABASE_USER_ID in .env (fastest); falls back to Supabase admin API lookup by your email |
| Ensure role | If you have no role yet, inserts USER into user_roles (safe no-op if already set) |
Upsert member_metrics |
One row per team member — if your row already exists it is updated (merged). The entire metrics_data.json is stored in the data column (JSONB) |
Upsert member_metrics_history |
Writes one snapshot per day keyed on team_member_name + usage_date — powers the long-term trend charts |
What gets written to Supabase
The team dashboard reads the data column for every member and renders the leaderboard from it.
metrics_data.json (computed numbers, no conversation text) is uploaded to the shared Supabase database.
KPI Overview Cards
The five summary numbers shown at the top of dashboard.html for the selected time period.
What each card means
| Card | Source field | Meaning |
|---|---|---|
| Claude Sessions | kpis.total_sessions |
Total number of separate Claude Code conversations in the period. One session = one conversation from start to finish. |
| Tokens Consumed | kpis.total_tokens |
Sum of all input + output tokens across every session. A token ≈ one word. |
| Lines of Code Gen | kpis.lines_generated |
Total lines Claude wrote or edited using Write/Edit tools. Reflects AI contribution to your codebase. |
| Avg Iterations | kpis.avg_iterations |
Average turns (messages you sent) per session. Lower = more precise prompts. |
| Tool Calls | kpis.total_tool_calls |
Total number of internal operations Claude performed (Read, Edit, Bash, Grep, etc.) across all sessions. |
Input vs Output tokens explained
| Type | What it is | Example |
|---|---|---|
| Input tokens | Text sent TO Claude | Your question + every file Claude reads to answer it |
| Output tokens | Text Claude sends BACK | Claude's answer + all the code it writes |
Weekly Summary Table
Your Claude Code activity grouped by calendar week — shown in dashboard.html.
What the Week column means — ISO week format
The Week column shows dates in ISO 8601 week format: YYYY-Www
Each week runs Monday → Sunday. Examples:
| Week | Date Range |
|---|---|
| 2026-W21 | Mon 18 May – Sun 24 May 2026 |
| 2026-W22 | Mon 25 May – Sun 31 May 2026 |
| 2026-W23 | Mon 1 Jun – Sun 7 Jun 2026 |
| 2026-W24 | Mon 8 Jun – Sun 14 Jun 2026 |
What each column means
| Column | Meaning |
|---|---|
| Week | ISO week — Monday to Sunday. Clickable: opens the daily drill-down modal. |
| Sessions | Number of separate Claude Code conversations that week. |
| Tokens | Total input + output tokens consumed that week. |
| Total Turns | Total number of messages you sent to Claude across all sessions that week. |
| Avg Iterations | Total Turns ÷ Sessions for that week. Lower means more efficient prompting. |
| Efficiency | A color-coded tag based on Avg Iterations — see table below. |
Efficiency tag thresholds
| Avg Iterations | Tag | Meaning |
|---|---|---|
| Less than 5 | Efficient | Prompts are clear and precise — Claude usually gets it right in a few turns. |
| 5 – 9 | Moderate | Some back-and-forth. Room to be more specific in prompts. |
| 10 or more | Complex | High iteration count — either a complex task or vague prompts. |
Search & pagination
Use the search box above the table to filter by week (e.g. W23, 2026). Use the page buttons below to navigate if you have many weeks of data.
Weekly Drill-Down
Click any week in the Weekly Summary table to open a detailed breakdown for that specific week.
What opens when you click a week
A modal popup appears with four stat cards and two bar charts:
| Element | Shows |
|---|---|
| 📅 Sessions card | Total sessions in that week |
| 🔤 Tokens card | Total tokens consumed in that week |
| ✍️ LOC Gen card | Lines of code generated that week |
| 🔄 Avg Turns card | Average turns per session (color-coded green/yellow/red) |
| Sessions per Day chart | Bar chart — one bar per day of the week |
| Tokens per Day chart | Bar chart — one bar per day of the week |
Avg Turns color coding in the drill-down
| Avg Turns | Color |
|---|---|
| 4 or fewer | Green — efficient |
| 5 – 7 | Yellow — moderate |
| 8 or more | Red — high iteration |
AI Efficiency Score — Full Calculation
A score out of 100 that measures how actively and effectively you use AI tools. Higher = you use AI more and better.
The 4 components
More sessions = higher score. Using Claude Code every day gets full 30 points.
More code generated by Claude each day = higher score.
Fewer back-and-forth messages = higher score. Clear, detailed prompts that get the answer in 1–3 turns score highest.
| Avg turns per session | Prompt Quality Score |
|---|---|
| 1 turn | 25 points (max) |
| 3 turns | 20 points |
| 5 turns | 15 points |
| 11 turns | 0 points (minimum) |
More tool calls per day = higher score. 20+ tool calls/day earns the full 20 points.
Final formula
Real example — score of ~70 (sample member)
| Input | Value |
|---|---|
| Total sessions | 90 |
| Days analyzed | 30 |
| Lines generated | 1,800 |
| Avg turns per session | 4.2 |
| Total tool calls | 460 |
Badge levels
| Score | Badge | Meaning |
|---|---|---|
| 75 – 100 | AI Champion | Heavy daily AI user, efficient prompts, high tool usage |
| 55 – 74 | Power User | Regular user with good habits |
| 35 – 54 | Active Learner | Growing usage, still building habits |
| 15 – 34 | Getting Started | Occasional use, not yet daily |
| 0 – 14 | Needs Coaching | Just starting out |
Team Dashboard — Overview & Leaderboard
Aggregates data from all team members via Supabase. Open team_dashboard.html to see this.
How team data works
Each team member runs refresh_silent.ps1 (Windows) or refresh_silent.sh (Mac/Linux) on their own machine. This syncs their metrics to the shared Supabase database:
Team Overview KPI strip
The five summary cards at the top of team_dashboard.html aggregate data across the whole team:
| Card | Meaning |
|---|---|
| Active Members | Members who have at least 1 session in the period, out of total members in Supabase. |
| Total Sessions | Sum of all sessions across the entire team. |
| Total Tokens | Sum of all input + output tokens across the entire team. |
| Total LOC Generated | Sum of all AI-written lines across the entire team. |
| Tool Calls | Total internal operations across the entire team. |
Leaderboard columns
The main ranking table sorted by AI Efficiency Score by default. Click any column header to re-sort.
| Column | Meaning |
|---|---|
| # | Rank. 🥇🥈🥉 medals for top 3. |
| Member | Name and role. Sortable A–Z. |
| Sessions | Total Claude Code conversations in the period. |
| Tokens | Total tokens consumed (input + output). |
| LOC Gen | Lines of code generated by Claude. |
| Avg Turns | Average turns per session. Color-coded: green ≤4, yellow ≤7, red >7. |
| Score | AI Efficiency Score (0–100) with color bar. |
| Badge | Level label — AI Champion, Power User, Active Learner, Getting Started, Needs Coaching. |
Team Weekly Summary
Shows each member's activity broken down by week, below the leaderboard in team_dashboard.html.
Columns in the team weekly table
| Column | Meaning |
|---|---|
| Member | Team member name. Clickable — opens the Weekly Drill-Down modal for that member and week. |
| Week | ISO week badge (e.g. 2026-W24). Shows the last 4 weeks per member by default. |
| Sessions | Sessions that member had in that week. |
| Tokens | Tokens consumed by that member that week. |
| Turns | Total message turns across all sessions that week. |
| Avg Iterations | Efficiency badge: Efficient (avg <5), Moderate (avg 5–9), or the raw number if ≥10. |
Search & pagination
Use the search box to filter by member name or week number (e.g. John, W23). Use the pagination buttons to navigate through all rows.
Export Report
Both dashboards have an Export Report button in the top-right header that downloads a spreadsheet.
dashboard.html — what's in the XLSX
| Sheet | Columns |
|---|---|
| KPI Summary | Metric, Value — your overall totals for the period |
| Daily Data | Date, Sessions, Tokens, Lines Generated, Turns — one row per day |
| Weekly Summary | Week, Sessions, Tokens, Total Turns, Avg Iterations — one row per week |
team_dashboard.html — what's in the XLSX
| Sheet | Columns |
|---|---|
| Team Leaderboard | Rank, Name, Role, Score, Badge, Sessions, Tokens, LOC Generated, Avg Iterations, Tool Calls |
| Daily Data | Member, Date, Sessions, Tokens, Lines, Turns — per-member per-day |
| Weekly Summary | Member, Week, Sessions, Tokens, Turns — per-member per-week |
How to Improve Your Score
Practical steps to increase your AI Efficiency Score.
Quick wins
| Action | Impact |
|---|---|
| Use Claude Code at least once every working day | +Usage Score (up to 30 pts) |
| Ask Claude to write new files, not just explain code | +Output Score (LOC Gen) |
| Write detailed prompts — include file name, expected behavior, constraints | +Prompt Quality Score (fewer turns) |
| Let Claude use tools freely on complex tasks (Read, Edit, Bash, Grep) | +Tool Diversity Score (20+ tool calls/day = full 20 pts) |
Good prompt vs bad prompt example
| Bad — many iterations | Good — few iterations |
|---|---|
| "Fix the bug" | "Fix the NullPointerException in OrderService.java line 45. The order.getUser() can return null when the guest checkout flag is true. Add a null check and return an empty Optional instead." |
| Results in 5–10 back-and-forth turns | Usually solved in 1–2 turns |
Refresh your dashboard
After using Claude Code, run the refresh script to update all metrics:
Or just wait — the scheduler does this automatically Mon–Fri at 18:30 if you set it up.