After incremental import via Electron IPC, the sidebar session list
showed stale message counts. Three contributing gaps:
1. The chat:incrementalImport IPC handler did not notify the renderer
to refresh the session list (unlike the API route which calls
notifySessionListChanged). Added win.webContents.send('api:importCompleted')
to trigger the Sidebar's existing onImportCompleted listener.
2. The postImportHook in worker adapters was async (due to dynamic
import()) but the caller did not await it, causing a race condition
where loadSessions() could read stale overview cache before
computeAndSetOverviewCache() finished. Converted to static import
making the hook synchronous, and updated the type to void | Promise<void>
with await at call sites in both incremental-importer and
streaming-importer.
3. The @imported handlers on group-chat and private-chat pages only
refreshed local analysis data without calling sessionStore.loadSessions().
Added the call so the sidebar updates immediately on the client side.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add scripts/changelog-to-markdown.mjs that renders changelogs/{cn,en,tw,ja}.json
into readable Markdown files. Runs idempotently; output passes Prettier without
changes.
Wire the script into the sync-changelog skill (step 4, before the release commit)
and update commit_release_changelogs.sh to include the four .md files in the
release: v<version> commit, with a preflight guard that errors if the md files
are missing.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Enable esbuild minification for main/preload (was renderer-only by default),
reducing main process bundle by ~55%. Extract cl100k_base BPE rank table out
of the synchronous startup path via dynamic import — it now lands in its own
chunk and is loaded on first agent run instead of at app startup.
Also fix Windows CI step to use PowerShell syntax for version injection.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
In edit mode the API key is intentionally not returned to the client,
causing both buttons to be disabled. Now the backend resolves the stored
key by configId when the client sends an empty key, and the frontend
passes configId for the reuse case so both buttons work without exposing
the key.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Migrate conversation/message CRUD and debug queries from IPC to HTTP
by having ElectronAIAdapter extend FetchAIAdapter. Remove 18 dead
handlers (14 CRUD + 3 debug + 1 compressContext) from ipc/ai.ts and
slim down preload AiApi to IPC-only methods (filtering, export, tool
testing, desensitize rules, native shell).
Co-authored-by: Cursor <cursoragent@cursor.com>