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
2 changes: 1 addition & 1 deletion .agents/skills/token-meter-development/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ that no longer qualifies.

### Dashboard styling

For any change to `page.html` styles, markup, or chart rendering:
For any change to dashboard styles, markup, or chart rendering (`dashboard/`):

1. Read `specs/DESIGN.md` → Tokens and Contract, Provider identity, and
Components before editing.
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ jobs:

- name: Parse the dashboard JavaScript
run: |
node -e "const fs=require('fs');const h=fs.readFileSync('page.html','utf8');const m=h.match(/<script>([\s\S]*)<\/script>/);new Function(m[1]);console.log('js ok')"
scripts/check-page

- name: Check shell syntax
run: |
Expand Down
4 changes: 2 additions & 2 deletions .impeccable/surfaces/page-html.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
---
version: 1
slug: "page-html"
primary_target: "page.html"
primary_target: "dashboard/"
related_targets: []
---

# Shared dashboard spectrum system

- Mode: Operate.
- Scope: all seven top-level routes in `page.html`, including Sessions overview/detail and its Run/Activity/Tools/Insights/Alerts panels.
- Scope: all seven top-level routes in the dashboard (`dashboard/` parts), including Sessions overview/detail and its Run/Activity/Tools/Insights/Alerts panels.
- Audience: a developer monitoring and reviewing local Claude, Codex, and Cursor evidence.
- Primary job: move from live Sessions through Logs, Spend, Models, Tools, Learn, and Settings without relearning the visual language.
- Required interactions: top-level navigation, route controls, filters, tables, cards, Sessions selection and reordering, deep links, settings anchors, tooltips, and narrow-width navigation.
Expand Down
66 changes: 24 additions & 42 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ Token Meter reads local agent traces, calculates clearly labeled usage estimates
|---|---|
| `meter.py` | Small executable/import compatibility facade for `token_meter.app` |
| `token_meter/app.py` | Composition, compatibility exports, settings, and application lifecycle |
| `token_meter/app_helpers/` | Leaf helpers moved out of `app.py`; `app.py` re-exports them. Find a name's home from `app.py`'s `app_helpers` imports |
| `token_meter/runtimes/` | Registered runtime discovery, parsing, revisions, and safe projections |
| `token_meter/platforms/` | Host paths, process/update policy, and trash behavior |
| `token_meter/domain/` | Runtime-neutral usage, timing, tools, insights, and aggregates |
| `token_meter/domain/compare.py` | Content-free session comparison, cheapest/fastest picks, and same-title matching |
| `token_meter/projections.py` | Explicit allowlisted public compatibility projections |
| `page.html` | Entire browser dashboard: markup, styles, routing, and JavaScript |
| `dashboard/` | Browser dashboard source, one file per view: `styles/*.css`, `markup/*.html`, `js/*.js`. `page.manifest` lists the serving order; the server concatenates the parts into one page. Read the one part you need, not the assembled page |
| `specs/DESIGN.md` | Visual system: tokens, provider identity, components, readability floor, contract |
| `tests/contracts/test_design_system.py` | Design-system contract: tokens, scales, contrast, components, dead CSS, provider colors |
| `scripts/style-snapshot.js` | Browser computed-style before/after diff for stylesheet-wide changes |
Expand All @@ -34,7 +35,7 @@ Token Meter reads local agent traces, calculates clearly labeled usage estimates
| `token_meter/domain/work_evidence.py` | Per-request cost slices and action evidence for Work insights |
| `token_meter/services/git_delivery.py` | Local push reflog scan, hashed Git ledger, commit work-type labels, Git payload |
| `token_meter_mcp.py` | Bounded MCP interface; evidence is read-only except explicit confirmed session-budget changes |
| `tests/test_meter.py` | Server, parser, UI-contract, installer, and Swift-source tests |
| `tests/test_*.py` | One module per surface (for example `test_dashboard_spend.py`, `test_menubar_tray.py`, `test_pricing.py`); shared fixtures live in `tests/*_support.py` and `tests/dashboard_page.py`. Run the one module you changed first |
| `tests/test_mcp_server.py` | MCP contract and privacy tests |
| `runtime-manifest.txt` | Shared source-to-runtime packaging contract |
| `scripts/install` | Stage user runtime and install both macOS LaunchAgents |
Expand All @@ -58,8 +59,9 @@ Token Meter reads local agent traces, calculates clearly labeled usage estimates
| `python3 scripts/run-tests` | Run the same suite across one worker per CPU (`-j N` to limit, `-v` for per-test times) |
| `python3 -m unittest tests.contracts.test_design_system -v` | Check dashboard styling against the design-system contract |
| `PYTHONPYCACHEPREFIX=/private/tmp/token-meter-pycache python3 -m py_compile meter.py token_meter_mcp.py $(find token_meter -type f -name '*.py' -print)` | Compile Python without polluting the repo |
| `node -e "const fs=require('fs');const h=fs.readFileSync('page.html','utf8');const m=h.match(/<script>([\\s\\S]*)<\\/script>/);new Function(m[1]);console.log('js ok')"` | Parse embedded dashboard JavaScript |
| `bash -n scripts/install scripts/install-linux scripts/install-launch-agent scripts/install-systemd-user scripts/run-menubar scripts/run-token-meter-mcp scripts/start-token-meter scripts/uninstall-launch-agent scripts/uninstall-systemd-user scripts/update scripts/update-linux scripts/setup-work-classifier` | Check shell syntax |
| `scripts/check-page` | Assemble the dashboard and parse its JavaScript |
| `scripts/show [FILE] NAME` | Print one Python or dashboard JS definition with line numbers; use it instead of a wide grep or `sed -n` range |
| `bash -n scripts/install scripts/install-linux scripts/install-launch-agent scripts/install-systemd-user scripts/run-menubar scripts/run-token-meter-mcp scripts/start-token-meter scripts/uninstall-launch-agent scripts/uninstall-systemd-user scripts/update scripts/update-linux scripts/setup-work-classifier scripts/check-page` | Check shell syntax |
| `swiftc menubar/TokenMeterMenuBar.swift -o /private/tmp/token-meter-menubar` | Compile the native companion |
| `TOKEN_METER_MENUBAR_SMOKE=1 /private/tmp/token-meter-menubar` | Run deterministic native smoke output |
| `powershell -NoProfile -Command "[void] [scriptblock]::Create((Get-Content -Raw scripts/install-windows.ps1))"` | Parse a Windows script on a Windows host |
Expand Down Expand Up @@ -200,44 +202,24 @@ Token Meter reads local agent traces, calculates clearly labeled usage estimates
- Before final handoff, report files changed, exact validation results,
installed-runtime checks when applicable, review findings and disposition,
and anything not verified.
- When Pratik explicitly asks to start the Token Meter team flow or manage a
linked reporter request end to end, use the `reporter-end-to-end` route. That
request is standing approval to commit only the scoped files so independent
gates can bind to that exact commit. After all required gates pass, push its
dedicated `codex/` branch, open the linked pull request, post detailed testing
instructions on the linked GitHub issue, and post one concise follow-up in the
existing Slack thread. Recheck and read back every write; do not pause for
another approval between these bounded delivery steps.
- For `reporter-end-to-end`, GitHub owns clone, checkout, install, health-check,
restoration, measurement, and procedural next steps. The communication
manager first drafts the pull request from the gated commit. After the GitHub
operator creates and reads back the pull request, the communication manager
uses its real URL to draft the detailed linked-issue handoff and a separate
Slack reply. The Slack reply is one short paragraph that thanks the reporter,
links the pull request, briefly asks them to try it, and identifies the reply
as from Pratik's agent. Do not put code, commands, clone/install steps,
procedural next steps, a test matrix, or a long technical summary in Slack.
- `reporter-end-to-end` standing approval does not include merge, release,
close, label changes, or hosted review requests. It applies only to the linked
issue/thread and only when the exact head has current required evidence with
no open finding.
- When the user authorizes checking out, reviewing, or managing pull requests,
post one contributor-facing status reply on each inspected PR after checking
its current head and discussion. Thank the contributor, state the
evidence-backed merge status or next step, and identify the reply as from
Pratik's agent. Mention a follow-up only when the team owns an actual next
action; when the work is complete, do not promise one. Do not duplicate an
equivalent same-head status reply. The PR-management request is standing
approval for these replies only; merges, closes, pushes, review requests,
and unrelated actions remain separately gated unless that request explicitly
authorizes them.
- When a contributor later reports results after Pratik's agent asked them to
check out or test a pull request, acknowledge every existing discussion
thread containing those results. Thank them, state any actual next action
without inventing a diagnosis or deadline, and identify the reply as from
Pratik's agent. Omit a follow-up promise when the work is complete. Keep Slack
to the same short follow-up contract with no code or procedural next steps.
This is standing approval for that narrow acknowledgment.
- Delivery flows and their standing approvals live in skills; load the skill
before acting:
- `reporter-end-to-end` (Pratik explicitly asks to start the Token Meter team
flow or manage a linked reporter request): `token-meter-intake` and
`token-meter-github-ops`. It authorizes committing only the scoped files
so the gates can bind to that exact commit. Once every required gate
passes on that head with no open finding, it also authorizes pushing a
dedicated `codex/` branch, the linked pull request, the issue testing
handoff, and one short Slack reply in the existing thread signed as
Pratik's agent, for that linked issue and thread only. GitHub owns clone,
install, and procedural next steps; Slack gets no code or procedural next
steps. It never includes merge, release, close, label changes, or hosted
review requests.
- Pull-request status replies and contributor result acknowledgments, also
signed as Pratik's agent: `token-meter-github-ops` and
`token-meter-communication`. Those approvals cover only one non-duplicate
reply per inspected head or result thread; merges, closes, pushes, review
requests, and every other action stay separately gated.
- Commits, pushes, pull requests, reviews posted to GitHub, Slack messages,
releases, and other external side effects require explicit user approval.

Expand Down
3 changes: 2 additions & 1 deletion agent-skills/token-meter-debug/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ only through the helper in section 3, which allows a fixed set of fields.
Code map, when a source checkout is available: read `specs/ARCHITECTURE.md` first.
Runtime parsing is in `token_meter/runtimes/`, costs in `token_meter/domain/usage.py`
and `token_meter/models/`, host paths in `token_meter/platforms/`, the HTTP server in
`token_meter/app.py` and `token_meter/web/`, the dashboard in `page.html`, the MCP in
`token_meter/app.py` and `token_meter/web/`, the dashboard in `dashboard/` (one file
per view; `dashboard/page.manifest` lists the order), the MCP in
`token_meter_mcp.py` and `token_meter/mcp/`, the companion in `menubar/`.

## 3. Gather evidence
Expand Down
7 changes: 7 additions & 0 deletions dashboard/head.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<!doctype html><html lang=en data-theme=classic><head><meta charset=utf-8>
<script id=theme-boot>(function(){var ids=['classic','nebula','monolith','voltage','phosphor','omarchy','jadehorse','ferrous','afterglow'];function resolve(pref){return ids.indexOf(pref)>=0?pref:'classic';}window.tokenMeterTheme={ids:ids,resolve:resolve};try{document.documentElement.dataset.theme=resolve(localStorage.getItem('tm_theme'));}catch(e){}})();</script>
<meta name=viewport content="width=device-width,initial-scale=1">
<title>Token Meter</title>
<link rel=icon type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Crect width='64' height='64' rx='14' fill='%2307090c'/%3E%3Cpath fill='%23fff' d='M47.03 36.16v-7.58L10 10v8.32l28.7 13.97L10 46.44v8.14l37.03-18.4z'/%3E%3C/svg%3E">
<meta name=theme-color content="#07090c">
<style>
Loading
Loading