ThinkWatch Core 0.47.0
This release adds a remote control port, through which ThinkWatch Lite on another machine can manage a core running on a server, together with an install script, a systemd unit and twcore upgrade for running twcore as a service on Linux. ThinkWatch Lite 2026.9.16 includes this version.
Upgrade notes
- A misspelled field under
proxies(for exampletyp:fortype:) is now a configuration error; it used to be ignored. A configuration that contains one does not passtwcore check, and core does not start with it. - Every connection to the control plane now begins with a Noise handshake, and control requests no longer use a bearer token. HTTP clients such as curl cannot call the control plane directly;
twcore callsends a request through the handshake. - Client adoption, MCP editing and the client configuration scan moved to ThinkWatch Lite, which runs on the machine where those files are. The
twcore scanandtwcore clientssubcommands and the related control-plane endpoints and events are removed;POST /clients/{id}/keyremains.
Control key. listen.control.key in config.yaml holds the key, and twcore serve adds one to a configuration that has none. Every control transport (the unix socket, the loopback port on Windows and the remote port) starts with a Noise_NNpsk0_25519_ChaChaPoly_BLAKE2s handshake keyed by it, and a wrong key is refused before any HTTP. twcore control-key prints the key; --rotate replaces it and closes the connections made with the previous one. The key is masked in GET /config, in the configuration history and in diagnostic bundles, and it cannot be changed through the control plane.
Remote control port. listen.control.remote opens a TCP port for ThinkWatch Lite on another machine, in addition to the local channel. twcore init writes the section disabled, with a random port from 20000–32000. twcore remote enable [--bind B] [--port N] [--allow CIDR], twcore remote disable and twcore remote show change and report it, and a running core applies a change within a second. A source outside allow_from (the private ranges by default; loopback is not added automatically) is closed before the handshake, and a source with five failed handshakes within 60 seconds is ignored for 60 seconds. Remote connections cannot shut core down, download diagnostics or change listen.control.
Server deployment. scripts/install.sh installs twcore on Linux (x86_64, aarch64) as a systemd service, with a thinkwatch system user, data in /var/lib/thinkwatch and environment variables in /etc/thinkwatch/env; it checks the SHA-256 and never starts or restarts the service. Releases now include twcore-<target>.tar.gz for both Linux targets, holding the binary, twcore.service and LICENSE. twcore upgrade [--check] [--restart] [--version X.Y.Z] replaces a separately installed twcore with a release from GitHub after checking its SHA-256 and running it once; it does not replace the copy inside ThinkWatch Lite, which the app updates itself. The guide is docs/server.md.
Configuration reference. docs/config.md (and docs/config.zh-CN.md) describes every section and field of config.yaml. The field tables and the lists of built-in rules are generated from the code, and a test fails when the manual and the code disagree.
Fix. On Linux, changing listen.gateway.bind between all and a single address on the same port now takes effect without a restart; it used to be reported as a port in use by another program.
Downloads
| Platform | Binary | Archive for server installation |
|---|---|---|
| Linux, x86_64 | twcore-x86_64-unknown-linux-gnu |
twcore-x86_64-unknown-linux-gnu.tar.gz |
| Linux, aarch64 | twcore-aarch64-unknown-linux-gnu |
twcore-aarch64-unknown-linux-gnu.tar.gz |
| macOS, Apple silicon | twcore-aarch64-apple-darwin |
— |
| Windows, x64 | twcore-x86_64-pc-windows-msvc.exe |
— |
| Windows, ARM64 | twcore-aarch64-pc-windows-msvc.exe |
— |
Each file is published with a .sha256 file beside it. A Linux archive contains twcore, the systemd unit twcore.service and LICENSE. ThinkWatch Lite includes its own copy of twcore; the files here are for running core separately, such as on a server.
Server installation
On Linux (x86_64 or aarch64), the install script sets up twcore as a systemd service. This installs 0.47.0:
curl -fsSL https://raw.githubusercontent.com/ThinkWatchProject/ThinkWatch-Core/main/scripts/install.sh | sudo sh -s -- --version 0.47.0An installation made with the script switches to 0.47.0 with:
sudo twcore upgrade --version 0.47.0 --restartConfiguration, the remote control port and connecting ThinkWatch Lite are described in docs/server.md.
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 Linux:
sha256sum -c twcore-x86_64-unknown-linux-gnu.tar.gz.sha256On macOS:
shasum -a 256 -c twcore-aarch64-apple-darwin.sha256On Windows, in PowerShell, the following prints True when the binary matches:
(Get-FileHash .\twcore-x86_64-pc-windows-msvc.exe).Hash -eq (Get-Content .\twcore-x86_64-pc-windows-msvc.exe.sha256).Split()[0]The install script and twcore upgrade check the SHA-256 themselves.
What's Changed
- feat(control): one control key and a Noise handshake on every control connection by @fylorn in #184
- Configuration reference, server deployment, and twcore upgrade by @fylorn in #183
- refactor!: move client adoption, MCP editing and the client scan to the desktop app by @fylorn in #186
- fix(gateway): switching the listen address on the same port takes effect live by @fylorn in #188
- test(watch): make the "a burst is one signal" tests independent of disk stalls by @fylorn in #189
- feat(control): a remote control port, opened in addition to the local channel by @fylorn in #187
- fix(config): a misspelled field under proxies is an error by @fylorn in #185
- chore: v0.47.0 by @fylorn in #190
Full Changelog: v0.46.0...v0.47.0