Commit Graph
100 Commits
Author SHA1 Message Date
digua 84b42a68f7 feat(cli): block incompatible data directories at startup 2026-06-08 10:14:42 +08:00
digua c518a4d968 feat(runtime): gate database access by data dir compatibility 2026-06-08 10:14:42 +08:00
digua c0885ba053 feat(runtime): add data directory compatibility gate 2026-06-08 10:14:42 +08:00
digua 2111abae5f docs: refine test maintenance guidance 2026-06-08 10:14:42 +08:00
digua 6b29c07326 test(routes,tools): cover high-risk analysis paths 2026-06-08 10:14:42 +08:00
digua 187268d8a5 test(core,import): rebalance database coverage 2026-06-08 10:14:42 +08:00
digua 2887f1cb73 test(parser,config): cover representative fixtures and migrations 2026-06-08 10:14:42 +08:00
digua 2d88215d63 test: add default test runner 2026-06-08 10:14:42 +08:00
diguaandClaude Sonnet 4.6 33353be9e2 docs(agents): expand development guidelines in AGENTS.md
Add review/judgment principles, project map, test strategy,
commands/validation guide, code conventions, architecture boundaries,
compatibility/migration rules, and security/release checklist.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 20:27:27 +08:00
diguaandClaude Sonnet 4.6 62ad3c6248 fix: normalize legacy tool names and harden cli chat command
- Add normalizeBuiltinToolNames() to map old session-based tool names
  (search_sessions, get_session_messages, get_session_summaries) to
  current segment names; applied in assistant parser, agent-stream-runner,
  and desktop tool-filter so existing assistant configs keep working
- Propagate agent stream error chunks as thrown Errors in CLI chat command
- Pass assistantId through ResolvedAIChatTarget to agent stream
- Preserve legacy chat_session rows in v6 migration when segment table
  already exists (INSERT OR IGNORE + DROP); revert v3/v5 DDL to chat_session
- Rename session_id alias to segment_id in relationship query
- Add tests: assistant-parser normalization, tool-filter legacy names,
  agent-stream-runner legacy allowlist, REPL error resilience, migration paths

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 20:27:27 +08:00
digua 9b17b09354 feat: add cli ai chat command 2026-06-07 20:27:27 +08:00
digua c2295e317f refactor: align ai chat and segment identifiers 2026-06-07 20:27:27 +08:00
digua 82bad3a23a release: v0.25.0 2026-06-07 15:21:12 +08:00
digua 093fdd1f2d chore(skills): remove maintainer skills from public repo 2026-06-07 14:38:50 +08:00
digua 4347c596ca docs: update iMessage export guide 2026-06-05 11:12:42 +08:00
digua 31f3c610ce fix(ai): increase default tool rounds 2026-06-05 11:12:42 +08:00
digua 9b1f359699 fix(ai): register chart tool for electron auto skills 2026-06-05 11:12:42 +08:00
digua f825c0734b refactor(ai): deduplicate skill menu and manager 2026-06-05 11:12:42 +08:00
digua 953471a514 fix(dev): clean up web backend lifecycle 2026-06-05 11:12:42 +08:00
digua 296573ed5c refactor(ai): centralize chart runtime policy 2026-06-05 11:12:42 +08:00
digua dbc377854a fix(desktop): reset titlebar overlay cache on theme change 2026-06-05 11:12:42 +08:00
digua 0bd4d31dd2 fix(ui): adjust preset chip stacking 2026-06-05 11:12:42 +08:00
digua 483907f1ac release: v0.24.1 2026-06-04 14:44:48 +08:00
digua 5144c8070a fix(update): suppress cli dev update badge 2026-06-04 14:37:12 +08:00
digua 8b2e6de479 fix: harden preferences and update notice checks 2026-06-04 14:37:12 +08:00
digua f4580c55f1 fix(ai): ensure builtin masking rules before preprocessing 2026-06-04 14:37:12 +08:00
digua cd9f297124 fix(update): harden update notice checks 2026-06-04 14:37:12 +08:00
digua 2a44f8b69e fix(preferences): preserve legacy builtin masking overrides 2026-06-04 14:37:12 +08:00
digua 9030d6b0c3 feat(update): add in-app update notice 2026-06-04 14:37:12 +08:00
digua 218c3c9ee9 feat(ai): group desensitize rules 2026-06-04 14:37:12 +08:00
digua 0c82a300e8 feat(ai): enable preprocess defaults 2026-06-04 14:37:12 +08:00
digua a780517539 docs: add contributor development guide 2026-06-04 14:37:12 +08:00
digua a42c23af15 ci(release): link markdown changelog 2026-06-04 14:37:12 +08:00
digua fbfe635838 release: v0.24.0 2026-06-03 13:37:02 +08:00
digua 6e016837bc fix(data): harden directory and database migrations 2026-06-03 00:46:34 +08:00
digua f234a25ff6 fix(storage): require legacy data before showing migrate hint 2026-06-03 00:46:34 +08:00
digua 42837278fa fix(data): migrate legacy chat database columns before reads 2026-06-03 00:46:34 +08:00
digua bb4986d703 fix(storage): reset legacy data hint after directory changes 2026-06-03 00:46:34 +08:00
digua e68ce77266 feat(data): support CLI web data directory migration 2026-06-03 00:46:34 +08:00
digua a94986f117 feat(storage): allow ignoring legacy data prompt 2026-06-03 00:46:34 +08:00
digua 04c97ca9cf fix(data): defer data directory migration until restart 2026-06-03 00:46:34 +08:00
diguaandClaude Sonnet 4.6 f978845dde fix(layout): migrate isSidebarCollapsed persistence from sessionStorage to localStorage
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 00:46:34 +08:00
diguaandClaude Opus 4.8 f09d40f436 feat(changelog): generate per-language markdown from JSON
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>
2026-06-03 00:46:34 +08:00
diguaandClaude Opus 4.8 2f8591fb8c perf(build): minify main process and lazy-load tiktoken rank table
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>
2026-06-03 00:46:34 +08:00
digua 3ff9437510 chore(tsconfig): align node type-check projects 2026-06-02 15:41:21 +08:00
digua 40d7d9e840 fix(ai): harden validation and db handle reuse 2026-06-02 15:41:21 +08:00
digua eea1dad907 fix(electron): offload chart plugin compute to worker 2026-06-02 15:41:21 +08:00
diguaandClaude Opus 4.8 d96299b16e fix(ai): enable fetch-models and validate buttons when editing with stored key
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>
2026-06-02 15:41:21 +08:00
digua b66aeb9737 fix(ui): resolve web type-check regressions 2026-06-02 15:41:21 +08:00
digua bf14c68899 refactor(ai): migrate remaining AI IPC to shared HTTP routes 2026-06-02 15:41:21 +08:00
digua 7dcc37e714 refactor(electron): remove session index IPC 2026-06-02 15:41:21 +08:00
digua 9a0e6093f3 fix(ai): harden shared SSE streaming 2026-06-02 15:41:21 +08:00
digua 1af644e4ab refactor(ai): migrate streaming to shared HTTP SSE
Squash Phase 2-2 streaming migration: frontend stream service, LLM SSE route, Agent SSE route, and IPC/preload cleanup.
2026-06-02 15:41:21 +08:00
diguaandCursor 769115240e feat(cache): migrate cache routes to shared HTTP package
Create CacheServiceAdapter + FetchCacheAdapter service layer and move
7 cache routes (info, clear, data-dir, import-log, save-to-downloads,
open-dir, show-in-folder) to @openchatlab/http-routes. Inject platform
callbacks (shell.openPath, showItemInFolder) via HttpRouteContext.
Frontend calls converge from window.cacheApi to useCacheService().
Electron IPC retains only selectDataDir/setDataDir (native dialog).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 15:41:21 +08:00
diguaandCursor fcca22a8dc refactor(ai): remove orphaned AI conversation/message IPC handlers
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>
2026-06-02 15:41:21 +08:00
diguaandClaude Sonnet 4.6 1310b04bc0 fix(ui): make data source token required in add modal
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 15:41:21 +08:00
diguaandClaude Sonnet 4.6 2f501a5503 ci(release): fix Windows zstd cache issue and add CLI update to release notes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-02 15:41:21 +08:00
diguaandCursor ae90db63a5 feat(merge): migrate merge routes from IPC to shared HTTP package
Unify the merge workflow (parse/conflicts/execute/clear/export-for-merge)
across CLI, Electron, and web-serve into a single set of shared routes in
@openchatlab/http-routes.

Key changes:
- Move MergeSessionCache from CLI to node-runtime shared package
- Add dual-mode parse route (multipart upload for web, JSON filePath for Electron)
- Integrate merge routes into Electron internal API server with @fastify/multipart
- Create installMergeShims() with filePath-to-handle mapping for frontend
- Remove Electron merge IPC handlers, merger module, and preload bridges (~790 lines deleted)
- Address CodeX review: CHAT_DB_TABLES in openDatabase, no chatApi patching,
  outputName sanitization, resp.ok checks, @fastify/multipart in desktop deps

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 15:41:21 +08:00
diguaandCursor 65fb5179cd refactor(electron): remove orphaned LLM/Assistant/Skill IPC handlers
Delete 40 IPC handlers in ipc/ai.ts whose preload bridges were
removed in the previous commit. These handlers are dead code since
the frontend now uses HTTP service layer (FetchLLMAdapter,
FetchAssistantAdapter, FetchSkillAdapter) via the Internal Server.

Removed:
- 20 llm:* CRUD handlers (config, provider registry, model catalog,
  custom provider/model, validate, remote models)
- 11 assistant:* handlers (CRUD, builtin catalog, import/reimport)
- 9 skill:* handlers (CRUD, builtin catalog, import/reimport)

Retained on IPC (still used):
- llm:chat, llm:chatStream (streaming)
- agent:runStream, agent:abort (streaming)
- All ai:* handlers (conversation CRUD, tool testing, compression,
  desensitize rules, debug SQL, filter/export)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 15:41:21 +08:00
diguaandCursor 3ab162162b feat(ai): migrate AI CRUD routes to shared package and establish frontend service layer
Extract LLM config, assistant, skill, conversation and summary CRUD
routes from CLI-specific ai.ts into @openchatlab/http-routes, enabling
Electron Internal Server to serve AI endpoints via shared routes.

Frontend service layer:
- Create src/services/{llm,assistant,skill}/ with typed adapters
- Migrate all window.llmApi/assistantApi/skillApi calls to service layer
- Clean up Electron preload: remove CRUD bridges, keep only streaming IPC

Shared AI routes (packages/http-routes):
- ai-llm: config CRUD, provider registry, model catalog, custom store
- ai-assistants: CRUD, import/reimport, tool catalog
- ai-skills: CRUD, import/reimport, builtin catalog
- ai-conversations: conversation/message/debug CRUD
- ai-summaries: summary generation with LLM config injection
- Add requireAi fail-fast option to registerSharedRoutes

Backend improvements:
- Extract CustomProviderStore/CustomModelStore to node-runtime
- Fix authProfile persistence (onApiKeyCreated returns profileName)
- Reuse AI manager singletons in Electron (avoid dual instances)
- Prevent plaintext API key leakage in addConfig response
- Add authProfile regression tests

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 15:41:21 +08:00
diguaandCursor 09a7d7c5e2 refactor: remove unused chart plugin and NLP API shims
Both shims were installed only in web-serve mode. Chart modules
already use useDataService() directly and NLP components use
HTTP helpers, so the window.chatApi.pluginQuery/pluginCompute/
getMemberActivity/getAvailableYears and window.nlpApi shims
have zero remaining callers.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 15:41:21 +08:00
diguaandCursor f9b5b6b13d refactor: consolidate IPC bridge to native-only
Remove business IPC handlers/preload APIs that are now served by
Internal HTTP Server: preferences, NLP, data queries, message search,
analytics, members, SQL lab. Migrate chart modules from window.*Api
direct calls to useDataService() and NLP components to HTTP.

Make Internal Server a hard dependency, delete ElectronDataAdapter/
MessageAdapter/PreferencesAdapter and IPC fallback path. Retain IPC
only for native capabilities: file import, AI/LLM, session-index
summaries, agent streaming.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 15:41:21 +08:00
digua 96a9d143c4 feat(electron): add internal http server for renderer adapters 2026-06-02 15:41:21 +08:00
diguaandCursor a8f0d5cb88 refactor: extract shared HTTP routes into @openchatlab/http-routes package
Migrate 30+ endpoints from apps/cli/src/http/ to packages/http-routes/
with a platform-agnostic HttpRouteContext DI interface, enabling future
reuse by Electron Internal Server.

Batch 1: auth, errors, context, sessions, members, preferences
Batch 2: analytics, sql, session-index, export, nlp
Batch 3: REST system, REST sessions

Includes 7 smoke tests via Fastify inject covering /api/v1/* and /_web/*
route groups.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 15:41:21 +08:00
diguaandCursor cd3ae8c5ba feat(auth): harden auth security and add remember-me login
Improve auth hook security: restructure URL classification to fix
/_web/* bypass when requireAuth is active, use HMAC-SHA256 for constant-
time token comparison, remove dead webModeEnabled code.

Improve frontend auth flow: extract initializeApp() with watch-based
re-init after login, add getToken callback for real-time store reads,
unify SSE 401 handling via fetchWithAuth, switch default storage to
sessionStorage, add router guard consuming meta.public.

Add "Remember this device" checkbox on login page with dual
localStorage/sessionStorage strategy and safety warning.

Add 23 unit tests for auth hook matrix and http client.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 15:41:21 +08:00
diguaandCursor 8490e2b257 feat(web): add token auth support for frontend with login page
Complete the frontend side of the --require-auth feature:

- Add configureHttpClient() with token injection and 401 handling
- Auto-inject Authorization header in all HTTP helpers and SSE
- Replace 32+ direct fetch('/_web/...') calls with fetchWithAuth
- Add login page for Server mode (token input + validation)
- Add auth store for token persistence (localStorage)
- Add logout button in Settings > About (Server mode only)
- Add i18n translations for login flow (zh-CN/en-US/zh-TW/ja-JP)
- Fix login redirect loop caused by concurrent 401 responses

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 15:41:21 +08:00
diguaandCursor a75fd0186d feat(cli): add --require-auth flag for /_web/* API protection
When enabled, all /_web/* routes require Bearer token authentication,
same as /api/v1/*. This hardens security for server/headless/public
deployments where the same-origin assumption doesn't hold.

- Add `require_auth` field to config schema (default: false)
- Add `setRequireAuth()` to auth hook, conditionally enforce auth on /_web/*
- Support `--require-auth` in both `chatlab start` and `--daemon` mode
- Read from config.api.require_auth or CLI flag override

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-02 15:41:21 +08:00
digua a6039d95ab release: v0.23.1 2026-06-01 11:23:00 +08:00
diguaandClaude Sonnet 4.6 d83c21caa2 docs: improve README for both end-users and developers
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 17:01:13 +08:00
diguaandClaude Sonnet 4.6 9853c33e0b fix(cli): improve port-check error handling
- isPortAvailable 只将 EADDRINUSE 映射为 false,其他错误(EACCES/
  EADDRNOTAVAIL 等)通过 reject 抛出,避免误报"端口被占用"
- 将端口预检移入 startup try/catch 块内,确保所有绑定错误都走
  统一的 "Startup failed" 报错路径,不产生未处理的 Promise rejection

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 16:56:08 +08:00
diguaandClaude Sonnet 4.6 1b596d664f fix(ui): fix sidebar tooltip placement and API for Nuxt UI v4
Nuxt UI v4 废弃 :popper="{ placement }",改为 :content="{ side }",
旧写法被忽略导致 tooltip 一律显示在下方。

- 展开态按钮(收起、搜索、排序、管理)→ side: bottom
- 折叠态元素(会话项、SidebarButton)→ side: right
- SidebarButton 重构:UTooltip 只包折叠态 div,避免 Reka UI as-child
  在 v-if/v-else 切换时 trigger 引用错乱导致 tooltip 位置错误

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 16:56:08 +08:00
diguaandClaude Sonnet 4.6 69d887c7e2 fix(ui): fix TitleBar dark mode red background and z-index layering
1. 移除 :global(.dark) + 子选择器写法(Vue scoped 编译时选择器泄漏导致
   html.dark { background: #e81123 } 使网页外背景变红),改用 CSS 变量
   + 独立非 scoped <style> 块覆盖深色模式
2. 将 z-index 从 30 提升至 40,使 TitleBar 高于 PageHeader 的
   titlebar-drag-cover (z-30),同时低于 header-actions (z-40, 后挂载),
   三层层叠关系正确:drag-cover < TitleBar ≤ header-actions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 16:56:08 +08:00
diguaandClaude Sonnet 4.6 b01c6c7e7a fix(daemon): use bin/chatlab.mjs as launchd/systemd entry point
dist/cli.mjs 只导出 run() 而不调用它,直接运行会立即静默退出(exit 0)。
bin/chatlab.mjs 才是真正调用 run() 的可执行入口,与 npm bin 字段一致。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 16:56:08 +08:00
diguaandClaude Sonnet 4.6 8c98daa654 feat(cli): pre-check port availability before startup with friendly error
启动前主动探测端口是否可用,被占用时立即给出可操作的引导(换端口 / lsof 命令),
避免先初始化 DB/路由后才抛 EADDRINUSE 的延迟报错体验。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 16:56:08 +08:00
diguaandClaude Sonnet 4.6 0a916e4b17 fix(types): use AIMessageRole type for message role params & strengthen conversation test assertion
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 16:56:08 +08:00
diguaandClaude Sonnet 4.6 c1e317a38a feat(cli): add clb as a short alias for the chatlab command
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 16:56:08 +08:00
diguaandClaude Sonnet 4.6 b96ec69730 fix(cli): add /_proxy/chatlab.fun reverse proxy for web mode
在 Web 生产模式(chatlab start)下,浏览器无法直连 chatlab.fun(CORS 限制),
导致首页底部社交链接(如小红书)及云端助手/技能预设拉取失败。
Vite dev proxy 已有对应配置,但生产 Fastify server 缺少该代理,现补全。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 16:56:08 +08:00
digua d1637b41b8 feat(ui): optimize page header and toolbar layout 2026-05-31 16:56:08 +08:00
digua 066564c64e release: v0.23.0 2026-05-31 14:01:13 +08:00
diguaandClaude Sonnet 4.6 9db9614246 fix(build): export getAllIndexStats from query index & add pre-release checks to changelog skill
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 14:01:13 +08:00
diguaandClaude Sonnet 4.6 334544880f fix(ai): enable thinking for effort-based models when 'auto' is selected
When the user selects 'auto' thinking level for an effort-based reasoning
model (Kimi, Doubao) that has thinkingLevelMap but no thinkingFormat,
the previous code fell through to `return undefined`, causing pi-agent-core
to treat it as 'off' and send reasoning_effort:'none' to the API —
silently disabling thinking.

pi-ai's clampThinkingLevel only covers EXTENDED_THINKING_LEVELS (no 'auto'),
so 'auto' cannot be forwarded verbatim. Return 'high' instead, matching
the behavior for thinkingFormat models, to at least enable reasoning.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 10:28:29 +08:00
diguaandClaude Sonnet 4.6 7558eed5a5 fix(ai): fall back to heuristic for non-builtin custom models in inferReasoning
Custom models auto-saved by ensureCustomProvidersAndModels carry only
capabilities:['chat'], so inferReasoning was returning reasoning=false
even for models like qwen3:8b whose names match the reasoning heuristic.
The UI still showed thinking levels via getSupportedThinkingLevels, but
selections were silently ignored by the backend.

Fix: for non-builtin (builtin=false) model definitions, also apply the
name/provider heuristic as a fallback alongside the capabilities check.
Builtin catalog models remain authoritative.

Adds a regression test covering the exact findModelFn shape produced by
ensureCustomProvidersAndModels.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 10:28:29 +08:00
diguaandCursor 999ce58007 fix(ai): use active slot modelId for thinking level and context window computation
The supportedThinkingLevels, modelContextWindow, and model name display
were reading from config.model (static config value) instead of the
slot's modelId (actual user-selected model). This caused the thinking
selector to show/hide incorrectly when users switched models.

Also fix HTTP utils sending Content-Type: application/json with empty
body when body is null (e.g. setFastModel(null)), which caused Fastify
to return 400.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-31 10:28:29 +08:00
diguaandCursor 9bc0c4279d refactor(ui): simplify model button and optimize session index loading
- StatusBar model button: show model name instead of provider, click opens
  settings directly (scrolls to default model section), remove dropdown
- SessionIndexSection: replace N serial pluginQuery calls with single batch
  API (GET /_web/sessions/index-stats), add IntersectionObserver lazy loading
- Full-stack implementation: CLI route, Electron IPC/Worker, frontend adapters

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-31 10:28:29 +08:00
diguaandCursor 783d61f742 feat(ai): upgrade thinking level control with default/auto options and broader model coverage
- Add 'default' option (no reasoning params sent, model uses native behavior)
- Add 'auto' option for models that natively support it (deepseek_hybrid, kimi, doubao)
- Expand model recognition with regex coverage for 15+ model families
- Add Gemini 2.5+ thinking level support via native Google provider
- Simplify deepseek_hybrid options to ['default', 'off', 'auto'] aligned with Cherry Studio
- Use primary theme color for thinking selector instead of hardcoded blue
- Update docs with thinking control architecture section

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-31 10:28:29 +08:00
diguaandClaude Opus 4.8 a31c672474 feat(ai): add per-model thinking level selector in chat status bar
Adds a lightbulb button next to the model switcher in ChatStatusBar
that lets users choose the thinking intensity for each reasoning model,
with the choice remembered per model slot (configId:modelId).

Key changes:
- packages/core/src/ai/thinking.ts (new): per-model-type thinking level
  table inspired by cherry-studio's MODEL_SUPPORTED_REASONING_EFFORT.
  Covers Qwen/GLM (on/off), DeepSeek V4 (high/max), o-series
  (low/medium/high), gpt-5.x (minimal–xhigh), Kimi/Doubao/Grok and a
  default bucket. Exports getSupportedThinkingLevels, isReasoningModel,
  getThinkingCompat.
- packages/node-runtime/src/ai/llm-builder.ts: inferReasoning now calls
  getThinkingCompat() which sets compat.supportsReasoningEffort and
  compat.thinkingLevelMap so pi-ai can inject the correct request param
  (reasoning_effort for OpenAI/DeepSeek, enable_thinking for Qwen/GLM).
- packages/node-runtime/src/ai/agent/types.ts + core.ts: AgentCoreOptions
  gains an optional thinkingLevel; core.ts:93 uses clampThinkingLevel()
  (from pi-ai) to honour it safely.
- Full transparent pass-through: desktop Agent → IPC handler → preload
  → agentApi.runStream; CLI HTTP route → runServerAgent → runAgentCore.
- src/stores/prompt.ts: thinkingLevels Record<configId:modelId,
  ThinkingLevel> persisted in backendPersist; getThinkingLevel/
  setThinkingLevel helpers.
- src/stores/aiChat.ts: reads current model slot and passes remembered
  level to both sendMessage and editCurrentRoundOnly runStream calls.
- ChatStatusBar.vue: UPopover thinking selector appears only for
  reasoning models, shows only the levels that model supports, highlights
  current choice, hides for non-reasoning models.
- 46 tests passing (26 new in thinking.test.ts + 20 in llm-builder).

Scope: openai-completions path only (Qwen, DeepSeek, OpenAI, xAI, Kimi,
Doubao, SiliconFlow, OpenRouter…). Anthropic/Gemini native thinking is
out of scope for this version.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 10:28:29 +08:00
diguaandClaude Opus 4.8 1716cf392f refactor(ai): replace manual reasoning switches with auto-inference
Remove the "Reasoning Model" and "Disable Thinking Mode" toggles from
the model config dialog. These switches were injecting `enable_thinking`
(a Qwen/DashScope-specific request parameter) into all providers,
causing 400 errors on OpenAI, Anthropic, Gemini, and other official
services.

Replace with automatic inference in buildPiModel:
- reasoning: true when the model's catalog capabilities include
  'reasoning'; falls back to a model-name heuristic for unlisted
  custom/self-hosted models (qwen3, qwq, deepseek-r, o1/o3, etc.).
- compat.thinkingFormat 'qwen': only set when reasoning is true AND
  the model is from the qwen provider or the model id contains
  "qwen"/"qwq". All other providers get compat: undefined and will
  never receive enable_thinking.

This means official reasoning models (o3, deepseek-reasoner, etc.) now
automatically get thinkingLevel:'medium', and self-hosted Qwen3
models continue to work as before — without any manual toggle.

Behavior change: models with 'reasoning' in their catalog capabilities
now default to thinkingLevel:'medium' (previously always 'off' unless
the manual switch was enabled).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 10:28:29 +08:00
diguaandCursor 886642c1a4 feat: split message view into type/time analysis tabs with enriched profile cards
Split the monolithic MessageView into two focused modules:
- TypeAnalysisView: type distribution, text depth analysis, length distributions
- TimeAnalysisView: hourly/weekday/monthly/yearly distributions, member trend, heatmap, calendar

Each tab has a redesigned narrative profile card with rich insights:
- TypeProfileCard: date range, total messages, non-text breakdown pills, 4 metric cards
- TimeProfileCard: active days narrative, time personality labels (multi-dimensional), 4 metric cards

Also: reduce responseLatency font size in RelationshipView for better readability.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-31 10:28:29 +08:00
diguaandClaude Sonnet 4.6 affb7a50e4 fix(daemon): quote ExecStart argv to handle paths with spaces on Linux
Wraps each argument in double quotes when building the systemd unit's
ExecStart= line, so installs under paths containing spaces (e.g. home
directories with spaces, nvm paths) no longer cause systemd to
mis-tokenize the command and fail to start the service.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 14:19:42 +08:00
diguaandCursor 969406915f feat(ai): add confirmation dialog before regenerating all session indexes
Warn users that regeneration will clear all existing AI summaries.
Uses the same UModal pattern as other confirmation dialogs in settings.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-30 14:19:42 +08:00
diguaandCursor fdb6d8f648 feat(import): update demo data sources to 4 files
Switch from 2 demo files (group + private) to 4 files:
- demo-group.json
- demo-private-A-cuilan.json
- demo-private-B-wukong.json
- demo-private-C-spider.json

Update DemoImportResult.privateSessionId to privateSessionIds array
to support multiple private chat demos.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-30 14:19:42 +08:00
diguaandCursor b3c2b20a9f fix(ai): make message editing safe against data loss and stale state
- insertMessageAfter: update active_message_id when appending to tail
  so the new reply is on the active path after reload
- editAndOverwriteAll: add hasConfig + abort checks before
  deleteMessagesFrom to prevent data loss when LLM is unconfigured or
  a concurrent request starts
- editCurrentRoundOnly: defer all DB mutations until after stream
  completes; on abort/error only in-memory state is restored
- sync in-memory parentId after relinking so follow-up edits send the
  correct historyLeafMessageId

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-30 14:19:42 +08:00
digua ce1065e295 docs(api): rename API import to API push 2026-05-30 14:19:42 +08:00
digua e78c8f9368 feat(ai): add fork conversation UI button on AI replies 2026-05-30 14:19:42 +08:00
diguaandCursor 6224ca996e refactor(ai): replace branching with edit-and-regenerate model
Remove the message branching/tree system in favor of a simpler editing model:
- Default: edit a message and only regenerate the current round's AI response
- Optional: overwrite all subsequent messages when editing

Key changes:
- Backend: add updateMessageContent, deleteAndRelinkMessage, insertMessageAfter,
  deleteMessagesFrom, forkConversation; remove createMessageBranch, switchMessageBranch
- Platform layer: add IPC/HTTP handlers for new methods across Electron and CLI
- Frontend store: refactor editMessageAndRegenerate with two modes
- UI: replace branch navigation with "overwrite subsequent" checkbox,
  auto-resizing edit textarea
- Fix insertMessageAfter missing debug_context from pendingDebugContextMap
- Update tests to cover new editing methods

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-30 14:19:42 +08:00
digua 3a8f61fdf0 fix(cli): start web dev backend with start command 2026-05-30 14:19:42 +08:00
diguaandClaude Sonnet 4.6 0e03295258 feat(cli): add daemon mode via start --daemon, stop, and status commands
- Replace 6-subcommand daemon group with simpler top-level design:
  chatlab start --daemon  install as system service (launchd/systemd)
  chatlab stop            uninstall service and disable auto-start
  chatlab status          show resident service status
- Drop temporary background process layer; daemon = system service only
- Store port/host meta in ~/.chatlab/daemon.json for status display
- Fix --no-open description: Web UI still runs, only browser is suppressed
- Update quick-start docs (cn/en/tw) to reflect new commands

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 14:19:42 +08:00
diguaandClaude Sonnet 4.6 6cdc040ce8 feat(cli): replace serve/web commands with unified start command
- Add `chatlab start` with --headless (API-only) and --no-open flags
- Remove redundant `serve` and `web` commands
- Update fetch adapter comments to reference chatlab start
- Add chatlab start usage examples to quick-start docs (cn/en/tw)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-30 14:19:42 +08:00
digua 8e01121b7a release: v0.22.1 2026-05-29 15:07:02 +08:00
diguaandClaude Opus 4.8 a653b5be6d docs: restructure docs nav and move quick-start under usage
- Move quick-start.md to usage/ across cn/en/tw
- Switch locale index pages from home to doc layout
- Add Baidu analytics script and adjust nav doc links

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-29 14:35:48 +08:00