This document codifies how to work with the OpenCode Token Meter codebase. It covers development, testing, and build requirements for both macOS and Windows.
To run the application directly from source:
# macOS/Windows
python App/webview_ui/main_tray.py --debugNote: The tray application will automatically start the background agent and stats worker as threads.
- Python: 3.9+
- Conda Environment: Recommended to use the
opencodeenvironment. - Dependencies:
pip install pyinstaller pywebview pystray pillow pyperclip- macOS specific:
pip install rumps pyobjc-framework-Cocoa - Windows specific:
pip install win10toast
- Agent: Monitors
~/.local/share/opencode/storage/message/(all platforms) for new JSON messages. - Stats Worker: Periodically aggregates database data for the tray display.
- Webview UI: Frontend built with HTML/CSS/JS (Tailwind, Chart.js, Lato font), communicating with Python via a
JsApibridge. - Database: Local SQLite database stored at:
- macOS:
~/Library/Application Support/OpenCode Token Meter/index.db - Windows:
%APPDATA%\OpenCode Token Meter\index.db
- macOS:
Before releasing, verify the following:
- Startup: App launches into the system tray/menubar.
- Webview: Selecting "Show Dashboard" opens the UI window.
- Data: Counters (In/Out/Cost) update correctly after message activity.
- Theme: Verify dark mode aesthetics and high-weight (900) typography for headers/charts.
- Export: Verify CSV/JSON export functionality from the Details page.
- Syntax Check:
python -m py_compile <path> - Formatting: Adhere to PEP 8. Headers and specific UI text use Lato with a font-weight of 900 for a premium look.
This repository uses a unified spec file (OpenCodeTokenMeter.spec) for all platforms.
- Build Commands:
- macOS:
./build.sh(produces.appand.dmg) - Windows:
.\build_windows.bat(produces.exe)
- macOS:
- Cleanup:
rm -rf build/ dist/
All logging in the agent codebase MUST use the logger functions from agent.logger:
from agent.logger import log_info, log_warn, log_error, log_debug
# Usage
log_info("Tag", "Message content")
log_warn("Tag", "Warning message")
log_error("Tag", "Error message")
log_debug("Tag", "Debug message") # Only when OPENCODE_DEBUG env var is set[ LEVEL ] 2026-03-15 10:30:00 - TAG Message content
- LEVEL: Fixed width 8 chars with brackets (INFO, WARN, ERROR, DEBUG)
- TAG: Fixed width 10 chars without brackets (e.g., "Agent", "Scanner", "Tray")
- Timestamp: ISO format (YYYY-MM-DD HH:MM:SS)
Agent- Main agent operationsScanner- File scanning operationsTray- System tray operationsIPC- Inter-process communicationDB- Database operationsStats- Statistics worker
- NEVER use
print()for logging in production code - Use descriptive tags to identify the component
- Keep messages concise but informative
- Use
log_error()for errors that need to be written toerror.log - Use
log_debug()only for development debugging (requiresOPENCODE_DEBUGenv var)
- SQL Safety: Always use parameterized queries (
?). Never use f-strings for SQL inputs. - Deduplication: Message counting must use the deduplication logic in
App/agent/agent/db.py. - Version Control: Follow Semantic Versioning. Update
CHANGELOG.mdfor every release.
The project uses a single VERSION file as the source of truth for version numbers. All components read from this file:
- Location:
VERSION(in project root) - Format: Plain text file containing only the version number (e.g.,
1.1.1)
-
Python Code:
App/webview_ui/__init__.py- Sets__version__App/webview_ui/backend/settings.py- SetsDEFAULT_SETTINGS["version"]
-
Build Scripts:
create_dmg.sh- Sets DMG filenameOpenCodeTokenMeter.spec- SetsCFBundleShortVersionString(macOS About dialog)
-
Documentation (Manual Update Required):
README.md- Update download linksREADME_CN.md- Update download links
When releasing a new version:
-
Update VERSION file:
echo "1.2.0" > VERSION
-
Update README files (manual):
- Update
OpenCodeTokenMeter-1.2.0.exein README.md - Update
OpenCodeTokenMeter-1.2.0.dmgin README.md - Update
OpenCodeTokenMeter-1.2.0.exein README_CN.md - Update
OpenCodeTokenMeter-1.2.0.dmgin README_CN.md
- Update
-
Update CHANGELOG.md:
- Add release notes for the new version
-
Build and Test:
./build.sh # macOS # or .\build_windows.bat # Windows
-
Commit Changes:
git add VERSION README.md README_CN.md CHANGELOG.md git commit -m "chore: bump version to 1.2.0"
All components have fallback versions in case the VERSION file is missing:
- Python: Falls back to
"1.1.1" - Shell scripts: Falls back to
"1.1.1" - PyInstaller spec: Falls back to
'1.1.1'
This ensures the build process won't fail if the VERSION file is accidentally deleted.