Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ instance/
# Logs & local data
*.log
export/
exports/

# IDE / OS
.idea/
Expand Down
12 changes: 10 additions & 2 deletions scripts/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,13 @@ def resolve_workspace_path() -> str:


def get_global_state_dir() -> str:
# Honor XDG_STATE_HOME when set so the export state file (and manifest)
# can be redirected — required for hermetic test runs and useful for
# users following the XDG Base Directory spec. Falls back to the
# historical ~/.cursor-chat-browser location when the env var is unset.
xdg = os.environ.get("XDG_STATE_HOME")
if xdg:
return os.path.join(xdg, "cursor-chat-browser")
return os.path.join(str(Path.home()), ".cursor-chat-browser")


Expand Down Expand Up @@ -486,8 +493,9 @@ def assign_workspace(cd, cid):
exported = []
count = 0

# Process IDE composers
for row in ide_composer_rows:
# Process IDE composers (skipped entirely when --no-composer was passed)
include_composer = opts.get("include_composer", True)
for row in ide_composer_rows if include_composer else []:
composer_id = row["key"].split(":")[1]
try:
cd = json.loads(row["value"])
Expand Down
90 changes: 90 additions & 0 deletions tests/cli-export-qa-checklist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# CLI export + browse — manual QA checklist

Companion to the automated `tests/test_cli_export_e2e.py` suite. Run this once
per release branch (or whenever `scripts/export.py`, `app.py`, or the
workspace-scan service modules are touched) on each supported platform.

Mark each row pass/fail and attach short notes for any unexpected output.

## Environment

| Item | Value |
|--------------------|------------------------------------------------|
| OS / version | |
| Python version | `python3 --version` |
| Repo SHA | `git rev-parse HEAD` |
| `WORKSPACE_PATH` | (env var, if overridden) |
| Cursor data layout | default `~/.config/Cursor/User/workspaceStorage` or override |

## 1. CLI: `python scripts/export.py --help`

- [ ] Exits 0
- [ ] Usage block lists `--since {all,last}`, `--out`, `--no-zip`, `--no-composer`, `--base-dir`, `--exclude-rules`
- [ ] No stack trace, no deprecation warning

## 2. CLI: default zip export

```bash
python scripts/export.py --out ./export
```

- [ ] Exits 0
- [ ] Final stdout line: `Exported N chat(s) to ./export/cursor-export-YYYY-MM-DD.zip`
- [ ] Archive opens with `unzip -l` and contains at least one `.md` entry
- [ ] Each `.md` inside the archive starts with a `---`-fenced YAML
frontmatter containing `log_id`, `title`, `workspace`, `created_at`,
`updated_at`

## 3. CLI: no-zip export

```bash
python scripts/export.py --out ./export --no-zip
```

- [ ] Exits 0
- [ ] `./export/manifest.jsonl` exists and is non-empty
- [ ] Each manifest line is valid JSON with `log_id`, `path`, `updated_at`
- [ ] At least one `.md` file is written under `./export/<date>/...`
- [ ] Frontmatter fields as in §2

## 4. CLI: incremental (`--since last`)

```bash
python scripts/export.py --out ./export --no-zip --since last
```

(run after §3)

- [ ] Exits 0
- [ ] If no new chats: stdout prints `No conversations found since last export.`
- [ ] Existing `.md` files in `./export` retain their previous mtimes (not rewritten)
- [ ] After producing a new chat in Cursor, re-running picks it up and writes
only the new file

## 5. App server launch

```bash
python app.py
```

- [ ] Process stays running for at least 30 s without crash
- [ ] `curl -sI http://127.0.0.1:3000/` returns `HTTP/1.1 200 OK` (or `HTTP/1.0 200 OK` under some dev-server configurations)
- [ ] Home page lists at least one workspace card (assuming real Cursor data)
- [ ] No `Exception` / `Traceback` in server log

## 6. Browse flow (web UI)

Open `http://127.0.0.1:3000/` in a browser.

- [ ] Workspace list renders without console errors
- [ ] Clicking a workspace card opens the workspace view
- [ ] Within a workspace, opening a chat renders its bubbles
- [ ] Markdown export button on a chat downloads a `.md` whose frontmatter
matches §2
- [ ] PDF export button on a chat downloads a `.pdf` that opens cleanly

## Sign-off

| Reviewer | Platform | Date | Result |
|----------|----------|------|--------|
| | | | |
Loading
Loading