Skip to content

Project list and workspace details show different conversation counts; workspace load still slow on large installs #95

Description

@bradjin8

Problem

After #88 (lazy-load + summary endpoints), two correctness issues and one performance gap remained on large Cursor installs:

  1. Count mismatch — The project list page showed a different conversationCount than the number of tabs on the workspace details page for the same project.
  2. Noisy logs — Loading workspace summaries logged warnings for composerData:empty-state-draft when the global KV row had a NULL payload (the JSON object must be str, bytes or bytearray, not NoneType).
  3. Slow first paint — On machines with many workspaceStorage folders, project list and sidebar summary took ~50s because composer ownership was rebuilt sequentially from local state.vscdb files, and some paths still over-fetched global composerData.

Expected behavior

  • Project card conversationCount matches GET /api/workspaces/<id>/tabs?summary=1 tab count for the same project.
  • Cursor UI placeholders (e.g. empty-state-draft) are skipped without decode warnings.
  • Project list and sidebar summary use workspace-scoped I/O with cached composer registry; first conversation auto-loads after sidebar render (~2s is acceptable).

Root cause (count mismatch)

Project list briefly counted conversations from local allComposers without applying the same global filters as the summary path (non-empty fullConversationHeadersOnly, composer validation, exclusion rules including model names).

A secondary regression dropped conversations during assembly: get_project_from_file_path was accidentally removed while refactoring workspace_resolver.py, causing NameError and parse/assembly warnings on large installs.


Resolution (branch fix/workspace-list-load-and-count)

Shared composer scan

  • Extracted services/workspace_composer_scan.py so list and summary paths share the same parse, exclusion, and workspace-assignment logic.

Count alignment

  • list_workspace_projects now applies the same filters as list_workspace_tab_summaries (headers, validation, exclusion rules, assignment).

Performance

  • Parallelized build_composer_id_to_workspace_id via ThreadPoolExecutor.
  • Bulk load_project_layouts_map instead of per-composer N+1 queries.
  • Reused mtime-keyed disk cache (summary_cache.py) for project list and tab summaries.

Correctness

  • Null/placeholder composerData rows skipped without warnings.
  • Restored get_project_from_file_path in workspace_resolver.py.

UI

  • Workspace page auto-selects the first tab when no ?tab= query param is present.
  • Deep links from search (?tab=<composerId>) fetch the requested conversation directly instead of falling back to the first sidebar item.

Tests

  • tests/test_workspace_list_count_alignment.py — count parity
  • tests/test_project_path_boundary.py — path helper / assignment regression
  • Updated parse-warning and API tests

Acceptance criteria

  • conversationCount on project cards equals summary tab count for the same workspace
  • No warnings for null/empty composerData placeholders
  • Parallel local registry build + scoped global fetches for list/summary paths
  • Regression tests for count alignment, workspace scope, and null payload handling
  • Workspace UI auto-selects first tab when no ?tab= query param

Out of scope (tracked separately)

Search performance and indexing work landed on the same branch but is not part of this issue:

  • 30-day default search window + all_history opt-in
  • Local FTS search index (search_index.sqlite) with background refresh
  • Search bubble-scan optimization and deep-link workspace assignment fixes

Those should be referenced in the PR and/or a dedicated search issue.


Verify

  1. Restart python app.py.
  2. Home page: project counts match sidebar totals per project.
  3. No “could not be fully assembled” banner from placeholder composers.
  4. Open a workspace without ?tab= — first conversation loads automatically.
  5. pytest tests/test_workspace_list_count_alignment.py tests/test_api_workspaces.py

Metadata

Metadata

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions