Skip to content

Release history

onWatch releases

Real-time API quota tracking across AI platforms

All releases

77 shown

v2.11.46 New feature
Notable features
  • Structured JSON logging available through --log-format=json or ONWATCH_LOG_FORMAT=json
Full changelog

What's New

Structured JSON logging (#70)

You can now switch log output from the default key=value text format to JSON via CLI flag or environment variable:

# CLI flag
onwatch --log-format json

# Environment variable
ONWATCH_LOG_FORMAT=json onwatch

JSON output uses Go's native slog.JSONHandler, producing machine-readable logs ideal for container logging pipelines (Fluentd, Loki, CloudWatch, etc.).

  • Accepts aliases: text, txt, fmt for text format; json for JSON
  • Case-insensitive input
  • Works in all modes: background, --debug, --debugstdout, and Docker
  • Defaults to text if unset or unrecognized

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.45...v2.11.46

v2.11.45 Bug fix
⚠ Upgrade required
  • After updating, re‑save each profile to restore correct tokens using `codex auth` followed by `onwatch codex profile refresh`.
Notable features
  • Auto-save settings in menubar apply changes immediately
  • Menubar fetches live data from main daemon, eliminating stale displays
  • Newly added providers appear automatically in the menubar
Full changelog

Bug Fix

Codex Team/Business workspace token cross-contamination (#69)

When multiple users from the same ChatGPT Team or Business workspace saved profiles, they shared the same account_id. The system credentials fallback only checked account_id match when picking up tokens from ~/.codex/auth.json - so one user's tokens would silently overwrite the other profile, causing both to poll with the same identity and show identical usage data.

The fallback now also checks user_id, rejecting system credentials that belong to a different user on the same workspace.

After updating, re-save your profiles to restore correct tokens:

# Log into first account
codex auth
onwatch codex profile refresh <profile1>

# Log into second account  
codex auth
onwatch codex profile refresh <profile2>

Menubar Improvements

  • Auto-save settings - changes apply immediately, no manual Save needed
  • Fixed menubar showing stale data - companion now fetches from the main daemon instead of building its own snapshot
  • New providers auto-visible - newly added providers appear in menubar without manual configuration

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.44...v2.11.45

v2.11.44 Maintenance

Routine maintenance release for onWatch.

Changelog

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.43...v2.11.44

v2.11.43 Bug fix

Fixed menubar to open the dashboard on the configured port rather than hardcoding port 9211.

Full changelog

What's Changed

  • fix(menubar): open dashboard on configured port, not hardcoded 9211 by @prakersh in https://github.com/onllm-dev/onWatch/pull/66

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.42...v2.11.43

v2.11.42 New feature
Notable features
  • Add Cursor provider support
Full changelog

What's Changed

  • Add Cursor provider support by @LeslieLeung in https://github.com/onllm-dev/onWatch/pull/59

New Contributors

  • @LeslieLeung made their first contribution in https://github.com/onllm-dev/onWatch/pull/59

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.41...v2.11.42

v2.11.41 Maintenance

Routine maintenance release for onWatch.

Changelog

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.40...v2.11.41

v2.11.40 New feature
Notable features
  • Custom API Integrations
Full changelog

What's Changed

  • Feat: Custom API Integrations by @sgogriff in https://github.com/onllm-dev/onWatch/pull/52

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.39...v2.11.40

v2.11.39 Maintenance

Routine maintenance release for onWatch.

Changelog

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.38...v2.11.39

v2.11.38 Maintenance

Routine maintenance release for onWatch.

Changelog

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.37...v2.11.38

v2.11.37 Maintenance

Routine maintenance release for onWatch.

Changelog

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.36...v2.11.37

v2.11.36 Maintenance

Routine maintenance release for onWatch.

Changelog

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.35...v2.11.36

v2.11.35 Bug fix
Notable features
  • Multi‑Account Support with full isolation and per‑account usage/history view in the dashboard
  • Status bar API source badges now show timestamps for last quota update
Full changelog

v2.11.35 - MiniMax Multi-Account Support

Track multiple MiniMax accounts with full isolation. Switch accounts in the dashboard to view per-account usage and history.

Bug Fix - Fixed cycle overview showing blank data on shared MiniMax plans. Usage history now always displays correctly.

Improved Status Bar - API source badges now show timestamps for last quota update.

v2.11.34 New feature
Notable features
  • Configurable quota display mode: toggle between usage (%) and available (%) for five_hour and seven_day quotas via `CODEX_SHOW_AVAILABLE` env var or Settings UI
  • Consolidated Codex provider card in Settings now lists all sub-profiles with individual telemetry/dashboard toggles
  • Beta Profile Management UI enables credential refresh and profile deletion directly from the Settings modal
Full changelog

Codex Display Mode Toggle

Toggle how you view Codex quotas - switch between "Usage" (utilization %) and "Available" (remaining %) for five_hour and seven_day quotas.

Configure via:

  • Environment: CODEX_SHOW_AVAILABLE=true (or false for usage mode, which is default)
  • Settings UI: Settings → Providers → Configure Codex → Quota Display

Consolidated Codex Settings Card

The Codex provider card in Settings now shows ONE entry with all sub-profiles listed below it. Each sub-profile retains its own telemetry/dashboard toggles for granular control.

Profile Management UI (Beta)

Manage Codex profiles directly from the Settings modal - refresh credentials or delete profiles without needing the CLI.

Bug Fixes

  • Added display_mode value validation (only accepts "usage" or "available")
  • CSS styling improvements for the consolidated Codex provider section
  • All tests pass with race detection
v2.11.33 Maintenance

Routine maintenance release for onWatch.

Changelog

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.32...v2.11.33

v2.11.32 New feature
Notable features
  • Use PDF vector icon for crisp menubar rendering
  • Add OpenRouter provider for credit/usage monitoring
Full changelog

What's Changed

  • feat: use PDF vector icon for crisp menubar rendering by @jinquan-shi in https://github.com/onllm-dev/onWatch/pull/43
  • fix: add explicit expiry to login session cookie by @goldmar in https://github.com/onllm-dev/onWatch/pull/47
  • Fix: Copilot quota tracking for free/limited plans by @sgogriff in https://github.com/onllm-dev/onWatch/pull/45
  • feat: add OpenRouter provider for credit/usage monitoring by @omnissiah-comelse in https://github.com/onllm-dev/onWatch/pull/44
  • fix: OpenRouter frontend + MiniMax zero-quota filter by @prakersh in https://github.com/onllm-dev/onWatch/pull/48

New Contributors

  • @goldmar made their first contribution in https://github.com/onllm-dev/onWatch/pull/47
  • @sgogriff made their first contribution in https://github.com/onllm-dev/onWatch/pull/45
  • @omnissiah-comelse made their first contribution in https://github.com/onllm-dev/onWatch/pull/44

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.31...v2.11.32

v2.11.31 New feature
Notable features
  • Added MiniMax endpoint support for CN region
  • Added ZHIPU (Z.ai) endpoint support for CN region
Full changelog

What's Changed

  • feat: add MiniMax & ZHIPU(Z.ai) CN region endpoint support by @jinquan-shi in https://github.com/onllm-dev/onWatch/pull/41

New Contributors

  • @jinquan-shi made their first contribution in https://github.com/onllm-dev/onWatch/pull/41

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.30...v2.11.31

v2.11.30 Maintenance

Routine maintenance release for onWatch.

Changelog

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.29...v2.11.30

v2.11.29 Maintenance

Routine maintenance release for onWatch.

Changelog

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.28...v2.11.29

v2.11.28 Maintenance

Routine maintenance release for onWatch.

Changelog

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.27...v2.11.28

v2.11.27 Maintenance

Routine maintenance release for onWatch.

Changelog

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.26...v2.11.27

v2.11.26 Maintenance

Routine maintenance release for onWatch.

Changelog

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.25...v2.11.26

v2.11.25 Maintenance

Routine maintenance release for onWatch.

Changelog

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.24...v2.11.25

v2.11.24 Maintenance

Routine maintenance release for onWatch.

Changelog

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.23...v2.11.24

v2.11.23 New feature
Notable features
  • Countdown timer on promo tags in dashboard and menubar displays time until next peak/off‑peak transition
  • Timer updates every 30 seconds purely client‑side with no API calls
  • Menubar promo now receives the promo end date for accurate countdown capping
Full changelog

What's New

Features

  • Countdown timer on promo tags in both dashboard and menubar - shows time remaining until the next peak/off-peak transition (e.g. "2x limits till 14h 20m", "Peak hours till 1h 45m")
  • Countdown updates every 30 seconds purely client-side with no API calls required
  • Menubar promo now receives the promo end date for accurate countdown capping

Bug Fixes

  • Fixed flaky CI test timeout in SetNotifier agent test by increasing wait deadlines for race-detected builds

Other

  • Updated all dashboard and menubar screenshots with the new promo countdown tags

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.22...v2.11.23

v2.11.22 Bug fix

Menubar promo tag now dynamically reflects peak/off-peak status in real time.

Full changelog

What's New

Bug Fixes

  • Menubar promo tag now dynamically shows peak/off-peak status based on current ET time without requiring a data refresh

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.21...v2.11.22

v2.11.21 New feature
Notable features
  • Anthropic March 2026 off‑peak 2x usage limits shown in dashboard quota cards and menubar provider header
  • Dashboard toggles between "2x limits" during off‑peak hours and "Standard limits" during peak (8 AM–2 PM ET weekdays)
  • Clickable promo tags link to the Claude help center article
Full changelog

What's New

Features

  • Anthropic March 2026 off-peak 2x usage limits display in dashboard quota cards and menubar provider header
  • Shows "2x limits" during off-peak hours and "Standard limits" during peak hours (8 AM - 2 PM ET weekdays)
  • Clickable promo tags link to the Claude help center article

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.20...v2.11.21

v2.11.20 Maintenance

Minor fixes and improvements.

Full changelog

What's Changed

  • fix(ci): switch macOS amd64 release runner to macos-14 by @prakersh in https://github.com/onllm-dev/onWatch/pull/29

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.19...v2.11.20

v2.11.19 Bug fix
Notable features
  • macOS menubar with three preset views
Full changelog

What's Changed

  • fix: Docker container fails to start with misleading OOM error by @kapdon in https://github.com/onllm-dev/onWatch/pull/22
  • fix: fail fast on unwritable Docker DB path by @prakersh in https://github.com/onllm-dev/onWatch/pull/28
  • feat: Add macOS menubar with three preset views by @prakersh in https://github.com/onllm-dev/onWatch/pull/25

New Contributors

  • @kapdon made their first contribution in https://github.com/onllm-dev/onWatch/pull/22

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.18...v2.11.19

v2.11.18 Bug fix

Stabilized SMTP email notification setup with automatic migration of legacy credential formats.

Full changelog

What's New

Bug Fixes

  • Stabilized SMTP email notification setup with automatic migration of legacy credential formats
  • Updated README badges and documentation

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.17...v2.11.18

v2.11.17 Maintenance

Minor fixes and improvements.

Full changelog

What's Changed

  • test: achieve 90%+ code coverage for awesome-go eligibility by @prakersh in https://github.com/onllm-dev/onWatch/pull/24

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.16...v2.11.17

v2.11.16 Bug fix
Notable features
  • Added MiniMax to the landing page provider showcase
  • Added Antigravity support to the summary endpoint
Full changelog

What's New

Features

  • Added MiniMax to the landing page provider showcase
  • Added Antigravity support to the summary endpoint

Bug Fixes

  • Fixed cross-provider data leakage in the synthetic summary endpoint
  • Fixed initial modal card render state not being populated
  • Summary endpoint now returns 400 for unknown providers instead of silently failing
  • Updated provider layout and documentation for all seven providers

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.15...v2.11.16

v2.11.15 New feature
Notable features
  • MiniMax provider integration
  • Dynamic provider control
Full changelog

What's Changed

  • feat: MiniMax provider integration + dynamic provider control by @prakersh in https://github.com/onllm-dev/onWatch/pull/21

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.14...v2.11.15

v2.11.14 Breaking risk
Breaking changes
  • Configuration file loading changed from the current directory to ~/.onwatch/.env.
Full changelog

What's New

Bug Fixes

  • Config now loads from ~/.onwatch/.env instead of the current directory, preventing config-not-found issues when running from different paths

Other

  • Added multi-account Codex feature highlight to landing page

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.13...v2.11.14

v2.11.13 Breaking risk
Notable features
  • Redesigned "All Providers" page with provider-centric cards
  • Per-account Codex settings toggles for multi-account configurations
  • Improved layout density across dashboard views
Full changelog

What's New

Features

  • Redesigned "All Providers" page with provider-centric cards
  • Per-account Codex settings toggles for multi-account configurations
  • Improved layout density across dashboard views

Bug Fixes

  • Fixed free-plan quota normalization display
  • Scoped Codex cycle overview to the selected account
  • Unified chart gap visualization with poll-aware thresholds
  • Fixed dynamic provider card height - removed fixed chart space allocation
  • Corrected layout density logic and centered insight cards
  • Replaced em-dashes with hyphens and respected telemetry settings on All page

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.12...v2.11.13

v2.11.12 New feature
Notable features
  • Multi‑account Codex support (Beta) – track multiple Codex accounts with account‑tagged data and parallel polling
Full changelog

What's New

Features

  • Multi-account Codex support (Beta) - track multiple Codex accounts and sessions simultaneously with account-tagged data and parallel polling

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.11...v2.11.12

v2.11.11 New feature
Notable features
  • Automatic bypass of Anthropic usage API rate limits via OAuth token refresh on 429 responses
  • OAuth refresh tokens rotated per spec for added security
Full changelog

What's New

Features

  • Automatic bypass of Anthropic's usage API rate limits via OAuth token refresh - when a 429 is encountered, onWatch refreshes the OAuth token for a fresh rate limit window and retries automatically
  • Refresh tokens are rotated per OAuth spec for security

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.10...v2.11.11

v2.11.10 Bug fix

Fixed grid layout adaptation and improved chart gap visualization.

Full changelog

What's New

Bug Fixes

  • Grid layouts now dynamically adapt to available providers instead of using hardcoded positions
  • Improved chart gap visualization using poll-interval-based thresholds instead of hardcoded values

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.9...v2.11.10

v2.11.9 New feature
Notable features
  • Default poll interval increased to 120 seconds for better rate limit management
  • Added Codecov coverage reporting to CI
Full changelog

What's New

Features

  • Increased default poll interval to 120 seconds for better rate limit management
  • Added Codecov coverage reporting to CI

Bug Fixes

  • Replaced flaky subprocess tests with in-process tests for improved CI reliability

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.8...v2.11.9

v2.11.8 Breaking risk

Fixed Windows process detection for Antigravity language server and corrected dashboard label display when no data is available.

Full changelog

What's New

Bug Fixes

  • Windows Antigravity detection: Fixed process detection on Windows by using Get-CimInstance (modern PowerShell) instead of deprecated wmic. Now correctly finds the language_server_windows_x64.exe binary, which runs as a separate process from the main Antigravity.exe Electron app.
  • Dashboard chart labels: Fixed Antigravity dashboard showing incorrect "Subscription/Search/Tool Calls" labels (Synthetic provider defaults) when no data is available yet.
  • Test stability: Fixed intermittent subprocess test failures under heavy parallel load.

Technical Details

  • The Antigravity language server on Windows runs as language_server_windows_x64.exe with --csrf_token and --extension_server_port arguments, not as Antigravity.exe. The detection pipeline now searches all processes by command line content and uses scoring to select the best candidate (language server scores highest due to CSRF token and LSP indicators).
v2.11.7 Bug fix

Fixed tilde expansion in file paths.

Full changelog

What's New

Bug Fixes

  • Proper handling of Anthropic 429 rate limiting with backoff
  • Fixed tilde (~) expansion in file paths
  • Improved daemon startup diagnostics

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.6...v2.11.7

v2.11.6 New feature
Notable features
  • Updated Go module path to v2 for compliance with the Go proxy, enabling `go install` support.
  • Added Homebrew installation option on the landing page.
Full changelog

What's New

Features

  • Updated Go module path to v2 for Go proxy compliance - enables go install support
  • Added Homebrew install option to landing page

Other

  • Applied gofmt formatting for Go Report Card A+ rating

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.5...v2.11.6

v2.11.5 New feature
Notable features
  • Homebrew tap support via `brew install onllm-dev/tap/onwatch`
  • Guided first-time configuration with `onwatch setup` command
  • CONTRIBUTING.md added for community contributors
Full changelog

What's New

Features

  • Homebrew tap support - install with brew install onllm-dev/tap/onwatch
  • New onwatch setup command for guided first-time configuration
  • Added CONTRIBUTING.md for community contributors

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.4...v2.11.5

v2.11.4 Breaking risk
⚠ Upgrade required
  • Removed hard 500‑record cap; logging history API scales up to 50,000 records per range
  • Windows Defender false‑positive handling guidance added in documentation
Breaking changes
  • 'Cycle Overview' → 'Session History'
Notable features
  • Logging history added for Synthetic, Z.ai, Anthropic, Copilot, and Codex dashboards
  • Dynamic time‑range filters (1h/3d/7d/15d/30d) now return correct data amounts without the previous ~3.3 hour cap
  • QueryRange now returns most recent records instead of oldest
Full changelog

What's New

  • Logging history for all providers — Session history now available for Synthetic, Z.ai, Anthropic, Copilot, and Codex dashboards
  • Dynamic range support — 1h/3d/7d/15d/30d time range filters now return the correct amount of data (previously capped at ~3.3 hours)
  • QueryRange fix — Historical queries now return most recent records instead of oldest
  • Windows Defender guidance — Added docs for handling false positive detections on Windows

Fixes

  • Logging history API now accepts range parameter and calculates appropriate limits per time window
  • Removed hard 500-record cap for logging history — ranges scale up to 50,000 records as needed
  • "Cycle Overview" renamed to "Session History" in dashboard

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.2...v2.11.4

v2.11.2 Bug fix
Notable features
  • PowerShell installer for Windows setup
  • Windows installation guide
Full changelog

What's New

Features

  • Windows support with PowerShell installer for easy setup
  • Windows installation guide

Bug Fixes

  • Fixed .env file encoding issue (UTF-8 BOM) on Windows
  • Handle Windows Firewall prompt during first startup

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.1...v2.11.2

v2.11.1 Bug fix
Notable features
  • Added Antigravity provider to the landing page with chart data and usage legend
  • Updated Antigravity model names to GPT OSS
Full changelog

What's New

Features

  • Added Antigravity provider to the landing page with chart data and usage legend

Bug Fixes

  • Fixed chart data ordering to display oldest-to-newest
  • Updated Antigravity model names to GPT OSS

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.11.0...v2.11.1

v2.11.0 New feature
Notable features
  • Antigravity provider added with logging history support
Full changelog

What's Changed

  • feat(antigravity): add Antigravity provider with logging history support by @prakersh in https://github.com/onllm-dev/onWatch/pull/12

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.10.4...v2.11.0

v2.10.4 New feature
Notable features
  • Added Codex OAuth provider support
Full changelog

What's Changed

  • feat(codex): add Codex OAuth provider support by @iota31 in https://github.com/onllm-dev/onWatch/pull/9
  • release: v2.10.4 codex fixes and screenshot refresh by @iota31 in https://github.com/onllm-dev/onWatch/pull/11

New Contributors

  • @iota31 made their first contribution in https://github.com/onllm-dev/onWatch/pull/9

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.10.1...v2.10.4

v2.10.3 New feature
Notable features
  • Codex OAuth provider support - track Codex usage quotas with OAuth-based authentication
Full changelog

What's New

Features

  • Codex OAuth provider support - track Codex usage quotas with OAuth-based authentication

Full Changelog: https://github.com/onllm-dev/onWatch/compare/v2.10.1...v2.10.3

v2.10.1 Bug fix
⚠ Upgrade required
  • For older versions, add `--debug` to the container command or set environment variable `DOCKER_CONTAINER=1` as a workaround.
Full changelog

Bug Fixes

  • Kubernetes container detectionIsDockerEnvironment() now also detects Kubernetes environments by checking for KUBERNETES_SERVICE_HOST env var and /var/run/secrets/kubernetes.io/serviceaccount mount. This fixes the "permission denied" error when running in k8s clusters where containerd/CRI-O don't create /.dockerenv like Docker does. (#7)

Download

| Platform | Architecture | Binary |
|----------|-------------|--------|
| macOS | Apple Silicon (M1/M2/M3) | onwatch-darwin-arm64 |
| macOS | Intel | onwatch-darwin-amd64 |
| Linux | x86_64 | onwatch-linux-amd64 |
| Linux | ARM64 | onwatch-linux-arm64 |
| Windows | x86_64 | onwatch-windows-amd64.exe |

Docker

docker pull ghcr.io/onllm-dev/onwatch:v2.10.1

Workaround (for users on older versions)

If you can't upgrade immediately, add --debug to your container command or set DOCKER_CONTAINER=1 in your pod's environment variables.

v2.10.0 Breaking risk
⚠ Upgrade required
  • Add COPILOT_TOKEN environment variable with a GitHub PAT that includes the `copilot` scope to enable the provider.
Notable features
  • Beta support for GitHub Copilot provider
  • Premium Requests quota monitoring (300‑1500 per plan)
  • Unlimited quotas displayed with ∞ badges
Full changelog

What's New

🚀 GitHub Copilot Provider (Beta)

onWatch now supports GitHub Copilot as a 4th provider! Track your Premium Requests, Chat, and Completions quotas alongside Synthetic, Z.ai, and Anthropic.

Features

  • Premium Requests Tracking — Monitor your monthly premium model request quota (300-1500 depending on plan)
  • Unlimited Quotas — Chat and Completions show ∞ badges for unlimited quotas
  • Monthly Reset Detection — Automatic cycle tracking based on quota_reset_date_utc
  • Purple Accent Colors — GitHub Copilot branding in dashboard UI
  • Beta Badge — Clear indication that this feature uses an undocumented API

Configuration

Add your GitHub Personal Access Token (classic) with the copilot scope to .env:

COPILOT_TOKEN=ghp_your_token_here

Generate a token at github.com/settings/tokens with the copilot scope.

Technical Details

  • Uses GitHub's internal API: GET https://api.github.com/copilot_internal/user
  • Authorization: Bearer token (GitHub PAT with copilot scope)
  • Full TDD implementation with comprehensive test coverage
  • Follows same architecture as other providers

Other Changes

  • Updated all provider screenshots
  • Added Copilot section to landing page
  • Updated documentation across all files

⚠️ Important Note

GitHub Copilot tracking uses an undocumented internal API. While it works today, GitHub may change or disable this API without notice. This feature is marked as Beta accordingly.


Full Changelog: https://github.com/onllm-dev/onwatch/compare/v2.9.0...v2.10.0

v2.9.0 New feature
Security fixes
  • Moved inline theme script to external file for CSP compliance
Notable features
  • Delta Display in Tables: quota columns show change between polling cycles
  • Enhanced Polling History: quotas displayed in column format matching Cycle Overview
  • Improved Cycle Overview: active cycles included with better sorting and styling
Full changelog

What's New in v2.9.0

Features

  • Delta Display in Tables: All quota columns in Cycle Overview and Polling History now show delta values, making it easier to track usage changes between polling cycles
  • Enhanced Polling History: Polling History table now displays all quotas in columns, matching the Cycle Overview layout for consistency
  • Improved Cycle Overview: Active cycles are now included in the overview with improved sorting and visual styling

Fixes

  • Session Tracking: Fixed quota order for Anthropic session tracking to ensure consistent display
  • Security: Moved inline theme script to external file for CSP compliance
  • Tracker: Fixed cycle detection to use hour precision for Synthetic provider and exclude reset snapshots from peak calculations

Changes

  • Updated all dashboard screenshots for documentation
  • Version bump to 2.9.0

Assets

| Platform | Binary |
|----------|--------|
| macOS ARM64 | onwatch-darwin-arm64 |
| macOS AMD64 | onwatch-darwin-amd64 |
| Linux AMD64 | onwatch-linux-amd64 |
| Linux ARM64 | onwatch-linux-arm64 |
| Windows AMD64 | onwatch-windows-amd64.exe |

Installation

curl -fsSL https://raw.githubusercontent.com/onllm-dev/onwatch/main/install.sh | bash

Or download the binary for your platform from the assets below.

v2.8.1 Security relevant
Security fixes
  • fix(security): Moved inline theme script to external file for CSP compliance
Notable features
  • Active cycles now appear at top of cycle overview with no end time
  • Improved table sort styling with visual indicators
Full changelog

What's Changed

Bug Fixes

  • fix(security): Move inline theme script to external file for CSP compliance
  • fix(session): Use fixed quota order for Anthropic session tracking
    • Ensures 5-Hour, Weekly, and Sonnet columns display correct data
  • fix(tracker): Exclude reset snapshot from peak to match cross-quota query
  • fix(tracker): Use hour precision for Synthetic cycle detection
    • Prevents false cycle creation from minute-level API jitter

Features

  • feat(cycle-overview): Include active cycles in cycle overview
    • Active cycles now appear at top with no end time
  • feat(ui): Improved table sort styling with visual indicators

Installation

Download the binary for your platform and run:

chmod +x onwatch-*
./onwatch-darwin-arm64  # or your platform binary

Or update an existing installation:

./onwatch update
v2.7.0 New feature
⚠ Upgrade required
  • Run the new binary or `onwatch update` then restart; the push_subscriptions table is created automatically.
  • In Settings → Notifications enable "Push Notifications" and grant browser permission when prompted.
  • Use the "Send Test Push" button to verify delivery.
Notable features
  • Progressive Web App with standalone install, manifest.json, SW.js for push handling
  • Browser push notifications via VAPID (RFC 8291/8292) without external services
  • SMTP email alerts now documented and include per‑quota threshold overrides
Full changelog

Downloads

| Platform | Binary | Size |
|----------|--------|------|
| macOS (Apple Silicon) | onwatch-darwin-arm64 | 13 MB |
| macOS (Intel) | onwatch-darwin-amd64 | 14 MB |
| Linux (AMD64) | onwatch-linux-amd64 | 13 MB |
| Linux (ARM64) | onwatch-linux-arm64 | 13 MB |
| Windows (AMD64) | onwatch-windows-amd64.exe | 14 MB |

One-line install (macOS/Linux):

curl -fsSL https://raw.githubusercontent.com/onllm-dev/onwatch/main/install.sh | bash

Or upgrade an existing installation:

onwatch update

What's New in v2.7.0

PWA Support with Push Notifications (Beta)

onWatch is now a Progressive Web App — install it from your browser for a native app experience on desktop and mobile.

  • Browser push notifications — Get system notifications when quotas cross warning or critical thresholds, or when quotas reset. No external push services required.
  • Web Push protocol (VAPID) — Full RFC 8291 (content encryption) and RFC 8292 (VAPID JWT) implementation using only stdlib + existing golang.org/x/crypto. Zero new Go dependencies.
  • VAPID keys auto-generated — ECDSA P-256 key pair created on first run and stored in the database. No configuration needed.
  • Delivery channels — Choose email, push, or both in Settings → Notifications → Delivery Channels. Each channel can be toggled independently.
  • Service worker — Minimal push-only service worker (no offline caching). Served from root /sw.js for full scope.
  • PWA manifestmanifest.json with standalone display mode, teal theme color, and SVG icon. Browser shows "Install app" option.
  • Test push button — Send a test push notification from the settings page (30s rate limit, same pattern as SMTP test).

SMTP Email Alerts (Stable)

The notification system from v2.6.0 is now fully documented across all user-facing pages:

  • Per-quota threshold overrides — Set custom warning/critical thresholds for individual quotas
  • SMTP password encryption — AES-256-GCM encryption at rest, key derived from admin password
  • Three alert types — Warning (configurable %), Critical (configurable %), and Reset notifications

Notification Deduplication Fix

  • Once per cycle per event — Notifications are now sent exactly once per reset cycle per quota+type (warning, critical, reset). Previously, the cooldown-based approach could re-send alerts every 30 minutes while a quota remained above threshold.
  • Automatic log clearing — Notification log entries are cleared when a quota resets, allowing fresh alerts in the new cycle.

Windows Cross-Compilation Fix

  • Added missing detectAnthropicCredentialsPlatform() and WriteAnthropicCredentials() to anthropic_token_windows.go — fixes the Windows build that broke after the OAuth token refresh feature in v2.6.0.

Backend Changes

| Component | Change |
|-----------|--------|
| internal/notify/push.go | New — Web Push sender: VAPID key generation, RFC 8291 content encryption, RFC 8292 JWT signing, HTTP delivery |
| internal/notify/push_test.go | New — Tests for VAPID generation, encryption round-trip, JWT signing, send with httptest |
| internal/web/static/sw.js | New — Service worker for push event handling and notification click |
| internal/web/static/manifest.json | New — PWA manifest with standalone display mode |
| internal/notify/notify.go | Extended — Dual-channel dispatch (email + push), channel config, once-per-cycle dedup |
| internal/store/store.go | Extended — push_subscriptions table, CRUD methods, ClearNotificationLog() |
| internal/web/handlers.go | Extended — Push API endpoints, extended Notifier interface |
| internal/web/server.go | Extended — Routes for /sw.js, /manifest.json, push API; CSP worker-src 'self' |
| internal/web/middleware.go | Updated — isStaticAsset() includes /sw.js and /manifest.json |
| internal/web/templates/layout.html | Updated — <link rel="manifest"> and <meta name="theme-color"> |
| internal/web/templates/settings.html | Extended — Delivery Channels section with email/push toggles |
| internal/web/static/app.js | Extended — SW registration, push subscription management, channel settings |
| internal/api/anthropic_token_windows.go | Fixed — Added missing OAuth credential detection and write stubs |
| main.go | Updated — notifier.ConfigurePush() call on startup |


Push Notification API Endpoints

| Endpoint | Method | Description |
|----------|--------|-------------|
| /api/push/vapid | GET | Returns VAPID public key for push subscription |
| /api/push/subscribe | POST | Subscribe a push endpoint |
| /api/push/subscribe | DELETE | Unsubscribe a push endpoint |
| /api/push/test | POST | Send test push notification (30s rate limit) |


Performance

No measurable impact on RAM. Push components add < 1 KB steady-state memory:

| Component | Cost |
|-----------|------|
| VAPID key pair in memory | ~200 bytes |
| Push subscriptions (1-3 devices) | ~500 bytes |
| sw.js + manifest.json (embed.FS) | ~1 KB (already in binary) |
| HTTP POST per push send | ~2 KB temp buffer |

Idle RSS remains ~28 MB with all three providers polling.


Dependency Impact

Zero new Go dependencies. Web Push uses:

  • crypto/ecdsa, crypto/ecdh, crypto/elliptic (stdlib)
  • crypto/aes, crypto/cipher (stdlib)
  • golang.org/x/crypto/hkdf (already a dependency)
  • encoding/base64, net/http (stdlib)

Upgrade Guide

  1. Download the binary for your platform or run onwatch update
  2. Restart onWatch — the push_subscriptions table is created automatically
  3. Open Settings → Notifications → Delivery Channels
  4. Enable "Push Notifications" and allow browser permission when prompted
  5. Click "Send Test Push" to verify

VAPID keys are generated automatically on first startup. No manual configuration required.


Full Changelog

Since v2.5.1:

  • feat: PWA support with push notifications (Beta) and SMTP email alerts
  • feat(anthropic): OAuth token refresh and auth failure rate limiting
  • feat(docker): Docker support with distroless base image
  • feat(settings): Provider-grouped overrides, dual toggles, polling control
  • refactor: Restructure project layout with docs/, tests/, app.sh entry point
  • refactor(insights): Remove duplicate Avg Window Usage cards, add sublabel to stats
  • ux(insights): Improve analyzing state for insufficient data
  • test: Comprehensive E2E and integration testing suite
  • docs: Update dashboard screenshots, fix capture tool for missing providers
  • fix: Windows cross-compilation for Anthropic OAuth stubs
  • fix: Notification dedup — once per cycle per event instead of cooldown-based
v2.5.1 Breaking risk
Security fixes
  • Replaced SHA-256 password hashing with bcrypt — critical upgrade to mitigate brute-force attacks
Notable features
  • Added comprehensive HTTP security headers (CSP, X-Frame-Options, etc.)
  • Enhanced session cookie security with Secure and SameSite=Strict flags
Full changelog

onWatch v2.5.1 — Security & Stability Release

This release includes comprehensive security improvements and infrastructure enhancements to make onWatch production-ready.


🔒 Security Enhancements

Password Security Upgrade

  • Migrated from SHA-256 to bcrypt for password hashing
  • bcrypt provides superior protection against brute-force attacks with adaptive cost factor
  • Backward compatible — existing SHA-256 password hashes continue to work
  • Automatic migration to bcrypt on next login

HTTP Security Headers

Added comprehensive security headers to all responses:

  • X-Content-Type-Options: nosniff — Prevents MIME type sniffing
  • X-Frame-Options: DENY — Blocks clickjacking attempts
  • X-XSS-Protection: 1; mode=block — Legacy XSS protection
  • Referrer-Policy: strict-origin-when-cross-origin — Controls referrer information
  • Content-Security-Policy — Comprehensive CSP restricting resources to trusted domains

Session Cookie Security

  • Secure flag — Cookies only transmitted over HTTPS (auto-detected)
  • SameSite=Strict — Protection against CSRF attacks
  • HttpOnly — Prevents JavaScript access to session tokens

Rate Limiting Framework

  • IP-based rate limiting with configurable windows
  • Returns 429 Too Many Requests with Retry-After header
  • Support for X-Forwarded-For headers (proxy-friendly)

IP Whitelist Middleware

  • CIDR notation support for network ranges
  • Single IP support
  • Comprehensive logging of blocked attempts

📊 Backend Changes

| Component | Change | Impact |
|-----------|--------|--------|
| Password Hashing | SHA-256 → bcrypt | Critical security improvement |
| Session Cookies | Added Secure, SameSite=Strict | High security improvement |
| HTTP Headers | 5 new security headers | Medium security improvement |
| Rate Limiting | New framework | Infrastructure for DoS protection |
| IP Whitelist | New middleware | Infrastructure for access control |


🎯 Performance

  • Binary size: ~13 MB (macOS/Linux), ~14 MB (Windows)
  • RAM usage: Unchanged (~28 MB idle with all providers)
  • Startup time: Unchanged (<100ms)
  • All existing functionality: Preserved and tested

🔄 Upgrade Guide

Automatic Update (Recommended)

onwatch update

Manual Update

  1. Download the appropriate binary for your platform below
  2. Replace your existing onwatch binary
  3. Restart: onwatch stop && onwatch

No Configuration Changes Required

  • All settings and data are preserved
  • Database schema unchanged
  • Environment variables unchanged

📥 Downloads

| Platform | Architecture | Size | Download |
|----------|-------------|------|----------|
| macOS | Apple Silicon (ARM64) | 13 MB | onwatch-darwin-arm64 |
| macOS | Intel (AMD64) | 13 MB | onwatch-darwin-amd64 |
| Linux | AMD64 | 13 MB | onwatch-linux-amd64 |
| Linux | ARM64 | 13 MB | onwatch-linux-arm64 |
| Windows | AMD64 | 14 MB | onwatch-windows-amd64.exe |

One-line install:

curl -fsSL https://raw.githubusercontent.com/onllm-dev/onwatch/main/install.sh | bash

🧪 Testing

  • All tests pass: 8 packages, 100+ test cases
  • Race detector: Verified (no race conditions)
  • End-to-end testing: Login, dashboard, settings, password change
  • Cross-platform: Verified on macOS, Linux, Windows
  • Backward compatibility: Legacy password hashes work

🛡️ Security Considerations for Production

While this release significantly improves security, please note:

  1. HTTPS Required: The Secure cookie flag requires HTTPS in production
  2. Reverse Proxy Recommended: Use nginx, Caddy, or Traefik with HTTPS
  3. Strong Passwords: bcrypt protects weak passwords, but use strong ones
  4. IP Whitelist: Consider enabling for public deployments
  5. Rate Limiting: Enable if exposing to public networks

See SECURITY.md for detailed deployment guidance.


📝 Full Changelog

Added:

  • bcrypt password hashing with automatic migration
  • 5 security headers (CSP, X-Frame-Options, etc.)
  • Secure and SameSite=Strict cookie flags
  • Rate limiting framework
  • IP whitelist middleware
  • Beta tag on Settings page
  • Beta banner on landing page

Changed:

  • Password hashing algorithm (SHA-256 → bcrypt)
  • Cookie security flags enhanced
  • README updated with beta notice

Deprecated:

  • SHA-256 password hashes (still supported for backward compatibility)

Fixed:

  • None (this is a security enhancement release)

Security:

  • Critical: Replaced weak SHA-256 password hashing with bcrypt
  • High: Added comprehensive HTTP security headers
  • High: Enhanced session cookie security
  • Medium: Added rate limiting infrastructure
  • Medium: Added IP whitelist infrastructure

🤝 Contributors

Thanks to everyone who contributed to this release through testing, feedback, and security audits.


Full commit history: https://github.com/onllm-dev/onwatch/compare/v2.5.0...v2.5.1

v2.5.0 New feature
Notable features
  • Cross-quota ratio insight card with updated documentation
  • Settings page adding SMTP notification and provider control options
Full changelog

🚀 onWatch v2.5.0 Released

📥 Download

| Platform | Architecture | Binary | Size |
|----------|-------------|--------|------|
| macOS | Apple Silicon | onwatch-darwin-arm64 | 13 MB |
| macOS | Intel | onwatch-darwin-amd64 | 13 MB |
| Linux | x86_64 | onwatch-linux-amd64 | 13 MB |
| Linux | ARM64 | onwatch-linux-arm64 | 13 MB |
| Windows | x86_64 | onwatch-windows-amd64.exe | 14 MB |

✨ What's New

Anthropic Token Auto-Detection Improvements

This release significantly improves Anthropic (Claude Code) token detection, particularly for users running onWatch as a systemd service:

  • Systemd Service Support: Fixed token detection when $HOME environment variable is not available (common in systemd services)
  • Dual Home Directory Resolution: Now attempts both os.UserHomeDir() (respects $HOME) and user.Current().HomeDir (reads from passwd database) for maximum compatibility
  • Enhanced Debug Logging: Added detailed debug logs for credential file lookup failures to help diagnose detection issues
  • Improved Error Handling: Better flow with explicit checks for empty tokens and credential parsing failures

Performance

  • RAM Usage: Maintains ~28 MB idle footprint with all three providers polling
  • Load Tested: 1,104 requests in 15 seconds with average response time of 2.58 ms
  • Memory Efficient: No ORM, single SQLite connection, bounded buffers throughout

🔧 Backend Changes

| Change | File | Description |
|--------|------|-------------|
| Enhancement | internal/api/anthropic_token_unix.go | Improved token detection with fallback home directory resolution |
| Chore | .gitignore | Added perf-monitor artifacts to ignore list |
| Version | VERSION | Bumped to 2.5.0 |

⬆️ Upgrade Guide

macOS (Homebrew - coming soon)

brew upgrade onwatch

Manual Installation

  1. Download the appropriate binary for your platform above
  2. Stop the current onWatch instance: ./onwatch stop
  3. Replace the binary: mv onwatch-darwin-arm64 /usr/local/bin/onwatch
  4. Restart: ./onwatch

Self-Update (v2.4.0+)

If running v2.4.0 or later:

./onwatch update

📝 Full Changelog

  • dfe1e4c chore: bump version to 2.5.0
  • 758dfd0 feat: improve Anthropic token detection for systemd services
  • 6fecc10 feat: cross-quota ratio insight card + docs update
  • edcb7b5 feat: settings page with SMTP notifications and provider controls
  • 1723117 fix: insight card layout and cycle overview raw values for Synthetic/Z.ai
  • 392e1b5 fix: show days in duration format and use 2-column Anthropic card grid

🙏 Thanks

Thanks to all users providing feedback and reporting issues. The systemd service improvements in this release were driven by community reports.

v2.4.0 Breaking risk
Notable features
  • Runtime memory tuning: GOMEMLIMIT=40MiB, GOGC=50, periodic FreeOSMemory goroutine
  • SQLite connection pool limited to MaxOpenConns=2, MaxIdleConns=1 with reduced cache_size=-500 (512 KB)
  • HTTP transport clients now use MaxIdleConns=1 and MaxIdleConnsPerHost=1
Full changelog

Downloads

| Platform | Binary | Architecture |
|----------|--------|-------------|
| macOS (Apple Silicon) | onwatch-darwin-arm64 | ARM64 (M1/M2/M3/M4) |
| macOS (Intel) | onwatch-darwin-amd64 | x86_64 |
| Linux | onwatch-linux-amd64 | x86_64 |
| Linux (ARM) | onwatch-linux-arm64 | ARM64 (Raspberry Pi 4+, AWS Graviton) |
| Windows | onwatch-windows-amd64.exe | x86_64 |

One-line install (macOS/Linux):

curl -fsSL https://raw.githubusercontent.com/onllm-dev/onwatch/main/install.sh | bash

Existing users: Click the update badge in the dashboard footer, or run onwatch update.


What's New

Runtime Memory Optimization

onWatch now actively manages its memory footprint through Go runtime tuning. Three techniques work together to keep RSS low:

| Technique | What It Does |
|-----------|-------------|
| GOMEMLIMIT=40MiB | Sets a soft heap limit that triggers MADV_DONTNEED on macOS/Linux, causing freed pages to actually be released back to the OS instead of being held as reclaimable (MADV_FREE) |
| GOGC=50 | Triggers garbage collection at 50% heap growth instead of the default 100%, running GC more frequently with negligible CPU cost for an I/O-bound daemon |
| FreeOSMemory() goroutine | Every 5 minutes, forces the Go runtime to return unused memory to the OS, preventing RSS from permanently ratcheting up after transient allocations |

This is a soft limit — it cannot crash the application. If the heap needs to exceed 40 MiB, Go simply exceeds the limit rather than OOM-killing.

SQLite Connection Pool Tuning

The default database/sql pool was creating multiple connections, each with its own 2 MB page cache. Now tuned to:

  • MaxOpenConns=2 — allows one concurrent read + write
  • MaxIdleConns=1 — keeps only one connection cached when idle
  • cache_size=-500 (512 KB) — reduced from 2 MB, sufficient for sequential inserts

HTTP Transport Optimization

All four HTTP clients (Synthetic, Z.ai, Anthropic, and the updater) now use MaxIdleConns=1, MaxIdleConnsPerHost=1. Each client only talks to a single host, so the default pool of 100 idle connections was wasteful.

Server-Side Chart Downsampling

History endpoints now downsample large datasets to a maximum of 500 data points before sending to the browser. This keeps chart rendering fast without truncating your data:

  • Algorithm: Even step sampling that always preserves the first and last data points
  • Threshold: Only activates when the dataset exceeds 500 points (e.g., 7-day view at 1-minute polling = ~10,080 points → 500)
  • No data loss: The full dataset is still queried from SQLite; only the JSON response is thinned
  • Time ranges unaffected: No artificial SQL LIMIT on chart/history endpoints — the time range remains the natural bound

Anthropic Query Optimization

The raw_json column (stored on every Anthropic snapshot INSERT for debugging) is no longer loaded on queries. This avoids unnecessary memory allocations when rendering the dashboard.

Bounded Cycle Table Queries

Cycle history endpoints now cap results at 200 per quota type, and insight cycle queries cap at 50. The frontend already paginates client-side, so this has zero visual impact while preventing unbounded memory growth as cycle history accumulates.


Performance

Measured with tools/perf-monitor while all three provider agents (Synthetic, Z.ai, Anthropic) ran in parallel:

| Metric | v2.3.4 | v2.4.0 | Budget |
|--------|--------|--------|--------|
| Idle RSS (avg) | 27.5 MB | 28.0 MB | 30 MB |
| Idle RSS (P95) | 27.5 MB | 28.0 MB | 30 MB |
| Load RSS (avg) | 28.5 MB | 35.1 MB | 50 MB |
| Load RSS (P95) | 29.0 MB | 35.9 MB | 50 MB |
| Load delta | +0.9 MB | +7.1 MB | <20 MB |
| Throughput | 1,160 reqs/15s | 1,104 reqs/15s | — |
| Avg API response | 0.28 ms | 0.75 ms | <5 ms |
| Avg dashboard | 0.69 ms | 2.58 ms | <10 ms |

Why is load RSS higher? The downsampling allocates temporary slices to process the full dataset before thinning. This is a deliberate tradeoff: the previous v2.3.4 numbers reflected hardcoded LIMIT 200 SQL queries that truncated 7-day charts. v2.4.0 queries the full time range and downsamples server-side, preserving data fidelity. Idle RSS (the number that matters for a background daemon) remains well within budget.


Backend Changes

| File | Change |
|------|--------|
| main.go | Added GOMEMLIMIT, GOGC, FreeOSMemory goroutine |
| internal/store/store.go | MaxOpenConns=2, MaxIdleConns=1, cache_size=-500 |
| internal/api/client.go | MaxIdleConns=1 on HTTP transport |
| internal/api/zai_client.go | MaxIdleConns=1 on HTTP transport |
| internal/api/anthropic_client.go | MaxIdleConns=1 on HTTP transport |
| internal/update/update.go | MaxIdleConns=1 on HTTP transport |
| internal/store/anthropic_store.go | Removed raw_json from SELECT queries |
| internal/web/handlers.go | Added downsampleStep() + maxChartPoints=500, applied to all 4 history handlers; cycle queries capped at 200, insight cycles at 50 |


Upgrade Guide

From v2.3.x: Update via dashboard or onwatch update. No configuration changes needed — all optimizations are internal.

From source:

git pull origin main
make build
./onwatch stop && ./onwatch

Full Changelog

https://github.com/onllm-dev/onWatch/compare/v2.3.4...v2.4.0

v2.3.4 Bug fix
⚠ Upgrade required
  • If the service is stopped after a failed update from v2.3.1, manually start it with `systemctl start onwatch` to run the migration in v2.3.3 before triggering the v2.3.4 update.
Full changelog

Downloads

| Platform | Binary | Architecture |
|----------|--------|-------------|
| macOS (Apple Silicon) | onwatch-darwin-arm64 | ARM64 (M1/M2/M3/M4) |
| macOS (Intel) | onwatch-darwin-amd64 | x86_64 |
| Linux | onwatch-linux-amd64 | x86_64 |
| Linux (ARM) | onwatch-linux-arm64 | ARM64 (Raspberry Pi 4+, AWS Graviton) |
| Windows | onwatch-windows-amd64.exe | x86_64 |

What's Fixed

Apply()-Time systemd Migration

v2.3.3 added startup migration to fix the systemd unit file, but it only worked when the new binary got to execute (v2.3.0 → v2.3.3 path where the old binary spawns a child). For v2.3.1 → v2.3.3, the old binary's Restart() called os.Exit(0) without spawning anything, so the new binary's migration code never ran.

v2.3.4 fixes this by moving the migration into Apply() itself. Now the unit file is fixed while the current process is still alive, before Restart() is ever called. This means:

  • Even if Restart() does os.Exit(0), the unit already has Restart=always
  • systemd will auto-restart the service after the process exits
  • The new binary starts and everything works

Three layers of protection (from v2.3.4+):

| When | What | Why |
|------|------|-----|
| Apply() | Fixes unit file before Restart() | Ensures Restart=always before any exit |
| Restart() | Runs systemctl restart | Proper systemd lifecycle management |
| Startup | MigrateSystemdUnit() before stopPreviousInstance() | Safety net for spawn-based upgrades |

Cumulative fixes (v2.3.1–v2.3.4)

  • v2.3.1: Anthropic token auto-refresh, systemd detection
  • v2.3.2: systemctl restart in Restart(), Anthropic 401 retry
  • v2.3.3: Startup unit migration, service name auto-detection from cgroup
  • v2.3.4: Apply()-time unit migration (this release)

Current State

If your service is stopped after a failed update from v2.3.1:

systemctl start onwatch

This starts v2.3.3 (already on disk from the previous update), which fixes the unit file. Then trigger the update to v2.3.4 from the dashboard — this time it will restart automatically.

Full Changelog

https://github.com/onllm-dev/onWatch/compare/v2.3.3...v2.3.4

v2.3.3 New feature
⚠ Upgrade required
  • If the service is running, trigger update via dashboard – v2.3.3 handles restart automatically.
  • If the service is stopped (e.g., after a failed v2.3.1 update), start it with `sudo systemctl start onwatch` to let the migration run.
  • Fresh installations can continue using the existing install script.
Notable features
  • Automatic migration of systemd unit file: Restart=on-failure → always and RestartSec=10 → 5 on each startup
  • Anthropic 401 token retry logic forces immediate credential re‑read and retries once
  • Self‑update under systemd now uses `systemctl restart` instead of spawning a child process
Full changelog

Downloads

| Platform | Binary | Architecture |
|----------|--------|-------------|
| macOS (Apple Silicon) | onwatch-darwin-arm64 | ARM64 (M1/M2/M3/M4) |
| macOS (Intel) | onwatch-darwin-amd64 | x86_64 |
| Linux | onwatch-linux-amd64 | x86_64 |
| Linux (ARM) | onwatch-linux-arm64 | ARM64 (Raspberry Pi 4+, AWS Graviton) |
| Windows | onwatch-windows-amd64.exe | x86_64 |

What's New

Zero-Touch systemd Self-Update Migration

Previous versions had a chicken-and-egg problem with systemd self-updates: the old binary needed to restart the service, but its restart code was broken under systemd, and the systemd unit file had Restart=on-failure which doesn't restart on clean exits.

v2.3.3 solves this by having the new binary fix things itself. On every startup, onWatch checks its own systemd unit file and auto-migrates stale settings:

  • Restart=on-failureRestart=always
  • RestartSec=10RestartSec=5

The critical insight is when this runs. The migration executes before stopPreviousInstance() in the startup sequence. Here's why that matters:

Upgrade sequence (v2.3.0 → v2.3.3 under systemd):

1. Old binary (v2.3.0) downloads v2.3.3, replaces binary on disk
2. Old binary spawns new binary as child process (same cgroup)
3. New binary starts run():
   a. Reads unit file, fixes Restart=on-failure → Restart=always
   b. Runs systemctl daemon-reload (synchronous, completes while parent alive)
   c. Calls stopPreviousInstance() → sends SIGTERM to parent
4. Parent dies (exit 0)
5. systemd starts cgroup cleanup → kills child too
6. systemd checks restart policy → now Restart=always → auto-restarts
7. Fresh v2.3.3 starts under systemd. Done!

Zero manual intervention. The child process is ephemeral — it fixes the unit file, triggers the kill chain, and lets systemd handle the rest.

This is idempotent: on subsequent starts, the unit file is already correct and nothing changes.

Also included (from v2.3.2)

  • Anthropic 401 token retry: On unauthorized response, forces immediate credential re-read and retries once
  • systemctl restart: Under systemd, self-update uses systemctl restart instead of spawning a child

Backend Changes

| File | Change |
|------|--------|
| internal/update/update.go | Added MigrateSystemdUnit() — reads/fixes/reloads systemd unit on startup |
| internal/update/update.go | Added findUnitFile() — locates system-level or user-level unit |
| main.go | Calls MigrateSystemdUnit() before stopPreviousInstance() |

Upgrade

If your service is currently running (any version)

Trigger the update from the dashboard — v2.3.3 handles the restart automatically.

If your service is currently stopped (from a failed v2.3.1 update)

sudo systemctl start onwatch
# v2.3.3 fixes the unit file on startup, future updates work automatically

Fresh install

curl -fsSL https://onwatch.onllm.dev/install.sh | bash

Full Changelog

https://github.com/onllm-dev/onWatch/compare/v2.3.2...v2.3.3

v2.3.2 Bug fix
⚠ Upgrade required
  • If using v2.3.0 or v2.3.1, edit `/etc/systemd/system/onwatch.service` to set `Restart=always` and `RestartSec=5`, then run `sudo systemctl daemon-reload`
  • Follow the provided upgrade steps when moving from v2.3.0/v2.3.1 to ensure systemd restarts correctly
Notable features
  • Systemd unit defaults changed to Restart=always with RestartSec=5 for safer restarts
  • Anthropic API client retries once after a 401 by re‑reading the token
Full changelog

Downloads

| Platform | Binary | Architecture |
|----------|--------|-------------|
| macOS (Apple Silicon) | onwatch-darwin-arm64 | ARM64 (M1/M2/M3/M4) |
| macOS (Intel) | onwatch-darwin-amd64 | x86_64 |
| Linux | onwatch-linux-amd64 | x86_64 |
| Linux (ARM) | onwatch-linux-arm64 | ARM64 (Raspberry Pi 4+, AWS Graviton) |
| Windows | onwatch-windows-amd64.exe | x86_64 |

What's Fixed

systemd Self-Update Now Restarts Properly

v2.3.1 issue: The systemd fix used os.Exit(0) to let systemd restart the service. However, most installations use Restart=on-failure in their systemd unit, which does not restart on a clean exit (code 0). Result: the service stopped and never came back.

v2.3.2 fix: Instead of exiting, onWatch now runs systemctl restart <service> directly. The service name is auto-detected from /proc/self/cgroup (falls back to onwatch.service). systemd handles the full stop→start lifecycle, so the service restarts reliably regardless of the Restart= setting.

Additionally, install.sh now creates systemd units with Restart=always and RestartSec=5 (previously on-failure / 10s) as a safety net.

If you're on v2.3.0 or v2.3.1 and experienced the restart issue, update your systemd unit:

# Edit the unit file
sudo nano /etc/systemd/system/onwatch.service
# Change: Restart=on-failure → Restart=always
# Change: RestartSec=10 → RestartSec=5
# Then reload:
sudo systemctl daemon-reload

Anthropic 401 Token Retry

v2.3.1 issue: Token auto-refresh re-reads credentials before each poll, but if the stored token is expired and gets a 401, onWatch just logged the error and waited 60s for the next poll — even if Claude Code had already refreshed the token on disk between the read and the API call.

v2.3.2 fix: On a 401 response, onWatch immediately:

  1. Clears the cached token (forces a fresh file/keychain read)
  2. Re-reads credentials from disk
  3. Retries the API call once with the new token

This handles the race condition where Claude Code rotates the token between our file read and API call. If the retry also fails, it logs the error and waits for the next poll cycle.

Backend Changes

| File | Change |
|------|--------|
| internal/update/update.go | Restart() now uses systemctl restart under systemd; added detectServiceName() from /proc/self/cgroup |
| internal/agent/anthropic_agent.go | poll() retries on 401 with forced token re-read |
| install.sh | systemd units now use Restart=always, RestartSec=5 |

Upgrade

From v2.3.0 or v2.3.1 (manual — recommended for this release)

sudo systemctl stop onwatch
curl -fsSL https://github.com/onllm-dev/onWatch/releases/download/v2.3.2/onwatch-linux-amd64 -o /root/.onwatch/bin/onwatch
chmod +x /root/.onwatch/bin/onwatch
sudo systemctl start onwatch

Dashboard self-update

If you're on v2.3.1 and your service is running, the update button will work — v2.3.2 will use systemctl restart for a clean restart.

Install script (fresh install)

curl -fsSL https://onwatch.onllm.dev/install.sh | bash

Full Changelog

https://github.com/onllm-dev/onWatch/compare/v2.3.1...v2.3.2

v2.3.1 Bug fix
Notable features
  • Systemd-aware self‑update restart exits cleanly, avoiding delayed service recovery
Full changelog

Downloads

| Platform | Binary | Architecture |
|----------|--------|-------------|
| macOS (Apple Silicon) | onwatch-darwin-arm64 | ARM64 (M1/M2/M3/M4) |
| macOS (Intel) | onwatch-darwin-amd64 | x86_64 |
| Linux | onwatch-linux-amd64 | x86_64 |
| Linux (ARM) | onwatch-linux-arm64 | ARM64 (Raspberry Pi 4+, AWS Graviton) |
| Windows | onwatch-windows-amd64.exe | x86_64 |

What's Fixed

Anthropic OAuth Token Auto-Refresh

Previously, the Anthropic OAuth token was read once at startup and never updated. If the token expired (which happens regularly — Claude Code rotates them), onWatch would log "anthropic: unauthorized - invalid API key" on every poll until manually restarted.

Now: The Anthropic agent re-reads the token from the credentials source (macOS Keychain, Linux keyring, or ~/.claude/.credentials.json) before each poll. When Claude Code rotates the token, onWatch picks it up automatically within 60 seconds. A log message "Anthropic token refreshed from credentials" confirms when a rotation is detected.

This works automatically — no configuration changes needed. Users upgrading from any previous version get this fix immediately.

systemd-Aware Self-Update Restart

Previously, the self-update (/api/update/apply) spawned a child process to replace the old one. Under systemd, this caused the tracked PID to die, making systemd think the service crashed. The result was a ~70-second gap (systemd's RestartSec delay) before the service came back.

Now: onWatch detects if it's running under systemd (via the INVOCATION_ID environment variable). If so, after replacing the binary it simply exits cleanly — systemd restarts the service instantly with the new binary. Standalone (non-systemd) mode continues to use the spawn-and-replace approach.

Backend Changes

| File | Change |
|------|--------|
| internal/api/anthropic_client.go | Added SetToken() method for runtime token updates |
| internal/agent/anthropic_agent.go | Added TokenRefreshFunc — re-detects credentials before each poll |
| internal/update/update.go | Added IsSystemd() detection; Restart() now exits cleanly under systemd |
| main.go | Wired token refresh to DetectAnthropicToken() for auto-detected tokens |

Upgrade

From v2.3.0 (dashboard self-update)

Click the update badge in the dashboard footer. Under systemd, the restart will now be instant instead of delayed.

From v2.2.x (manual)

# systemd
sudo systemctl stop onwatch
# Download new binary for your platform
sudo cp onwatch-linux-amd64 /root/.onwatch/bin/onwatch
sudo chmod +x /root/.onwatch/bin/onwatch
sudo systemctl start onwatch

Install script

curl -fsSL https://onwatch.onllm.dev/install.sh | bash

Full Changelog

https://github.com/onllm-dev/onWatch/compare/v2.3.0...v2.3.1

v2.3.0 Breaking risk
Notable features
  • All HTTP responses are gzip‑compressed (BestSpeed) using sync.Pool for writer reuse
  • Static files served with Cache-Control: public, max-age=31536000, immutable and versioned URLs
Full changelog

Downloads

| Platform | Binary | Architecture |
|----------|--------|-------------|
| macOS (Apple Silicon) | onwatch-darwin-arm64 | ARM64 (M1/M2/M3/M4) |
| macOS (Intel) | onwatch-darwin-amd64 | x86_64 |
| Linux | onwatch-linux-amd64 | x86_64 |
| Linux (ARM) | onwatch-linux-arm64 | ARM64 (Raspberry Pi 4+, AWS Graviton) |
| Windows | onwatch-windows-amd64.exe | x86_64 |

What's New

Gzip Compression

All HTTP responses are now gzip-compressed, reducing transfer sizes by 60–70%. The dashboard's JS + CSS payload drops from ~170 KB to ~50 KB over the wire. Uses sync.Pool for writer reuse with BestSpeed level — minimal CPU overhead.

Immutable Static Asset Caching

Static files (app.js, style.css, favicon.svg) are now served with Cache-Control: public, max-age=31536000, immutable. URLs are versioned via ?v=2.3.0 query params for automatic cache busting on upgrades. Repeat visits load instantly — zero network requests for cached assets.

Parallel API Fetches

The dashboard's 4 critical above-fold API calls (/api/current, /api/history, /api/insights, /api/settings) now fire in parallel via Promise.all() instead of sequentially. Saves 300–400ms on initial render.

Lazy Loading for Below-Fold Sections

Cycles table, Cycle Overview, and Sessions table are now loaded on-demand via IntersectionObserver when they scroll into view (with 200px pre-fetch margin). Auto-refresh only refreshes sections that have been loaded. 3 fewer API calls on initial page load.

Font Optimization

  • Google Fonts reduced from 11 weights (Inter 5 + JetBrains Mono 3) to 5 weights (Inter 3 + JetBrains Mono 2)
  • Added preconnect for cdn.jsdelivr.net (Chart.js CDN)
  • Added <link rel="preload"> hints for critical CSS and JS
  • Moved scripts to end of <body> with defer — no longer render-blocking

Production Cleanup

All 17 console.log/warn/error statements removed from app.js. Error handling still works — UI shows fallback states on failure — but the browser console is clean.

Performance Impact

| Metric | Before | After | Improvement |
|--------|--------|-------|-------------|
| Transfer size (JS+CSS) | ~170 KB | ~50 KB | -70% |
| Initial API calls | 7 sequential | 4 parallel + 3 lazy | -400ms |
| Repeat visit asset load | ~170 KB | 0 KB (cached) | -100% |
| Font payload | 11 weights | 5 weights | -55% |
| Console noise | 17 statements | 0 | Clean |

Estimated total improvement: 1.5–2.5 seconds faster initial dashboard load.

RAM budget remains unchanged — idle ~28 MB, load ~29 MB (all 3 agents polling).

Backend Changes

| File | Change |
|------|--------|
| internal/web/server.go | Gzip middleware, Cache-Control headers, sync.Pool writer |
| internal/web/templates/layout.html | Versioned URLs, preload hints, font reduction, deferred scripts |
| internal/web/static/app.js | Promise.all, IntersectionObserver lazy loading, console removal |

Upgrade

Existing users (binary)

onwatch stop
# Download new binary for your platform from assets below
chmod +x onwatch-*
./onwatch

Existing users (install script)

curl -fsSL https://onwatch.onllm.dev/install.sh | bash

Self-update (v2.2.0+)

If running v2.2.0 or later, click the update badge in the dashboard footer.

Full Changelog

https://github.com/onllm-dev/onWatch/compare/v2.2.5...v2.3.0

v2.2.5 New feature
⚠ Upgrade required
  • Self‑update command `onwatch update` works from v2.2.1+; use one‑line install script for fresh installs.
  • Manual updates require downloading the binary, making it executable (`chmod +x`), and replacing the existing binary.
Notable features
  • Self‑update robustness: binary replacement uses os.Remove + os.Rename on Unix and fallback backup‑rename on Windows.
  • Truncated pagination UI shows compact `1 … n … last` format for tables with many pages.
  • Dashboard HTML now served with Cache-Control: no-store to prevent stale content.
Full changelog

Downloads

| Platform | Binary |
|----------|--------|
| macOS (Apple Silicon) | onwatch-darwin-arm64 |
| macOS (Intel) | onwatch-darwin-amd64 |
| Linux (x86_64) | onwatch-linux-amd64 |
| Linux (ARM64) | onwatch-linux-arm64 |
| Windows (x86_64) | onwatch-windows-amd64.exe |

What's New

Self-Update Robustness (3 bugs fixed)

  • Binary replacement: Uses os.Remove + os.Rename on Unix (avoids lstat .old: no such file or directory errors on Linux). Falls back to backup-rename on Windows.
  • Update badge visibility: Fixed CSS where display: inline-flex overrode the HTML hidden attribute — badge now properly hides when no update is available.
  • Server restart after dashboard update: Fixed pollForRestart() to detect server downtime before reloading, and uses cache-busting URL to prevent stale page from browser cache. Fixed /proc/self/exe resolution on Linux after binary replacement.

Mobile Dashboard Fix

  • Truncated pagination: Tables with many pages now show compact 1 … 4 5 6 7 … 31 format instead of all page buttons.
  • No horizontal overflow: Added flex-wrap and overflow-x: hidden.

Other Improvements

  • Apply() forces a fresh GitHub API check (bypasses stale 1-hour cache)
  • Version comparison handles pre-release suffixes (e.g., 2.2.5-test)
  • Dashboard HTML served with Cache-Control: no-store
  • Download timeout increased from 30s to 2min for slow connections
  • 4 new unit tests for replaceBinary and filterArgs

E2E Tested

Full update flow verified with browser automation:

  1. Dashboard shows "Update to vX.Y.Z" badge when update available
  2. Click update → binary downloaded, validated, replaced
  3. Server restarts → page reloads with new version
  4. Badge correctly hidden after update (no update available)

Upgrade

One-line install (Linux/macOS)

curl -fsSL https://raw.githubusercontent.com/onllm-dev/onwatch/main/install.sh | bash

Self-update (v2.2.1+)

onwatch update

Or click the update button in the dashboard footer.

Manual

Download the binary for your platform, chmod +x, and replace the existing binary.

Full Changelog

https://github.com/onllm-dev/onWatch/compare/v2.2.4...v2.2.5

v2.2.4 New feature
⚠ Upgrade required
  • Install script now downloads to /tmp then moves into place to avoid `ETXTBSY` errors on Linux upgrades
  • Enhanced error logging in install.sh includes curl exit codes, download size, URL and destination path
  • Sanity check rejects downloads under 1 MB; `stop_existing()` polls up to 5 seconds with pgrep
Notable features
  • CLI command `onwatch update` checks GitHub, downloads latest binary atomically and restarts the daemon
  • Dashboard footer button triggers automatic server update when a newer version is available
Full changelog

Downloads

| Platform | Binary |
|----------|--------|
| macOS (Apple Silicon) | onwatch-darwin-arm64 |
| macOS (Intel) | onwatch-darwin-amd64 |
| Linux (x86_64) | onwatch-linux-amd64 |
| Linux (ARM64) | onwatch-linux-arm64 |
| Windows (x86_64) | onwatch-windows-amd64.exe |

What's New (v2.2.1 – v2.2.4)

Self-Update Feature

onWatch can now update itself — no more manual downloads or re-running install.sh:

  • CLI: onwatch update — checks GitHub for the latest release, downloads the binary, replaces itself atomically, and restarts the daemon if running
  • Dashboard: A footer button appears when a newer version is available. Click to update and the server restarts automatically.

Technical details:

  • GitHub release check cached for 1 hour (respects API rate limits)
  • Streaming download via io.Copy — no buffering entire binary in RAM
  • Atomic binary swap via rename (backup → swap → cleanup)
  • Magic byte validation (ELF, Mach-O, PE) before replacing
  • ~200 bytes idle RAM overhead, zero new dependencies

Install Script Improvements

  • Downloads to /tmp first, then moves into place — avoids ETXTBSY (text file busy) errors on Linux when upgrading a running binary
  • Detailed error logging: curl exit codes, download size, URL, and destination path
  • Sanity check rejects downloads under 1MB
  • stop_existing() now polls up to 5 seconds with pgrep instead of a fixed 1-second sleep

Bug Fixes

  • Fixed CLI onwatch update daemon restart (v2.2.3): was re-running the update command instead of starting a fresh daemon
  • Fixed fail() in install.sh: \n in error messages now renders as actual newlines

Upgrade

# From any previous version with self-update:
onwatch update

# Fresh install:
curl -fsSL https://raw.githubusercontent.com/onllm-dev/onwatch/main/install.sh | bash

# Manual download:
curl -fsSL https://github.com/onllm-dev/onWatch/releases/download/v2.2.4/onwatch-$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m | sed 's/x86_64/amd64/' | sed 's/aarch64/arm64/') -o /usr/local/bin/onwatch
chmod +x /usr/local/bin/onwatch

Full Changelog

  • v2.2.1 — Self-update feature (CLI + dashboard API + footer button)
  • v2.2.2 — Version bump
  • v2.2.3 — Fix CLI update daemon restart
  • v2.2.4 — Version bump + install.sh fixes (download to /tmp, error logging)
v2.2.3 Bug fix

Fixed `onwatch update` CLI command to properly stop the old daemon and spawn a fresh one.

Full changelog

Downloads

| Platform | Binary |
|----------|--------|
| macOS (Apple Silicon) | onwatch-darwin-arm64 |
| macOS (Intel) | onwatch-darwin-amd64 |
| Linux (x86_64) | onwatch-linux-amd64 |
| Linux (ARM64) | onwatch-linux-arm64 |
| Windows (x86_64) | onwatch-windows-amd64.exe |

Changes

  • Fixed onwatch update CLI command not properly restarting the daemon after update — was re-running the update command instead of spawning a fresh daemon
  • The old daemon is now stopped via SIGTERM and a fresh daemon process is spawned

Upgrade

onwatch update

Note: v2.2.4 is the latest release with additional install.sh fixes.

v2.2.2 Maintenance

Minor fixes and improvements.

Full changelog

Downloads

| Platform | Binary |
|----------|--------|
| macOS (Apple Silicon) | onwatch-darwin-arm64 |
| macOS (Intel) | onwatch-darwin-amd64 |
| Linux (x86_64) | onwatch-linux-amd64 |
| Linux (ARM64) | onwatch-linux-arm64 |
| Windows (x86_64) | onwatch-windows-amd64.exe |

Changes

  • Version bump (includes self-update feature from v2.2.1)

Upgrade

onwatch update

Note: v2.2.4 is the latest release with daemon restart and install.sh fixes.

v2.2.1 New feature
⚠ Upgrade required
  • Run `onwatch update` to upgrade; note that v2.2.4 contains additional daemon restart fixes
Notable features
  • CLI command `onwatch update` for automatic self‑update with atomic binary swap and daemon restart
  • Dashboard footer button triggers server self‑update when a newer version is available
Full changelog

Downloads

| Platform | Binary |
|----------|--------|
| macOS (Apple Silicon) | onwatch-darwin-arm64 |
| macOS (Intel) | onwatch-darwin-amd64 |
| Linux (x86_64) | onwatch-linux-amd64 |
| Linux (ARM64) | onwatch-linux-arm64 |
| Windows (x86_64) | onwatch-windows-amd64.exe |

What's New

Self-Update Feature

onWatch can now update itself! Two interfaces:

  • CLI: onwatch update — checks GitHub for the latest release, downloads the binary, replaces itself atomically, and restarts the daemon if running
  • Dashboard: A footer button appears when a newer version is available. Click to update and the server restarts automatically.

Technical Details

  • GitHub release check cached for 1 hour (respects rate limits)
  • Streaming download — no buffering entire binary in RAM
  • Atomic binary swap via rename (backup + swap + cleanup)
  • Magic byte validation (ELF, Mach-O, PE) before replacing
  • ~200 bytes idle RAM overhead
  • Zero new dependencies
  • 19 unit tests covering version comparison, cache TTL, error cases, binary validation

Upgrade

onwatch update

Note: v2.2.4 is the latest release with daemon restart and install.sh fixes.

v2.2.0 Breaking risk
⚠ Upgrade required
  • Drop‑in binary replacement; no config or database changes required. The stale connection issue will stop occurring immediately upon upgrade.
Breaking changes
  • Removed `/robots.txt` and `/llms.txt` route handlers and associated files from the app binary.
Notable features
  • Custom `http.Transport` with ResponseHeaderTimeout, IdleConnTimeout, TLSHandshakeTimeout, and increased client Timeout for Anthropic API clients.
  • Per-request context timeout of 30 s added to all agent goroutines.
  • Panic recovery (`defer/recover`) implemented on all three agent goroutines.
Full changelog

Download

| Platform | Binary |
|----------|--------|
| macOS (Apple Silicon) | onwatch-darwin-arm64 |
| macOS (Intel) | onwatch-darwin-amd64 |
| Linux (x86_64) | onwatch-linux-amd64 |
| Linux (ARM64) | onwatch-linux-arm64 |
| Windows (x86_64) | onwatch-windows-amd64.exe |

What's New

Fixed: Anthropic API connection stale hang

The Anthropic polling agent would occasionally stop updating because the HTTP connection to api.anthropic.com entered a stale ESTABLISHED state — the TCP connection was alive but no data flowed. The http.Client.Timeout of 10s failed to fire due to an HTTP/2 dead-stream edge case on a "live" TCP connection, blocking the polling goroutine indefinitely.

Symptoms:

  • Synthetic and Z.ai snapshots stayed fresh (< 1 min old)
  • Anthropic snapshots became 50+ minutes stale
  • lsof showed a hung ESTABLISHED connection to api.anthropic.com
  • Process was alive, but the Anthropic goroutine was blocked on httpClient.Do(req)

Root cause: All three API clients used http.Client{Timeout: 10s} with no custom Transport — they shared http.DefaultTransport which lacks ResponseHeaderTimeout and has a 90s IdleConnTimeout that doesn't prevent this issue.

Fix Details

Custom http.Transport for all API clients — each client now uses a dedicated transport with:

  • ResponseHeaderTimeout: 30s — fires if server accepts connection but doesn't send response headers (the key fix)
  • IdleConnTimeout: 30s — closes idle keep-alive connections between 60s polls
  • TLSHandshakeTimeout: 10s — prevents TLS negotiation hangs
  • ForceAttemptHTTP2: true — keeps HTTP/2 with proper timeouts
  • Client-level Timeout raised from 10s to 30s to match

Per-request context timeout — belt-and-suspenders context.WithTimeout(ctx, 30s) in every FetchQuotas() method, ensuring requests have a hard deadline even if the client timeout fails to fire.

Panic recovery on agent goroutines — all three agent goroutines now have defer/recover to log and surface panics instead of silently dying.

Removed: robots.txt and llms.txt

Removed robots.txt and llms.txt from the app binary. These belong on the landing page (onwatch.onllm.dev), not the dashboard. The v2.1.2 release that added them has been deleted.

Changes

| File | Change |
|------|--------|
| internal/api/anthropic_client.go | Custom Transport + per-request context timeout |
| internal/api/client.go | Custom Transport + per-request context timeout |
| internal/api/zai_client.go | Custom Transport + per-request context timeout |
| internal/api/client_test.go | Updated timeout assertion (10s → 30s) |
| internal/api/zai_client_test.go | Updated timeout assertion (10s → 30s) |
| main.go | Panic recovery on all 3 agent goroutines |
| internal/web/server.go | Removed /robots.txt and /llms.txt route handlers |
| internal/web/middleware.go | Removed isPublicFile() auth bypass |
| internal/web/static/robots.txt | Deleted |
| internal/web/static/llms.txt | Deleted |
| static/robots.txt | Deleted |
| static/llms.txt | Deleted |
| VERSION | 2.1.2 → 2.2.0 |

Performance

No impact on RAM or response times — this is a networking reliability fix only.

| Metric | Value | Budget |
|--------|-------|--------|
| Idle RSS (avg) | 27.5 MB | 30 MB |
| Load RSS (P95) | 29.0 MB | 50 MB |
| Avg API response | 0.28 ms | < 5 ms |
| Avg dashboard response | 0.69 ms | < 10 ms |

Upgrade

Drop-in binary replacement — no config or database changes needed. The stale connection issue will stop occurring immediately.

# One-line upgrade (macOS/Linux)
curl -fsSL https://raw.githubusercontent.com/onllm-dev/onwatch/main/install.sh | bash

# Or manual: download binary, replace, restart
onwatch stop
# replace binary
onwatch

Full changelog: https://github.com/onllm-dev/onWatch/compare/v2.1.1...v2.2.0

v2.1.1 New feature
Notable features
  • Header controls (change password, theme toggle, logout) wrapped in .header-controls with a compact 6px gap
Full changelog

Download

| Platform | Binary |
|----------|--------|
| macOS (Apple Silicon) | onwatch-darwin-arm64 |
| macOS (Intel) | onwatch-darwin-amd64 |
| Linux (x86_64) | onwatch-linux-amd64 |
| Linux (ARM64) | onwatch-linux-arm64 |
| Windows (x86_64) | onwatch-windows-amd64.exe |

What's New

Header controls spacing fix — The change password, theme toggle, and logout buttons in the dashboard header are now grouped tightly together in the top-right corner. Previously, these three buttons were spread apart by the header's space-between flex layout, creating an awkward gap between them. They are now wrapped in a .header-controls container with a compact 6px gap for a cleaner, more polished look.

Changes

| File | Change |
|------|--------|
| internal/web/templates/dashboard.html | Wrap 3 header buttons in .header-controls div |
| internal/web/static/style.css | Add .header-controls flexbox container (6px gap) |
| static/style.css | Sync copy |
| VERSION | Bump to 2.1.1 |

Upgrade

Replace your existing binary with the one for your platform — no config or database changes needed.

Full changelog: https://github.com/onllm-dev/onWatch/compare/v2.1.0...v2.1.1

v2.1.0 Breaking risk
⚠ Upgrade required
  • No database migration required; new tables auto‑create on startup.
  • Run the install script `curl -fsSL https://raw.githubusercontent.com/onllm-dev/onwatch/main/install.sh | bash` for fresh installations.
Notable features
  • Dynamic Y‑axis scaling zooms to actual data range with 30% headroom
  • Per‑minute Anthropic cycle history with burn rate and time‑to‑exhaustion projections
  • Stable key‑based chart colors mapped by quota key
Full changelog

onWatch v2.1.0 — Stable Anthropic Support, Dynamic Charts, Comprehensive Screenshots

onWatch v2.1.0 solidifies Anthropic (Claude Code) as a first-class provider with production-ready tracking, dynamic chart scaling, per-minute cycle granularity, and a polished dashboard experience across all three providers.


Download

| Platform | Binary |
|----------|--------|
| macOS ARM64 (Apple Silicon) | onwatch-darwin-arm64 |
| macOS AMD64 (Intel) | onwatch-darwin-amd64 |
| Linux AMD64 | onwatch-linux-amd64 |
| Linux ARM64 | onwatch-linux-arm64 |
| Windows AMD64 | onwatch-windows-amd64.exe |

Or install with one command (macOS/Linux):

curl -fsSL https://raw.githubusercontent.com/onllm-dev/onwatch/main/install.sh | bash

What's New

Dynamic Y-Axis Scaling

  • Charts now zoom into the actual data range instead of always showing 0-100%
  • Peak data value + 30% headroom, rounded to clean tick marks
  • Example: if your 5-Hour Limit peaks at 45%, the chart Y-axis scales to ~60% — making trends and variations far more visible
  • Works on all views: single-provider, "All Providers" multi-chart, and modal mini-charts

Per-Minute Anthropic Cycle History

  • Cycle History table now shows per-minute polled snapshots instead of coarse reset cycles (which only had 1 row per 5-hour window)
  • Grouping controls (1m, 5m, 30m, 1h) now work properly — aggregate multiple snapshots into rows
  • Each row shows: utilization peak, delta from previous snapshot, and burn rate (delta/hr)
  • Range filters (1h, 3d, 7d, 15d, 30d) limit the time window naturally

Burn Rate Insights for Anthropic

  • Current burn rate calculated from recent utilization deltas
  • Time to exhaustion projection based on current consumption rate
  • Average window usage across recent 5-hour cycles
  • Provider-specific insight cards with severity coloring (positive/warning/negative)

Key-Based Chart Colors (Stable)

  • Anthropic chart colors are now mapped by quota key, not array index:
    • five_hour → Coral (#D97757)
    • seven_day → Emerald (#10B981)
    • seven_day_sonnet → Blue (#3B82F6)
    • monthly_limit → Violet (#A855F7)
    • extra_usage → Amber (#F59E0B)
  • Colors remain stable regardless of quota sort order or dynamic addition/removal

Consistent Display Names

  • Anthropic display names synchronized across Go backend and JS frontend:
    • five_hour → "5-Hour Limit"
    • seven_day → "Weekly All-Model"
    • seven_day_sonnet → "Weekly Sonnet"
    • monthly_limit → "Monthly Limit"
    • extra_usage → "Extra Usage"

Provider Tab Reordering

  • Default tab order changed to: Anthropic → Synthetic → Z.ai → All
  • Anthropic is now the default selected provider on dashboard load

Session Manager Extraction

  • Shared session lifecycle logic (create, heartbeat, close) extracted into session_manager.go
  • All three agents (Synthetic, Z.ai, Anthropic) now use the same clean session management
  • Reduced code duplication across agent files by ~300 lines

Comprehensive Dashboard Screenshots

  • 8 new screenshots captured: all 4 provider views × light/dark mode
  • Cropped to top half for gallery readability (quota cards + charts + cycle history)
  • Landing page gallery updated with Anthropic-first filter, provider + theme toggles
  • Login page screenshot removed from gallery

Dashboard Screenshots

| Provider | Light | Dark |
|----------|-------|------|
| Anthropic | anthropic-light.png | anthropic-dark.png |
| Synthetic | synthetic-light.png | synthetic-dark.png |
| Z.ai | zai-light.png | zai-dark.png |
| All Providers | all-light.png | all-dark.png |


Performance

Measured with all three agents (Anthropic + Synthetic + Z.ai) polling in parallel:

| Metric | Value |
|--------|-------|
| Idle RSS | ~30 MB avg |
| Load RSS (under sustained HTTP traffic) | ~30 MB avg |
| Load delta | +0.4 MB (+1.3%) |
| Avg API response | 0.28 ms |
| Avg dashboard response | 0.61 ms |
| Throughput | 1,160+ reqs/15s |


Backend Changes

| Component | File(s) | Change |
|-----------|---------|--------|
| Session Manager | internal/agent/session_manager.go | New — shared session lifecycle for all agents |
| Anthropic Agent | internal/agent/anthropic_agent.go | Refactored to use session manager |
| Synthetic Agent | internal/agent/agent.go | Refactored to use session manager |
| Z.ai Agent | internal/agent/zai_agent.go | Refactored to use session manager |
| Store | internal/store/store.go | Added QueryAnthropicUtilizationSeries, session manager support |
| Handlers | internal/web/handlers.go | Rewrote cyclesAnthropic() for per-minute data, added burn rate insights |
| Config | internal/config/config.go | Anthropic-first provider ordering |
| Frontend | app.js, style.css | Dynamic Y-axis, key-based colors, display names, removed height hacks |


Upgrade Guide

For existing users: Just replace the binary. No database migration needed — all new tables auto-create on startup.

For new users:

curl -fsSL https://raw.githubusercontent.com/onllm-dev/onwatch/main/install.sh | bash

Full Changelog

31 files changed: +1,359 lines, -720 lines

| Category | Count |
|----------|-------|
| New Go files | 2 (session_manager.go + test) |
| Modified Go files | 11 |
| Frontend | app.js, style.css, dashboard.html |
| Screenshots | 8 new PNGs |
| Docs | README, CLAUDE.md, DEVELOPMENT.md, INDEX.md, landing page |

Full diff: v2.0.0...v2.1.0

v2.0.0 New feature
⚠ Upgrade required
  • Upgrade guide: update binary; onWatch will auto‑detect Claude Code credentials and prompt to enable tracking during upgrade
  • Installer (`install.sh`) now offers five provider options (Synthetic only, Z.ai only, Anthropic only, Multiple – choose one at a time, or All) with 20 bash test cases validating all flows
Notable features
  • Auto‑detection of Claude Code credentials from macOS Keychain, Linux keyring, and fallback JSON file
  • Dynamic quota tracking for Anthropic with utilization percentages, reset cycle detection, and detailed modal charts
  • Dashboard enhancements: amber‑themed Anthropic tab, 'All' view auto‑fit grid for up to three providers, per‑quota history modals
Full changelog

onWatch v2.0.0 — Anthropic (Claude Code) Provider

onWatch now tracks three providers: Anthropic (Claude Code), Synthetic, and Z.ai — all running in parallel with a unified dashboard.

This is a major release that adds comprehensive Anthropic/Claude Code support with auto-detection of credentials, dynamic quota tracking, and a beautiful amber-themed dashboard experience.


Download

| Platform | Binary |
|----------|--------|
| macOS ARM64 (Apple Silicon) | onwatch-darwin-arm64 |
| macOS AMD64 (Intel) | onwatch-darwin-amd64 |
| Linux AMD64 | onwatch-linux-amd64 |
| Linux ARM64 | onwatch-linux-arm64 |
| Windows AMD64 | onwatch-windows-amd64.exe |

Or install with one command (macOS/Linux):

curl -fsSL https://raw.githubusercontent.com/onllm-dev/onwatch/main/install.sh | bash

What's New

Anthropic (Claude Code) Provider

  • Auto-detection of Claude Code credentials — onWatch automatically finds your token from:
    • macOS Keychain (Claude Code-credentials)
    • Linux keyring via secret-tool
    • File fallback: ~/.claude/.credentials.json
  • Dynamic quota tracking — Anthropic quotas (5-Hour, 7-Day, 7-Day Sonnet, Monthly, Extra Usage) are variable and change over time. onWatch handles this dynamically instead of hardcoding quota types.
  • Utilization-based display — Anthropic reports quotas as utilization percentages (0-100%), displayed with the same progress bars, countdowns, and status badges as other providers.
  • Full reset cycle tracking — Detects quota resets via resets_at timestamp changes, tracks peak utilization and deltas per cycle.

Dashboard Updates

  • Anthropic tab with amber/orange accent color (#D97706) and dynamically rendered quota cards
  • "All" view (formerly "Both") — auto-fit grid that adapts to 2 or 3 providers
  • Per-quota modal with chart history and cycle details for each Anthropic quota
  • Chart.js datasets created dynamically from the active quotas in each API response

Install Script Improvements

  • New "Multiple" option in provider selection — choose providers one at a time instead of all-or-nothing
  • Anthropic auto-detection during install — if Claude Code is installed, the installer offers to enable tracking automatically
  • Cross-platform token help — shows macOS, Linux, and Windows commands for retrieving Claude Code credentials regardless of the current OS (useful for VPS setups)
  • Upgrade flow — existing installations are offered Anthropic tracking when upgrading
  • Fixed color rendering — escape codes now render correctly in all terminal contexts
  • 20 bash test cases validating all install flows

Bug Fixes

  • Fixed SQLite BUSY on 3-provider startup — agents now start with staggered delays to prevent concurrent session creation contention
  • Fixed installer color codes — ANSI escape sequences now render correctly when piped through curl | bash

Backend Architecture

| Component | File(s) |
|-----------|---------|
| API Types | internal/api/anthropic_types.go — Dynamic quota response parsing with null filtering |
| HTTP Client | internal/api/anthropic_client.go — OAuth usage API with anthropic-beta header |
| Token Detection | internal/api/anthropic_token.go + platform files — Build-tagged for unix/windows |
| DB Schema | internal/store/store.go — 3 new tables: anthropic_snapshots, anthropic_quota_values, anthropic_reset_cycles |
| Store | internal/store/anthropic_store.go — Normalized key-value queries for dynamic quotas |
| Tracker | internal/tracker/anthropic_tracker.go — Reset detection, cycle management, utilization deltas |
| Agent | internal/agent/anthropic_agent.go — Background polling loop |
| Config | internal/config/config.goANTHROPIC_TOKEN env var, HasMultipleProviders() |
| Handlers | internal/web/handlers.go — All API endpoints extended with anthropic provider case |


Configuration

# Auto-detected from Claude Code (no manual setup needed if Claude Code is installed)
ANTHROPIC_TOKEN=your_token_here

# Existing providers unchanged
SYNTHETIC_API_KEY=syn_your_key_here
ZAI_API_KEY=your_zai_key_here

At least one provider is required. All three can run simultaneously.


Upgrade Guide

For existing users: Just update the binary. On next start, onWatch will:

  1. Auto-detect Claude Code credentials if present
  2. Log that Anthropic tracking is available
  3. The installer (install.sh) will prompt to enable Anthropic during upgrade

For new users: Run the one-liner:

curl -fsSL https://raw.githubusercontent.com/onllm-dev/onwatch/main/install.sh | bash

The installer now offers 5 provider options: Synthetic only, Z.ai only, Anthropic only, Multiple (choose one at a time), or All available.


Full Changelog

Files changed: 27 files, +4,800 lines

| Category | Changes |
|----------|---------|
| New Go files | 9 (types, client, token detection, store, tracker, agent) |
| Modified Go files | 7 (config, store schema, handlers, server, main) |
| Frontend | dashboard.html, app.js, style.css updated |
| Install | install.sh with 5 provider options + test suite |
| Docs | README.md, CLAUDE.md, .env.example updated |

v1.8.0 Breaking risk
⚠ Upgrade required
  • `SYNTRACK_*` environment variables still work as fallback during transition period
  • Process detection recognizes both `onwatch` and `syntrack` binaries temporarily
  • Automatic migration script provided for standalone binary users before upgrading
Breaking changes
  • Binary renamed from `syntrack` to `onwatch`
  • Go module changed to `github.com/onllm-dev/onwatch`
  • Default data directory moved to `~/.onwatch/data/onwatch.db`
Notable features
  • Interactive installer with guided provider setup and key collection
  • Detect missing providers in `.env` and offer to add them
  • Compact insight cards into single-line layout
Full changelog

onWatch v1.8.0 — The Rebrand Release

SynTrack is now onWatch by onLLM. Same tool, new identity — reflecting multi-provider support and the onLLM ecosystem.

What Changed

Full Rebrand: SynTrack → onWatch

  • Binary renamed from syntrack to onwatch
  • Go module: github.com/onllm-dev/onwatch
  • Domain: onwatch.onllm.dev
  • GitHub: github.com/onllm-dev/onWatch
  • Default data directory: ~/.onwatch/data/onwatch.db
  • All environment variables renamed to ONWATCH_* (e.g. ONWATCH_PORT, ONWATCH_POLL_INTERVAL)
  • Session cookie, HTTP Basic Auth realm, User-Agent headers all updated
  • Dashboard branding, localStorage keys, page titles updated

Backward Compatibility

  • SYNTRACK_* environment variables still work as fallback — no need to update your .env immediately
  • Process detection recognizes both onwatch and syntrack binaries during the transition period

Automatic Migration

Two migration paths for existing users:

Installer users — just re-run the installer:

curl -fsSL https://raw.githubusercontent.com/onllm-dev/onWatch/main/install.sh | bash

The installer detects ~/.syntrack/ and automatically migrates your config, database, and systemd service.

Standalone binary users — run the migration script before upgrading:

curl -fsSL https://raw.githubusercontent.com/onllm-dev/onWatch/main/scripts/migrate-from-syntrack.sh | bash

This moves ~/.syntrack/~/.onwatch/, renames env vars in .env, migrates the database, updates PATH in shell rc files, and cleans up old systemd services.

Also Included (since v1.7.0)

  • refactor: Compact insight cards into single-line layout
  • fix: KPI modal chart not loading due to range-selector misfire
  • fix: Login page infinite refresh loop and systemd restart storm
  • fix: Interactive prompts display correctly and handle all edge cases
  • feat: Detect missing providers in existing .env and offer to add them
  • feat: Interactive installer with guided provider setup and key collection

Platforms

| Platform | Binary |
|----------|--------|
| macOS (Apple Silicon) | onwatch-darwin-arm64 |
| macOS (Intel) | onwatch-darwin-amd64 |
| Linux (x86_64) | onwatch-linux-amd64 |
| Linux (ARM64) | onwatch-linux-arm64 |
| Windows (x86_64) | onwatch-windows-amd64.exe |

Upgrade

Via installer (recommended):

curl -fsSL https://raw.githubusercontent.com/onllm-dev/onWatch/main/install.sh | bash

Manual: Download the binary for your platform, replace the existing one, and restart.

v1.7.0 Bug fix
⚠ Upgrade required
  • After upgrading, reload the systemd unit with `systemctl --user daemon-reload` or `systemctl daemon-reload` (as root) to apply the new restart rate‑limiting settings.
Full changelog

SynTrack v1.7.0

Bug Fixes

Login Page Infinite Refresh Loop (Critical)

The login page was constantly refreshing in an infinite loop after a fresh install. Root cause: loadHiddenInsights() was calling the /api/settings API endpoint on every page — including the login page. Since the user wasn't authenticated, the API returned 401, and the authFetch helper immediately redirected back to /login, creating:

/login → app.js loads → authFetch('/api/settings') → 401 → redirect to /login → repeat

Fixes applied:

  • Moved loadHiddenInsights() into the dashboard-only code block (only runs when authenticated on the dashboard)
  • Added a guard in authFetch() to skip redirect when already on the /login page (safety net against future regressions)

Systemd Restart Storm (Linux)

On Linux systems using the installer, the systemd service had Restart=on-failure with no rate limiting. If the app failed to start due to a persistent issue (missing API key, port conflict, DB permission error), systemd would restart it infinitely every 10 seconds.

Fix: Added StartLimitBurst=3 and StartLimitIntervalSec=120 to both system-wide and user systemd service units. The service now stops after 3 failures within 2 minutes instead of looping forever.

Improvements

Auth Rejection Logging

Authentication rejections (401 API responses and login redirects) were previously completely silent on the server side — making it impossible to diagnose auth issues from server logs.

Fix: SessionAuthMiddleware now logs auth rejections at Debug level with path, method, and remote address. Enable debug logging (--debug or SYNTRACK_LOG_LEVEL=debug) to see these entries.

Platforms

| Platform | Binary |
|----------|--------|
| macOS (Apple Silicon) | syntrack-darwin-arm64 |
| macOS (Intel) | syntrack-darwin-amd64 |
| Linux (x86_64) | syntrack-linux-amd64 |
| Linux (ARM64) | syntrack-linux-arm64 |
| Windows (x86_64) | syntrack-windows-amd64.exe |

Upgrade

Via installer (recommended):

curl -fsSL https://raw.githubusercontent.com/onllm-dev/syntrack/main/install.sh | bash

Manual: Download the binary for your platform, replace the existing one, and restart.

Linux systemd users: After upgrading, reload the service unit to pick up the new rate-limiting config:

systemctl --user daemon-reload    # user service
systemctl daemon-reload           # system service (as root)
v1.6.0 Breaking risk
Notable features
  • Time range selector (1d/7d/30d) for insights with default 7 days
  • Provider boxes in "Both" mode show distinct colored labels per provider
  • Responsive stats grid and insight cards adapt from 4‑column to single column on mobile
Full changelog

What's New in v1.6.0

Usage Insights Redesign

Fixed grid layouts — no more orphan cards:

  • Stats grid now always displays exactly 4 cards per provider in a single row
  • Removed the 5th "Tracking Days" stat card that caused asymmetric 4+1 layouts
  • Insight cards use a clean 2-column grid with last-odd-child spanning full width

Time range selector for insights:

  • New 1d / 7d / 30d range pills in the insights section header
  • Stats (Requests, API Calls, Tool Calls, Sessions) recalculate for the selected range
  • Default range is 7 days

"Both" mode provider boxes:

  • Replaced ugly "(Syn)" / "(Z.ai)" suffix interleaving with visually separated provider boxes
  • Each provider gets its own labeled box with distinct accent color (teal for Synthetic, peach for Z.ai)
  • Stats and insight cards are fully independent per provider

Removed duplicate data:

  • Eliminated computeClientInsights() — live quota percentages were already displayed in KPI cards at the top of the dashboard
  • Session average stat moved server-side into the stats grid

Responsive Improvements

  • Stats grid: 4 columns → 2 columns on tablet → 1 column on mobile
  • Insight cards: 2 columns → 1 column on tablet/mobile
  • Provider boxes in Both mode stack vertically on narrow screens

All Platforms

Binaries for all supported platforms:

  • macOS ARM64 (Apple Silicon) — syntrack-darwin-arm64
  • macOS AMD64 (Intel) — syntrack-darwin-amd64
  • Linux AMD64syntrack-linux-amd64
  • Linux ARM64syntrack-linux-arm64
  • Windows AMD64syntrack-windows-amd64.exe

Upgrade Notes

Drop-in replacement. No database migration or config changes required.

Full Changelog: https://github.com/onllm-dev/syntrack/compare/v1.5.1...v1.6.0

v1.5.1 Breaking risk
⚠ Upgrade required
  • Drop‑in replacement. No database migration or config changes required.
Notable features
  • Production landing page with Material Design 3, dark/light mode toggle, interactive dashboard mockup, one‑line install command, screenshots gallery, feature comparison tables, audience cards, FAQ accordion, alternatives comparison, Google Analytics integration, and SEO enhancements
  • Header & footer redesign moving password change to header, updating footer links, removing version string from footer
  • Version command (`syntrack version`, `--version`, `-v`) now reads embedded VERSION file, prints GitHub URL and attribution
Full changelog

What's New in v1.5.1

Landing Page

Production landing page at syntrack.onllm.dev:

  • Material Design 3 with dark/light mode toggle
  • Interactive dashboard mockup with provider tabs (Synthetic, Z.ai, Both)
  • One-line install command with copy button
  • Screenshots gallery with lightbox, filters, and scroll-based zoom
  • Side-by-side comparison tables for Synthetic and Z.ai features
  • "Who is SynTrack for?" section with 6 target audience cards
  • FAQ accordion with 8 searchable Q&A items
  • Alternatives comparison (SynTrack vs Quotio vs Helicone vs Langfuse)
  • Google Analytics integration for traffic insights
  • SEO: JSON-LD structured data (SoftwareApplication + FAQPage), Open Graph, Twitter Cards

Dashboard Improvements

Header & Footer:

  • Password change button moved from footer to header for easier access
  • Footer updated with project links and tech attribution
  • Removed version string from dashboard footer for cleaner layout

Version Command

  • syntrack version, syntrack --version, and syntrack -v all work
  • Version now reads from embedded VERSION file — no more "vdev" when built without ldflags
  • Prints GitHub URL and attribution alongside version number

README Overhaul

  • Complete rewrite — 35% smaller, focused on value proposition
  • Added "Who Is SynTrack For?" section targeting 6 audience segments
  • Added FAQ section with 5 LLM-targeted Q&A pairs for AI discoverability
  • Keyword-rich intro mentioning compatible tools (Cline, Roo Code, Kilo Code, Claude Code, Cursor, Windsurf)
  • Added badges (License, Go, Platform) and landing page link

Bug Fixes

  • Fix version printing "vdev" when built with plain go build
  • Fix install cards not centering due to grid overflow
  • Fix feature card icons and text alignment
  • Show all 3 install cards at tablet widths
  • Correct license references from MIT to GPL-3.0

Install Script

  • One-line install: curl -fsSL https://raw.githubusercontent.com/onllm-dev/syntrack/main/install.sh | bash
  • Auto-detects root/sudo for systemd service type
  • Downloads binary to ~/.syntrack/, sets up PATH and service

All Platforms

Binaries for all supported platforms:

  • macOS ARM64 (Apple Silicon) — syntrack-darwin-arm64
  • macOS AMD64 (Intel) — syntrack-darwin-amd64
  • Linux AMD64syntrack-linux-amd64
  • Linux ARM64syntrack-linux-arm64
  • Windows AMD64syntrack-windows-amd64.exe

Upgrade Notes

Drop-in replacement. No database migration or config changes required.

Full Changelog: https://github.com/onllm-dev/syntrack/compare/v1.5.0...v1.5.1

v1.5.0 New feature
Notable features
  • --stop and --status now accept both subcommand (syntrack stop) and flag (--stop) syntax
  • New --test flag provides isolated PID and log files for development/CI without affecting production
  • Dashboard gains SVG favicon and header logout button
Full changelog

What's New in v1.5.0

CLI Improvements

--stop and --status Aliases:

  • Support both subcommand and flag syntax: syntrack stop or syntrack --stop
  • Same for status: syntrack status or syntrack --status
  • Improves discoverability for users who prefer flag-style commands

--test Mode Isolation:

  • New --test flag for complete process isolation
  • Uses separate PID file (.syntrack-test.pid) and log file (.syntrack-test.log)
  • Test instances never interfere with production — no port scanning or PID killing
  • Ideal for development and CI environments

Dashboard Enhancements

Favicon:

  • Added SVG favicon (teal circle with brand icon) for browser tab identification
  • Shows in bookmarks, browser tabs, and mobile home screen

Logout Button:

  • New logout button in the dashboard header (arrow-right icon)
  • Red hover indicator for visual clarity
  • Clears session and redirects to login page

All Platforms

Binaries for all supported platforms:

  • macOS ARM64 (Apple Silicon) — syntrack-darwin-arm64
  • macOS AMD64 (Intel) — syntrack-darwin-amd64
  • Linux AMD64syntrack-linux-amd64
  • Linux ARM64syntrack-linux-arm64
  • Windows AMD64syntrack-windows-amd64.exe

Upgrade Notes

Drop-in replacement. No database migration or config changes required.

Full Changelog: https://github.com/onllm-dev/syntrack/compare/v1.3.0...v1.5.0

v1.3.0 Breaking risk
⚠ Upgrade required
  • Update any scripts or configurations referencing port 8932 to use the new default port 9211.
  • If using Z.ai, add `ZAI_API_KEY` and optionally `ZAI_POLL_INTERVAL` entries to your `.env` file.
Breaking changes
  • Default listening port changed from 8932 to 9211
Notable features
  • Unified "Both" view showing Synthetic and Z.ai usage side‑by‑side with combined insights panel
  • Tab‑based provider selector replacing dropdown for faster switching
  • Quota visibility toggle on quota cards with persistent localStorage state and dynamic Y‑axis scaling
Full changelog

What's New in v1.3.0

Multi-Provider Support: Z.ai Integration

SynTrack now tracks both Synthetic API and Z.ai usage in a single dashboard. This is a major expansion beyond Synthetic-only tracking.

Z.ai Support:

  • Full quota tracking for Z.ai's token-based and time-based limits
  • Token usage tracking with 15B token monthly limit
  • Time-based quota tracking (5 minutes/hour) with smart reset detection
  • Per-tool token consumption breakdown
  • Token efficiency metrics (tokens per tool call)

Z.ai Quota Tracking Features:

  • Token Reset Detection: Tracks monthly token resets via NextResetTime field
  • Time Reset Detection: Smart value-drop detection for time-based quotas
  • Rate Calculations: Usage rate and projection to limit
  • Tool Breakdown: Per-tool token consumption with sortable table

New "Both" Provider View

A new unified view showing Synthetic and Z.ai side-by-side:

  • Dual-column layout with independent quota cards for each provider
  • Combined insights panel comparing usage across both services
  • Dual charts: Separate time-series charts for Synthetic and Z.ai
  • Merged sessions table: All sessions from both providers with provider badges
  • Unified reset cycles: All cycles with provider identification

UI/UX Improvements

Tab-Based Provider Selector:

  • Replaced dropdown with clean tab selector (Synthetic / Z.ai / Both)
  • Faster provider switching with single click
  • Visual indication of active provider
  • Mobile-responsive horizontal scroll on small screens

Quota Visibility Toggle:

  • New eye icon on each quota card to hide/show on graph
  • Hidden quotas shown at 50% opacity for visual clarity
  • Persistent state: Your visibility preferences saved in localStorage
  • Dynamic Y-axis scaling: Automatically recomputes based only on visible datasets
  • Supports both Synthetic (3 quotas) and Z.ai (2 quotas) providers

Improved Y-Axis Scaling:

  • Renamed "Performance" section to "Usage Graphs" for clarity
  • Dynamic scaling with 20% padding (was 100%) for better visual resolution
  • Rounded to nearest 5 for cleaner axis labels
  • Proper handling of zero values (shows max at 10%)

Performance & RAM Optimizations

Server-Side Pagination:

  • Bounded queries for RAM efficiency on large datasets
  • Configurable page sizes for sessions and cycles tables
  • Prevents unbounded memory growth with long-running instances

Measured Performance (v1.3.0):

  • Idle RAM: ~26-28 MB (stable)
  • Dashboard Load: ~28-30 MB
  • Both Provider View: Minimal overhead (~1-2 MB)
  • Binary Size: ~12-13 MB per platform

Infrastructure Changes

Default Port Change: 9211

  • New default port is 9211 (was 8932)
  • Better mnemonic: "9211" = "SynTrack"
  • Backwards compatible: syntrack stop checks both ports
  • All documentation updated

Documentation Updates

  • Updated README with Z.ai configuration instructions
  • Added Z.ai environment variables to .env.example
  • New zai_integration.md documenting Z.ai API specifics
  • Updated screenshots showing new UI features

Bug Fixes

  • Fixed Y-axis computation when highest value dataset is hidden
  • Fixed provider badge display in merged tables
  • Improved reset detection accuracy for rapid polling scenarios

All Platforms

This release includes binaries for:

  • macOS ARM64 (Apple Silicon) - syntrack-darwin-arm64
  • macOS AMD64 (Intel) - syntrack-darwin-amd64
  • Linux AMD64 - syntrack-linux-amd64
  • Linux ARM64 - syntrack-linux-arm64
  • Windows AMD64 - syntrack-windows-amd64.exe

Upgrade Notes

  1. Update your .env file to include Z.ai credentials (optional):

    ZAI_API_KEY=your_zai_key_here
    ZAI_POLL_INTERVAL=60
    
  2. Port change: If you have scripts referencing port 8932, update them to 9211

  3. Database: Existing Synthetic data is preserved; Z.ai tables created automatically

Known Limitations

  • Z.ai API token usage shows aggregated values (API limitation)
  • Time-based quota resets are detected via value-drop heuristic
  • "Both" view requires at least one poll from each provider to show data

Full Changelog: https://github.com/onllm-dev/syntrack/compare/v1.2.0...v1.3.0

v1.2.0 Maintenance
Notable features
  • New perf-monitor tool for tracking RAM and HTTP performance
  • Performance metrics added to README
Full changelog

What's New in v1.2.0

Performance & Resource Usage

This release includes comprehensive performance testing and updated resource targets:

Measured Performance:

  • Idle RAM: 26.3 MB (very stable baseline)
  • Dashboard Load RAM: 28.3 MB (+2.0 MB / +7.7% overhead)
  • API Response Times: 0.27-0.32 ms average
  • Dashboard Response: 0.71 ms
  • Request Throughput: ~77 requests/second

Updated RAM Targets:

  • Idle: 30 MB max (was 10 MB)
  • Load: 50 MB max (was 15 MB)

Performance Monitoring Tool

New developer tool for tracking RAM and HTTP performance:

cd tools/perf-monitor
go build -o perf-monitor .
./perf-monitor --restart  # Test with clean baseline

See DEVELOPMENT.md for details.

Documentation Updates

  • Added Performance section to README with measured metrics
  • Updated CLAUDE.md with corrected RAM budgets
  • Added performance monitoring documentation

All Platforms

This release includes binaries for:

  • macOS ARM64 (Apple Silicon)
  • macOS AMD64 (Intel)
  • Linux AMD64
  • Linux ARM64
  • Windows AMD64

Full Changelog: https://github.com/onllm-dev/syntrack/compare/v1.0.0...v1.2.0

Beta — feedback welcome: [email protected]