Preserve batch support through telemetry, forward item-scoped progress across Desktop and CLI Web, and retain original backend failure details for diagnostics and unfinished results.
Add self-hosted Umami reporting alongside existing telemetry across Desktop and CLI Web.
Track normalized startup, import, feature, and AI usage with a stable anonymous ID and strict privacy allowlists. Keep incremental usage platform-independent and preserve accurate failure classifications and platform metadata across import paths.
Rebase official Demo timelines against the browser timezone, bound stalled downloads, and roll back partial batches across Desktop, CLI Web, and Web WASM. Document the platform cleanup hook's established best-effort boundary.
Load standalone CLI assistant configs through the shared manager so fresh data directories receive locale defaults. Back up custom assistants that occupy newly reserved default IDs before installing canonical templates.
Share auto-import planning between preview and write paths, expose a machine-readable CLI result envelope, and preserve explicit parser options during analysis.
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>
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.
Removes the legacy apps/cli/src/import/importer.ts (hand-rolled FTS, dedup,
session-ID generation) and apps/cli/src/import/chatlab-reader.ts (buffered
in-memory JSON/JSONL parser). DirectImporter in sync/adapters.ts now calls
streamImport / incrementalImport from stream-import.ts, which use the
@openchatlab/parser streaming pipeline and node-runtime shared logic.
Changes:
- Add sessionId? to StreamImportOptions so callers can fix the target session
ID instead of auto-generating one (needed by pull engine full-import path)
- Rewrite DirectImporter.incrementalImportFile and fullImportFile to use
the shared importers; map IncrementalImportResult fields to ImportResult
- Remove legacy exports from apps/cli/src/import/index.ts
- Rewrite importer.test.ts to use streamImport + a temp ChatLab JSON file
(same two data-dir compatibility gate assertions as before)
- Delete importer.ts and chatlab-reader.ts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Session index (segment/message_context tables) was previously generated
inconsistently: CLI used postImportHook, Desktop relied on a separate
explicit RPC call, and the CLI sync/pull legacy importer never built it.
Move generateSessionIndex / generateIncrementalSessionIndex into the
shared importers (streaming-importer.ts, incremental-importer.ts) so
every caller gets it automatically. Remove the now-redundant calls from
CLI's postImportHook. Also add the calls to the legacy importer.ts used
by CLI sync/pull, which had no session index at all.
Incremental imports use generateIncrementalSessionIndex, which preserves
existing AI summaries. Full imports call generateSessionIndex only on
newly created sessions where no summaries exist.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add archive reader, Google Chat resolver and source manager in node-runtime.
Expose prepared archive sources via CLI HTTP route and Electron IPC.
Add frontend service adapters and an import selection flow with i18n support
for all four locales. Fix rescanning on repeated archive imports.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Front-end error reporter was posting to /_web/_web/logs/report (double
base URL prefix); fixed to /logs/report
- uncaughtException/unhandledRejection handlers in CLI and Electron did not
exit after logging, overriding Node's default crash behavior; added
process.exit(1)
- NodePathProvider constructor in run() and chatlab status triggered
migrateFromElectronIfNeeded() as a side effect; added getSystemLogsDir()
to get the system logs path without resolving user data
- formatData() was called outside write()'s try/catch, so errors with
circular cause objects could escape appLogger.error(); moved inside
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Build a shared appLogger (node-runtime) that all three runtimes write to a
single rolling logs/app.log (10 MB → rename to app.old.log). Replaces the
four independent hand-written loggers (app.log/api.log Electron wrappers)
with a unified entry point while leaving AiLogger/perf-logger intact.
Key additions:
- packages/node-runtime/src/logging/app-logger.ts: initAppLogger/appLogger
singleton, INFO threshold by default (CHATLAB_LOG_LEVEL to override),
atomic rename rotation, Error data auto-extracts message+stack
- Three-runtime init: Electron main, CLI Web (http/index.ts), CLI (run())
- Global crash capture: uncaughtException + unhandledRejection on all three
Node runtimes now land in app.log scope 'crash'
- Fastify setErrorHandler fallback logs scope 'http' on CLI Web and Electron
internal server for unexpected 5xx errors
- Frontend: window.onerror + unhandledrejection + Vue errorHandler feed into
POST /_web/logs/report (scope 'web') with dedup+throttle
- AGENTS.md: logging rules section requiring key-path logs on new/changed features
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Extract shared AnalyticsService to packages/node-runtime using direct
Aptabase HTTP API (removes @aptabase/electron dependency)
- Add POST /_web/telemetry/track route for generic event reporting
- Desktop: migrate analytics.json from userData to systemDir (~/.chatlab/),
trigger daily active from renderer via new IPC so user-selected locale is used
- CLI: inject APTABASE_APP_KEY at build time, create AnalyticsService on
server start, report app_active with platform: cli-web
- Both platforms report user-selected locale via platform service abstraction
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When deleteConfig was called, the auth profile written to
auth-profiles.json during addConfig was never cleaned up, leaving
orphaned credentials on disk indefinitely.
Add onApiKeyDeleted callback to LLMConfigStoreDeps and call it in
deleteConfig with the removed config so callers can clean up the
corresponding auth profile. Wire up deleteAuthProfile in both the
CLI HTTP server and the Desktop internal API.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>