Treat more than two real senders as stronger evidence than a conflicting private marker while preserving genuine private chats with system placeholders.
Use timestamp and message ID as the stable viewer cursor so historical messages imported later remain in chronological order. Resolve timeline anchors by message time and cover out-of-order IDs with SQLite regressions.
Share auto-import planning between preview and write paths, expose a machine-readable CLI result envelope, and preserve explicit parser options during analysis.
Keep the sidebar header below the fixed 32px title bar after removing the outer margin. This prevents header controls from being covered on non-macOS platforms.
Route Desktop JSON dry-runs through a shared read-only push analyzer so validation, deduplication, and member inference match actual writes. Keep JSONL on the file analyzer path and cover new and incremental predictions without database mutations.
Use the long-running worker timeout and refresh Desktop caches after successful push imports.
Align auto-created member metadata and counts across initial and incremental imports, exclude SYSTEM from member updates, and keep existing-session writes validated and atomic.
Thread ownerId and member aliases through the TS and native parsers. Persist aliases across full and incremental imports so exported ChatLab JSON retains user identity metadata.
Stream members and messages in one pass so nested member metadata is parsed structurally. Cover exports whose complete member list exceeds the filtered messages.
Remove persisted annual summary snapshots whenever a session is deleted through shared or desktop cleanup paths. Drop cached in-memory snapshots when their backing files disappear so stale responses cannot expose deleted session data.
An ambient npm_config_runtime=electron (common in Electron dev shells
and CI) makes bare prebuild-install "succeed" with an Electron-ABI
binding, bypassing the source-build fallbacks and leaving the CLI
unable to start. Pin -r node -t to the current system Node instead.
Co-authored-by: Cursor <cursoragent@cursor.com>
Prepending all of System32 to PATH made WSL bash.EXE shadow Git Bash,
breaking every later shell: bash step (first hit: dtolnay/rust-toolchain);
now only tar.exe is exposed. Passing --target after -- hid the triple
from napi, which then emitted a host-named darwin-arm64 artifact for the
x64 build; pass --target to napi directly instead.
Co-authored-by: Cursor <cursoragent@cursor.com>
prebuild-install was invoked with -r napi, but better-sqlite3 only
publishes per-ABI node/electron prebuilds, so the download branch always
failed and every run fell back to a ~1.5min node-gyp source build.
Co-authored-by: Cursor <cursoragent@cursor.com>
Avoid switching legacy DELETE-journal session databases to WAL from readonly validation paths. This prevents sync existence checks from treating valid databases as unreadable and deleting them.
The UI stayed on "parsing messages" during the whole post-parse phase:
the importer emitted an 'importing' stage the frontend had no text for,
and on CLI Web the synchronous DB writes / index / FTS build starved the
event loop so buffered SSE progress events only arrived after the import
finished.
- Replace 'importing' with 'saving' (message writes) and a new 'indexing'
stage (indexes / FTS / session index) in ParseProgress, with UI texts
for all four locales.
- Yield a macrotask between native parser batches and before heavy
synchronous steps so SSE progress events flush while importing.
Co-authored-by: Cursor <cursoragent@cursor.com>
getJieba() invalidated its cache whenever no dict file existed on disk,
so users without a custom dict rebuilt a Jieba instance per tokenize call.
FTS indexing tokenizes every message, making imports seconds slower
(43MB sample: 9.2s -> 3.5s after the fix). Cache now only invalidates
when the on-disk dict state actually changes (added or removed).
Co-authored-by: Cursor <cursoragent@cursor.com>
Add @openchatlab/parser-native (napi-rs v3) with a shared byte-level JSON
scanner and two format kernels. Parsing large exports is 4-10x faster in
real-data benchmarks. The native module is an optional local build; the
pure-TS parsers remain as automatic fallback when it is unavailable,
disabled via CHATLAB_DISABLE_NATIVE_PERF=1, or rejects off-spec files.
The ChatLab kernel also parses the members array structurally, fixing the
TS head-regex heuristic that silently dropped avatars/roles for files with
nested arrays or long member lists.
Co-authored-by: Cursor <cursoragent@cursor.com>
Clamp CLI SQL output after execution so user-provided LIMIT clauses cannot bypass the requested row cap. Add a deterministic message id tie-breaker for response-time statistics.