Commit graph

2 commits

Author SHA1 Message Date
Resham Joshi
04d0b65327
feat(cursor): show the Cursor sync status and an on/off switch in the apps (#1638)
* feat(cursor): show the cursor.com sync in the apps, with an off switch

status --format menubar-json gains an additive cursorSync block (enabled,
state, lastSuccessAt, and a fixed errorCode/error on failure), read from
the sync sidecar, the config and the Cursor app's login. It never syncs,
never makes a request and never carries the token, the account hash or
server text. It is absent when Cursor is not signed in and has never
synced, and it is attached after the snapshot and per-device payloads.

With the Cursor provider selected, the desktop overview, the macOS menu
bar and the Windows tray show one line under the total: "Synced from
cursor.com 12 min ago", or the error in a muted warning colour. A
"Sync Cursor usage from cursor.com" switch writes config cursorSync:
Settings > Providers > Cursor on the desktop, the Cursor settings pane
on macOS and Windows. Desktop and mac strings are in all six locales;
the tray stays English until its localization lands.

* fix(cursor): guard config writes, show the env override in the switches

The tray's shared config writer now refuses to write over a config.json
that does not parse or is not an object (it used to replace it with an
empty map plus the one key), which also protects the currency, budget
and Claude config directory writers. The desktop writer rejects null
and array configs the same way.

With CODEBURN_CURSOR_SYNC=0 set, the desktop, mac and tray switches show
"Turned off by CODEBURN_CURSOR_SYNC=0" and are disabled. A failed mac
save now says so under the switch. The tray hero note uses the warning
ink and maps errorCode to its own messages.
2026-10-05 17:11:41 +02:00
Resham Joshi
0d6c59b011
feat(cursor): sync your Cursor usage from cursor.com automatically (#1637)
* Sync Cursor usage from cursor.com automatically (#1545)

Reports that show Cursor dollars download the account's own usage export
with the Cursor app's session, at most every 15 minutes, and merge it into
the Cursor import store as source-tagged events. Manual CSV imports are
never replaced; synced rows dedupe against them by hash. codeburn import
cursor --sync forces one. Off with cursorSync: false or
CODEBURN_CURSOR_SYNC=0.

* Cursor sync: hourly with jitter, keep every account's history

The throttle is now an hour plus up to 5 minutes of jitter, and three
failed requests in a row back off 6 hours. After the first month, a sync
starts at the day of the newest synced event, and a quiet account
remembers that it synced, so closed days are downloaded once.

Synced rows and ranges carry the hashed account. An account change no
longer drops the earlier account's rows; the new account's window starts
after their coverage. A closed synced day stays in the daily cache when
a later sync fails or the store goes missing.

* Cursor sync: longer first backfill, safer merges, provider gate

The month-long first backfill gets 45s (it took 11-12.5s on a real
account and could hit the old 15s cap); incrementals keep 15s. The sync
heartbeats through the download for the app watchdogs. An incremental
starts the day before the newest synced event so late rows land, and
rows from before the window are ignored instead of failing the sync.

A manual import of a row a sync stored first turns it into a manual
row, so a later sync can never delete what manual coverage relies on.
The sidecar records the account only after the request. Commands
filtered to a non-Cursor provider no longer sync.

* Cursor sync: manual coverage wins inside its range

A sync skips rows dated inside a manual import's coverage, so a row
Cursor revised there is not priced twice. Rows after the manual
coverage end still land.
2026-10-05 15:52:08 +02:00