### Setup Project Environment Source: https://github.com/xiufengsun/tokentracker/blob/main/CONTRIBUTING.md Clone the repository, install dependencies, and build the dashboard for local development. ```bash git clone https://github.com/xiufengsun/TokenTracker.git cd TokenTracker npm install # Build the dashboard once so the CLI can serve it cd dashboard && npm install && npm run build && cd .. ``` -------------------------------- ### Development Build Commands Source: https://github.com/xiufengsun/tokentracker/blob/main/TokenTrackerLinux/README.md Commands to install dependencies, build the dashboard, bundle the node server, and start the development environment. ```bash npm ci --prefix TokenTrackerLinux npm run dashboard:build # from the repo root npm --prefix TokenTrackerLinux run bundle:node # stages EmbeddedServer/ npm --prefix TokenTrackerLinux run dev ``` -------------------------------- ### Global CLI Installation and Commands Source: https://github.com/xiufengsun/tokentracker/blob/main/README.md Install the CLI globally to access commands for dashboard management, manual synchronization, and status reporting. ```bash npm i -g tokentracker-cli tokentracker # Open the dashboard tokentracker sync # Manual sync tokentracker status # Check hook status tokentracker status --json # Machine-readable summary (pipe to jq, ingest from AI agents) tokentracker status --light # Plain ASCII table (CI / SSH, no spinner) tokentracker doctor # Health check ``` -------------------------------- ### Install and manage TokenTracker via npm Source: https://github.com/xiufengsun/tokentracker/wiki/Installation Install the CLI globally and use standard commands for dashboard access, synchronization, and maintenance. ```bash npm i -g tokentracker-cli tokentracker # Opens the dashboard tokentracker sync # Manual sync tokentracker status # Integration status tokentracker doctor # Health check tokentracker uninstall ``` -------------------------------- ### Initialize TokenTracker Project Source: https://github.com/xiufengsun/tokentracker/blob/main/README.md Commands to clone the repository, install dependencies, build the dashboard, and run the CLI. ```bash git clone https://github.com/xiufengsun/TokenTracker.git cd TokenTracker npm install # Build dashboard + run CLI cd dashboard && npm install && npm run build && cd .. node bin/tracker.js # Tests npm test ``` -------------------------------- ### Manual OpenClaw plugin installation Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/openclaw-integration.md Manually link and enable the session sync plugin if the automated installation fails. ```bash openclaw plugins install --link ~/.tokentracker/tracker/openclaw-plugin/openclaw-session-sync openclaw plugins enable openclaw-session-sync ``` -------------------------------- ### Run Manual Verification Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Command to start the tracker service for manual testing. ```bash node bin/tracker.js serve --no-sync ``` -------------------------------- ### Build Arch Package Source: https://github.com/xiufengsun/tokentracker/blob/main/TokenTrackerLinux/README.md Build and install the package from a local repository checkout. ```bash cd TokenTrackerLinux/packaging/arch/tokentracker-linux makepkg -si ``` -------------------------------- ### Install GNOME AppIndicator Extension Source: https://github.com/xiufengsun/tokentracker/blob/main/TokenTrackerLinux/README.md Install the required extension to enable tray icon support on Debian/Ubuntu or Fedora. ```bash # Debian / Ubuntu sudo apt install gnome-shell-extension-appindicator # Fedora sudo dnf install gnome-shell-extension-appindicator ``` -------------------------------- ### Check Node.js version Source: https://github.com/xiufengsun/tokentracker/wiki/Installation Verify that Node.js version 20 or higher is installed before proceeding with installation. ```bash node --version ``` -------------------------------- ### Install and upgrade TokenTracker via Homebrew Source: https://github.com/xiufengsun/tokentracker/wiki/Installation Manage the macOS menu bar application and CLI using Homebrew formulas. ```bash # Menu bar app + CLI (recommended on macOS) brew install --cask mm7894215/tokentracker/tokentracker brew install mm7894215/tokentracker/tokentracker # Upgrade brew upgrade --cask mm7894215/tokentracker/tokentracker brew upgrade mm7894215/tokentracker/tokentracker ``` -------------------------------- ### Run TokenTracker with npx Source: https://github.com/xiufengsun/tokentracker/wiki/Installation Execute the CLI tool without a permanent global installation. ```bash npx tokentracker-cli ``` -------------------------------- ### Activate TokenTracker Integrations Source: https://github.com/xiufengsun/tokentracker/wiki/Supported-AI-Tools Run this command to re-run detection and activate integrations after installing a new AI tool. ```bash tokentracker activate-if-needed ``` -------------------------------- ### Run CLI Commands Source: https://github.com/xiufengsun/tokentracker/blob/main/CONTRIBUTING.md Execute various CLI operations including starting the dashboard server, syncing, checking status, and running health checks. ```bash node bin/tracker.js # Start the local dashboard server (default: http://localhost:7680) node bin/tracker.js sync # Manual sync node bin/tracker.js status # Check hook status node bin/tracker.js doctor # Health check ``` -------------------------------- ### Pass Device ID to Fetcher Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Example of passing the device parameter to the daily fetcher call. ```ts dailyFetcher({ baseUrl, accessToken: tokenForFetch, from, to, device: deviceId, timeZone, tzOffsetMinutes, }), ``` -------------------------------- ### Update Cloud Fetcher Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Example of updating a cloud fetcher function to accept and pass the device parameter. ```ts export async function fetchCloudUsageSummary({ from, to, source, model, device, timeZone, tzOffsetMinutes, rolling = false, accessToken, }: AnyRecord = {}) { const tzParams = buildTimeZoneParams({ timeZone, tzOffsetMinutes }); const filterParams = buildFilterParams({ source, model, device }); const rollingParams = rolling ? { rolling: "1" } : {}; return fetchAccountFunction( ACCOUNT_PATHS.summary, { from, to, ...filterParams, ...tzParams, ...rollingParams }, accessToken, ); } ``` -------------------------------- ### Run tests and commit changes Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Command-line instructions to verify the implementation and commit the new files. ```bash cd dashboard && npx tsc --noEmit && cd .. git add dashboard/src/hooks/use-account-devices.ts dashboard/src/hooks/use-account-devices.test.tsx git commit -m "feat(dashboard): add useAccountDevices hook" ``` -------------------------------- ### Execute AppImage Source: https://github.com/xiufengsun/tokentracker/blob/main/TokenTrackerLinux/README.md Make the AppImage executable and run it. ```bash chmod +x TokenTracker-linux-x86_64.AppImage ./TokenTracker-linux-x86_64.AppImage ``` -------------------------------- ### Bundle a self-contained runtime for distribution Source: https://github.com/xiufengsun/tokentracker/blob/main/TokenTrackerWin/README.md Prepares the application for distribution by building the dashboard, bundling the Node runtime, and publishing the .NET project. ```powershell npm run dashboard:build # from repo root powershell -ExecutionPolicy Bypass -File scripts\bundle-node.ps1 dotnet publish -c Release -r win-x64 --self-contained false ``` -------------------------------- ### Build macOS Application Source: https://github.com/xiufengsun/tokentracker/blob/main/README.md Steps to bundle the dashboard, generate the Xcode project, and package the application into a DMG. ```bash cd TokenTrackerBar npm run dashboard:build # Build the dashboard bundle ./scripts/bundle-node.sh # Bundle Node.js + tokentracker source xcodegen generate # Generate the Xcode project ruby scripts/patch-pbxproj-icon.rb # Patch in the Icon Composer asset xcodebuild -scheme TokenTrackerBar -configuration Release clean build ./scripts/create-dmg.sh # Package the .app into a DMG ``` -------------------------------- ### Run Test Suite Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Command to execute the device scope tests. ```bash cd dashboard && npx vitest run src/hooks/use-usage-data.device.test.tsx ``` -------------------------------- ### Run TokenTracker in development mode Source: https://github.com/xiufengsun/tokentracker/blob/main/TokenTrackerWin/README.md Builds the dashboard and launches the application using the system Node runtime and local CLI source. ```powershell npm run dashboard:build $env:TOKENTRACKER_NODE = (Get-Command node).Source $env:TOKENTRACKER_ENTRY = "$PWD\..\bin\tracker.js" # from TokenTrackerWin\ .\bin\Debug\net8.0-windows\TokenTracker.exe ``` -------------------------------- ### Build the TokenTracker application Source: https://github.com/xiufengsun/tokentracker/blob/main/TokenTrackerWin/README.md Compiles the project using the .NET 8 SDK. ```powershell dotnet build -c Debug # output: bin\Debug\net8.0-windows\TokenTracker.exe ``` -------------------------------- ### Run verification tests Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Execute the test suite to ensure new device-specific functionality works without regressing existing all-devices behavior. ```bash cd dashboard && npx vitest run src/hooks/use-usage-data.device.test.tsx src/hooks/use-trend-data.test.tsx src/hooks/use-usage-data.account-resolving.test.tsx ``` -------------------------------- ### Build Local DMG for Testing Source: https://github.com/xiufengsun/tokentracker/blob/main/CLAUDE.md Commands to build the TokenTracker application locally. Note that CI is the authoritative source for production releases. ```bash cd TokenTrackerBar && npm run dashboard:build && ./scripts/bundle-node.sh xcodegen generate && ruby scripts/patch-pbxproj-icon.rb xcodebuild -scheme TokenTrackerBar -configuration Release clean build APP="$(find ~/Library/Developer/Xcode/DerivedData/TokenTrackerBar-*/Build/Products/Release -name 'TokenTracker.app' -maxdepth 1)" bash scripts/create-dmg.sh "$APP" ``` -------------------------------- ### Run test suite Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Command to execute the vitest suite for the UsageOverview component. ```bash cd dashboard && npx vitest run src/ui/dashboard/components/UsageOverview.device.test.jsx ``` -------------------------------- ### Handle TokenTracker Startup Errors Source: https://github.com/xiufengsun/tokentracker/blob/main/TokenTrackerLinux/src/index.html JavaScript event listener to catch and display startup errors reported by the backend. ```javascript // The server is started on a worker thread so this page can paint // immediately; main.rs reports a failure through this event rather than // leaving the window stuck on the loading message forever. window.addEventListener('tokentracker:startup-error', (event) => { document.getElementById('loading').hidden = true; document.getElementById('error').hidden = false; // textContent, never innerHTML: the detail carries filesystem paths. document.getElementById('error-detail').textContent = String(event.detail ?? 'Unknown error'); }); ``` -------------------------------- ### Configure PetWindow CSS Source: https://github.com/xiufengsun/tokentracker/blob/main/dashboard/pet.html Sets the window to be fully transparent and enables drag-to-move functionality via cursor styles. ```css /* Fully transparent surface: the Windows PetWindow composites the WebView2 alpha with its DWM backdrop, so anything not painted here stays see-through. */ html, body, #pet-root { margin: 0; padding: 0; width: 100%; height: 100%; background: transparent !important; overflow: hidden; } body { /* Whole surface is a drag handle (the host starts a native move on mousedown); show the grab affordance. */ cursor: grab; -webkit-user-select: none; user-select: none; } body:active { cursor: grabbing; } ``` -------------------------------- ### Run verification tests Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Command to execute the test suite for the account device filter. ```bash node --test test/account-device-filter.test.js ``` -------------------------------- ### Run Tests and Linting Source: https://github.com/xiufengsun/tokentracker/blob/main/TokenTrackerLinux/README.md Execute Rust tests and run clippy for code analysis. ```bash cd TokenTrackerLinux/src-tauri cargo test cargo clippy --all-targets -- -D warnings ``` -------------------------------- ### Run component tests Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Command to execute the Vitest suite for the DeviceUsageCard component. ```bash cd dashboard && npx vitest run src/ui/dashboard/components/DeviceUsageCard.test.jsx ``` -------------------------------- ### Verify and commit changes Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Run type checking and commit the implemented features. ```bash cd dashboard && npx tsc --noEmit && cd .. git add dashboard/src/ui/dashboard/components/UsageOverview.jsx dashboard/src/ui/dashboard/components/UsageOverview.device.test.jsx git commit -m "feat(dashboard): device dropdown in UsageOverview top bar" ``` -------------------------------- ### Execute common project commands Source: https://github.com/xiufengsun/tokentracker/blob/main/CLAUDE.md Use these npm scripts and node commands for testing, development, and validation tasks. ```bash npm test # node --test test/*.test.js (209 files) node --test test/.test.js # single test file npm run ci:local # tests + validations + builds npm run dashboard:dev # Vite dev server with local API mock (port 5173) npm run dashboard:build # build to dashboard/dist/ npm run validate:copy # copy registry completeness npm run validate:ui-hardcode # no hardcoded UI strings npm run validate:guardrails # architecture guardrails node bin/tracker.js serve --no-sync # local dashboard server on :7680 ``` -------------------------------- ### Configure OpenCode Go environment variables Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/opencode-go-limits.md Set these variables in your local environment to enable usage tracking. Never commit these secrets to version control. ```dotenv # Preferred: official OpenCode Go usage API. OPENCODE_GO_API_KEY= # Legacy compatibility fallback: signed-in workspace dashboard scrape. OPENCODE_GO_WORKSPACE_ID= OPENCODE_GO_AUTH_COOKIE= # Optional and explicitly unverified local historical estimate. # TOKENTRACKER_OPENCODE_GO_LOCAL_ESTIMATE=1 ``` -------------------------------- ### Execute Tests Source: https://github.com/xiufengsun/tokentracker/blob/main/CONTRIBUTING.md Run the full test suite, individual test files, or the complete CI validation pipeline. ```bash npm test # Full suite (96 test files, node --test) node --test test/rollout-parser.test.js # A single test file npm run ci:local # Tests + validations + builds (everything CI runs) ``` -------------------------------- ### Run TokenTracker diagnostics Source: https://github.com/xiufengsun/tokentracker/wiki/FAQ Dumps machine state, integration status, and configuration flags to a JSON file for inspection. ```bash tokentracker diagnostics > /tmp/tt.json ``` -------------------------------- ### Dashboard Development Commands Source: https://github.com/xiufengsun/tokentracker/blob/main/CONTRIBUTING.md Commands for running the Vite development server, building for production, and validating the copy registry. ```bash npm run dashboard:dev # Vite dev server with mocked API npm run dashboard:build # Production build (output: dashboard/dist/) npm run validate:copy # Validate copy registry completeness ``` -------------------------------- ### Run Verification Commands Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Commands to run tests and commit changes. ```bash cd dashboard && npx tsc --noEmit && cd .. git add dashboard/src/lib/api.ts dashboard/src/lib/api.device.test.ts git commit -m "feat(dashboard): thread device_id through api + add fetchAccountDevices" ``` -------------------------------- ### Monitor server logs Source: https://github.com/xiufengsun/tokentracker/wiki/Troubleshooting Displays the tail of the server log file to diagnose startup failures or port binding issues. ```bash tail -f ~/Library/Logs/TokenTrackerBar/server.log ``` -------------------------------- ### Initialize Native App and Theme State Source: https://github.com/xiufengsun/tokentracker/blob/main/dashboard/index.html Detects native bridge availability and synchronizes the UI theme from local storage before the first paint to prevent visual flashes. ```javascript (function () { try { if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.nativeBridge) { document.documentElement.classList.add("native-app"); } } catch (e) {} })(); // Sync theme before first paint to prevent dark→light flash (FOUC) (function(){ var t; try { t = localStorage.getItem("tokentracker-theme"); } catch(e) {} var dark = t === "dark" || (t !== "light" && matchMedia("(prefers-color-scheme:dark)").matches); if (dark) document.documentElement.classList.add("dark"); })(); ``` -------------------------------- ### Implement fetchAccountDevices Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Adds the new fetcher for retrieving account devices. ```ts export async function fetchAccountDevices({ from, to, timeZone, tzOffsetMinutes, accessToken, }: AnyRecord = {}) { const tzParams = buildTimeZoneParams({ timeZone, tzOffsetMinutes }); return fetchAccountFunction(ACCOUNT_PATHS.devices, { from, to, ...tzParams }, accessToken); } ``` -------------------------------- ### Execute OpenCode Go tests Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/opencode-go-limits.md Run targeted tests for the OpenCode Go implementation or the full local validation suite. ```bash node --test test/opencode-go-limits.test.js npm run ci:local ``` -------------------------------- ### Check TokenTracker Status and Diagnostics Source: https://github.com/xiufengsun/tokentracker/wiki/Supported-AI-Tools Use these commands to verify the configuration state of integrated tools, perform health checks, or export diagnostic data. ```bash tokentracker status # Per-tool state (configured / skipped / error) tokentracker doctor # Deeper health check — paths, permissions, queue size tokentracker diagnostics # Full JSON dump (safe to attach to issues) ``` -------------------------------- ### Manage sync and upload queue Source: https://github.com/xiufengsun/tokentracker/wiki/Troubleshooting Commands to force synchronization or reset the upload queue. ```bash tokentracker sync ``` ```bash tokentracker doctor ``` -------------------------------- ### Configure DashboardPage State and Logic Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md State management and filtering logic for device selection in the dashboard. ```jsx const [selectedDevice, setSelectedDevice] = useState(null); const { devices: accountDevices } = useAccountDevices({ from, to, timeZone, tzOffsetMinutes, accountView, accountAccessToken, accountRevision, }); // Device filter is meaningful only across 2+ devices in account view. const showDeviceFilter = accountView && accountDevices.length >= 2; // Reset the filter when leaving account view, or when the selected device // disappears (revoked / not in the latest list). useEffect(() => { if (!showDeviceFilter) { if (selectedDevice !== null) setSelectedDevice(null); return; } if (selectedDevice && !accountDevices.some((d) => d.id === selectedDevice)) { setSelectedDevice(null); } }, [showDeviceFilter, accountDevices, selectedDevice]); const deviceOptions = useMemo(() => { if (!showDeviceFilter) return []; return [ { value: "", label: copy("dashboard.device_filter.all") }, ...accountDevices.map((d) => ({ value: d.id, label: d.device_name || copy("dashboard.device_card.unnamed"), })), ]; }, [showDeviceFilter, accountDevices, resolvedLocale]); const deviceUsageBlock = showDeviceFilter ? ( setSelectedDevice(id || null)} /> ) : null; ``` -------------------------------- ### Diagnose Provider Issues Source: https://github.com/xiufengsun/tokentracker/blob/main/README.md Commands to check integration status and run health checks for providers. ```bash tokentracker status ``` ```bash tokentracker doctor ``` -------------------------------- ### Check TokenTracker Status Source: https://github.com/xiufengsun/tokentracker/wiki/Troubleshooting Verify if hooks are correctly configured for AI tools. ```bash tokentracker status ``` -------------------------------- ### Update TokenTracker via Homebrew Source: https://github.com/xiufengsun/tokentracker/wiki/FAQ Use these commands to upgrade the CLI or macOS application cask via Homebrew. ```bash brew upgrade mm7894215/tokentracker/tokentracker ``` -------------------------------- ### Configure OpenClaw plugin settings Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/openclaw-integration.md Manually update the OpenClaw configuration file to enable the plugin and allow conversation access. ```json { "plugins": { "entries": { "openclaw-session-sync": { "enabled": true, "hooks": { "allowConversationAccess": true } } } } } ``` -------------------------------- ### Run Diagnostics Source: https://github.com/xiufengsun/tokentracker/wiki/Troubleshooting Generate sanitized diagnostic information for troubleshooting issues in GitHub issues. ```bash tokentracker diagnostics ``` -------------------------------- ### Implement ES2022 Polyfills for WebKit Source: https://github.com/xiufengsun/tokentracker/blob/main/dashboard/share.html Provides compatibility for Object.hasOwn and Array.prototype.at in browsers older than Safari 15.4. Execute this before the main application bundle. ```javascript (function () { try { if (typeof Object.hasOwn !== "function") { Object.defineProperty(Object, "hasOwn", { value: function (o, k) { return Object.prototype.hasOwnProperty.call(o, k); }, configurable: true, writable: true, }); } function at(n) { n = Math.trunc(n) || 0; if (n < 0) n += this.length; return n < 0 || n >= this.length ? undefined : this[n]; } if (typeof Array.prototype.at !== "function") { Object.defineProperty(Array.prototype, "at", { value: at, configurable: true, writable: true }); } if (typeof String.prototype.at !== "function") { Object.defineProperty(String.prototype, "at", { value: at, configurable: true, writable: true }); } } catch (e) {} })(); ``` -------------------------------- ### Implement Device-Scoped Storage Key Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Logic for generating a storage key that includes the device scope. ```ts const deviceScope = deviceId || "all"; const storageKey = (() => { if (!cacheKey) return null; const host = safeHost(baseUrl) || "default"; const dailyKey = includeDaily ? "daily" : "summary"; const tzKey = getTimeZoneCacheKey({ timeZone, offsetMinutes: tzOffsetMinutes }); return `tokentracker.usage.${cacheKey}.${scopeKey}.${host}.${from}.${to}.${dailyKey}.${tzKey}.${deviceScope}`; })(); ``` -------------------------------- ### Define Dashboard Styles Source: https://github.com/xiufengsun/tokentracker/blob/main/dashboard/index.html Sets base background colors and handles transparency overrides for native webview environments. ```css /* Prevent dark flash: set background before CSS loads */ html { background: #fafafa; } html.dark { background: #0a0a0a; } /* Native app: must override the two lines above — otherwise WKWebView stays opaque over NSVisualEffectView */ html.native-app, html.native-app.dark { background: transparent !important; } html.native-app body { background: transparent !important; } .js .aeo-seed-content { display: none; } .aeo-seed-content { margin: 0; padding: 1.5rem; font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; line-height: 1.55; } .aeo-seed-content h1, .aeo-seed-content h2, .aeo-seed-content h3 { margin: 0.75rem 0; } ``` -------------------------------- ### Initialize ES2022 Polyfills and DOM State Source: https://github.com/xiufengsun/tokentracker/blob/main/dashboard/index.html Provides polyfills for Object.hasOwn and Array.prototype.at to ensure compatibility with WebKit versions older than 15.4. Also marks the document root to handle initial rendering states. ```javascript (function () { try { if (typeof Object.hasOwn !== "function") { Object.defineProperty(Object, "hasOwn", { value: function (o, k) { return Object.prototype.hasOwnProperty.call(o, k); }, configurable: true, writable: true, }); } function at(n) { n = Math.trunc(n) || 0; if (n < 0) n += this.length; return n < 0 || n >= this.length ? undefined : this[n]; } if (typeof Array.prototype.at !== "function") { Object.defineProperty(Array.prototype, "at", { value: at, configurable: true, writable: true }); } if (typeof String.prototype.at !== "function") { Object.defineProperty(String.prototype, "at", { value: at, configurable: true, writable: true }); } } catch (e) {} })(); document.documentElement.classList.add("js"); ``` -------------------------------- ### Commit implementation changes Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Git commands to stage and commit the new edge endpoint and test files. ```bash git add dashboard/edge-patches/tokentracker-account-devices.ts test/account-device-filter.test.js git commit -m "feat(edge): add account-devices endpoint (per-device usage totals)" ``` -------------------------------- ### Test UsageOverview device filtering Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Verifies that the device select dropdown appears when multiple devices are present and triggers the correct callback on selection. ```jsx import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { describe, expect, it, vi } from "vitest"; import { UsageOverview } from "./UsageOverview"; const baseProps = { period: "month", periods: ["day", "month"], onPeriodChange: () => {}, summaryValue: "0", summaryLabel: "Total", fleetData: [], from: "2026-06-01", to: "2026-06-30", }; describe("UsageOverview device dropdown", () => { it("renders the device select when 2+ devices and fires onDeviceChange", async () => { const onDeviceChange = vi.fn(); render( , ); const trigger = screen.getByLabelText("Filter by device"); expect(trigger).toBeTruthy(); await userEvent.click(trigger); await userEvent.click(await screen.findByText("Mac mini")); expect(onDeviceChange).toHaveBeenCalledWith("d2"); }); it("hides the device select with fewer than 2 devices", () => { render( {}} />, ); expect(screen.queryByLabelText("Filter by device")).toBeNull(); }); }); ``` -------------------------------- ### Commit Changes Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Command to stage and commit the updated edge patches and test file. ```bash git add dashboard/edge-patches/tokentracker-account-*.ts test/account-device-filter.test.js git commit -m "feat(edge): narrow account-* endpoints by optional device_id" ``` -------------------------------- ### Update TokenTracker CLI via npm Source: https://github.com/xiufengsun/tokentracker/wiki/FAQ Use this command to update the global npm package for the TokenTracker CLI. ```bash npm update -g tokentracker-cli ``` -------------------------------- ### Uninstall TokenTracker Source: https://github.com/xiufengsun/tokentracker/wiki/FAQ Removes all hooks and the local configuration directory. ```bash tokentracker uninstall ``` -------------------------------- ### Query OpenCode Go usage API Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/opencode-go-limits.md Use a Bearer token to authenticate requests to the official OpenCode Go usage endpoint. ```bash curl -sS https://opencode.ai/zen/go/v1/usage \ -H "Authorization: Bearer $OPENCODE_GO_API_KEY" ``` -------------------------------- ### Typecheck and commit changes Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Run the TypeScript compiler to verify types and commit the updated hook files. ```bash cd dashboard && npx tsc --noEmit && cd .. git add dashboard/src/hooks/use-usage-data.ts dashboard/src/hooks/use-usage-model-breakdown.ts dashboard/src/hooks/use-trend-data.ts dashboard/src/hooks/use-activity-heatmap.ts dashboard/src/hooks/use-usage-data.device.test.tsx git commit -m "feat(dashboard): forward deviceId through usage hooks + cache scoping" ``` -------------------------------- ### Commit changes Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Stage and commit the updated copy and translation files. ```bash git add dashboard/src/content/copy.csv dashboard/src/content/i18n/*/dashboard.json git commit -m "feat(dashboard): copy for device filter + per-device card" ``` -------------------------------- ### Native-to-Web Bridge Communication Source: https://github.com/xiufengsun/tokentracker/blob/main/CLAUDE.md Communication patterns between JavaScript and Swift via the native bridge. ```text JS → window.webkit.messageHandlers.nativeBridge.postMessage({ type, key?, value?, name? }) Swift → NativeBridge.shared.handle(message:) via WKScriptMessageHandler Swift → JS: webView.evaluateJavaScript("window.dispatchEvent(new CustomEvent('native:settings', { detail }))") React → useNativeSettings() subscribes ``` -------------------------------- ### Generate SCIP index Source: https://github.com/xiufengsun/tokentracker/blob/main/scripts/graph/README.md Executes the SCIP generation script, which uses tsconfig.scip.json for configuration. ```bash npm run graph:scip ``` -------------------------------- ### Commit Dashboard Changes Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Commands to validate types and commit the new DeviceUsageCard component. ```bash cd dashboard && npx tsc --noEmit && cd .. git add dashboard/src/ui/dashboard/components/DeviceUsageCard.jsx dashboard/src/ui/dashboard/components/DeviceUsageCard.test.jsx git commit -m "feat(dashboard): DeviceUsageCard component" ``` -------------------------------- ### Apply graph auto-index Source: https://github.com/xiufengsun/tokentracker/blob/main/scripts/graph/README.md Executes the auto-indexing process and applies the changes to generate index files. ```bash npm run graph:auto-index -- --apply ``` -------------------------------- ### Configure UsageOverview Props Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Passing device-related props to the UsageOverview component. ```jsx deviceOptions={deviceOptions} selectedDevice={selectedDevice} onDeviceChange={onDeviceChange} ``` -------------------------------- ### Test Account Device Endpoint Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Verifies the existence of the endpoint, JWT authentication, and required database fields. ```javascript test("account-devices endpoint exists, verifies JWT, queries devices, sums per-device", () => { const src = readEdge("tokentracker-account-devices.ts"); assert.ok(src.includes("verifiedUserIdFromJwt"), "missing JWT verification"); assert.ok( src.includes('.from("tokentracker_devices")'), "does not query tokentracker_devices", ); assert.ok(src.includes('"device_name"') || src.includes("device_name"), "no device_name field"); assert.ok(src.includes("account_usage_grouped"), "does not sum usage via the RPC"); assert.ok(src.includes("total_tokens"), "does not return per-device total_tokens"); }); test("account-devices is NOT in the pricing-parity mirror set (no MODEL_PRICING block)", () => { const src = readEdge("tokentracker-account-devices.ts"); assert.ok(!src.includes("const MODEL_PRICING"), "account-devices must not embed a pricing block"); }); ``` -------------------------------- ### Diagnose provider and tool status Source: https://github.com/xiufengsun/tokentracker/wiki/Troubleshooting Commands to inspect the health and state of detected providers and tools. ```bash tokentracker status # See per-tool state tokentracker doctor # Deeper health check tokentracker activate-if-needed # Re-run detection ``` -------------------------------- ### Implement useAccountDevices hook Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Custom React hook that fetches device usage data when in account view. Requires accountAccessToken and accountView flags to trigger data fetching. ```ts import { useCallback, useEffect, useState } from "react"; import { resolveAuthAccessToken } from "../lib/auth-token"; import { fetchAccountDevices } from "../lib/api"; /** * Lists the signed-in account's active devices with per-device usage totals * for [from, to]. Only fetches in account view (cross-device cloud reads); * outside it the dashboard is single-device and there is nothing to compare. */ export function useAccountDevices({ from, to, timeZone, tzOffsetMinutes, accountView = false, accountAccessToken = null, accountRevision = 0, }: any = {}) { const enabled = Boolean(accountView && accountAccessToken); const [devices, setDevices] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const refresh = useCallback(async () => { if (!enabled) { setDevices([]); setLoading(false); setError(null); return; } setLoading(true); setError(null); try { const token = await resolveAuthAccessToken(accountAccessToken); const res = await fetchAccountDevices({ from, to, timeZone, tzOffsetMinutes, accessToken: token }); setDevices(Array.isArray(res?.devices) ? res.devices : []); } catch (e: any) { setError(e?.message || String(e)); setDevices([]); } finally { setLoading(false); } }, [enabled, accountAccessToken, from, to, timeZone, tzOffsetMinutes, accountRevision]); useEffect(() => { refresh(); }, [refresh]); return { devices, loading, error, refresh }; } ``` -------------------------------- ### Inject Device ID into Usage Hooks Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Configuration object addition for account-scoped usage hooks. ```jsx deviceId: selectedDevice, ``` -------------------------------- ### Test DeviceUsageCard component Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Unit tests for verifying device rendering and selection interaction logic. ```jsx import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { describe, expect, it, vi } from "vitest"; import { DeviceUsageCard } from "./DeviceUsageCard"; const devices = [ { id: "d1", device_name: "MacBook Pro", platform: "darwin", total_tokens: 600 }, { id: "d2", device_name: "Mac mini", platform: "darwin", total_tokens: 400 }, ]; describe("DeviceUsageCard", () => { it("shows each device with its share of total tokens", () => { render( {}} />); expect(screen.getByText("MacBook Pro")).toBeTruthy(); expect(screen.getByText("60.0%")).toBeTruthy(); expect(screen.getByText("40.0%")).toBeTruthy(); }); it("selects a device on click and clears it when re-clicked", async () => { const onSelectDevice = vi.fn(); const { rerender } = render( , ); await userEvent.click(screen.getByText("MacBook Pro")); expect(onSelectDevice).toHaveBeenCalledWith("d1"); rerender(); await userEvent.click(screen.getByText("MacBook Pro")); expect(onSelectDevice).toHaveBeenLastCalledWith(""); }); }); ``` -------------------------------- ### Implement UsageOverview changes Source: https://github.com/xiufengsun/tokentracker/blob/main/docs/superpowers/plans/2026-06-25-per-device-usage-breakdown.md Code modifications required to integrate the Select component into UsageOverview. ```jsx import { Select } from "../../components/Select.jsx"; ``` ```jsx deviceOptions = [], selectedDevice = "", onDeviceChange, ``` ```jsx {deviceOptions.length > 1 ? (