
终极开源工具,用于浏览、搜索、导出和备份您的 Cursor AI 聊天历史。
遵循 Unix 哲学的 POSIX 风格 CLI 工具:专注于一件事并做到极致——访问您的 Cursor AI 聊天历史。简单、可组合、专注。
# 管道友好:可与其他工具组合使用cursor-history list --json | jq '.[] | select(.messageCount > 10)'cursor-history export 1 | grep -i "api" | head -20cursor-history search "bug" --json | jq -r '.[].sessionId' | xargs -I {} cursor-history export {}
再也不会丢失任何对话。无论您需要查找上周的完美代码片段、将历史记录迁移到新机器,还是为所有 AI 辅助开发会话创建可靠备份——cursor-history 都能满足您的需求。免费、开源,由社区为社区打造。
# 全局安装npm install -g cursor-history # 使用 CLIcursor-history list
# 克隆并构建git clone https://github.com/S2thend/cursor_chat_history.gitcd cursor_chat_historynpm installnpm run build # 直接运行node dist/cli/index.js list # 或全局链接npm linkcursor-history list
cursor-history 支持两种 SQLite 驱动,以获得最大兼容性:
| 驱动 | 描述 | Node.js 版本 |
|---|---|---|
node:sqlite | Node.js 内置 SQLite 模块(无需原生绑定) | 22.5+ |
better-sqlite3 | 通过 better-sqlite3 的原生绑定 | 20+ |
默认情况下,cursor-history 会自动选择最佳可用驱动:
您可以使用环境变量强制指定驱动:
# 强制使用 better-sqlite3CURSOR_HISTORY_SQLITE_DRIVER=better-sqlite3 cursor-history list # 强制使用 node:sqlite(需要 Node.js 22.5+)CURSOR_HISTORY_SQLITE_DRIVER=node:sqlite cursor-history list
查看正在使用哪个驱动:
DEBUG=cursor-history:* cursor-history list
在将 cursor-history 作为库使用时,您可以通过编程方式控制驱动:
import { setDriver, getActiveDriver, listSessions } from 'cursor-history'; // 在任何操作之前强制指定驱动setDriver('better-sqlite3'); // 检查当前活动的驱动const driver = getActiveDriver();console.log(`使用驱动: ${driver}`); // 或通过 LibraryConfig 配置const result = await listSessions({ sqliteDriver: 'node:sqlite' // 为此调用强制使用 node:sqlite});
# 列出最近的会话(默认:20 个)cursor-history list # 列出所有会话cursor-history list --all # 列出带有 composer ID 的会话(用于外部工具)cursor-history list --ids # 限制结果数量cursor-history list -n 10 # 仅列出工作区cursor-history list --workspaces
# 按索引号显示会话cursor-history show 1 # 显示截断的消息(快速概览)cursor-history show 1 --short # 显示完整的 AI 思考/推理文本cursor-history show 1 --think # 显示完整的文件读取内容(不截断)cursor-history show 1 --fullread # 显示完整的错误消息(不截断为 300 字符)cursor-history show 1 --error # 按消息类型过滤(user, assistant, tool, thinking, error)cursor-history show 1 --only usercursor-history show 1 --only user,assistantcursor-history show 1 --only tool,error # 组合选项cursor-history show 1 --short --think --fullread --errorcursor-history show 1 --only user,assistant --short # 输出为 JSONcursor-history show 1 --json
# 搜索关键词cursor-history search "react hooks" # 限制结果数量cursor-history search "api" -n 5 # 调整匹配周围的上下文cursor-history search "error" --context 100
# 导出单个会话为 Markdowncursor-history export 1 # 导出到指定文件cursor-history export 1 -o ./my-chat.md # 导出为 JSONcursor-history export 1 --format json # 导出所有会话到目录cursor-history export --all -o ./exports/ # 覆盖现有文件cursor-history export 1 --force
# 将单个会话移动到另一个工作区cursor-history migrate-session 1 /path/to/new/project # 移动多个会话(逗号分隔的索引或 ID)cursor-history migrate-session 1,3,5 /path/to/project # 复制而非移动(保留原件)cursor-history migrate-session --copy 1 /path/to/project # 预览将发生的操作而不实际更改cursor-history migrate-session --dry-run 1 /path/to/project # 将一个工作区的所有会话移动到另一个cursor-history migrate /old/project /new/project # 复制所有会话(备份)cursor-history migrate --copy /project /backup/project # 强制与目标现有会话合并cursor-history migrate --force /old/project /existing/project
# 创建所有聊天历史的备份cursor-history backup # 创建备份到指定文件cursor-history backup -o ~/my-backup.zip # 覆盖现有备份cursor-history backup --force # 列出可用备份cursor-history list-backups # 列出指定目录中的备份cursor-history list-backups -d /path/to/backups # 从备份恢复cursor-history restore ~/cursor-history-backups/backup.zip # 恢复到自定义位置cursor-history restore backup.zip --target /custom/cursor/data # 强制覆盖现有数据cursor-history restore backup.zip --force # 查看备份中的会话而不恢复cursor-history list --backup ~/backup.zipcursor-history show 1 --backup ~/backup.zipcursor-history search "query" --backup ~/backup.zipcursor-history export 1 --backup ~/backup.zip
# 输出为 JSON(适用于所有命令)cursor-history --json list # 使用自定义 Cursor 数据路径cursor-history --data-path ~/.cursor-alt list # 按工作区过滤cursor-history --workspace /path/to/project list
浏览聊天历史时,您将看到:
--fullread 查看完整内容)toolFormerData.additionalData.status 提取)--think 查看完整文本)--short 模式 - 将用户和助手消息截断为 300 字符,便于快速浏览--think 标志 - 显示完整的 AI 推理/思考文本(不截断)--fullread 标志 - 显示完整的文件读取内容而非预览--error 标志 - 显示完整的错误消息而非 300 字符预览--only <types> 标志 - 按类型过滤消息:user、assistant、tool、thinking、error(逗号分隔)| 平台 | 路径 |
|---|---|
| macOS | ~/Library/Application Support/Cursor/User/ |
| Windows | %APPDATA%/Cursor/User/ |
| Linux | ~/.config/Cursor/User/ |
该工具会自动从这些位置查找并读取您的 Cursor 聊天历史。
除了 CLI,您还可以在 Node.js 项目中将 cursor-history 作为库使用:
import { listSessions, getSession, searchSessions, exportSessionToMarkdown} from 'cursor-history'; // 列出所有会话并分页const result = listSessions({ limit: 10 });console.log(`找到 ${result.pagination.total} 个会话`); for (const session of result.data) { console.log(`${session.id}: ${session.messageCount} 条消息`);} // 获取特定会话(从零开始的索引)const session = getSession(0);console.log(session.messages); // 在所有会话中搜索const results = searchSessions('authentication', { context: 2 });for (const match of results) { console.log(match.match);} // 导出为 Markdownconst markdown = exportSessionToMarkdown(0);
import { migrateSession, migrateWorkspace } from 'cursor-history'; // 将会话移动到另一个工作区const results = migrateSession({ sessions: 3, // 索引或 ID destination: '/path/to/new/project'}); // 复制多个会话(保留原件)const results = migrateSession({ sessions: [1, 3, 5], destination: '/path/to/project', mode: 'copy'}); // 在工作区之间迁移所有会话const result = migrateWorkspace({ source: '/old/project', destination: '/new/project'});console.log(`迁移了 ${result.successCount} 个会话`);
import { createBackup, restoreBackup, validateBackup, listBackups, getDefaultBackupDir} from 'cursor-history'; // 创建备份const result = await createBackup({ outputPath: '~/my-backup.zip', force: true, onProgress: (progress) => { console.log(`${progress.phase}: ${progress.filesCompleted}/${progress.totalFiles}`); }});console.log(`备份已创建: ${result.backupPath}`);console.log(`会话数: ${result.manifest.stats.sessionCount}`); // 验证备份const validation = validateBackup('~/backup.zip');if (validation.status === 'valid') { console.log('备份有效');} else if (validation.status === 'warnings') { console.log('备份有警告:', validation.corruptedFiles);} // 从备份恢复const restoreResult = restoreBackup({ backupPath: '~/backup.zip', force: true});console.log(`恢复了 ${restoreResult.filesRestored} 个文件`); // 列出可用备份const backups = listBackups(); // 扫描 ~/cursor-history-backups/for (const backup of backups) { console.log(`${backup.filename}: ${backup.manifest?.stats.sessionCount} 个会话`);} // 从备份读取会话而不恢复const sessions = listSessions({ backupPath: '~/backup.zip' });
| 函数 | 描述 |
|---|---|
listSessions(config?) | 列出会话并分页 |
getSession(index, config?) | 按索引获取完整会话 |
searchSessions(query, config?) | 在会话中搜索 |
exportSessionToJson(index, config?) | 将会话导出为 JSON |
exportSessionToMarkdown(index, config?) | 将会话导出为 Markdown |
exportAllSessionsToJson(config?) | 将所有会话导出为 JSON |
exportAllSessionsToMarkdown(config?) | 将所有会话导出为 Markdown |
migrateSession(config) | 将会话移动/复制到另一个工作区 |
migrateWorkspace(config) | 在工作区之间移动/复制所有会话 |
createBackup(config?) | 创建所有聊天历史的完整备份 |
restoreBackup(config) | 从备份恢复聊天历史 |
validateBackup(path) | 验证备份完整性 |
listBackups(directory?) | 列出可用的备份文件 |
getDefaultBackupDir() | 获取默认备份目录路径 |
getDefaultDataPath() | 获取特定平台的 Cursor 数据路径 |
setDriver(name) | 设置 SQLite 驱动 ('better-sqlite3' 或 'node:sqlite') |
getActiveDriver() | 获取当前活动的 SQLite 驱动名称 |
interface LibraryConfig { dataPath?: string; // 自定义 Cursor 数据路径 workspace?: string; // 按工作区路径过滤 limit?: number; // 分页限制 offset?: number; // 分页偏移 context?: number; // 搜索上下文行数 backupPath?: string; // 从备份文件读取而非实时数据 sqliteDriver?: 'better-sqlite3' | 'node:sqlite'; // 强制指定 SQLite 驱动 messageFilter?: MessageType[]; // 按类型过滤消息 (user, assistant, tool, thinking, error)}
import { listSessions, getSession, createBackup, isDatabaseLockedError, isDatabaseNotFoundError, isSessionNotFoundError, isWorkspaceNotFoundError, isInvalidFilterError, isBackupError, isRestoreError, isInvalidBackupError} from 'cursor-history'; try { const result = listSessions();} catch (err) { if (isDatabaseLockedError(err)) { console.error('数据库已锁定 - 关闭 Cursor 后重试'); } else if (isDatabaseNotFoundError(err)) { console.error('未找到 Cursor 数据'); } else if (isSessionNotFoundError(err)) { console.error('未找到会话'); } else if (isWorkspaceNotFoundError(err)) { console.error('未找到工作区 - 请先在 Cursor 中打开项目'); }} // 过滤错误处理try { const session = getSession(0, { messageFilter: ['invalid'] });} catch (err) { if (isInvalidFilterError(err)) { console.error('无效的过滤类型:', err.invalidTypes); console.error('有效类型:', err.validTypes); }} // 备份特定错误try { const result = await createBackup();} catch (err) { if (isBackupError(err)) { console.error('备份失败:', err.message); } else if (isInvalidBackupError(err)) { console.error('无效的备份文件'); } else if (isRestoreError(err)) { console.error('恢复失败:', err.message); }}
npm installnpm run build
npm test # 运行所有测试npm run test:watch # 监视模式
本项目使用 GitHub Actions 进行自动 NPM 发布。要发布新版本:
更新 package.json 中的版本:
npm version patch # 用于 bug 修复 (0.1.0 -> 0.1.1)npm version minor # 用于新功能 (0.1.0 -> 0.2.0)npm version major # 用于破坏性更改 (0.1.0 -> 1.0.0)
推送版本标签以触发自动发布:
git push origin main --tags
GitHub 工作流将自动:
首次设置:将您的 NPM 访问令牌添加为名为 NPM_TOKEN 的 GitHub secret:
NPM_TOKEN 的新仓库 secret,值为您的 NPM 令牌我们欢迎社区贡献!以下是您可以参与的方式:
git checkout -b feature/my-feature)npm test && npm run lint)git commit -m 'Add my feature')git push origin feature/my-feature)git clone https://github.com/S2thend/cursor_chat_history.gitcd cursor_chat_historynpm installnpm run buildnpm test
MIT