Thanks for helping. Bug reports, new tools, fixes and UI polish are all welcome.
Open an issue with your OS, the Tokenmeter version (the release you installed), what you expected and what happened. For a card showing wrong numbers, say which tool and plan you use. Never paste API keys or tokens.
Security problems: report them privately through GitHub security advisories, not a public issue.
You need Node.js 22 (what CI uses) and git.
git clone https://github.com/mugeshk97/tokenmeter.git
cd tokenmeter
npm install
npm run demo # the UI with sample data
npm start # the real app, reading your own tools
npm test # must pass before a pull requestIf npm start says Electron failed to install, your npm may have skipped install scripts; run node node_modules/electron/install.js once.
- Main process (
src/main.js): the window, tray, IPC, polling and settings.src/updater.jshandles auto-update,src/config.jssettings and encrypted secrets, andsrc/poller.jsrefresh scheduling. - Providers (
src/providers/): one module per tool. Each returns a plain card object; they never touch the UI. - Renderer (
src/renderer/): plain HTML, CSS and JavaScript, with no framework. It runs with a strict Content Security Policy and no Node.js. Inlinestyle="…"attributes are blocked by the CSP, so use classes (orelement.style.setPropertyfrom JavaScript). - Tests (
test/):node:test, with mocked HTTP responses and fake log folders. They never touch the network.
-
Write the provider in
src/providers/<tool>.js, exporting an async function that returns a card:{ headline: { value: '29%', label: 'left this week', short: 'left this week' }, // short: Compact label foot: 'resets in 2d 4h', // one-line footnote in Compact meters: [{ label: 'Weekly limit', pct: 71, detail: '29% left · 2d 4h' }], // pct = share USED, 0-100 stats: [{ label: 'Tokens today', value: '1.2M' }], spark: { label: 'tokens / hour, today', points: [/* numbers */] }, // or null note: 'Shown in Detailed', // or null }
Lead with what's left. The widget turns a meter red when
pctreaches 80, and sorts cards by their tightest meter. Throw anErrorwith a friendly message on failure; the card then shows it with a Retry or Fix key button. The helpers insrc/providers/util.jscover HTTP with timeouts, number formatting and the budget headline. Local cards are re-read every minute, so wrap any network call in a local provider withcachedJson(a few minutes' TTL; it keeps the last good copy on errors).Using a tool's own sign-in (as the Claude Code and Codex cards do for plan limits): only read the token the tool saved, never refresh or write it back, and send it only to that tool's own provider. Fall back to the local numbers when the sign-in is missing, expired or rejected, and say why in
note. -
Register it in
src/providers/index.jswith anid,name,shortname,kind('local'or'remote'),console(its usage page),secrets,isConfiguredandrun. -
Add it to the defaults in
src/config.js(orderandproviders). -
Add its Settings fields in
PROVIDER_FIELDSinsrc/renderer/app.js: help text, key and any folder or budget fields. -
Add a demo card in
src/demo.js, sonpm run demoshows it. -
Test it in
test/providers.test.jswith a mocked response (passfetchImpl) or a fake log folder, including the error and fallback cases. -
Document it in the Supported tools table in
README.mdand the tools list on the landing page (site/index.html). If it sends anything over the network, add that to the README's Privacy and security section too.
- Check both themes (
AIU_THEME=dark npm run demo, thenlight) and all three card sizes. - Keep it keyboard-usable: every control needs an accessible name, and nothing should rely on hover or color alone.
- Use the color tokens at the top of
src/renderer/styles.cssrather than raw colors. - Include before and after screenshots in the pull request.
- Branch from
dev. - Keep each pull request to one change, and match the style of the code around it.
- Run
npm test. CI runs it on Linux, Windows and macOS. - Describe what changed and why; link the issue if there is one.
The app, tray and installer icons are all rendered from assets/logo.svg and assets/tray.svg. After editing those, run npm run icons to regenerate the PNGs, the Windows .ico and the macOS .icns.
npm version patch # or minor / major: bumps package.json and tags vX.Y.Z
git push origin dev --follow-tagsThe tag starts .github/workflows/release.yml, which:
- builds the Linux
.deb, Windows installer and macOS.zip(Apple Silicon and Intel) into a draft release; - checks every installer and update file (
latest*.yml) is there, then publishes the release; - rebuilds the signed apt repository on GitHub Pages from the new
.deb; - updates the Homebrew cask in mugeshk97/homebrew-tap to the new macOS
.zipfiles (needs theHOMEBREW_TAP_TOKENsecret: a fine-grained token with Contents read and write on that repo). The tap's own workflow then test-installs it on a Mac.
The release starts with auto-generated notes; replace them with a short, user-facing summary (what's new, install per OS, upgrade notes) using gh release edit vX.Y.Z --notes-file notes.md. See v1.0.2 for the format.
The apt repository is signed with the key in the APT_GPG_PRIVATE_KEY repository secret; its public half is packaging/apt/tokenmeter-archive-keyring.asc. If a release fails partway, nothing is published: delete the draft and the tag (gh release delete vX.Y.Z --yes, git push origin :vX.Y.Z, git tag -d vX.Y.Z), fix the problem and tag again.
By contributing, you agree that your contributions are licensed under the MIT License.