Skip to main content

Local Cursor chat summary indexer and search tool

Project description

Curlens

PyPI version Python 3.12+ License: MIT Cursor CLI

Search and resume your Cursor CLI chat sessions by description.

Curlens Demo

The Problem

You use Cursor CLI across multiple projects. After a few days, you have dozens of chats scattered across different workspaces. You remember discussing "flink job optimization" somewhere, but:

  • Which folder was it in?
  • What was the chat called?
  • How do you resume it?

Cursor stores all chats internally like this:

~/.cursor/chats/
├── a14702e33628716ed.../   # MD5 hash of workspace path (not human-readable!)
│   ├── 8616c508-cbce.../   # Chat UUID
│   │   └── store.db        # Messages stored in SQLite
│   └── 2134a03e-7cdb.../
├── 1dd0fd26bc4627ee.../    # Another workspace hash
│   └── ...
└── (dozens more)

This is Cursor's internal structure—not your project folders. The hash a14702e33628... is actually MD5("/Users/you/workspace/myproject"). There's no easy way to:

  1. Know which workspace a hash folder belongs to
  2. Search chat contents without opening each store.db
  3. Find the right chat to resume with cursor agent --resume <id>

The Solution

Curlens indexes your chats with AI-generated summaries and lets you search by description:

$ curlens -d "flink optimization"

Found 2 matching chat(s):

[1] Flink Job Tuning
    Dir: /Users/you/workspace/data-pipeline
    Optimized Flink checkpointing and parallelism settings for better throughput...

[2] Stream Processing Debug  
    Dir: /Users/you/workspace/analytics
    Fixed watermark issues in Flink streaming job...

Select chat [1-2]: 1
→ Resuming: Flink Job Tuning
→ Directory: /Users/you/workspace/data-pipeline

How It Works

┌─────────────────────────────────────────────────────────────────┐
│                        CURSOR CLI                               │
│  cursor agent (shell commands, file edits, MCP calls)          │
└─────────────────────┬───────────────────────────────────────────┘
                      │ hooks fire
                      ▼
┌─────────────────────────────────────────────────────────────────┐
│                     CURLENS HOOK                                │
│  1. Read chat messages from ~/.cursor/chats/<hash>/<id>/        │
│  2. Extract user queries + assistant responses                  │
│  3. Generate summary via LLM (cursor agent -p)                  │
│  4. Store in ~/.cursor/curlens/summary.db                       │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│                     CURLENS SEARCH                              │
│  curlens -d "your query"                                        │
│  1. Load summaries from SQLite                                  │
│  2. Rank by keyword match (or LLM with --smart)                 │
│  3. Display top results                                         │
│  4. Resume selected chat with cursor agent --resume             │
└─────────────────────────────────────────────────────────────────┘

Cursor's Internal Structure

Curlens reads from Cursor's internal storage:

~/.cursor/
├── chats/
│   └── <md5(workspace_path)>/      # Hash of workspace path
│       └── <conversation_id>/
│           └── store.db            # SQLite with chat messages
├── projects/
│   └── Users-you-workspace-myproject/  # Encoded workspace path
│       └── worker.log              # Contains workspace mapping
└── curlens/                        # Created by curlens
    ├── config.json
    ├── summary.db
    └── hook.log

The hash folders in chats/ are MD5 hashes of workspace paths. Curlens maps them back using the projects/ folder names.

Install

pip install curlens

Or from source:

git clone https://github.com/cnighut/curlens
cd curlens
pip install -e .

Quick Start

1. Backfill Existing Chats (Do This First)

Index your existing chats before setting up hooks:

# Preview what will be processed
curlens --backfill --dry-run

# Process all chats (creates DB automatically)
curlens --backfill

# Or process in batches
curlens --backfill --limit 50

This scans ~/.cursor/chats/, generates summaries, and stores them. Chats with unknown workspace paths are skipped.

⚠️ Backfill is slow - Each chat requires an LLM call (~10-30 seconds). For 100+ chats, expect 30-60 minutes. Use --limit to process in batches. Already-processed chats are skipped on re-runs.

2. Setup Hooks (For Auto-Indexing)

Hooks automatically update summaries as you chat. Without hooks, you'd need to re-run backfill manually.

Create/edit ~/.cursor/hooks.json:

{
  "version": 1,
  "hooks": {
    "afterShellExecution": [
      {"command": "python3 /path/to/curlens/curlens/hooks/session_end.py"}
    ],
    "afterMCPExecution": [
      {"command": "python3 /path/to/curlens/curlens/hooks/session_end.py"}
    ],
    "afterFileEdit": [
      {"command": "python3 /path/to/curlens/curlens/hooks/session_end.py"}
    ]
  }
}

Important: Replace /path/to/curlens with your actual install path.

Why these hooks?

  • afterShellExecution - Fires after terminal commands
  • afterMCPExecution - Fires after MCP tool calls
  • afterFileEdit - Fires after file modifications

These are the only hooks that work reliably with Cursor CLI.

3. Search & Resume

# Basic search (fast, keyword-based)
curlens -d "configuring nvim"

# Smart search (LLM-ranked, slower but smarter)
curlens -d "kubernetes deployment issue" --smart

Config

~/.cursor/curlens/config.json (created automatically):

{
  "summary_model": "grok",
  "search_model": "grok",
  "summary_max_words": 70,
  "search_window_days": 20,
  "hooks_enabled": true,
  "debug": false
}
Key Description
summary_model Model for generating summaries
search_model Model for --smart ranking
summary_max_words Max words per summary
search_window_days How far back to search
hooks_enabled Enable/disable hook processing
debug Log to ~/.cursor/curlens/hook.log

Cost Considerations

Curlens uses cursor agent -p to generate summaries, which consumes API tokens from your Cursor subscription.

Estimated usage per chat:

  • Summary generation: ~500-1000 tokens
  • Smart search (optional): ~200 tokens per search

To minimize costs:

  1. Use a cheaper/faster model in config:

    {"summary_model": "grok", "search_model": "grok"}
    
  2. Skip smart search - Default search uses keyword matching (free):

    curlens -d "query"        # Free (keyword match)
    curlens -d "query" --smart  # Uses LLM tokens
    
  3. Use self-hosted models - If you have Ollama or similar:

    {"summary_model": "ollama/llama3", "search_model": "ollama/llama3"}
    

    (Requires Cursor to be configured with your local model endpoint)

  4. Backfill in batches to control spend:

    curlens --backfill --limit 20  # Process 20 at a time
    

Note: Hooks fire frequently during active chats. Each hook only processes new messages incrementally, so repeated summaries for the same chat are efficient updates, not full regenerations.

Auto-skipped chats (no LLM calls):

  • "New Agent" chats created after Jan 2026 (these are curlens's own cursor agent -p calls)
  • Chats with trivial content (<100 chars or <50 alphabetic chars)
  • Meta-chats containing summarization prompts

CLI-Only

This tool is designed for Cursor CLI (cursor agent). IDE-originated chats are automatically skipped.

Tested on: Cursor CLI version 2026.01.23-6b6776e

cursor agent --version  # Check your version

Troubleshooting

No chats found?

  • Run curlens --backfill --dry-run to check discovery
  • Ensure hooks are configured correctly

Debug mode:

{"debug": true}

Check ~/.cursor/curlens/hook.log for hook events.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

curlens-0.1.2.tar.gz (21.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

curlens-0.1.2-py3-none-any.whl (20.3 kB view details)

Uploaded Python 3

File details

Details for the file curlens-0.1.2.tar.gz.

File metadata

  • Download URL: curlens-0.1.2.tar.gz
  • Upload date:
  • Size: 21.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.8

File hashes

Hashes for curlens-0.1.2.tar.gz
Algorithm Hash digest
SHA256 6f0a2876bfe5351cb64c1d7022b1569e739bb4681296e853de7b87bcdb46f8a4
MD5 47450f6004aeb3f7748e31ee3d452033
BLAKE2b-256 7602180453fdcfbb684f8174a4eb6430b51d00395fe9aab81a7fc338b29aec5a

See more details on using hashes here.

File details

Details for the file curlens-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: curlens-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 20.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.8

File hashes

Hashes for curlens-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 d39914f02b6294a45fb10b314c4028832e069fd7e58dd6064e1dce4cc2d57591
MD5 9e7deb2bb76f5feec33016167a17987d
BLAKE2b-256 f09ed3c788a31d4082519e2ae30a19f2c85ae3fbf4a8b7bc0f280e67515efd3a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page