* fix(cursor-agent): leave Cursor IDE chat transcripts to the cursor provider
Cursor IDE agent chats write agent transcripts too, so on days without a
Cursor import they were counted by both cursor (state.vscdb) and
cursor-agent. Discovery now skips a transcript or store whose id is an IDE
composerData key; cursor keeps them with per-bubble times and models.
Daily cache v73 lets cursor-agent days shrink once.
* fix(cache): drop old cursor-agent slices the IDE parse now explains
On an existing cache, settled days kept their old cursor-agent slice after
v73 because the fresh parse no longer has one there and the merge carries
missing slices forward. While cursor-agent is pending its v73 re-derive, a
day the fresh parse explains with a cursor slice and no cursor-agent slice
drops the old cursor-agent slice; days with no fresh cursor slice keep it.
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.
* fix(cursor-agent): read CLI sessions that exist only in ~/.cursor/chats store.db (#986)
A session with no exported transcript is read from its store.db; one with
a transcript is read from the transcript alone, so nothing counts twice.
Store turns follow the transcript accounting, take their time from the
prompt's <timestamp> tag and their model from the reasoning block, and
merge every conversation root so summarized history is kept. Daily cache
moves to v39 so settled days re-derive.
* cursor-agent: price store.db turns at the Cursor (auto) rate like transcripts
* fix: count every Cursor Agent assistant message instead of one turn per user message
Agentic loops emit dozens of assistant messages per user message and
the parser kept only the first (on one real corpus: 247 of 4,946
messages, ~4% of assistant text). Each message now carries the last
user message forward, tool_use inputs join the output text, and input
tokens use the full user text while the display stays truncated at
500 chars. Parse version bumped so cached sessions re-parse.
* cursor-agent: a transcript that ended before any assistant message is not an unrecognized format
* cursor-agent: bill the user text once per user message, not once per assistant message
* cursor-agent: re-derive finalized days and cached sessions under the new accounting
---------
Co-authored-by: Resham Joshi <65915470+iamtoruk@users.noreply.github.com>
Document the contributor onboarding path:
- CONTRIBUTING.md: setup, npm scripts, coding conventions, PR process,
the block-claude-coauthor enforcement, and the five providers without
test coverage today (claude, gemini, goose, qwen, antigravity).
- docs/architecture.md: 12-command CLI surface, parser pipeline, three
cache layers, 14 optimize detectors, and the mac / gnome / build
layouts with cited line numbers.
- docs/providers/: one file per provider (17 providers plus the shared
vscode-cline-parser helper). Each covers data path, storage format,
caching, dedup key, quirks, and a "when fixing a bug here" checklist.
Also fix two pre-existing documentation issues surfaced while writing
the new docs:
- RELEASING.md claimed GitHub Actions auto-publishes the CLI when a
v* tag is pushed. There is no such workflow; CLI publishing is
manual via npm publish. Updated the CLI section to reflect reality
and kept the menubar (mac-v* tag) automation accurate.
- .gitignore had CLAUDE.md unanchored, which on case-insensitive
filesystems also matched docs/providers/claude.md. Anchored to
/CLAUDE.md so the root-level memory file stays ignored without
affecting subdirectory docs.
All cited file paths, line numbers, function names, and test counts
were verified against current code (41 test files, 558 tests passing).