When a pullAllSessions was already running, the reloadTimer triggered
by adding sessions would be skipped by the source-level concurrency
lock, causing newly added sessions to wait until the next scheduled
interval (up to 60 minutes) before syncing.
Fix: trigger individual per-session pulls via triggerPull(sourceId,
sessionId) which bypasses the source-level lock, ensuring immediate
sync for newly added sessions regardless of concurrent pulls.
Also includes: connection pre-check on data source add, removal of
duplicate "browse remote sessions" button, hiding "other" session
types, and full resync fix for deleted local sessions.
Co-authored-by: Cursor <cursoragent@cursor.com>
Extract shared business logic from monolithic web.ts into reusable
services in @openchatlab/node-runtime (session, member, index, summary,
export), using SessionRuntimeAdapter to abstract platform differences.
Split web.ts into 12 domain-specific route modules under routes/web/.
Co-authored-by: Cursor <cursoragent@cursor.com>
MiniMax models embed thinking content as <think> tags in the content
field rather than using a separate reasoning field. Add a streaming
think-tag parser that detects these tags in real-time during streaming
and routes them to the thinking UI instead of displaying raw tags.
Co-authored-by: Cursor <cursoragent@cursor.com>
Add directory import support for multi-file formats (e.g. shuakami chunked-jsonl).
Users can select or drag-and-drop a directory via the "Import Folder" checkbox.
- Add `findEntryFileInDirectory()` to parser layer for format-agnostic entry file discovery
- Add `importDirectory` method to ImportAdapter interface
- Implement FetchImportAdapter.importDirectory with multi-file FormData upload
- Add `POST /_web/import-directory` CLI route with directory reconstruction
- Add `chat:importDirectory` IPC handler in Electron main process
- Enhance FileDropZone with `directory` prop and drag-and-drop directory support
- Refactor FetchImportAdapter to extract reusable `consumeSseStream` helper
Co-authored-by: Cursor <cursoragent@cursor.com>
The IncrementalImportModal was Electron-only: showOpenDialog returned
canceled in web mode and FetchImportAdapter threw notSupported for both
analyzeIncrementalImport and incrementalImport despite CLI routes
already existing. Fix by using FileDropZone's built-in file input for
file selection and implementing the two fetch adapter methods via
FormData upload + SSE streaming.
Co-authored-by: Cursor <cursoragent@cursor.com>
The MCP entry was loading better-sqlite3 from node_modules which may
have been compiled for a different Node.js ABI. Now passes the
pre-built native binding from apps/cli/native/ (maintained by
ensure-native.mjs), matching how other CLI commands handle this.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Expand MCP_TOOL_REGISTRY from 8 to 33 tools by including all
AGENT_TOOL_REGISTRY tools (analytics, deep search, conversation, etc.)
- Add format=text|json parameter to all MCP tools (default: text for
most, json for SQL tools) for token-efficient LLM consumption
- Create format.ts: message filtering, consecutive-sender merging,
content truncation, and compact text output
- Inspired by community chatlab-mcp-server project
Co-authored-by: Cursor <cursoragent@cursor.com>
Move MCP Server logic (tool registration, resource registration, schema
conversion) from apps/cli/src/mcp.ts to packages/mcp-server so both CLI
and Desktop can share the same MCP implementation.
- New package: chatlab-mcp (packages/mcp-server) with McpDatabaseManager
interface abstraction
- CLI mcp.ts slimmed to thin entry (~37 lines) calling startMcpServer()
- Desktop helper prototype at apps/desktop/helper/mcp.ts for dev-time
MCP without GUI
- All 8 MCP tools and 3 resources unchanged
Co-authored-by: Cursor <cursoragent@cursor.com>
Add @electron/rebuild devDependency and postinstall script to
apps/desktop so that better-sqlite3 is automatically recompiled
against Electron's Node.js headers after every pnpm install,
preventing NODE_MODULE_VERSION mismatch at runtime.
- Add backendPersist Pinia plugin for declarative preferences.json persistence
- Move Preferences types to @openchatlab/shared-types (single source of truth)
- Migrate sessionGapThreshold from localStorage to config.toml [ui]
- Migrate chatlab_filter_history from localStorage to preferences.json
- Fix stale localStorage locale read in i18n/index.ts
- Simplify usePreferencesSync (172 → 75 lines) by delegating to plugin
Adding a new backend-synced preference now only requires 3 changes:
1. shared-types interface 2. node-runtime DEFAULTS 3. store backendPersist.pick
When a desktop app user installs the CLI, automatically detect existing
Electron data directory (including custom paths via storage.json),
repoint config.toml, and migrate system data (ai, settings, cache, etc.)
to ~/.chatlab/. Block CLI execution with actionable instructions when
Electron was used but databases cannot be located.
- Remove "type": "module" from apps/cli/package.json to avoid
ESM/CJS interop issues with workspace packages in tsx dev mode
- Configure tsup to output .mjs files (always treated as ESM by Node.js)
- Rename bin entry from chatlab.js to chatlab.mjs
- Change chatlab web default port to 3100 (serve keeps 3110)
- Fix vite plugin: use pnpm instead of npx for tsx invocation
All command descriptions, console output, option labels, comments
and error messages are now in English, consistent with AGENTS.md
rules and npm package positioning.
- Rename package to `chatlab-cli`, version 0.1.0
- Add tsup config with ESM output, bundle @openchatlab/* + stream-json
- Update bin/chatlab.js from stub to actual entry point
- Unify version reading via src/version.ts (CLI/MCP/HTTP API)
- Add publishing fields: type, files, engines, publishConfig, keywords
- Move @openchatlab/* to devDependencies (bundled into dist/)
- Add better-sqlite3 to dependencies, @node-rs/jieba to optionalDependencies
- Fix --web default path for bundled dist/ directory structure
Move the CLI application from packages/server/ to apps/cli/ to align
with the monorepo convention (apps/ for deployable applications,
packages/ for shared libraries). Rename package to @openchatlab/chatlab.
Also fix a bug in ensureToken() that used raw string manipulation to
write config.toml, causing duplicate token fields that corrupted the
TOML file. This led to config parse failures and user_data_dir being
overwritten with defaults. Now uses writeConfigField() for safe writes.
Worker thread crashed in packaged builds with "Cannot find module 'electron'"
because streamImport.ts transitively imported paths.ts (which requires electron)
through merger/tempCache.ts. Replaced with worker-local implementations that
receive tempDir via workerData, matching the existing dbDir/cacheDir pattern.
The extraction of Electron code to apps/desktop/ changed the package name
from "ChatLab" to "@openchatlab/desktop", which caused app.getPath('userData')
to return a wrong path in dev mode. This made the migration system unable to
find existing databases, resulting in a fresh-app experience for upgrading users.
- Add productName "ChatLab" to desktop package.json to ensure correct userData path
- Add verifyDataPath() safety net: auto-correct config.toml when configured dir
has no databases but old Electron path does
- Pin electron to 35.7.5 (electron-builder requires fixed version)
- Remove redundant @electron/rebuild (built into electron-builder)
- Use electron-builder install-app-deps for postinstall
Adds a zero-dependency Node.js script with arrow-key selection
for choosing between Desktop (Electron), Web (CLI serve + frontend),
Server Only (API backend), and Frontend-only dev modes.
Remembers last selection in node_modules/.cache/dev-mode.
Move Electron-specific code (main, preload, shared) and configs
(electron.vite, electron-builder) into apps/desktop/ to prepare
for multi-platform support (Web Browser standalone).
- Create apps/desktop/ with dedicated package.json and tsconfig
- Split Electron deps (electron, electron-updater, better-sqlite3,
etc.) from shared frontend deps in root package.json
- Declare better-sqlite3 and @node-rs/jieba in packages/node-runtime
- Add stream-json to packages/parser where it belongs
- Update all path aliases (@electron/* → apps/desktop/*) in tsconfig,
vite configs, and relative imports in preload/main
- Keep slim root tsconfig.node.json as shared base for packages
- Update CI/CD release workflow for new directory layout
- Fix pre-existing type errors (pi-ai Model generic, SQLLabTab
LLMChatStreamChunk, filter.test.ts empty methods)
These are frontend-only Vue/ECharts components that depend on app internals (@/),
not cross-platform shared packages. Moving them to src/features/charts-* keeps
packages/ purely for reusable Node.js libraries.
The query barrel file was missing re-exports for getSessionsByTimeRange,
getRecentChatSessions, loadSessionMessages, getPrivateChatMemberAvatar,
getExportSessionData, and searchMessagesWithFtsAsync.
- Extract getPrivateChatMemberAvatar to @openchatlab/core
- Extract getExportSessionData (meta/members/messages SQL) to @openchatlab/core
- Extract loadSessionMessages for summary generation to @openchatlab/core
- Replace inline SQL in summary buildDeps with shared core query functions
- Extract createCompressionLlmAdapter factory to @openchatlab/node-runtime
- Simplify server and electron compression adapter creation via shared factory
- Extract formatAIError to @openchatlab/node-runtime, eliminate duplicate in Electron and Server
- Extract stripAvatarFields to @openchatlab/core
- Extract FTS message search SQL to core (searchMessagesWithFtsAsync)
- Remove redundant sync searchMessagesWithLike from Electron worker
- Remove dead code: electron/main/ai/agent/content-parser.ts (duplicate of @openchatlab/core)
- Extract getSessionsByTimeRange and getRecentChatSessions to @openchatlab/core
- Route IPC session:getByTimeRange and session:getRecent through Worker instead of inline SQL
- Eliminate duplicate getSessionSummaries in workerManager.ts, delegate to core via Worker
- All distribution targets share root package.json version (lock-step)
- Commit scope: free-form for shared changes, platform scope (electron/
cli/web) only when the change is platform-specific
Inject __APP_VERSION__ from package.json via Vite define, read it in
WebPlatformAdapter.getVersion(), and call getVersion() on all platforms
(not just Electron) in Sidebar onMounted.
tsx watch's symlink-based file watching doesn't trigger on changes to
pnpm workspace packages (tsx#221). Add --include flags for packages/core
and packages/node-runtime source directories to both dev:serve script
and vite.web.config.mts auto-serve plugin. Extract long command to
scripts/dev-serve.sh for cleaner package.json.
- Extract runSimpleLlmStream to @openchatlab/node-runtime for shared
Electron/Server streaming with thinking_start/delta/end event handling
- Simplify Electron IPC ai.ts by delegating to shared stream function
- Add thinking/thinkingDone fields to LlmStreamChunk and preload types
- Add collapsible thinking process display in SQL LAB with auto-scroll
- Implement Web chatStream via SSE with proper error propagation
- Add /_web/cache/save-to-downloads and show-in-folder server routes
- Add cacheApi shim in Web registry for server-side file operations
- Increase SQL LAB maxTokens to 4096 to accommodate reasoning models
- Detect finishReason:length and show token limit error message
- Add i18n keys for thinking/thinkingProcess/errorTokenLimit (4 locales)
- Replace mapCoreEventToStream with shared AgentEventHandler for rich
status events (contextTokens, totalUsage, updatedAt)
- Add formatAIError for user-friendly error messages (429/503/quota)
- Compute maxToolResultTokens dynamically from model contextWindow
- Add steerMessage (answerWithoutTools) and onConvertToLlm callback
- Forward ownerInfo/mentionedMembers from web frontend to server
Move AI-related translations (tools, agent prompts, LLM, summary) from
Electron-specific locale files into @openchatlab/node-runtime, enabling
single-source maintenance across Electron and Server.
- Add packages/node-runtime/src/ai/i18n/ with createAiTranslate() and
bundled locale data (zh-CN, en-US, ja-JP, zh-TW)
- Electron locale files now compose: Electron-specific keys + shared AI
translations from node-runtime
- Server agent.ts switches to shared buildSystemPrompt with evidence
policy, data snapshot injection, ownerInfo and mentionedMembers support
- Server route fetches dataSnapshot from getChatOverview before agent run