365 Commits
Author SHA1 Message Date
digua ec822cb1b0 fix(import): deduplicate mixed message identities
Track unmatched fallback-only keys separately so messages with and without platform IDs bridge safely without collapsing distinct stable IDs.
2026-07-13 01:01:42 +08:00
digua 61d42b2500 fix(import): harden automatic incremental imports 2026-07-13 01:01:42 +08:00
digua 6dc35722c0 fix(import): disambiguate ChatLab reimports 2026-07-13 01:01:42 +08:00
digua 0606d5f5f7 feat(cli): enable automatic incremental imports 2026-07-13 01:01:42 +08:00
digua 6cf4c063fc feat(import): orchestrate automatic imports 2026-07-13 01:01:42 +08:00
digua 27f46dfcb6 feat(import): add automatic session matcher 2026-07-13 01:01:42 +08:00
digua a9a1557867 fix(import): preserve ChatLab owner and aliases
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.
2026-07-12 21:27:39 +08:00
digua 96235915b8 fix(export): generate importable ChatLab JSON 2026-07-12 21:27:39 +08:00
digua e1288c3cc7 fix(insight): invalidate snapshots on session deletion
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.
2026-07-12 15:29:09 +08:00
digua b15f38c4a5 fix(insight): address annual summary review findings 2026-07-12 15:29:09 +08:00
digua 1713e0d577 fix(insight): remove session facts on deletion 2026-07-12 15:29:09 +08:00
digua f198b41bdb feat(settings): manage session owner identities 2026-07-12 15:29:09 +08:00
digua d7692b5bfc feat(runtime): add global insight service and worker 2026-07-12 15:29:09 +08:00
digua 81be26b68e feat(runtime): add global insight cache pipeline 2026-07-12 15:29:09 +08:00
digua 740c410d7b refactor(core): centralize contact identity resolution 2026-07-12 15:29:09 +08:00
digua 2aeb912dec test(ai): type legacy auth profile fixtures 2026-07-12 01:22:43 +08:00
diguaandCursor 74971c624a fix(semantic-index): only clamp sender names when over shared budget
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-10 15:11:51 +08:00
digua b2f20a15bd fix(semantic-index): harden embedding input guards 2026-07-10 15:11:51 +08:00
digua dd40fc6502 feat(semantic-index): add local model download sources 2026-07-10 15:11:51 +08:00
digua ba2f09f56e fix(semantic-index): clamp oversized embedding inputs 2026-07-10 15:11:51 +08:00
digua ac662d319d feat(contacts): relax relationship entry threshold 2026-07-05 22:51:39 +08:00
digua c0548f63c8 feat(import): prepare native parser rollout 2026-07-05 22:49:38 +08:00
diguaandCursor c265925e3e fix(import): report accurate post-parse progress stages in real time
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>
2026-07-05 22:49:38 +08:00
diguaandCursor f7150e2cff fix(nlp): stop rebuilding jieba instance on every call without custom dict
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>
2026-07-05 22:49:38 +08:00
digua 801e7fc66a fix(cli): harden agent query safeguards
Tighten agent-facing query validation, privacy guards, SQL result handling, config writes, and LIKE search semantics for the CLI query workflow.
2026-07-04 15:12:50 +08:00
digua fd97c55681 feat(query): extend shared chat query capabilities 2026-07-04 15:12:50 +08:00
digua da781bfdd9 fix(import): preserve avatars from streamed members (resolve #249) 2026-07-02 10:35:02 +08:00
digua d3d2661882 fix(relationships): address galaxy review regressions
Bundle relationship worker entries for packaged builds.

Refresh and surface galaxy task failures, clean detached Pixi layers, cap focused neighborhoods, merge owner nodes across platforms, apply manual friend overrides, and track owner group activity.
2026-06-30 14:41:46 +08:00
digua 9c2ab48b1c feat(relationships): refine galaxy exploration 2026-06-30 14:41:46 +08:00
digua eaf46c01f9 feat(relationships): improve galaxy focus and relevance 2026-06-30 14:41:46 +08:00
digua d04eddc37c fix(relationships): rank active close contacts accurately 2026-06-30 14:41:46 +08:00
digua 3afc2a7329 feat(relationships): enhance galaxy graph interactions 2026-06-30 14:41:46 +08:00
digua 85b9e203ab feat(people): add relationship galaxy graph 2026-06-30 14:41:46 +08:00
diguaandClaude Sonnet 4.6 d8034b3546 fix(semantic-index): stabilize embedding warmup (#261)
* fix(semantic-index): stabilize embedding warmup

Improve warmup job reliability and prevent raw API response body from
reaching app.log. Status code alone is sufficient for diagnosing failures;
stripping the response detail eliminates the risk of chat content being
written to the log via OpenAI-compatible services that echo submitted input.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(semantic-index): clear preload error after warmup retry

When local model preload fails, a later warmup can successfully recreate the extractor through embedDocuments but leave modelPreloadStatus stuck on error.

Mark the local model ready after a completed warmup writes chunks, and cover the retry path with a regression test.

* fix(semantic-index): guard warmup model status updates

Capture the model configuration used by a warmup job before it starts, and only clear local preload errors when the current local model still matches that job.

Add a regression test for switching local models while an older warmup is still completing.

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-29 10:54:22 +08:00
digua 0d5d49a491 fix(contacts): stabilize navigation and facts cache
Wait for initial contact rows before scrolling to groupmates so tab navigation does not land on temporary rows. Avoid writing contacts session facts or latest facts when a session DB fingerprint changes during computation.
2026-06-27 22:13:25 +08:00
digua 1e2148a4d2 perf(contacts): cache session facts 2026-06-27 22:13:25 +08:00
digua ba500bd462 feat(contacts): mark groupmates as friends 2026-06-27 20:02:23 +08:00
digua e9e19f1b05 refactor(contacts): remove low signal groupmate concept 2026-06-27 20:02:23 +08:00
digua 114ae79885 feat(contacts): paginate virtualized contacts list 2026-06-27 20:02:23 +08:00
digua 95f0e91c0d feat(contacts): add time range filtering 2026-06-27 20:02:23 +08:00
digua 103df0eba9 fix(contacts): address review regressions 2026-06-27 15:54:08 +08:00
digua 9563c26645 refactor(contacts): group contacts service files 2026-06-27 15:54:08 +08:00
digua c8c4e1aca6 feat(contacts): compute contacts in background worker 2026-06-27 15:54:08 +08:00
digua d48665b2ed feat(contacts): simplify contacts experience 2026-06-27 15:54:08 +08:00
digua 9c8faeba09 feat(node-runtime): add contacts aggregation service 2026-06-27 15:54:08 +08:00
digua f304146c8f fix(semantic-index): honor proxy for local model downloads
Pass a model download proxy through the semantic index worker and local embedding provider so local Hugging Face downloads use the effective proxy.

Restart idle local workers when the proxy changes before preload, build, or search calls, and initialize app logging inside the worker process for preload diagnostics.
2026-06-26 09:56:32 +08:00
digua 851166188d fix(import): harden push and pull import guards
Combine the PR review fixes for push import validation, deduplication, system sender handling, and pull import lock scoping into one reviewable change.
2026-06-25 21:45:16 +08:00
diguaandClaude Sonnet 4.6 4e2130b2d7 fix(import): address review findings in push import API and pipeline
- Reject path-traversal sessionIds (SAFE_SESSION_ID_RE)
- Reject X-Dry-Run header with 400 instead of silently writing
- Propagate DataDirCompatibilityError as 409 instead of swallowing to 500
- Scope concurrency lock to session instead of process-wide boolean
- Fix hash dedup hole: load hashes for ALL existing messages, not just
  those without platformMessageId
- Fix backfill segment index: detect when written timestamps predate the
  existing tail and use full generateSessionIndex rebuild instead of
  incremental; apply same fix to shared incremental-importer used by
  Desktop and pull sync
- Validate member platformId, message content/platformMessageId types, and
  option enum values in validatePayload before any writes
- Use writeParseResultToDb in fullImport to populate member_name_history;
  pre-deduplicate messages before delegating and auto-create minimal members
  for senders absent from the members list
- Add content-hash to existingKeys when accepting a pmid-keyed row so a
  same-content no-pmid copy later in the same batch is caught

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 21:45:16 +08:00
diguaandClaude Sonnet 4.6 ced4ed16bd feat(import): auto-generate session index after all import paths
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>
2026-06-25 21:45:16 +08:00
diguaandClaude Sonnet 4.6 419b3002c4 feat(import): add POST /api/v1/imports/:sessionId push import API
Implements the Push Import protocol documented in chatlab-import.md.
Creates a new session on first call, appends and deduplicates on
subsequent calls (platformMessageId preferred, content hash fallback).
Adds IMPORT_IN_PROGRESS (409) and IMPORT_FAILED (500) error codes.
Includes a global concurrency lock and incremental session index
generation after each write.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-25 21:45:16 +08:00