Skip to content

fix: Cursor new-schema adapter + progress log append-only#53

Merged
rohitsux merged 3 commits into
mainfrom
fix/cursor-schema-and-progress-log
Apr 30, 2026
Merged

fix: Cursor new-schema adapter + progress log append-only#53
rohitsux merged 3 commits into
mainfrom
fix/cursor-schema-and-progress-log

Conversation

@rohitsux

Copy link
Copy Markdown
Contributor

Summary

  • Cursor sessions not captured: Cursor migrated conversation storage from globalStorage/state.vscdb (single DB) to per-workspace workspaceStorage/<hash>/state.vscdb files. Rewrote the adapter to read composer.composerHeaders from the global DB for workspace routing, then per-workspace aiService.prompts for actual messages. Old schema (pre-migration) kept as automatic fallback.
  • Progress log reset on daemon restart: Changed build_progress_log to always append — never wipe existing entries on session change. Progress now accumulates indefinitely across all sessions and restarts.
  • Cursor prompts not triggering fs-watcher: Added workspaceStorage/ as a second transcript watch path so the daemon fires on prompt writes (they no longer touch globalStorage).
  • Duplicate progress entries: Two composers sharing the same workspace both re-read it from skip=0. Fixed by using new_seen_prompts within a batch so the second composer sees the workspace already consumed.

Test plan

  • cargo test — 246 tests pass
  • Local daemon test: Cursor prompts appear in .carryover/ for correct project dir
  • Progress log grows on each prompt without resetting
  • No duplicate entries for same prompt
  • Old-schema Cursor installs (pre-migration) still work via fallback path

…torage watcher

Cursor migrated prompts from globalStorage to per-workspace DBs. The old
adapter read aiService.generations/prompts from the global DB which was empty
after migration, so no sessions were captured.

Changes:
- Rewrite cursor adapter to read composer.composerHeaders from global DB,
  then per-workspace aiService.prompts from workspaceStorage/<id>/state.vscdb
- Track seen_prompts per workspace to avoid re-reading on each poll
- Use new_seen_prompts within a batch so two composers sharing the same
  workspace don't both re-read it (fixes duplicates)
- Include project_dir in CursorCursor JSON so infer_project_dir_from_cursor
  routes fs-watcher events to the correct .carryover/ directory
- Old schema (aiService.generations/composerData in global DB) kept as
  automatic fallback for pre-migration Cursor installs
- Add workspaceStorage/ to Cursor transcript_paths so the fs-watcher fires
  when prompts are written (they no longer modify globalStorage)
- Fix progress log to never reset on session change — always append
- Deduplicate progress entries by exact line within each build call
- Add new-schema fixtures under globalStorage/ + workspaceStorage/
- Old fixture moved to oldSchema/ for fallback-path tests
Cursor and Codex both shipped storage-format changes. The old adapters
were silently capturing nothing on current versions of either tool. This
release rewrites both, hardens the pipeline, and reshapes the handoff
into an accumulating record that survives daemon restarts.

Adapters
- Cursor: composer.composerHeaders + per-workspace aiService.prompts
  (new schema), with old-schema fallback for pre-migration installs.
- Codex: event_msg.payload.{type,message} parsing, session_id captured
  from session_meta and re-injected on incremental reads, plus
  history.jsonl as a real-time user-prompt source.
- Both now persist project_dir in their cursors so fs-watcher events
  route to the correct project directory.
- Skip-on-error parsing — one corrupt JSON line no longer blocks ingest.
- New watched paths: ~/.config/Cursor/User/workspaceStorage and
  ~/.codex/history.jsonl.

Pipeline / handoff
- Task and Next action accumulate (newest first, full-list dedupe).
- Progress log never resets — appends across all sessions and tools.
- New ## Session activity section: git diff --stat HEAD when available,
  filesystem mtimes otherwise. Preserved across ingests when the recent
  scan is empty.
- Strict response rules in the preamble — agents read silently, don't
  narrate the file structure, two short paragraphs in user's tone.
- Preamble auto-refresh on daemon start so rule updates propagate to
  existing handoffs without waiting for a new prompt.
- Next action falls back to the latest user prompt prefixed with
  "Continue: " when no assistant text is captured (Cursor case).
Cursor caps `aiService.prompts` at ~10 entries — when a user types a new
prompt and the array is full, Cursor drops the oldest. The old index-based
watermark (`seen_count == array.length`) then incorrectly read as
"caught up" and silently missed every subsequent prompt.

Fix: persist `last_prompt_text[workspace_id]` in CursorCursor. On each
read, find the rposition of that text in the array and resume from the
next index. If the text is no longer present (deeply truncated), fall
back to emitting the full array — progress-log + Task accumulation
dedupe by content downstream.

Also clippy fixes: replace `sort_by` with `sort_by_key`, `iter().any()`
with `contains()`, and `>= MAX + 1` with `> MAX`.
@rohitsux rohitsux merged commit 52e771b into main Apr 30, 2026
8 checks passed
@rohitsux rohitsux deleted the fix/cursor-schema-and-progress-log branch April 30, 2026 06:44
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.

1 participant