# Cursor

> Import Cursor CLI conversations, Cursor app agent transcripts and older Cursor history from its local databases, and Cursor cloud agents on request.

Hansard reads the Cursor CLI's own conversation stores, the Cursor app's agent
transcripts, and the app's older SQLite history. Cursor cloud agents are a
separate source that you import on request, and they always stay separate from
local Cursor sessions.

## Source IDs

| Source         | Use it for                                                                                                                                                                                        |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `cursor-cli`   | Cursor CLI (`cursor-agent`) conversations: interactive and headless `-p` runs from `~/.cursor/chats` and ACP sessions from `~/.cursor/acp-sessions`, including saved Cursor CLI account profiles. |
| `cursor`       | Cursor app agent transcripts and older local SQLite history.                                                                                                                                      |
| `cursor-cloud` | Cursor cloud agents, read from Cursor's API. Runs when you ask for it or turn it on in **Settings → Imports → Cloud agents**.                                                                     |

Stats, filters, and the session header show where each conversation ran:
Cursor CLI, Cursor cloud agents, or the Cursor app release it came from
(Cursor 1, Cursor 2, or Cursor 3). The app keeps every release's conversations
in the same stores and records no version for each one, so Hansard assigns the
release from the conversation's start date (2.0 from October 29, 2025, 3.0
from April 2, 2026; earlier releases, 0.x included, count as Cursor 1), lowered
to the app version Hansard recorded when it imported the conversation. Filter
with `hansard history --provider cursor-cli`, `cursor-3`, `cursor-2`, or
`cursor-1`.

Recovered Cursor app conversations use the same generation rule. The grouping
refreshes without a reimport. A recovery record without a usable start date
still has an unknown generation.

## How the import works

For the Cursor CLI, Hansard reads each conversation's `store.db` read-only from
a copy, so the running CLI is never disturbed. The store keeps the model behind
every reply (including the model Auto picked), tool calls with their results,
per-step timestamps, the branch and time zone, and how full the context window
was. Headless `-p` runs count as scripted jobs, like other SDK sessions, while
interactive and ACP conversations count as your own. When the CLI also writes
an agent transcript for a conversation, Hansard archives the richer store
and replaces a transcript-only copy imported earlier once the store's
copy holds everything that copy recorded. A simulated prompt recorded as
provider-generated system context can hold a transcript twin's matching user
prompt. A prompt or reply that cannot be compared keeps its copy. Saved Cursor CLI
account profiles are read from their own folders.

For the Cursor app's current history, Hansard scans Cursor's agent transcript folders for each
project. It groups files by session and reads messages, tool calls and results,
errors, models, usage, and subagent links. The project comes from the recorded
path or from the project folder name. For older history, Hansard also reads
Cursor's workspace and global SQLite databases, including Composer, chat, and
message records, and puts them in the most complete order the database allows.
A session that has only prompts or applied edits left imports as a partial
conversation.

Cursor can leave the same Composer session in several places. Hansard combines
them only when they share the exact Composer ID. The agent transcript takes
priority over the global database, which takes priority over workspace data
and partial recovery. Lower-priority copies can still add a title, working
directory, timestamps, usage, or the original files. Sessions with similar text
but different IDs stay separate, so one conversation does not appear several
times and unrelated work is never merged.

The watcher follows transcript files as they change. A full `--since all`
import also recovers older conversations from the SQLite databases, so run it
first after you install Hansard. The separate `cursor-cloud` command reads
cloud agent details, usage, and any message text Cursor's API returns. Cloud
agent IDs and local Composer IDs never overlap, so a cloud agent always stays
its own conversation.

The cloud import also reads each retained v1 run stream. It preserves thinking,
tool calls, JSON arguments, JSON results, and truncation flags. The legacy v0
conversation and run streams have independent ordering, so stream activity
appears as a separate block. Hansard does not invent per-message clocks or
model identities. SDK interaction updates remain raw evidence, including any
turn usage or nested tool details that the simplified events omit.

Run streams expire. An expired stream retains its archived events and terminal
run metadata, but Hansard cannot recover events Cursor no longer returns.
Large tool values can also be absent with an explicit truncation flag. Cloud
attachment references stay raw and do not establish a downloaded file.

`hansard init` and `hansard doctor` count older SQLite entries without decoding
them, so the number they show is an estimate; the import finds the exact
count. Hansard applies `--since` before it reads message rows, reads large
databases in batches, and prints progress as it goes. A `--since all` import
can still take a while when Cursor's `state.vscdb` is several gigabytes,
because every selected conversation is decoded once.

## Import and keep current

**Import now**

```sh
hansard import --source cursor --since all
hansard import --source cursor-cli --since all
hansard import cursor-cloud --since all
hansard index rebuild
```

`cursor-cloud` uses `CURSOR_API_KEY` or `cursor.apiKey` in Hansard's config.
It only reads from Cursor, and Hansard never stores the key in the archive.

**Keep current**

With **Automatic** source selection, the watcher already includes `cursor`
and `cursor-cli`. With a **Custom** list, enable them. The watcher picks them up within 30 seconds:

```sh
hansard config sources enable cursor
hansard config sources enable cursor-cli
```

To keep cloud agents current, turn on **Cursor cloud agents** in **Settings →
Imports → Cloud agents**. The watcher then checks it every minute, after any
earlier scheduled Cursor cloud import finishes. Capture remains subject to
API retention, rate limits, and import queue delays.
Otherwise, run the command again when you want newer cloud agents.

## Recover models and token counts

Most local Cursor conversations record no model or token counts. Cursor keeps
a usage history for each account that names the model, the tokens, and the
conversation of every request. To add it to your archive:

```sh
hansard import cursor --recover
```

Or open **Settings**, then **Recover Cursor models and usage**.

- It reads every account signed in on this computer: the Cursor app, the
  Cursor CLI, and saved Cursor CLI profiles, each account once. It only reads,
  and Hansard never stores or prints a token.
- Each request joins the local conversation with the same Composer id. Usage
  never creates a conversation.
- Cursor keeps a limited history. Hansard keeps every request it has recovered,
  so later imports retain them after they leave Cursor's history. A
  conversation's totals count as exact only when it began inside that history.
- Conversations made under an account that is not signed in on this computer
  need Cursor or the Cursor CLI signed in to that account. Sign in, run the
  command again, then switch back.
- Cursor CLI conversations take their token counts from the same history, so
  run it after CLI work to fill them in.

## Review the import in the app

1. When the import finishes, open **Conversations** and select **Filter & sort**.
2. Set **Source** to **Cursor or Cursor cloud agents** and set **Time** to the window you imported. Use **Folder** to narrow the list when you use this harness in several projects.
3. Select a conversation to check its messages, tool calls, files, commits, model, and token usage.

To keep archiving new sessions from a local harness, open **Settings → Imports**. **Automatic** follows every supported harness installed on this computer. **Custom** lets you turn individual harnesses on or off. Cloud sources and account exports never run from here; each needs its own import command. If a conversation you expect is missing after you reset the filters, run the import command on this page again with `--explain-skips` where the source supports it.

## What Hansard preserves

- Current agent transcripts with tool calls, errors, model settings, and
  workspace details when Cursor wrote them.
- Context window snapshots and Cursor's cost buckets from older SQLite history,
  kept separate from input and output tokens.
- The model on each reply in the older chat panel, and the models older
  Composer conversations billed.
- Cloud agent status, run times, duration, branch, pull request, token totals,
  available message text, and retained stream tools and thinking.
- Both the model and the harness, so Composer appears in model views and Cursor
  appears in harness views.

## Recovery boundaries

An older app conversation can have only prompts or edits left in its local
database. Opening that conversation in Cursor and sending a short prompt may
make Cursor write a modern transcript. This action changes native history and
can use model quota. Hansard does not perform it automatically, and the route
still requires native validation. Usage recovery with `--recover` is a separate
read-only operation. It cannot recreate missing conversation text.

Raw replay through `hansard rebuild` currently supports modern Cursor agent
transcripts. Cursor CLI stores, app SQLite stores, and cloud captures preserve
raw evidence but do not have a built-in replay entrypoint. Repeat their import
to refresh parser output. Repeat `hansard import cursor-cloud --since all` to
read available stream evidence for older cloud captures. Expired events remain
unavailable.

## Known limitations

- `promptTokenBreakdown`, `contextTokensUsed`, and `contextTokenLimit` show how
  full the context window was, not billed usage.
- Composer conversations from before Cursor saved a model setting with each
  conversation record a model only when Max mode billed it, and only for the
  conversation as a whole. Their replies carry no model, and other
  conversations from that period carry none unless
  [recovery](https://www.hansard.dev/imports/cursor/#recover-models-and-token-counts) finds them in Cursor's usage
  history.
- Simplified cloud run streams supply no model ID or per-event clocks.
  Expired streams cannot supply missing tools. Available conversation text,
  earlier stream evidence, and terminal run replies remain usable.
- Local Composer IDs and cloud agent IDs never overlap, so Hansard never treats
  a local session and a cloud agent as the same session.
- Cursor CLI stores retain context-window counts, but the native sample has
  no token-usage totals or CLI version. Usage totals come from
  [recovery](https://www.hansard.dev/imports/cursor/#recover-models-and-token-counts).
- Cursor 1, 2, and 3 follow release dates, so a conversation started on an
  older release after a newer one shipped counts as the newer release unless
  Hansard recorded the older version when it imported it.

> **Find out why a session was skipped:** If a local session is missing, run
> `hansard import --source cursor --since all --explain-skips`. Add `--json` for
> a machine-readable report.

## Refresh an existing archive

```sh
hansard import --source cursor --since all
hansard index rebuild
```

A full reimport is the clean way to update Cursor history that an older
Hansard version imported.
