Skip to content

feat(menubar): translate the Windows tray app - #1

Draft
shanhe0814 wants to merge 100 commits into
mainfrom
cursor/menubar-zh-ce11
Draft

shanhe0814 wants to merge 100 commits into
mainfrom
cursor/menubar-zh-ce11

Conversation

@shanhe0814

Copy link
Copy Markdown
Owner

Summary

  • CodeBurn Menubar (Windows tray popover, settings window, Capacity Dock, and the tray right-click menu) now uses the same six languages as the macOS menu bar: English, French, Japanese, Korean, Simplified Chinese, and Traditional Chinese.
  • The default is System, which follows Windows. A Simplified Chinese install shows 简体中文 without the Electron desktop app. Settings → General → Language can override it.
  • Shared copy comes from the macOS Localizable.strings catalogs. Strings that exist only in the Windows port are in windows/src/i18n/extra.json.

Testing / Verification

  • I have tested this locally against real data (not just unit tests)
  • npm test passes
  • npm run build succeeds — npx tsc --noEmit in windows/ is clean. The Rust tray crate could not be compiled here (Cargo 1.83 cannot parse an edition2024 dependency).
  • Not a UI change
  • UI change: before and after screenshots attached below

Verified the generated mac-catalog.json matches zh-Hans Localizable.strings (636 keys, no mismatches), and that t('Your AI Bill, Itemized') / t('Open Full Report') resolve to the Simplified Chinese catalog entries.

For new providers only:

  • I installed the tool and generated real sessions by using it
  • npm run dev -- today shows correct costs and session counts for this provider
  • npm run dev -- models --provider <name> shows correct model names and pricing
  • Screenshot or terminal output attached below proving it works with real data
Open in Web Open in Cursor 

iamtoruk and others added 30 commits October 6, 2026 11:49
…tagentseal#1645)

* feat(sessions): explain why one session cost what it did

`codeburn sessions --id <id> --why` reads one Claude Code transcript on
demand and returns where the money went: a verdict, findings ranked by
dollars, spend by prompt with helper (sub-agent) cost stacked, and every
prompt's model calls and tool steps with timing, cost parts and step detail.
Money comes from the parser's own dedupe, turn grouping and calculateCost,
so the session total matches its `sessions` row.

The desktop app opens this as a focused session view when a Claude Code
session is clicked. Transcript content is read on demand only: never cached,
never routed through serve's output memo, never synced or sent in telemetry.

* fix(sessions): audit fixes for the session cost view

Recovery after a failed step stays inside its prompt; neutral note when the
view and the row differ (forked/resumed transcripts); starting-context
estimate compares against the cached prefix; local dates with the end date
when the session spans days; idle gaps that end with a helper reporting back
say so; savings are the difference of the shown figures; singular counts;
more secret patterns (sk_live_/sk_test_, aws_secret_access_key, URL
credentials); a note when the prompt count differs from the row's turns.
…etagentseal#1649)

The cold background index takes the hydration lock once per phase. The
setup accepted any lock that survived 150 ms, so on a loaded runner it
could return during a short opening phase, and the pre-exit lock check
then landed in the gap before the next phase.
…l#1651)

* fix(copilot): count VS Code agent-host requests and their output

VS Code now runs Copilot's agent through the Copilot CLI engine. Its
assistant.message events carry no outputTokens (CLI 1.0.8x writes the same
shape), so every request was skipped and the shutdown rollup, which assumed
per-turn events own output, dropped it: 0 calls and 0 output.

Tokenless messages now count as calls with zero tokens, and a leg with no
per-turn output takes its output from the rollup. The rollup also carries
modelMetrics totalNanoAiu, so the session's credits are exact. Tokens and
credits appear when the session ends.

* test(copilot): serve an open agent-host session

* fix(copilot): serve store-session output via the residual, count credit requests

CLI 1.0.8x sessions with session-store rows lost their output: the rows
replace the rollup and carry output only for compaction requests. The
per-leg residual now carries rollup output minus compaction-row output.

The credits note counted store rows, rollups and per-turn twins as separate
requests. It now counts requests by behavioral weight, rated when the
session carries an exact figure.

* fix(copilot): keep paired store-row credits, running nanoAiu delta

A behavioral store row (compaction or crash tail) made the credit sum drop
every paired row. Store rows now always count; a rollup counts only when
nothing behavioral carries nanoAiu.

totalNanoAiu is a running bill that does not reset at compaction, so its
per-leg delta uses its own sentinel instead of the token reset.

copilot's PENDING_REDERIVE contract moves to 56: a store row and its
message straddling midnight can move one call to the next day.
…k-4.6 at xAI rates (getagentseal#1652)

Session-store rows carried output only for compaction requests; every
other request's output was left to the per-turn assistant.message or the
shutdown rollup residual. CLI 1.0.8x and ACP hosts (JetBrains AI Chat via
copilot --acp) write no per-turn output, and an ACP session usually ends
without session.shutdown, so its whole output was lost. Rows now carry
their own output_tokens; at serve time a row that pairs with a per-turn
call carrying output (older CLIs) serves with output 0, so output counts
once in every shape.

grok-4.6 priced at $1.25/M input: LiteLLM has no bare grok-4.6 row and
the stripped azure_ai/grok-4.6 row claims the bare id ahead of
xai/grok-4.6, in the bundler and the live fetch alike. A builtin price
pins xAI's list rate ($2/$6/$0.50 per M), which is what GitHub bills.

On real data every Copilot model's cost now equals GitHub's
total_nano_aiu to the digit.
…#1653)

* fix(pricing): bare model ids take the maker's price, not a reseller's

A bare id with no direct LiteLLM row went to whichever prefixed row came
first in the JSON, so azure_ai priced grok-4.6 at $1.25/M instead of xAI's
$2/M, and the free codestral/ row priced codestral-latest at $0. The
bundler and the live fetch now let the maker's own row claim the bare id,
and a $0 row yields to any priced one. Snapshot patched for the 9 keys
this changes; cache schema 8 so live caches rebuild. The grok-4.6 builtin
override is now identical to the snapshot and live rows, so it goes.

* fix(pricing): the maker's row wins a bare id even at $0

Gemma is free on Google's own API, so gemini/'s $0 row must not lose
gemma-4-26b-a4b-it and gemma-4-31b-it to a reseller's price. Priced beats
$0 only among non-maker rows; codestral-latest still goes to mistral/.
Snapshot now differs from main in 7 keys. Drops the stale
mistral-large-latest example from the fills-only comment.

* fix(pricing): pin deepseek-v3.2 output at DeepSeek's published $0.42
…del sync rows estimated (getagentseal#1654)

Cursor Agent transcripts dated every turn at the session's last write. A
synced usage export ends its coverage at its newest billed event, so a
session that started before it and finished after it kept all its local
estimates on top of the billed rows. Date transcript turns by their
prompt's <timestamp> tag instead, like store.db turns already are. On a
real account this removed 101 double-counted calls on the last synced day,
and 2,748 of the 2,767 calls stamped on 22 Sep moved back to 17-20 Sep,
where Cursor billed them.

Synced plan rows carry no dollars (Included, Free), and Auto and Grok Bot
rows never name the model that served them, so their list price is a
stand-in: mark them costIsEstimated. Named models stay exact.

Daily cache to v58; cursor-agent joins PENDING_REDERIVE at 58 since a day's
call count can drop when turns move to their prompt day.
…del (getagentseal#1655)

* fix(antigravity): count cache reads and price the standalone app's model

The standalone Antigravity app (2.19) stores usage as ModelUsageStats in
gen_metadata. Field 5 (cache_read_tokens) was never read, on the SQLite
path or the RPC path, so every cached prompt token was dropped. Fields 9
and 10 are thinking and response output, the reverse of what the SQLite
path assumed. The rows carry only MODEL_PLACEHOLDER_M16 and
"gemini-pro-default", so the model priced at $0.

Read cache read (and cache write) in both paths, read 9/10 in the right
order, drop the input fallback to field 1 (the model enum), and map the
placeholders seen in the app's own model catalog, flagged as estimated.
Bump the antigravity results cache, its parse version and the daily cache.

* fix(antigravity): keep .pb history across the cache bump, step times, 200k tier

With the results cache at v8 and Antigravity closed, .pb cascades had no
entry and no server, so they vanished until the app was next opened.
Serve the v7 entry meanwhile, stored with mtimeMs -1, and preload the
results cache so the session cache reparses such sources and the next run
with the server up re-fetches them with cache reads.

Standalone .db rows without created_at take their first step's time
(steps.metadata #1), which equals created_at wherever both exist, instead
of the file mtime.

Price antigravity at the Gemini long-context tier: add it to
TIERED_PRICING_PROVIDERS and pass the provider at both calculateCost sites.
…l#1599)

* Restore usage from Mistral Vibe Unified Harness sessions

* fix(mistral-vibe): read unpinned Vibe 2.26 unified sessions exactly

An unpinned session has session_metadata.active_model null, so the parser
dropped it entirely. Fall back to config.toml's active_model, then Vibe's
default mistral-medium-3.5.

Split the rotated journal prefix into as many calls as runtime state lists
completions, so call counts match. Drop the tool group prefix from history
names (file_system.bash) and attach a turn's tools to its first call only.

Re-derive settled days (DAILY_CACHE_VERSION 58). Adds a redacted fixture from
a real 2.26.0 session.

---------

Co-authored-by: Resham Joshi <65915470+iamtoruk@users.noreply.github.com>
…#1657)

* Mark estimated costs with the same ~ in every view

The ~ marker and legend that report already used now appear wherever a
dollar figure is mostly a guess: the models and sessions CLI output, the
desktop Models, Overview, Sessions and Settings provider rows, the macOS
menu bar model rows and provider tabs, and the Windows tray.

One rule decides the marker everywhere: the estimated portion is at least
1% of the figure. report, overview and the MCP tables switch to it from
"any estimated cent", so a metered Codex row holding a few text-estimated
turns stays unmarked.

JSON is additive: estimatedCostUSD and isEstimated on models rows,
estimatedCost and isEstimated on sessions rows, estimatedCostUSD on
menubar providerDetails rows. Totals are unchanged.

* Skip the ~ marker on figures that print as zero

A sub-cent row that is fully estimated printed as "~$0.00": nothing visible
to qualify. The shared helper now also requires the amount, as the surface
prints it in the active currency, to show a non-zero digit. CLI, desktop,
macOS and Windows helpers all apply it.
* feat: Command Code support

Reads the cmd CLI's session transcripts at
~/.commandcode/projects/<slug>/<id>.jsonl (CODEBURN_COMMANDCODE_DIR moves
the root). Checkpoint and prompt sidecars are skipped.

usage.inputTokens includes cacheReadTokens, so fresh input is
inputTokens - cacheReadTokens. The recorded costUsd is kept per call
(costFromBilling); a call without one is priced from tokens and marked
estimated. Forks copy parent message ids into a new file, so calls dedupe
by message id across sessions.

Desktop: Electron sandbox read path, macOS and Windows change watchers,
Windows tab colour. No quota adapter.

* fix(command-code): dedupe on meta.messageId, not the 8-hex line id

The top-level id is randomUUID().slice(0, 8) and only unique within one
file, so calls from unrelated sessions could collide and vanish.
meta.messageId is a full uuid that survives forks. Fixture ids now use
the real 8-hex shape.

* test(command-code): check sidecar skipping by file name, not a posix path
…gentseal#1666)

Bumps [source-map-js](https://github.com/7rulnik/source-map-js) from 1.2.1 to 1.2.2.
- [Release notes](https://github.com/7rulnik/source-map-js/releases)
- [Changelog](https://github.com/7rulnik/source-map-js/blob/main/CHANGELOG.md)
- [Commits](7rulnik/source-map-js@v1.2.1...v1.2.2)

---
updated-dependencies:
- dependency-name: source-map-js
  dependency-version: 1.2.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…al#1633)

Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.3.0 to 4.3.2.
- [Changelog](https://github.com/nodeca/js-yaml/blob/4.3.2/CHANGELOG.md)
- [Commits](nodeca/js-yaml@4.3.0...4.3.2)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.3.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [proxy-addr](https://github.com/jshttp/proxy-addr) from 2.0.7 to 2.0.8.
- [Release notes](https://github.com/jshttp/proxy-addr/releases)
- [Changelog](https://github.com/jshttp/proxy-addr/blob/master/HISTORY.md)
- [Commits](jshttp/proxy-addr@v2.0.7...v2.0.8)

---
updated-dependencies:
- dependency-name: proxy-addr
  dependency-version: 2.0.8
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…tagentseal#1663)

Bumps [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk) from 1.30.1 to 1.31.0.
- [Release notes](https://github.com/modelcontextprotocol/typescript-sdk/releases)
- [Commits](modelcontextprotocol/typescript-sdk@1.30.1...1.31.0)

---
updated-dependencies:
- dependency-name: "@modelcontextprotocol/sdk"
  dependency-version: 1.31.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…tseal#1662)

Bumps [source-map-js](https://github.com/7rulnik/source-map-js) from 1.2.1 to 1.2.2.
- [Release notes](https://github.com/7rulnik/source-map-js/releases)
- [Changelog](https://github.com/7rulnik/source-map-js/blob/main/CHANGELOG.md)
- [Commits](7rulnik/source-map-js@v1.2.1...v1.2.2)

---
updated-dependencies:
- dependency-name: source-map-js
  dependency-version: 1.2.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…l#1632)

Bumps [postcss](https://github.com/postcss/postcss) from 8.5.15 to 8.5.29.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](postcss/postcss@8.5.15...8.5.29)

---
updated-dependencies:
- dependency-name: postcss
  dependency-version: 8.5.28
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…tagentseal#1631)

Bumps [browserslist](https://github.com/browserslist/browserslist) from 4.28.2 to 4.29.3.
- [Release notes](https://github.com/browserslist/browserslist/releases)
- [Changelog](https://github.com/browserslist/browserslist/blob/main/CHANGELOG.md)
- [Commits](browserslist/browserslist@4.28.2...4.29.3)

---
updated-dependencies:
- dependency-name: browserslist
  dependency-version: 4.29.3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…gentseal#1661)

Bumps [source-map-js](https://github.com/7rulnik/source-map-js) from 1.2.1 to 1.2.2.
- [Release notes](https://github.com/7rulnik/source-map-js/releases)
- [Changelog](https://github.com/7rulnik/source-map-js/blob/main/CHANGELOG.md)
- [Commits](7rulnik/source-map-js@v1.2.1...v1.2.2)

---
updated-dependencies:
- dependency-name: source-map-js
  dependency-version: 1.2.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…#1668)

Bumps [joi](https://github.com/hapijs/joi) from 18.2.3 to 18.2.9.
- [Commits](hapijs/joi@v18.2.3...v18.2.9)

---
updated-dependencies:
- dependency-name: joi
  dependency-version: 18.2.9
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
getagentseal#1659)

Bumps [rustls](https://github.com/rustls/rustls) from 0.23.38 to 0.23.45.
- [Release notes](https://github.com/rustls/rustls/releases)
- [Changelog](https://github.com/rustls/rustls/blob/main/CHANGELOG.md)
- [Commits](rustls/rustls@v/0.23.38...v/0.23.45)

---
updated-dependencies:
- dependency-name: rustls
  dependency-version: 0.23.45
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [source-map-js](https://github.com/7rulnik/source-map-js) from 1.2.1 to 1.2.2.
- [Release notes](https://github.com/7rulnik/source-map-js/releases)
- [Changelog](https://github.com/7rulnik/source-map-js/blob/main/CHANGELOG.md)
- [Commits](7rulnik/source-map-js@v1.2.1...v1.2.2)

---
updated-dependencies:
- dependency-name: source-map-js
  dependency-version: 1.2.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* refactor(app): move the bridge handlers out of main.ts

createBridgeHandlers and the argv builders now live in
app/electron/bridge-handlers.ts with no electron import, so a host other
than Electron can run the same channel to argv mapping. main.ts keeps its
default deps and re-exports, so the desktop app and its tests are unchanged.

Two additive hooks for that host: scopeProjectFilter narrows the saved
project filter before it becomes argv, and CODEBURN_NODE_BIN runs the
bundled CLI with a named Node instead of Electron-as-Node.

* feat(app): let the renderer run inside an editor

The bridge can now say it is the VS Code host. When it does, the chord
shortcuts and their hints step aside for the editor's own, Settings hands
theme, language, default period and refresh to the editor's settings,
the top bar shows a this workspace / all projects switch, and the editor
can send a section, a period or a refresh to an open dashboard.

formatResetTime moves to lib/format.ts so the status bar and the summary
use the Plans wording. New strings are in all six locales. Nothing
changes in the desktop app.

* feat(app): build the renderer for VS Code webviews

app/vite.vscode.config.ts builds two webview entries into
vscode/dist/webview: the whole dashboard and the activity bar summary.
renderer/vscode/bridge.ts implements window.codeburn over postMessage,
forwarding only the channels in channels.ts; telemetry, update checks and
the desktop companions are answered in the webview. localStorage is
prefixed per scope so one workspace's cached views never paint in
another's, and the theme follows the editor's light, dark and high
contrast kinds through its --vscode-* tokens.

* feat(vscode): CodeBurn extension for VS Code and its forks

A status bar item with today's spend (~ when estimated) and a tooltip
with the week, the month, this workspace, the top model and plan quotas;
an activity bar summary; the desktop dashboard in an editor tab, scoped
to the open workspace; eight commands and eight settings.

The bundled CLI runs as the desktop's resident serve child through the
shared client. Current VS Code, Cursor and Antigravity ship Node 24, so
it runs on the editor's own Node; an older editor gets a system Node
22.13+ or a degraded run that says what it cannot read. A workspace
folder maps to a rooted --project the way the CLI keys sessions,
worktrees folding into their main repository.

npm run package:vscode builds the .vsix. Unit tests cover the bridge
host, status bar formatting, workspace mapping, settings and runtime
choice; test:smoke drives a real VS Code against a fixture home.

* ci, docs: build, test and package the VS Code extension

A vscode job typechecks, unit tests, packages the .vsix, runs the smoke
test in VS Code under xvfb and uploads the .vsix. docs/vscode.md covers
the architecture, the measured editor runtimes and how to test.

* fix(vscode): keep the currency setting out of workspace settings

Changing codeburn.currency runs the CLI's own currency command, which
every CodeBurn app shares, so a repository's .vscode/settings.json must
not be able to set it: the setting is application scoped now.

The smoke test also checks that the dashboard's renderer booted inside
the webview and called the host, not only that its tab opened.

* feat(vscode): version the extension 1.0.0, apart from the CLI

The extension carried the CLI's 0.9.25. It now has its own version,
1.0.0. The host passes it to the webview, and the dashboard's nav
footer, About dialog and Settings show it there instead of the
renderer's package version; Settings adds "Bundled CLI 0.9.25" beneath
it. The desktop app is unchanged. Nothing in the build or packaging
writes the extension's version from the CLI.

* fix(vscode): run the smoke test in Cursor, keep the demo shim out

Cursor 3 opens its Agents window on a fresh profile, which starts no
extension host, so the smoke run against Cursor.app hung; it now passes
--classic for Cursor. The webview build no longer copies
renderer/public/demo-shim.js, a browser demo harness, into the .vsix.

* feat(vscode): a quiet star line in the summary, and a Star on GitHub command

From the third day of use, the activity bar summary ends with the
desktop's "Enjoying CodeBurn? Star us on GitHub" line, in the same six
languages, with a close button. Clicking it or closing it hides it for
good (kept in the extension's globalState). It is never a notification.
The new "CodeBurn: Star on GitHub" command opens the repository page.
No tracking parameters, no telemetry.

* docs(vscode): marketplace screenshots in the README

Five screenshots of the extension on real data (Overview in dark and
light, the why it cost view, the status bar hover and the activity bar
summary), 1600 px wide, each with a one-line caption. They live in
vscode/media/screenshots, stay out of the .vsix, and the package script
points vsce at the raw GitHub URLs on main.

* fix(vscode): review fixes for settings trust, serve lifecycle and the tooltip

- codeburn.provider and codeburn.quotaProviders are application scoped,
  like currency, so a repository's settings cannot turn quota requests
  back on, even in Restricted Mode.
- deactivate removes the serve pid file once the child is stopped, and
  changing codeburn.nodePath restarts the serve child on the new Node.
- codeburn.currency is applied at startup when the CLI's currency
  differs, not only when the setting changes.
- The dashboard's Settings no longer shows per-plan quota switches in the
  editor, where the editor setting rewrites them on every boot; it points
  to the editor settings instead.
- Workspace and model names are escaped in the status bar tooltip.
- The README lists the dashboard actions that reach the network.
- The staged CLI drops its dependencies' tests and TypeScript sources
  (466 files, 9.9 MB to 9.2 MB).
…agentseal#1608)

Localizes the Windows tray menu, tooltip, usage row, dock menu and footer into Simplified Chinese, reusing the macOS menubar glossary. Refs getagentseal#1336, getagentseal#1646.
)

Read Claude Desktop 3p usage-ledger records for the Cowork and Code surfaces, drop a ledger call that matches a transcript call, daily cache v61.
SWE-2 calls showed $0. Cognition publishes SWE-2 list pricing at
docs.devin.ai/desktop/models: $3 input, $15 output, $0.30 cache read per
1M tokens. swe-1-7-lightning now normalizes to swe-1.7-lightning so it
prices too. Devin caches parse-time cost, so its parse version and the
daily cache version are bumped.
* Scan WSL homes for Mistral Vibe sessions (getagentseal#1630)

* style(mistral-vibe): indent discoverRoot, drop the issue number from a comment
…etagentseal#1682)

* feat(quota): Command Code quota and ClinePass from the Cline sign-in

Command Code: reads the CLI's ~/.commandcode/auth.json key and the billing
credits and subscription endpoints. 5-hour and weekly windows as used of
cap, remaining credits as a note, plan from planId. Live in the Mac dock
from the local CLI, in codeburn quota and the Windows dock.

ClinePass: without a saved or env key, falls back to the Cline CLI's
providers.json session (accessToken, then apiKey, then auth.apiKey, with
Cline's path overrides). Read-only; an expired session stops before the
network and says to run cline. The Mac catalog adds the local CLI source
so Automatic connects without a key.

* fix(quota): keep retrying after an expired Cline sign-in

Running cline refreshes the session file CodeBurn only reads, so an
expired or rejected Cline session is now a retryable failure that keeps
the last quota and shows the guidance, on the Mac and in the CLI. A
rejected API key and a missing credential stay terminal.

* test(quota): build expected Cline paths with path.join for Windows
…seal#1683)

* feat: Google AI plan presets and the Antigravity tier label (getagentseal#1614)

Plan presets google-ai-pro, google-ai-ultra-5x and google-ai-ultra-20x
at Google's US monthly prices, scoped to Antigravity usage.

The Antigravity quota readers (CLI, desktop, menu bar) now also ask
GetUserStatus when the summary answers and label the windows with
userTier.name. planStatus.planInfo is not used: it says Pro on a free
tier account.

* docs: Antigravity probe comments and README preset list
iamtoruk and others added 14 commits October 10, 2026 07:06
…al#1725)

The fork-parent memo lived in module state, so every parse worker indexed
the Codex home and read the same parent rollouts again (58 reads of 10
parents, 8 GB for 1.28 GB on a real corpus). Workers now ask the main
thread over a message port, which keeps one memo for the whole parse.
…eal#1726)

The sessions.db query returned each message's whole metadata blob and
parsed it in JS (617 MB on a real store) to use five fields. The query now
builds an object of just those fields; a missing or non-object metadata
still comes back NULL.
)

Warm reports re-derived the display name of every cached call, a linear
scan of the short-name table each time (about 0.5 s on a lifetime run).
The name depends only on the aliases and the pricing namespaces, so it is
memoized per model id and cleared when either changes.
…tagentseal#1724)

* perf(cursor): stop JSON and menubar answers waiting on cursor.com

report/today/month --format json, overview and status --format menubar-json
awaited the hourly Cursor usage download (15 s cap, 45 s on the first
backfill) before parsing. The download now runs beside the command and its
import applies after the command (serve: between two requests, then its
memos are dropped), so the next run shows it. Dashboards still wait.

* test(cursor-sync): keep the in-process sync enabled when the shell disables it

* test(cursor-sync): wait for the serve memo instead of a fixed answer count

The serve test expected the second answer to be memoized, but serve only
memoizes once its root watchers are armed, which on a slow CI runner lands
after that answer. Keep asking until two answers share a generation. The
spawn now imports the fake fetch by file URL so Windows accepts the path,
and the in-process test points USERPROFILE at the temp home too.
…h placeholders (getagentseal#1712)

When an Antigravity response left out the model, the parser crashed on the legacy .pb path and the whole session was skipped. It now falls back to the chat's own model and passes it through the live model map.

Maps the Gemini 3.8 Flash placeholders M318/M319/M320 to the high/medium/low ids from Antigravity's model catalog, and the gemini-3-flash-a/-d family strings to gemini-3-flash-preview (LiteLLM prices, nothing hardcoded). Parse version, results cache v9 and daily cache v74 bumped so cached rows re-parse; calls and cost only rise.

Thanks @dcaldr.
…eloper ID cert (getagentseal#1731)

Keychain Access exports the Developer ID p12 with RC2-40 encryption and a 1-iteration sha1 MAC, which the runner's security import rejects as a wrong password. Both workflows rewrap it with openssl@3 -legacy (3DES, 2048 iterations) under a masked one-off password; the desktop workflow now signs from its own keychain because electron-builder's temporary keychain failed to unlock. Verified: both workflows green on dispatch, signed, notarized and stapled.
…nd follow-ups (getagentseal#1733)

* fix(pr): a subagent whose description names a PR folds into that PR

A subagent run folded into whatever PR its parent's last pr-link carried, so
review runs for getagentseal#1703, getagentseal#1712, getagentseal#1728 and getagentseal#1729 landed on a stale closed getagentseal#24.
The Agent description ("Review PR 1729 ...") is now read from the subagent's
.meta.json at report time; a single PR it names outranks the carried PR.

* fix(pr): date each PR by its own turns and count its agent runs

Every PR row carried the whole session's first and last timestamp, so one
long orchestrator session stamped the same span and "1 session" on all of
them. Rows now span their first to last attributed turn or folded run, and
a new `runs` field counts contributing sessions plus folded subagent runs.

* feat(pr): local one-shot, follow-up rounds, review runs, merge time and cost split per PR

Each PR row now carries signals read from cached commands, no GitHub calls:
openedAt (gh pr create paired with the PR's first pr-link), follow-up rounds
(pushes naming its --head branch, or from a run whose description names it,
in 10-minute bursts), oneShot only when the open and its branch were seen,
reviewRuns and reviewCostUSD, mergedAt and timeToMergeMs, a build/review/fixes
cost split that sums to the row, and linkEvidence to flag pr-link-only rows.

* feat(session-why): PRs the session opened, their follow-up rounds and review runs

The why view now carries prWork: each gh pr create whose output printed a PR
URL, the pushes after it on its --head branch (or from a helper whose
description names that PR) in 10-minute rounds, and the helpers that read a
PR without committing or pushing, with their cost.

* perf(pr): only parse commands that can name a push or a PR

* feat(app): local PR facts on PR cards and PR work in the session view

Each PR card gets one line of facts from the CLI's local signals: the review
run and its cost, one shot or follow-up rounds, and merge time after open.
Unknowns are left out; a pr-link-only row says so. The count shows agent runs
instead of sessions. The expanded card splits spend into building, review runs
and after first review, and lists the review runs. The session view lists the
PRs it opened and the review runs it spawned.

* perf(pr): read subagent descriptions only for PR attribution

Every report, status and menubar refresh read each subagent's .meta.json
(about 2,000 files in 30 days) and the cross-provider correlation scanned
every folded run's commands for PR signals it never uses. Sessions now carry
the sidecar path; the description is read on demand, memoized by mtime, only
for folded runs and runs that push, and correlation skips the command scan.
The by-pr footer now counts runs to match the Runs column.
Command Code's credits endpoint only reports monthly credits left, so the
monthly window was dropped. For an active subscription on a known plan the
plan price now comes from a small table (the API has no monthly cap field):
pool = max(plan, left), used = pool - left, reset = currentPeriodEnd.
Unknown plans and purchased/free credits stay out. CLI and menubar mirrored.
…order (getagentseal#1735)

* fix(menubar): check Cursor when its settings pane opens, keep the dock seed stable

Generic providers were only refreshed while selected in the dock, so a
signed-in Cursor outside a full dock read "Not connected". Opening a
provider's settings pane now runs a quiet probe that records nothing on
failure. Auto-seed also keeps the providers already in the dock and only
fills free slots, so a newly connected provider no longer pushes one out or
resets the preferred card. Remaining edge: after an explicit Disconnect,
reopening the pane re-probes, and a free dock slot would take it back.

* fix(menubar): keep a disconnected provider off until the user connects it

The explicit-disconnect flag Copilot already persists is now per provider.
Disconnect sets it for generic providers too, Connect clears it, and while
it is set the settings pane's quiet probe and the dock auto-seed skip that
provider, so reopening the pane no longer silently reconnects Cursor.

* fix(menubar): only the Disconnect action opts a provider out

Clear Override and Remove saved override share the disconnect path but
mean "go back to automatic", so they no longer set the explicit-disconnect
flag; the pane probe and dock auto-seed keep working after them.

* fix(menubar): the quiet pane probe hides only a missing sign-in

The Settings pane probe recorded nothing on any failure, so an expired login
opened before any refresh read "Not connected". Fetch failures now carry
whether the provider had no credentials or local data at all; the quiet probe
suppresses only that case and records every other failure like a refresh.

* fix(menubar): keep the not-signed-in flag clear of the ClinePass failure fields
…etagentseal#1736)

* fix(clinepass): say when the Cline login expired and how to renew it

An expired saved Cline login only said "Run cline to refresh it". It now
reads "Cline login expired 3h ago" (age from the saved expiry, when known)
and asks to send a message in Cline or run `cline auth cline`, then press
Retry. Still a retryable state, so the last quota is kept. CLI and menubar.

* fix(menubar): title an expired Cline login instead of "Retrying"

A provider failure can now carry a short status title. The expired Cline
login sets "Cline login expired", which the settings pane and the dock
caption show in place of the generic retrying text. It stays a retryable
state and keeps the last quota; the title clears with the error.

* fix(clinepass): match the expired-login hint to the visible control

"Then press Retry" only fits where a Retry button shows: the settings pane
with no last quota. Everywhere else, including the CLI, the hint now ends
with "CodeBurn picks up the new login on its next refresh."
…ls (getagentseal#1737)

* fix(pr): push evidence beats the carried pr-link, show every PR fact

Claude Code's pr-link tags a session with its latest PR and CodeBurn carried
that tag to every later turn and subagent run. A run or turn that pushes the
head branch of a PR opened in the same data (paired gh pr create --head) now
goes to that PR, same repo only; spend left only on the tag is carriedUSD.
Rows also get runList (why each run counts), a locally evidenced state and
follow-up round times, and a call opening several PRs pairs its pr-link with
the last create. The PR card states every unknown and the expanded view shows
timeline, runs, cost by phase and work as compact tables.

* fix(app): full text on hover for cropped PR cells, plainer wording for same-session spend

Truncated PR labels, run descriptions, table labels and summary figures now show their full text in the shared tooltip surface while cut off. The carried-from-session-tag wording becomes 'from other work in the same session' in all six locales.

* fix(pr): explain carried spend without the pr-link jargon
Version 0.9.26 in the CLI, desktop app and Windows tray; CHANGELOG, README download links, Flathub metainfo and url, VS Code changelog.
@cursor
cursor Bot force-pushed the cursor/menubar-zh-ce11 branch from 5f28e78 to 90ee610 Compare October 11, 2026 01:52
…etagentseal#1744)

The CSV row is stamped two hours before now, so a today window failed between 00:00 and 02:00 UTC.
…op (getagentseal#1740)

Adds codeburn update [--check] [--cli|--menubar|--desktop|--all] [--local] [--json] with a fixed JSON step/result contract that the desktop app, menu bar and Windows tray call, so every surface updates in one click without Terminal. Also documents the npm-first release order and adds always-latest /download links.
…etagentseal#1741)

The desktop app runs codeburn update for the CLI and menu bar on launch and after it updates itself, and the update banner installs and restarts in one click with a Try again path if the install fails.
…agentseal#1742)

When the CLI is 0.9.27 or newer, the menu bar update pill checks and updates every surface through codeburn update, and polls every 6 hours. Older CLIs keep the previous path.
…ntseal#1743)

The Windows tray updates the CLI through codeburn update, for Store and non-Store installs, and hands desktop updates to the desktop app.
… mid-update (getagentseal#1745)

Electron's Node 24 undici asserts and kills the process when a server closes the socket while a piped download is paused on the file write. The menu bar zip is now read whole and written once.
Version 0.9.27 in the CLI, desktop app and Windows tray; CHANGELOG and Flathub metainfo and url.
sha256 of the published codeburn-desktop_0.9.27_amd64.deb.
…turn is split evenly (getagentseal#1749)

Corrects the 0.9.27 changelog wording and the session drawer PR caption in all six languages to match the code.
@cursor
cursor Bot force-pushed the cursor/menubar-zh-ce11 branch from 90ee610 to 7f75153 Compare October 11, 2026 15:50
iamtoruk and others added 3 commits October 13, 2026 01:02
…at sessions (getagentseal#1752)

* Copilot: count every agent round and exact credits in VS Code chat sessions

Copilot Chat 0.69 keeps only the last model call of an agent request in result.metadata. Read the request's modelTotals (input, cache reads, output over every call) first, then root completionTokens, then metadata. Carry copilotCredits as nanoAiu so plan credits are exact. Bump the copilot parse tag so cached chat sessions re-parse.

modelKeyMatches no longer lets claude-sonnet-4 capture claude-sonnet-4-6.

* Copilot: bill chat-session credits exactly and skip agent-host twins

A chat-session request that records copilotCredits now costs credits x $0.01 through costFromBilling; requests without it stay priced from tokens. A chat session whose id matches a session-state dir is left to the agent-host path so it is counted once.

* Copilot: drop agent-host twins at serve time, rate chat requests one by one, re-derive past days

A chat-session journal request is left out when the same session has billed agent-host usage (session-state calls with tokens or nanoAiu, or session-store rows). Plan credits rate chat-session requests individually, so older requests in a mixed session keep their estimate. DAILY_CACHE_VERSION 75 with copilot pending re-derive so settled days pick up the new counts.
…nstalls (getagentseal#1753)

The desktop app starts the tray with CODEBURN_BIN set to its own
codeburn-cli.cmd launcher, which the tray took as final. When that launcher
failed (getagentseal#1750: exit 1, "The system cannot find the path specified"), the
Volta install under a relocated VOLTA_HOME was never tried.

The setup check now probes CODEBURN_BIN, every install the PATH and prefix
search finds, then the recorded launcher, and keeps the first whose
--version answers. When none does, the error lists each path with its own
failure. Export and terminal actions use the probed CLI. The desktop app no
longer overwrites a CODEBURN_BIN the person set themselves.
Pull request 1608 already localized the tray menu, tooltip, usage row, dock menu and footer. This adds the surfaces that issue still lists: the popover, General settings, the Capacity Dock window, a language row that writes the shared config.json language, a live switch when that file changes, Traditional Chinese, and the tray-badge label.

macOS Localizable.strings is the source of truth. Windows-only sentences live in extra.json, with a real zh-Hant table instead of a Simplified copy.

Refs getagentseal#1646
@cursor
cursor Bot force-pushed the cursor/menubar-zh-ce11 branch from 7f75153 to 0c9068b Compare October 13, 2026 14:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants