Skip to content

Releases: Nanako0129/syrtis

Syrtis 2.2.0

Choose a tag to compare

@github-actions github-actions released this 28 Sep 15:02
7cac056

Features

  • Releases are signed with a Developer ID and notarized by Apple. #445

    macOS now opens a downloaded Syrtis without a Gatekeeper warning, so the Homebrew cask no longer removes the quarantine flag on install. Installed copies update through the in-app updater as before: in testing, an installed v2.1.0 updated itself to a Developer-ID build, and launch at login and quota reads were unaffected.

  • Each release has an installer DMG. #454

    Syrtis-2.2.0.dmg on the release page opens a window with the app and an Applications folder to drag it onto. It is signed and notarized like the app. In-app updates and the Homebrew cask keep using Syrtis.app.tar.gz.

  • A new animated menu bar icon: Sand shoal. #441

    Sand falls onto a dune while a current carries grains off its far side. It plays at a fixed 24 fps in four levels: as the live token rate passes 50K, 300K and 1.5M tokens per minute at the default pace, more sand falls and the dune grows and erodes further. Suggested on Discord by charliie.

  • Animated icons follow a new speed curve, set by an animation pace. #441

    The cat and parrot run at 2 fps up to 50K tokens per minute, then speed up on a log curve to 40 fps at 3M. The previous curve was linear and reached full speed at 1M. A pace choice under Settings → Menubar icon scales this for how busy your agents are: Light reaches full speed at 600K tokens per minute, Moderate (the default) at 3M, and Heavy at about 10M. The same pace moves the Sand shoal's level thresholds.

  • First-run setup cards on the Overview. #442 — relates to #435

    Cards at the top of the Overview cover which agents get a tab, the menu bar icon and text, the animation pace, usage attribution, starting at login, and the Discord profile. They show at once and each is answered on its own; "Skip setup" answers the rest. Existing users see them once too, with their current choices already selected. The Discord card replaces the Discord alert that appeared at launch, and neither of its buttons turns the Discord profile on.

Fixes

  • With no quota reading, the menu bar gauge looked like a full allowance. #439 — fixes #419

    When no reading is available, for example when every provider fails at once under Auto, the gauge is now drawn faded with a diagonal slash, in every gauge style and in the Settings preview.

  • An old reading's title kept its warning color. #440 — fixes #420

    v2.1.0 turned the gauge grey once its reading was more than 30 minutes old, but the "Quota left" title beside it stayed red or amber, and with the cat or parrot nothing showed the reading was old. The title now turns the same grey, over both automatic and custom colors, and takes its color back with the next fresh reading.

  • Switching pages kept the previous scroll position. #444

    A new Settings page, or a new tab or view in the dashboard, now starts at the top.

  • Two Settings hints described behavior the app does not have. #443

    Data refresh said the live tokens-per-minute figure updates every few seconds whatever the setting, which is not how the app reads it; the hint now says the setting sets how often all logs are reread in full. Overview cards said the list sets their order; the order is fixed. The Settings hints, the usage attribution page, the Claude setup-token note and the Grok Bot Keychain notice were also rewritten in shorter, plainer language in English, Traditional Chinese and Simplified Chinese.

Syrtis 2.1.0

Choose a tag to compare

@github-actions github-actions released this 27 Sep 19:43
07d6592

Features

  • A card offers to attribute your usage to subscriptions. #437

    Until usage is attributed, a subscription's window history lists 0 tokens and $0.00 for every window, which reads like an idle window rather than a missing setting. When nothing is attributed yet, a card at the top of Overview and of the Quota view on every client tab lists the suggested assignments, each as the source, its provider and the subscription it would count toward, and applies them in one click. Settings → Usage attribution suggests the same assignments. "Set up manually…" opens that page, and "Not now" hides the card for good. The window history also says why its figures are 0 and links to the page, and the "Nothing is classified yet" hints in Stats now open it too.

  • Grok Build models are listed under one name. #417

    Grok Build reports usage as grok-4.6-build while its session names grok-4.6, so one model showed up as two rows. Models, Monthly, Daily and the Grok quota card's per-model breakdown now list grok-4.6 and grok-4.7 once each, in one color. Totals are unchanged.

  • The menu bar gauge turns grey when its reading is old. #418

    The gauge used to draw the last reading in its warning colors however old it was. It now turns grey once the reading it shows is more than 30 minutes old, and takes its color back with the next fresh reading.

Fixes

  • Setting the clock back could erase quota history. #415

    When the history file held readings stamped later than the current time, loading it dropped each such series whole. A poll that recorded anything then saved the loss. On a copy of a real history file with the clock set back 10 minutes, the previous version dropped 3 of 18 series in memory, 10,163 readings down to 3,780. That the next recording poll would have saved the loss was derived from the code, not run on the copy. This version drops only the 4 readings stamped in the future and keeps every series. Repairs made while loading are also written back to the file once, instead of being redone in memory on every load.

  • The window history said "Quota history could not be read. It will be retried." for good. #433 #434

    Some sources record no quota history: Antigravity read through the agy CLI, which carries no account identity, and a Grok Bot token that names no account. Reading their history failed on every update, and the failure was reported as one that would be retried. Their window history now shows "No earlier windows recorded yet." The retry message stays for history that exists and could not be read.

  • Model prices stopped updating while you were idle. #413 — fixes #191

    The model report, and the "Prices updated …" time on the Models card, only refreshed when an agent wrote new usage. While the dashboard is open, the report is now fetched again once it is an hour old.

  • A signed-in agy that Syrtis could not find started a login shell on every refresh. #402 — relates to #353

    When Antigravity's other routes fail and agy is signed in but not on the app's PATH, Syrtis starts a login shell to look for it. If that search found nothing, it ran again on the next refresh. It now runs at most once every 15 minutes.

  • Claude credential errors said only "could not be loaded". #411 — relates to #225 and #226

    Each failure now names its cause in a fixed message, and no message includes credential content. A Keychain credential with a character outside printable ASCII came back from macOS as hex and was treated as unusable. It is now decoded and read.

  • A malformed Codex token could skip the refresh check. #397 — fixes #385, thanks @snowman12320

    A token with a missing, extra or empty segment could supply an expiry that kept Codex from refreshing. Such a token's expiry is no longer trusted, and the refresh falls back to the time of the last refresh.

  • Quota history that failed to load was described as never recorded. #405

    Past windows and the heatmap now say "Quota history could not be read. It will be retried." when a window's history failed to load and nothing is left to show.

  • The separators in the light glass panel were harsh. #436

    On macOS 27 in light mode, the lines under the row of views (Overview, Quota, Models…) and above the footer are now lighter. Dark mode is unchanged.

Full Changelog: v2.0.1...v2.1.0

Syrtis 2.0.1

Choose a tag to compare

@github-actions github-actions released this 26 Sep 20:16
59f2c9d

Fixes

  • Hover tooltips in the glass panel were hard to read over a list. #399 — relates to #398

    On macOS 27 the tooltips used clear glass, which barely blurs what is behind it, so over the window history the rows beneath showed through the tooltip's own figures. The tooltips now use the same frosted glass as the panel.

Full Changelog: v2.0.0...v2.0.1

Syrtis 2.0.0

Choose a tag to compare

@github-actions github-actions released this 26 Sep 03:39
7a807f3

Syrtis

Before you update

TokenBar is now Syrtis, and the first launch renames the app on disk. #392 #395 #390

The update installs over TokenBar.app. On its first launch the app renames itself to Syrtis.app in the same folder and starts again from there. The bundle identifier has not changed, so settings, usage history and the login item carry over.

If TokenBar.app is pinned in the Dock, the tile is repointed at Syrtis.app and the Dock restarts once. Two things follow from that restart. Windows you had minimized to the Dock leave it; clicking their app brings them back. The pinned tile may keep the old icon until you click it once.

The rename is skipped when a Syrtis.app already sits beside it, or when the account cannot write to the Applications folder. The app then keeps the file name TokenBar.app and works the same.

Homebrew has a new tap. New installs use brew install --cask nanako0129/tap/syrtis. An existing install from nanako0129/tokenbar keeps updating through the app itself; that cask stays on the last TokenBar release. To move an existing install to the new tap, quit the app, run brew uninstall --cask tokenbar, move Syrtis.app (or TokenBar.app) from Applications to the Trash, then run brew install --cask nanako0129/tap/syrtis. The uninstall alone can leave the renamed Syrtis.app behind. Settings and usage history are kept.

Some clients re-scan once, and several count differently. #386 #389

The engine moves forward, and Copilot, Grok, OpenClaw, RooCode, KiloCode, Cline, Cursor, OpenCode, Pi and Droid each rebuild their cache once on the first launch. Every other client, Claude and Codex included, is read from its existing cache.

  • Pi counts fall if you fork sessions. A forked session copies the parent's replies into the new file with the same response id, and each copy was counted again. Each reply now counts once.
  • OpenClaw counts can move either way. Archived sessions (.jsonl.zst) are now read, which adds usage that was missing, and compaction checkpoints are no longer counted as usage.
  • OpenCode 2.x usage appears. It read as zero because the old session lookup failed on 2.x.
  • Grok usage after an invalid UTF-8 line is recovered. A session file used to be dropped from its first invalid line onwards.

Droid totals are unchanged: a session's usage is now split across its replies instead of landing as one record. Cursor's Input (w/ Cache Write) is now counted as cache write, and a $0.00 cost Cursor reports is kept as $0.00.

Costs for claude-fable-5-1 and claude-opus-5-5 fall by 16.7%. #389

The previous engine could not match OpenRouter's dotted names for these two models (claude-fable-5.1, claude-opus-5.5) and fell back to an AWS GovCloud Bedrock price entry that is 1.2 times the list price on every rate. They now resolve to Anthropic's own entry. Token counts are unchanged, and past usage is repriced the same way. claude-opus-4-8, and claude-haiku-4-5 used through OpenCode, rise slightly where some of their cache writes had been priced at $0.

Features

  • On macOS 27, the dashboard opens in a Liquid Glass panel. #380 #391

    The popover blurred the desktop before the dashboard could see it, so its glass could only show a flat tone. The panel's glass refracts the actual wallpaper. It closes on Esc or a click anywhere else, and right-clicking the menu bar item still opens the menu. Tab selections slide, bar charts regrow and heatmaps crossfade between views. Below macOS 27 the popover is unchanged.

  • A new icon and name in the app. #392

    The panel header shows the Syrtis mark and the Greek wordmark Σύρτις, the Settings sidebar uses the same mark, and Discord presence shows the new icon. The site is now syrtis.nyanako.com, with a page on where the name comes from. Old links to the TokenBar site and repository redirect.

Fixes

  • A quota window's readings were deleted when they could not be modelled. #373 — relates to #370

    History kept only the windows a pace curve could be fitted to. When a provider moved a reset later, the window's recorded reset no longer qualified, and its readings were erased: on the store behind #370, two weekly windows of 51 readings each. They are now kept, within the usual history limits. They still do not feed the pace model.

  • Codex asked you to sign in again while a refresh token was available. #344 — thanks @snowman12320

    Codex access tokens can expire before the eight-day interval TokenBar used to decide when to refresh them. The token's own expiry is now checked, and it is refreshed within five minutes of it.

  • Switching windows on the quota window card paused the app. #383

    Each switch re-read the whole quota history once per part of the card that wanted it: 131–144 ms on the main thread in a release build. Each series is now read once per update, and a switch takes 12–15 ms.

  • Opening the dashboard right after launch computed the usage graph up to three times. #384

    Requests that arrive while the graph is being computed now wait for that result. In three paired runs on real data, the graph was ready after 2.4, 2.2 and 2.1 s, down from 5.6, 3.7 and 4.6 s.

  • The Local Network prompt did not say why it appeared. #374 — thanks @mvanhorn

    macOS can ask for local network access when a VPN routes provider traffic through a local network. The prompt now explains that Syrtis connects to your providers to read quota information.

New Contributors

Full Changelog: v1.20.2...v2.0.0

TokenBar 1.20.2

Choose a tag to compare

@github-actions github-actions released this 24 Sep 02:27
425514e

Fixes

  • With the Antigravity CLI signed out, TokenBar could open a Google sign-in page on every refresh. #378

    When the Antigravity IDE is closed and no Gemini CLI login is available, TokenBar asks the agy CLI for quota instead. Signed out, that command opens a browser tab for Google sign-in and waits, and TokenBar ran it on every refresh: once a minute with the popover open.

    TokenBar now checks that agy's login item exists in the Keychain before running it, and skips the CLI when it does not. Only the item's presence and modification date are read, never the token. If agy runs and still fails, it is not run again until you sign in to agy again or restart TokenBar; until then the Antigravity card shows the error from the other routes.

Full Changelog: v1.20.1...v1.20.2

TokenBar 1.20.1

Choose a tag to compare

@github-actions github-actions released this 22 Sep 20:17
098f681

Fixes

  • A model with no price read $0.00, the same as free usage. #375

    A row that shows a token count beside an amount now shows — when those tokens could not be priced. That happens when a model is not in the pricing data yet: Claude Opus 5.5 read $0.00 until LiteLLM and OpenRouter listed it on 2026-09-22. The Models tab, the model breakdown, Agents, the Daily and Monthly rows, the usage chart, the heatmap and the usage attribution rows all follow this.

    In the same places, a positive amount under half a cent now reads <$0.01 instead of $0.00. Totals shown without a token count beside them are unchanged, and they still count unpriced usage as nothing.

Full Changelog: v1.20.0...v1.20.1

TokenBar 1.20.0

Choose a tag to compare

@github-actions github-actions released this 21 Sep 06:30
ac0becb

Before you update

Repairing an unwritable history file drops a few stored samples, once. #371

A history file the engine could no longer write is now repaired on the first poll rather than refused, and the repair drops the samples that were making it fail validation. Measured on one real store: 39 samples of 5815 in one series, 0.67%. The polls after it needed no repair.

Features

  • Hovering a row in a window's history shows what its tokens were. #368

    Input, output, cache read and cache write, each with its share as a percentage, under a heading naming the window's date and time span. The whole row is the hover target rather than the token count alone, and each model line carries its own breakdown.

Fixes

  • Pace and history read "unavailable" for every provider, and stayed that way. #371 — relates to #370

    A write the engine refused wrote nothing and quarantined nothing, so the next poll met the same file and refused it identically. The refusal was permanent rather than transient, and it takes every window in the batch with it: one series stopped the whole lens reporting pace. The write is now repaired inside a bounded allowance instead of refused.

    The cost was worse than a blank field. While writes were refused the window in progress stopped gaining readings, and a window that ends with no readings near its end was deleted outright — so a refused write destroyed the window it had been unable to extend.

    #370 is not closed. A separate defect still deletes a window whose reset the provider later revises.

  • One provider's unreadable credential erased every other provider's history. #360 — relates to #359

    A read that fails now costs only its own window. A card whose read failed keeps what it already had, instead of the failure emptying the lens.

  • A few seconds of drift in a provider's reset time split one window into two. #369 — relates to #367

    The second of the pair read 0% against the full span's tokens. Readings a few seconds apart are grouped as one window again, and the group reports the reset time most of its readings agree on.

  • The quota cards were recomputed from scratch every time the popover opened. #361 #364

    The history strip, the heatmap and the equivalences are drawn from the reopen cache, so they are present when the popover appears rather than arriving a moment after it.

  • The daily chart flashed empty for a frame when the popover opened. #362

    A series' rows are folded when the view is constructed, not on its first task tick.

Full Changelog: v1.19.1...v1.20.0

TokenBar 1.19.1

Choose a tag to compare

@github-actions github-actions released this 19 Sep 02:29
07c8cad

Fixes

  • The Quota lens could report that no history had ever been recorded, about history that was still on disk. #356 — reported in #355

    Past windows and When the allowance goes fill on launch and could go empty after the app had been running a while, saying No completed windows recorded yet. Nothing was lost — relaunching brought the cards back.

    A refresh that cannot read any history no longer replaces what is already on screen. Quota history accumulates, so a refresh returning nothing after those cards have been filled is that pass failing to answer rather than the history ceasing to exist, and the cards now keep what they have.

    Why those reads come back empty is still open in #355. This does not claim to have fixed that; it stops it from erasing what was already recorded.

Full Changelog: v1.19.0...v1.19.1

TokenBar 1.19.0

Choose a tag to compare

@github-actions github-actions released this 18 Sep 23:19
8fe76bb

Before you update

Tabs for providers you never set up disappear, and Antigravity's two tabs become one. #348 #349

Both are visible the first time you open the popover.

v1.18.0 began including configured quota sources in the tab bar alongside local usage, which is right for a provider you use and wrong for one you don't. Codex, Claude and Antigravity are built as cards that always exist, so the presence of a card said nothing about whether anything had been set up, and Codex and Antigravity took a tab on every install. Reported in #345. A provider with no credential at all now has no tab. One whose credential exists and cannot be read — a permission problem, a corrupt file — keeps its tab and shows what went wrong.

Antigravity's IDE and CLI clients draw on one subscription and had a tab each. They now share one, labelled Antigravity, the arrangement Grok Build and Grok Bot already use: the CLI's usage and the IDE's quota card sit under it together. Your own settings survive the merge — a hidden Antigravity CLI tab stays hidden, and its place in your saved tab order becomes the merged tab's.

Fixes

  • An agy installed after TokenBar started was never found. #330 — thanks @iF2007

    Antigravity's CLI discovery cached its answer for the life of the process, including the answer that there was nothing to find. Installing agy while TokenBar was running therefore changed nothing until the next launch, and the card went on reporting the error it had been given before. An empty result is now retried on a later refresh.

Full Changelog: v1.18.0...v1.19.0

TokenBar 1.18.0

Choose a tag to compare

@github-actions github-actions released this 16 Sep 13:22
78c44db

Before you update

Codex turn counts jump from zero to thousands, and the first launch rescans Codex transcripts once. #315

Codex used to announce a human turn as an event_msg of type user_message. Around version 0.145 it stopped, and now reports the same input as an item_completed carrying a UserMessage item. TokenBar recognised only the old shape, so is_turn_start never fired on a recent transcript and the Daily and Monthly cards read 0 turns for Codex on essentially every day.

Nothing was recounted. On every day with Codex activity, every other figure is byte-identical before and after — tokens, cost, messages, models. Only the turn column moves, which is what makes this checkable: the number that was wrong is the only one that changed.

Reading turns out of the old cache is not possible, so parser_version for Codex moves 5 to 6 and every Codex shard is rebuilt once on first launch. No other client's cache is touched — Claude, Copilot, Gemini and the rest are read from their existing shards as usual. The launch after it is normal speed.

Features

  • The paid OpenCode Go plan now has a quota card. #301 — thanks @binhonglee

    OpenCode stores the Go plan under a separate api key, and TokenBar read only the Copilot quota that lives in the same auth.json. Its rolling, weekly and monthly windows now appear under the existing opencode client rather than as a new tab, the same arrangement the Copilot quota already uses.

  • Kiro's monthly allowance now appears as a quota card. #305 — thanks @binhonglee

    Kiro was already recognised as a subscription for attribution, but no quota was ever fetched for it, so the plan had no usage bar. The token is discovered from either the kiro-cli store or the Kiro IDE token file.

  • Grok Bot's weekly allowance now appears alongside Grok Build's. #316 — thanks @savourylie

    The two are separate allowances and only Grok Build's was read. Both now appear together under a Grok Build & Bot tab in Overview and Quota, including on machines with no local Grok usage records at all.

    Reading that allowance needs your permission once. #338

    Grok Bot keeps its login in your Keychain, and the weekly limit cannot be read without decrypting it. Rather than letting macOS ask out of nowhere, the card says what it needs and waits. Allow proceeds, and the system dialog follows a second or two later; Not now leaves the card as a single grey line, with Allow still there whenever you change your mind. If macOS itself refuses, or never answers, the card says so and TokenBar stops asking rather than raising the dialog again every cycle — Allow tries once more when you want it to.

    The login is used for one thing: asking Grok Bot's usage endpoint (api2.cursor.sh) what your weekly limit is. TokenBar does not store it, does not log it, and sends it nowhere else. Declining affects that card and nothing else — there is no setting to find and nothing to undo later, because once macOS holds the grant only macOS can withdraw it.

    Having Grok Bot signed in already does not change this: the card still asks, and macOS may still want to confirm. Reading the item is what this integration does for the first time in this release, so there is no prior grant to rely on, and TokenBar cannot check for one without performing the read it is asking about — asking macOS whether it would allow the read is the read.

  • Window history grows past twelve rows. #334

    The card drew twelve cycles with no way to reach the thirteenth. It still opens at twelve, and a Show N more link under the list adds twelve per press until every cycle is on screen. Pressing to exhaustion reaches 32, which is where the engine's fold stops.

Fixes

  • A quota poll could open a browser tab you never asked for. #332 — reported by @banahaker in #329

    agy --print is documented as non-interactive and is not: with an expired token and no DNS, it treats the network failure as an authentication failure and starts an interactive sign-in, which opens a tab. The defect is the CLI's, but TokenBar is the only thing invoking it unattended, and its timer fires exactly when that path is most likely. TokenBar now resolves the endpoint first and gives up without invoking the CLI when that fails.

  • A window-history card said usage was never recorded, about usage sitting in the same scan. #322

    Two different statements were collapsed into one flag: this machine recorded nothing, and this machine recorded it and you have not said which subscription it belongs to. Three places computed that flag, each the same wrong way, so a client you had not classified was reported as having no records at all. The flag is now decided per subscription.

  • One long model name stretched a whole usage card past the edge of the popover. #336 — reported in #335

    The layout measured every legend item at its ideal width and took the widest row as the card's own width, so a single entry wider than the popover stretched everything around it. Locally-served model names reach that length easily — the report had one running to hauhaucs/qwen3.8-27b-uncensored-…. Items are now measured against the row they sit on, which lets the label's single-line truncation do the job it was already there to do.

  • An OpenCode Go window could be dated to a cycle that had already reset. #327

    The clock was read on the first line of the fetch and held across the credential load and the HTTP round trip, so a reset that expired while the request was in flight still compared as being in the future. The clock is now read after the response arrives.

  • A cancelled quota poller kept running for the rest of its minute. #331

    Closing the popover cancels the poller, but the sleep it was parked in observed only its own timeout, so the task stayed alive for up to a minute after the window it served had gone. Nothing observable went wrong, which is why it lasted: the work was not incorrect, only late to stop.

New Contributors

Full Changelog: v1.17.0...v1.18.0