ThinkWatch-Lite

skill
Guvenlik Denetimi
Basarisiz
Health Gecti
  • License — License: MIT
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Community trust — 19 GitHub stars
Code Basarisiz
  • rm -rf — Recursive force deletion command in scripts/install.sh
  • network request — Outbound network request in scripts/install.sh
Permissions Gecti
  • Permissions — No dangerous permissions requested

Bu listing icin henuz AI raporu yok.

SUMMARY

Local gateway for Claude Code, Codex and other AI clients on macOS, Windows and Linux: switch upstreams without touching clients, redact keys before requests leave, trace every request's route and cost.

README.md

Tauri 2 React 19 License: MIT macOS Windows Linux

ThinkWatch Lite

English | 中文

ThinkWatch Lite is a desktop app for macOS, Windows and Linux that runs an AI
API gateway on the local machine. Claude Code, Codex and other clients of the
OpenAI and Anthropic APIs send their requests through it, and the app records
what each request cost, which upstream served it and which keys were redacted
before it was sent. The gateway can also be deployed on a server; the app then
connects to ThinkWatch Core on that server over an encrypted control channel.

The overview for the last seven days: tokens, cost and requests against the seven days before, with the estimated part of the cost and the unpriced requests stated; a trend chart stacked by model with the periods that had failures marked; and the models ranked by tokens and cost

The app runs in the menu bar on macOS and in the system tray on Windows and
Linux. It requires macOS 12 or later on Apple silicon, Windows 10 21H2 or later
on x64 or ARM64, or Linux on x86_64 or aarch64 (Ubuntu 22.04, Debian 12,
Fedora 36 or later). The interface is available in English and Simplified
Chinese; it follows the system language and can be changed in Settings. The
app updates itself on all three platforms, except that a Homebrew installation
is updated through Homebrew.

Install

Platform Install
macOS, Apple silicon brew install --cask thinkwatchproject/tap/thinkwatch-lite, or ThinkWatch-Lite-<version>-arm64.dmg
Windows, x64 ThinkWatch-Lite-<version>-x64-setup.exe
Windows, ARM64 ThinkWatch-Lite-<version>-arm64-setup.exe
Linux, x86_64 or aarch64 curl -fsSL https://github.com/ThinkWatchProject/ThinkWatch-Lite/releases/latest/download/install.sh | sh, or ThinkWatch-Lite-<version>-<arch>.AppImage

The Lite page offers a one-click download
of the latest version and selects the Windows or Linux architecture
automatically. The gateway,
ThinkWatch Core, ships
inside the app; nothing else needs to be installed.

macOS

brew install --cask thinkwatchproject/tap/thinkwatch-lite

A disk image is also available from the
latest release:
download ThinkWatch-Lite-<version>-arm64.dmg, check it against the sha256
published beside it, and drag ThinkWatch Lite into Applications. The app is
not signed by a registered Apple developer, so macOS quarantines a
downloaded copy and refuses to open it until the attribute is removed:

xattr -dr com.apple.quarantine "/Applications/ThinkWatch Lite.app"

The same can be done without a terminal: after the first refused launch,
choose Open Anyway in System Settings › Privacy & Security. Removing that
attribute is the only thing
the cask does beyond
copying the app out of the disk image.

Windows

Download the installer for the machine's architecture from the
latest release:
ThinkWatch-Lite-<version>-x64-setup.exe for most PCs, or
ThinkWatch-Lite-<version>-arm64-setup.exe for a PC with an ARM processor.
Check it against the sha256 published beside it:

Get-FileHash .\ThinkWatch-Lite-<version>-x64-setup.exe

The installer sets the app up for all users in Program Files, so Windows asks
for administrator permission. It requires Windows 10 21H2 or later; WebView2,
which Windows 11 already includes, is downloaded during installation if it is
missing.

The installer is not code-signed, and no certificate will be bought.
Running a downloaded copy brings up SmartScreen's full-screen warning,
"Windows protected your PC". Choose More info, then Run anyway.

Once installed, the app runs from the notification area. Data is kept in
%APPDATA%\ThinkWatch.

Linux

curl -fsSL https://github.com/ThinkWatchProject/ThinkWatch-Lite/releases/latest/download/install.sh | sh

The script downloads the AppImage for the machine's architecture, checks it
against the sha256 published beside it, installs it as
~/Applications/ThinkWatch-Lite.AppImage and starts it. Running it again
installs the latest version over the old one.

To install by hand, download ThinkWatch-Lite-<version>-x86_64.AppImage or
ThinkWatch-Lite-<version>-aarch64.AppImage from the
latest release,
check it with sha256sum -c, allow it to run (chmod +x, or Properties ›
"Allow executing file as program" in the file manager) and open it. Keep it in
a folder the user can write to, such as ~/Applications, so that it can
update itself. The first launch adds ThinkWatch Lite to the application menu,
together with its icon and the thinkwatch:// link handler. Only the AppImage
is published; there are no deb, rpm, Flatpak or Snap packages.

An AppImage mounts itself with FUSE and needs fusermount3 from the fuse3
package (libfuse2 is not needed). Most desktops already include it; otherwise:

Distribution Command
Ubuntu, Debian sudo apt install fuse3
Fedora sudo dnf install fuse3
Arch Linux sudo pacman -S fuse3
openSUSE sudo zypper install fuse3

The tray icon relies on AppIndicator. Ubuntu ships the GNOME extension for it;
Fedora's stock GNOME does not, and the AppIndicator extension has to be added.
Without a tray, closing the window leaves the gateway running, and launching
ThinkWatch Lite again from the application menu brings the window back. Data is
kept in ~/.thinkwatch.

  • Blank window on NVIDIA under Wayland: start the app with
    WEBKIT_DISABLE_DMABUF_RENDERER=1.
  • Other machines cannot reach the gateway: firewalld, which Fedora enables
    by default, blocks the gateway port until it is opened; Settings shows a
    note about this when the gateway listens on the local network.
  • Uninstalling: use Settings › Full uninstall first, which restores the clients
    the app configured and removes the autostart and application menu entries,
    then delete the AppImage.

Features

The main window has nine pages: Overview, Traffic, Clients, Keys, Upstreams,
Routing, Security, MCP and Settings.

Usage and cost

The Overview page reports tokens, cost and requests for the last 24 hours,
7 days, 30 days or a custom range, each against the period before; a live view
follows the last ten minutes. A trend chart stacks tokens or cost by model, and
the model ranking beneath it opens the matching requests. Further sections
cover the prompt cache (hit rate, the net savings it brought and the hit rate
per model), latency (median and 95th-percentile time to first token, per model
and per upstream), generation speed (median tokens per second, per model and
per upstream) and what each protection found.

The cost figure states how much of it is estimated, for instance for a
response that was cut off before it finished. Requests whose model has no
price, and requests whose upstream reported no usage, are counted separately
and never added in as zero. Prices come from price sheets: the default one
follows LiteLLM's public prices and is refreshed once a day, and a custom one
applies a multiplier and its own prices for particular models, as needed for a
relay whose prices differ from the official ones. A subscription account such
as a ChatGPT sign-in is priced from the price sheet like any other upstream,
and an upstream such as a local model can be set to free. Each request's cost
is fixed when the request finishes, and the request records the price sheet
and the date of the prices it was costed with.

Traffic and sessions

The Traffic page lists requests as they arrive: status, key, model, upstream,
time to first token and total time (with the generation speed on hover), tokens
and cost, with marks for a converted
API format, redacted keys and a blocked or suspicious tool call. The list can
be filtered by key, upstream and model, or narrowed to failed or unpriced
requests. The Sessions view groups the requests of one conversation into
turns, with the input tokens and the cost of each turn.

A request opens into its timeline, its routing (the rule it matched, the group
it went through and each attempt with its status and duration), the request
and response bodies, and its usage and cost. A request from DeepSeek Harness
also shows the size of the session log it carried, the whole conversation the
client attaches to every request; the gateway removes it before a request goes
to an upstream other than DeepSeek. A finished request can be sent
again, unchanged, to another upstream after an estimate of its cost, and the
two responses are shown side by side.

The traffic page: each request with its key, model, upstream, time to first byte and total time, tokens and cost, with marks for converted formats, redacted keys and a blocked request, and one request answered locally by the gateway

Client setup

The Clients page points Claude Code, Claude Desktop, Codex, opencode, Zed,
Aider and DeepSeek Harness at the gateway. Before anything is written, it lists
the fields that change and what else the change affects (the ChatGPT desktop
app, for instance, reads the same configuration file as Codex), shows the full
diff and backs up the original file. Only the settings that point the client at
the gateway change, and each client receives a key of its own. Claude Desktop is
connected through its official third-party inference mode, and the page lists
each of the files that change for it; a Claude Desktop managed by an
organization is left as it is. A connected client can be restored at any
time, on its own or together with all the others; a restored Codex keeps a
plain OpenAI entry in place of the gateway's, so sessions started while it was
connected can still be opened. opencode (v1 and v2) also
gets the list of models its key can use on the gateway; when that list
changes, the page offers to update it, through the same diff. Cursor, Continue
and Antigravity CLI come with step-by-step instructions and a key created for
them. For every client the page shows whether it is in use, waiting for its first
request or not in effect, and its requests over the last 24 hours.

On Windows, Claude Code and Codex installed inside WSL appear in a group of
their own for each distribution, next to the clients on the computer itself.
They are pointed at the gateway on Windows, restored and diagnosed the same
way, each with a key separate from the Windows copy, and their files are edited
through \\wsl.localhost. They are given 127.0.0.1, the same address as the
clients on Windows, which WSL reaches in two setups:

  • WSL 1, which shares the network with Windows.
  • WSL 2 with mirrored networking: networkingMode=mirrored under [wsl2]
    (or the older [experimental]) in %USERPROFILE%\.wslconfig. It needs
    Windows 11 22H2 or later and WSL 2.0.5 or later.

WSL 2 uses NAT networking by default, and the gateway on Windows cannot be
reached from inside WSL that way; the gateway does not listen on the WSL
virtual adapter for it. The WSL group then explains this instead of offering to
connect, and offers to switch to mirrored networking: networkingMode in
.wslconfig is added or changed, and nothing else in the file is touched,
through the same diff, confirmation and full backup as a client. The switch
takes effect once WSL restarts, which the page also offers (wsl --shutdown,
which stops every running distribution). A full uninstall leaves .wslconfig
as it is, and its backup is kept. On Windows 10 and Windows 11 21H2, which
have no mirrored networking, and with a WSL older than 2.0.5, the group says
so. When connected to a remote core, clients in WSL are pointed at the server
like those on Windows, whatever the networking.

The clients page: Claude Code and Codex connected, each with its own key and its requests over the last 24 hours; opencode not connected; Cursor set up by hand and in use; Continue and Antigravity CLI not yet set up; Zed and Aider not detected

Keys

Clients reach the gateway with a key, on the local machine as well. The Keys
page lists the default key, used by clients that were not given one of their
own, and a key for each connected client, labelled with the client it belongs
to so that its requests can be told apart in Traffic. Each key has a route,
the models it may use (all, none, or chosen models and patterns such as
gpt-5*), an optional limit on concurrent requests, and its requests and cost
over the last 24 hours. A key can be disabled, which rejects every request
made with it, or rotated; rotating writes the new key into the configuration
of the client that uses it.

The keys page: the default key and one key each for Claude Code, Codex and Cursor, with the route each key uses, the models it may use, and its requests and cost over the last 24 hours

Upstreams

Upstreams are the services requests are forwarded to: API keys for Anthropic,
OpenAI, Google Gemini, DeepSeek or any compatible endpoint, a ChatGPT account
or a Z.ai / BigModel account signed in from the app, relays such as
OpenRouter, and local models such as Ollama. A ChatGPT account shows its usage
limits and reset times. So does an upstream on a GLM Coding Plan, that is, one
whose address is on api.z.ai or open.bigmodel.cn, whether it was signed in
from the app or added with a key: its 5-hour and weekly limits and, on a plan
billed in credits, the credits left (“1,976 / 2,000 credits left”). When a
client and an upstream use different API formats, requests are converted
between Anthropic Messages, OpenAI Chat Completions, OpenAI Responses and
Gemini, and the fields that cannot be carried over are listed on the request.
Upstreams can be reached through an outbound proxy and priced with a price
sheet of their own; proxies and price sheets have tabs on the same page. A
connection test times the DNS lookup and the TCP, TLS and proxy handshakes
without incurring any cost; an inference test measures the time to first token
and estimates its cost before it runs.

API keys and header values can be written as ${NAME} to read a system
environment variable. On macOS these come from the login shell, so variables
exported in ~/.zshrc and similar files apply, and the same holds on Linux
(~/.bashrc, ~/.profile and so on); on Windows they are the
environment variables configured in system settings. After a variable changes,
reopening the app picks it up. Proxy variables such as HTTPS_PROXY, and
PATH, are not read.

The upstreams page: API-key upstreams for Anthropic, DeepSeek and Gemini, a relay priced with its own price sheet, a ChatGPT Plus account with 58% of its 5-hour limit used, OpenRouter through a proxy and a local Ollama set to free, each with its requests, cost and median time to first byte over 24 hours

A relay or vendor can hand out an import link, thinkwatch://import?… or its
web form https://thinkwat.ch/import#…, that pre-fills a new upstream with a
name, base URL, protocol, API key and model list. The app shows the settings
and the host that will receive requests and the key in a confirmation dialog,
and writes nothing and contacts nothing before Create is chosen. A link only
ever adds one upstream: it cannot change existing ones, headers, proxies,
pricing or routing, and a key that refers to an environment variable is
rejected. The parameters and a link builder are in
Import links.

Routing and failover

Each key follows a route, and keys without one follow the default route. A
route is a list of rules evaluated in order. A rule matches on the model, the
key, the client's API format, input tokens, max_tokens, the number of tools,
images, extended thinking, streaming, prompt caching or the kind of auxiliary
request; it then forwards the request to an upstream or a group, or refuses
it, and can rewrite the model, max_tokens or extended thinking. A group puts
several upstreams behind one name and decides the order in which they are
tried: as listed, manually selected, in turn, lowest latency first or lowest
cost first. When an attempt fails, the request moves on to the next upstream,
and by default a session stays on one upstream so that its prompt cache keeps
hitting. A map at the top of the page traces every key through its route and
groups to the upstreams.

The routing page: a map from keys through routes and groups to upstreams, and the three routes with the rules each applies in order

Auxiliary requests that clients send on their own (health checks, warm-ups,
titles, topic detection and input suggestions) can be answered locally at no
cost, passed through, or routed by the rules.

Every request records the rule it matched, the group it went through and each
attempt with its status and duration. A dry run evaluates the rules for a
given request and shows where it would go and why, without sending anything
and without incurring any cost.

A routing dry run: a request from the cursor key for claude-sonnet-5 in the OpenAI Chat Completions format does not match the gemini rule, which says why, matches the catch-all rule and goes to the lowest-cost group, which tries relay and then anthropic, converting the request to Anthropic Messages

Security

The Security page holds five protections. They apply to every upstream and
every key alike, and each runs in one of three modes: Off, Observe (detect and
record, change nothing) or Enforce. The output limit starts Off and the other
four start in Observe, so out of the box no request is changed or blocked.

  • Outbound redaction looks for credentials in a request before it leaves:
    API keys and tokens for Anthropic, OpenAI, GitHub, Slack, AWS, Google,
    GitLab, Stripe, npm, DigitalOcean and SendGrid, private keys, JWTs and
    passwords in connection strings. In Enforce mode they are replaced with
    placeholders and restored where the response repeats them. Rules for
    internal IP addresses and internal domains are included and start off.
  • Tool-call inspection checks the tool calls a model returns for commands
    that download or decode code and run it, send out environment variables or
    credential files, read private keys or cloud credentials, or install startup
    items and scheduled jobs. In
    Enforce mode such a call cuts the response off, so the client never receives
    a complete call to run. Deleting the home or root directory and making files
    world-writable are only recorded by default.
  • Hidden characters looks for Unicode tag characters and bidirectional
    control characters in what the client sends, tool results included, and in
    Enforce mode refuses the request.
  • Content filter matches keywords or regular expressions against the
    messages the client sends, tool results included, and in Enforce mode
    refuses a request that matches a blocking rule. Of the built-in rules, the
    three against explicit "ignore previous instructions" phrasing are on by
    default; rules for jailbreaks, persona manipulation, prompt extraction and
    their Chinese counterparts can be switched on.
  • Output limit stops an answer that grows past a set number of characters,
    100,000 by default: a streamed answer is cut off at that point and a
    non-streamed one is replaced with an error. Reasoning and tool-call
    arguments do not count towards the limit.

The page lists every rule. Built-in rules can be switched on or off one at a
time, and those for tool calls and content can be set to act or only record in
Enforce mode. Custom rules are regular expressions, or keywords for the content
filter, and any rule can be tried on a sample text first. Everything the
protections find is kept in the log on the first tab, together with the
request it came from.

The security log: credentials replaced before a request left, one of them matched by a custom rule; a download-and-run tool call cut off; and hidden characters, a delete command and an injected instruction recorded. Each entry names the key, client, model and upstream of its request

MCP

The MCP page covers what clients load from their own configuration files,
which does not pass through the gateway.

  • Servers: the MCP servers configured in Claude Code, Claude Desktop,
    Cursor, Codex, opencode, Antigravity CLI, Zed and DeepSeek Harness, side by
    side. A server can be copied from one client to another or removed from a
    client; the change is shown before anything is written, and the original file
    is backed up. Copying and removing work for Claude Code, Claude Desktop,
    Cursor and Codex; opencode, Antigravity CLI, Zed and DeepSeek Harness are
    listed but not written to. A remote server on another host is marked as
    third party, since using it sends the surrounding context to that host, and
    a server configured differently in different clients is marked as well and
    can be compared side by side.
  • Skills and hooks: the installed skills and configured hooks, with the
    client each belongs to.
  • Findings: client configuration, skills, hooks, slash commands, subagents
    and project instruction files are scanned for hidden characters, prompt
    injection, dangerous commands and overly broad permissions, and each finding
    is graded high, medium or low. The scan only reports; it never changes a
    file.

The app watches these files while it runs, and a new finding raises a system
notification.

The MCP page: the MCP servers configured in Claude Code, Claude Desktop, Cursor, Codex, opencode, Antigravity CLI and Zed side by side, with remote third-party servers and a server configured differently in two clients marked; the header counts one high, one medium and one low finding in 11 scanned files

Settings

Settings has six sections. Connection lists the local core and the saved
remote cores, described below. General sets
the language, the appearance, what the menu bar item shows on macOS, launch at
login, and whether notices arrive as system notifications, in the app only or
not at all. Listening sets who can reach the gateway (this machine only, the
local network of a chosen interface, or every interface), its port and the
allowed address ranges. Log retention sets how long request payloads and
request records are kept, and a size cap for payloads. About shows the
version, checks for updates and produces a diagnostics bundle with keys and
addresses masked. Uninstall restores every connected client and removes the
autostart entry, and is meant to be run before the app is deleted.

Menu bar, system tray and notifications

On macOS the menu bar shows today's tokens above today's cost; the numbers turn
orange when a subscription quota is nearly used up and red when it is, and
Settings can reduce the item to the icon or to the numbers.

The menu bar item: the ThinkWatch mark with a dot for a request in progress, and today's 13.3M tokens above today's cost of $9.34

Clicking it opens a native menu with the gateway's address, its generation speed
over the last minute and its state, unread
notices, today's requests, tokens and cost, the quotas and reset times of each
subscription account and GLM Coding Plan upstream (with the credits left under
the bar on a plan billed in credits), and the requests in progress, followed by
actions: choosing the upstream of a manually selected group, copying the
gateway address or the default key, switching connections and checking for
updates, all without opening the main window.

The menu it opens: the gateway's address, output speed and state; the ChatGPT account's 5-hour and weekly quotas with their reset times; today's requests, tokens and cost; the request in progress; and actions to copy the gateway address or the default key, undo the last configuration change, switch connections, open settings and check for updates

On Windows the icon sits in the notification area. Hovering over it shows the
gateway's state and today's tokens and cost; a left click opens the main
window, and a right click opens the same menu, with quota bars written out as
text.

On Linux the icon sits in the system tray. Clicking it opens the same menu,
with Open ThinkWatch Lite as its first item and quota bars written out as text.

System notifications, native on macOS and Windows and sent through the
desktop's notification service on Linux, report when the gateway stops
forwarding or keeps restarting, the connection to a remote core drops, a
subscription quota runs out, a sign-in expires or an upstream rejects its
credential, a proxy cannot be reached, the configuration file fails validation,
a tool call matches a rule that cuts the response off, or suspicious content
appears in a client's configuration. A new version found by the automatic check
is announced the same way (see Updates). An unreachable upstream,
which a fallback usually covers, is only listed in the app. Notices as a whole
can be set to system notifications, in-app only, or off. Marking a notice as
read stops the bell from counting it; the notice stays in the list until the
problem behind it clears or the list is cleared.

Connecting to a remote core

The gateway can also run on a server, where ThinkWatch Core runs as a system
service and the app connects to it over the network.
Server deployment
in the ThinkWatch Core repository covers installing twcore on Linux,
enabling its remote control port and reading its key.

In the app, Settings › Connection › Add remote connection takes a name, the
server's address, the control port and the key that twcore control-key
prints on the server. Testing the connection completes the encrypted handshake
and reads the server's core version; the connection can then be saved and
switched to. The connection menu at the foot of the sidebar, and the
Connection submenu of the menu bar or tray menu, switch between the local core
and any saved server.

Adding a remote connection in Settings: the server's address, its control port and the key from twcore control-key; the connection test has completed the handshake and reports core 0.48.0 and the server's gateway address
  • The app connects to one core at a time. While it is connected to a server,
    the local core stops once its requests in progress have finished; its
    configuration, keys and request history are kept, and it starts again when
    the app switches back. If the server cannot be reached, the app keeps
    retrying and never falls back to the local core on its own; the local core
    is always listed and can be switched back to in one step.
  • Overview, Traffic, Keys, Upstreams, Routing and Security show and change the
    server's configuration and data. Settings separates the app's own settings
    from the server's configuration, and the remote control listener and its key
    can only be changed on the server. The Clients and MCP pages always act on
    the machine the app runs on: connecting a client points it at the server's
    gateway. When switching from the local core to a server, the connected
    clients that still point to the local gateway, those in WSL included, can be
    pointed at the server in the same step; any left as they were can be pointed
    at it later from the Clients page.
  • The connection key is stored in a private file in the app's data directory,
    readable only by the current user.
  • A ChatGPT account is signed in with a device code, because a browser sign-in
    returns to the machine that runs core. ${NAME} in keys and header values
    reads the environment of the core process on the server. The diagnostics
    bundle is only offered for the local core.
  • The server has to run the core version this release of the app expects. The
    app checks this when it connects; if the versions differ, it names both and
    gives the command that installs the expected version on the server, whether
    it is newer or older than the installed one:
    sudo twcore upgrade --version <version> --restart.
The connection menu at the foot of the sidebar while the app is connected to the remote core homelab: the local core on this Mac is stopped, and a second server is available to switch to

Updates

The app looks for a new version shortly after it starts and once a day after
that, reading a small manifest and nothing else. It can be turned off in
Settings.

When the check finds one, the app sends a system notification, unless notices
are set to in-app only or off. The update window opens from that notification,
from the Install Version item that replaces Check for Updates in the menu bar or
tray menu, and from the update button in Settings › About. What happens next
depends on how the app was installed.

Downloaded from the releases page on macOS: one press on the install
button does the rest. The app downloads the update, verifies it against a key
compiled into itself, waits for the requests the gateway is serving to
finish — up to three minutes — then replaces itself and restarts. A Claude
Code task in the middle of a response is not cut off to make room for the
update.

On Windows: the same single press. The app downloads the new installer,
verifies it against the key compiled into itself, waits for the requests in
flight to finish in the same way, then runs the installer, and the new version
starts once it is done. The app is installed for all users, so Windows asks for
administrator permission at every update; declining leaves the current version
running.

On Linux: the same single press, and no password is asked for. The app
downloads the new AppImage, verifies it against the key compiled into itself,
waits for the requests in flight to finish, then replaces its own file and
restarts. The AppImage has to be in a folder the user can write to.

Installed with Homebrew: the window gives the command to copy, and the app
never replaces itself. Homebrew records which version it put in
/Applications; an app that overwrote it would be written back over by the
next brew upgrade. For a Homebrew installation the check reads the version in
the tap's cask instead of the release manifest, so a new version is only
reported once the tap carries it, and the command always has something to
install:

brew update && brew upgrade --cask thinkwatch-lite

brew update comes first because brew upgrade refreshes taps at most once a
day on its own.

Build from source

pnpm install
bash src-tauri/scripts/fetch-core.sh
pnpm tauri dev

fetch-core.sh downloads the twcore release that Cargo.lock pins, checks
its sha256 and places it in src-tauri/resources/, which every build needs.
See CONTRIBUTING.md for the checks to run before opening a
pull request.

Layout

src/              React 19 + Tailwind 4 interface
src-tauri/        Tauri 2 shell: supervises the local core, connects to a
                  local or remote core, draws the menu bar item and the tray
                  menu, sends system notifications, installs updates
src-tauri/crates/ tw-adopt (pointing clients at the gateway, MCP configuration)
                  and tw-scan (scanning client configuration)
scripts/shots/    the product screenshot pipeline (see CONTRIBUTING.md)

The gateway itself lives in ThinkWatch Core; this repository holds no routing,
forwarding, or accounting logic. The app reaches core's control channel over a
unix socket on macOS and Linux and over a loopback port on Windows, or over a
TCP port when core runs on a server. Every connection begins with an encrypted
handshake (Noise NNpsk0) keyed with the control key from core's
configuration (listen.control.key); no TLS certificates are involved.

License

MIT. See LICENSE.

Yorumlar (0)

Sonuc bulunamadi