Repository navigation
ThinkWatch Lite 2026.9.17
Upgrade notes: the bundled core is upgraded to 0.49.0. The request store has a new format: on its first start, the new core empties the request history, the stored request and response bodies and the security log, and statistics such as usage and cost start again from zero. The configuration is kept. A remote server has to run the same core version, 0.49.0 (ThinkWatch Lite 2026.9.16 cannot connect to a server running 0.49.0), so the server and the app are updated together. When the versions differ, the app gives the command to run on the server, sudo twcore upgrade --version 0.49.0 --restart, which applies whether the installed version is newer or older. When the core on a server is upgraded from 0.47.0, its first start empties the server's request history as well.
Redesigned interface: every page is rebuilt on a common design, with a summary in the page header, skeletons while data loads and a Retry button when a read fails. Turning keys, upstreams, security rules and similar items on or off can be undone from the notification that follows. On macOS, the sidebar of the main window is translucent.
Overview: the model, cache, latency and upstream rows and the failure marks can be clicked, and open Traffic filtered to what was clicked; a model is matched by its exact name. The model ranking distinguishes Unpriced, No usage and a cost that is actually zero, and when a model has unpriced requests, clicking its cost shows those requests. The latency section now covers the selected time range; it used to cover the current day only.
Traffic: the page header shows the requests in progress, the failed requests and the requests per minute over the last 30 minutes; clicking the failed count shows failed requests only. A request in progress shows how long it has been running, updated every second, and belongs to its session from the moment it starts. Requests that a rule denies before an upstream is chosen, and requests that no upstream could serve, are now recorded, marked Denied or No upstream, and counted as failures. The Routing tab of the request details lists the route, the matched rule, the group, the rules that rewrote the request, the rule that denied it and the reason. The token column shows the total input, including cache reads and cache writes, followed by the output.
Clients and Keys: the Clients page counts clients by state in its header, and its Set up by hand and Not detected sections can be collapsed. On the Keys page, each key shows its requests per hour over the last 24 hours and is marked In progress while one of its requests is running.
Upstreams: each upstream shows its vendor's logo and its requests per hour over the last 24 hours, with the hours that had failures marked in red; the row menu has a new View traffic item. The email and plan of a ChatGPT account are now read from the saved credential, without a network request, and are the same everywhere; once the sign-in has expired, the account is still named and its quota is no longer queried. Plans carry the names that Codex gives them. A completed ChatGPT sign-in names the account that was signed in, and a completed Z.ai sign-in no longer occasionally leaves out the account name.
Routing: a map at the top of the page shows where requests go, from keys through routes and groups to upstreams. Hovering a table row or a node highlights the paths through it, and a request in progress lights its path according to core's routing decision. Each rule shows its hits over the last 7 days, a rule without hits in that time is marked No hits, and on the map the lines leaving a route grow thicker with the number of requests. When fewer than 7 days of requests are recorded, the counts are labelled with the span the records cover, such as 5-hour hits.
Security and MCP: the Security page header shows how many protections are enforcing, observing or off, and the exact number of matches in the selected period, broken down by outcome. The log is grouped by day. A single click opens a rule, where a double click was needed before. The MCP page header summarizes the findings by severity and the time of the scan; clicking a server row shows its configuration in each client, with the fields that differ marked.
Settings: an index of the sections on the left follows the scrolling and marks a section with unsaved changes; unsaved changes remain after switching pages. The page header shows the current connection, the gateway address and the version. Uninstall is a confirmation dialog that lists what will be done and reports the result of each step, and its title says when a step failed.
Command palette: ⌘K opens the command palette (on Windows and Linux, Ctrl takes the place of ⌘ here and below). It opens pages; runs actions such as creating items, the inference and connection tests, the routing dry run and switching connections; and searches upstreams, keys, routes, clients, Settings sections, the requests already loaded and more. ⌘1 to ⌘9 switch pages, ⌘R now refreshes the data of the current page, and ? outside a text field shows the keyboard shortcuts.
Menu bar: the running time under In Progress in the menu is now computed by core, so a difference between the clocks of the two machines no longer affects it when the app is connected to a remote core. In the English interface, the text in the Quota and Today parts of the macOS menu bar menu no longer overlaps, and the tray on Windows and Linux names the local connection This computer.
Downloads
| Platform | File |
|---|---|
| macOS, Apple silicon | ThinkWatch-Lite-2026.9.17-arm64.dmg |
| Windows, x64 | ThinkWatch-Lite-2026.9.17-x64-setup.exe |
| Windows, ARM64 | ThinkWatch-Lite-2026.9.17-arm64-setup.exe |
| Linux, x86_64 | ThinkWatch-Lite-2026.9.17-x86_64.AppImage |
| Linux, aarch64 | ThinkWatch-Lite-2026.9.17-aarch64.AppImage |
Each file is published with a .sha256 file beside it. latest.json is the manifest for in-app updates, and install.sh is the Linux install script.
On macOS, Homebrew installs the same disk image:
brew install --cask thinkwatchproject/tap/thinkwatch-liteOn Linux, the install script downloads the AppImage for the machine's architecture, checks its SHA-256 and installs it as ~/Applications/ThinkWatch-Lite.AppImage:
curl -fsSL https://github.com/ThinkWatchProject/ThinkWatch-Lite/releases/latest/download/install.sh | shBoth commands install the latest release. First-launch steps for each platform, such as removing the quarantine attribute from a copy downloaded on macOS, are described in the README.
Verifying a download
A .sha256 file holds the SHA-256 of the file followed by its name. With both files in the current directory, on macOS:
shasum -a 256 -c ThinkWatch-Lite-2026.9.17-arm64.dmg.sha256On Linux:
sha256sum -c ThinkWatch-Lite-2026.9.17-x86_64.AppImage.sha256On Windows, in PowerShell, the following prints True when the installer matches:
(Get-FileHash .\ThinkWatch-Lite-2026.9.17-x64-setup.exe).Hash -eq (Get-Content .\ThinkWatch-Lite-2026.9.17-x64-setup.exe.sha256).Split()[0]The Homebrew cask and the Linux install script check the SHA-256 themselves.
What's Changed
- test(control_plane): let core pick its own gateway port by @fylorn in #185
- UI foundation: design system, shell and translucent sidebar by @fylorn in #187
- Security and MCP pages: design kit, day-grouped log, undoable rule changes by @fylorn in #188
- Keys and Clients pages: design kit, per-key 24-hour sparklines, live state by @fylorn in #190
- Routing page: chain map hero, design kit, live paths by @fylorn in #191
- Upstreams page: design kit, vendor logos, 24-hour sparklines, undoable enable/disable by @fylorn in #193
- Command palette: search entities, open page dialogs, shortcut sheet by @fylorn in #192
- Settings: preferences page with section index, grouped rows and complete states; update window polish by @fylorn in #194
- Traffic page: design kit, live summary with sparkline, row motion, drawer states by @fylorn in #197
- Overview page: design kit, skeleton and error states, live edge, clickable breakdowns by @fylorn in #196
- Traffic: exact model filter for overview drill-downs by @fylorn in #198
- Uninstall: report success per step and say when a step failed by @fylorn in #199
- docs: list the current release platforms in the PR template by @fylorn in #186
- Menu bar: size columns from measured text; name the local connection per platform by @fylorn in #195
- docs: product screenshots from a committed, deterministic pipeline by @fylorn in #189
- Use core v0.48.0 by @fylorn in #202
- Security header: exact match count from core, broken down by outcome by @fylorn in #203
- Upstreams: one account label everywhere, read from the token; no live call for a broken sign-in by @fylorn in #205
- Routing: live paths from core's routing decision, 7-day hit counts by @fylorn in #207
- Overview: tell unpriced, free and no-usage models apart by @fylorn in #206
- Traffic: running turns live in their sessions; running rows tick on core's clock by @fylorn in #208
- Version mismatch: give the command that installs the core version this app pins by @fylorn in #204
- ci(release): write the release page from a template, with an English summary by @fylorn in #200
- docs: rewrite the READMEs for the current app and use the new screenshots by @fylorn in #201
- Request drawer: the whole routing decision; name requests that reached no upstream by @fylorn in #209
- Use core v0.49.0 by @fylorn in #210
- chore: 2026.9.17 by @fylorn in #211
Full Changelog: v2026.9.16...v2026.9.17