Commit Graph
42 Commits
Author SHA1 Message Date
diguaandCursor 6c3d36e7df feat(ai): upgrade pi-ai from @mariozechner 0.54 to @earendil-works 0.74
- Replace @mariozechner/pi-ai and pi-agent-core with @earendil-works scope
- Adapt to AgentTool.execute() params type change (Record → unknown)
- Migrate Agent constructor to use initialState for systemPrompt/tools/messages
- Update onPayload callback signature to include model parameter
- Filter finalMessages with isPiMessage() for new AgentMessage union type
- Use state.errorMessage instead of deprecated state.error

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:19:47 +08:00
diguaandCursor 0ba9ae04a6 chore: migrate workspace packages to ESM
- Add "type": "module" to all workspace package.json files
- Replace __dirname with import.meta.url-based resolveCliPath() helper
- Convert stream-json/stream-chain CJS named imports to default + destructure
  for ESM compatibility
- Use createRequire() for @node-rs/jieba native module loading in ESM context

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:19:47 +08:00
digua 83151fd8e7 fix(cli): improve update checker with async cache, keypress UX, and dev bypass 2026-05-26 23:19:47 +08:00
digua a105d7ab8e feat(cli): implement update checking and auto-update for CLI and CLI Web 2026-05-26 23:19:47 +08:00
diguaandCursor 6ec03d330f fix(electron): prevent unified migration from reverting data dir changes
The unified directory migration (needsUnifiedDirMigration) would
re-trigger after a user changed their data directory, overwriting
config.toml back to the old Electron path.

Root cause: no persistent flag tracking whether the migration had
already completed. If old databases remained (cleanup failure or
timing), it would re-detect and re-run.

Fix:
- Add `electron_migration_done` flag to config.toml [data] section
- Set flag after migrateToUnifiedDirs succeeds and in setCustomDataDir
- Check flag at start of needsUnifiedDirMigration to skip if done
- Add "migrate to default" button when data is at non-default path
- Fix NLP directory path: move from userDataDir to systemDir (~/.chatlab/nlp)

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:19:47 +08:00
diguaandCursor 8819dff62c feat(cli): implement storage management for CLI Web
CLI Web's Settings > Storage Management was completely non-functional
(stub cacheApi returning empty data). This adds real HTTP endpoints
and wires the frontend to use them.

Backend (cache.ts):
- GET /_web/cache/info — scan databases/ai/cache/logs directory sizes
- POST /_web/cache/clear — clear cache or logs directory (allowlist)
- POST /_web/cache/open-dir — open directory in system file manager
- GET /_web/cache/data-dir — return current data directory path
- GET /_web/cache/latest-import-log — find latest import log file

Frontend:
- Replace cacheApi stubs with real HTTP calls in registry.ts
- Hide data directory migration UI in CLI Web (IS_ELECTRON guard)
- Add "Open Root Dir" button for ~/.chatlab/ in header area

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-26 23:19:47 +08:00
digua 9e88dcbd09 feat(changelog): bundle changelogs locally 2026-05-26 23:19:47 +08:00
digua a5bbff34e4 feat(sync): use incremental session index after pull sync
After pull-sync imports new messages, generate session index incrementally
instead of full regeneration. This preserves existing sessions and their
summaries, only processing newly imported (unindexed) messages.

Adds generateIncremental method across the full stack:
- core: already had generateIncrementalSessionIndex
- node-runtime: expose generateIncrementalIndex
- CLI: add POST /_web/sessions/:id/generate-incremental-index route
- Electron: add session:generateIncremental IPC handler
- Frontend: add generateIncremental to SessionIndexAdapter interface
2026-05-23 16:28:50 +08:00
digua 7d5c541933 feat(sync): add option to delete imported chats when removing subscription
- Show confirmation dialog with two choices: keep data or delete imported chats
- Backend supports deleteData param across CLI routes and Electron IPC
- DataSourceManager.removeSession now returns the removed session info
- Add i18n strings for the delete confirmation dialog (zh-CN/en-US/ja-JP/zh-TW)
2026-05-23 16:28:50 +08:00
digua 31fc9be1ed fix(sync): improve pull reliability with retry logic and simplified pagination
- Add multi-retry (3 attempts, 2s/3s/5s delays) for cold-start empty responses
- Remove unused offset/end parameters from fetch URL construction
- Fix Accept header to application/json only (avoids content negotiation issues)
- Add PullProgress type and progress tracking in PullEngine
- Export progress via getProgress() for frontend polling
2026-05-23 16:28:50 +08:00
diguaandClaude Sonnet 4.6 f55fb9cf00 fix(desktop): fall back to package version when app.getVersion returns 0.0.0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 16:28:50 +08:00
digua 5aaf1ce331 fix(sync): validate DB schema in sessionExists to prevent "no such table: message" error
sessionExists() previously only checked file existence, causing pull sync
to enter incremental import path on invalid/empty DB files. Now validates
that the message table exists, and maps schema errors to needFullResync
as a safety fallback.
2026-05-23 16:28:50 +08:00
digua 795d10d8c9 feat(changelog): add icon and i18n for ci change type 2026-05-23 16:28:50 +08:00
digua 3a2d4e753a refactor(mcp): trim exposed tool registry 2026-05-21 22:38:10 +08:00
digua 5db4b3bf9d fix(import): harden directory import path handling 2026-05-21 22:26:55 +08:00
digua 56902fea1c ci(release): publish CLI package from release workflow 2026-05-21 21:59:10 +08:00
digua 1e7325197c fix(web): preserve session not-found and member history behavior 2026-05-22 10:20:39 +08:00
diguaandCursor 5f76e65359 fix(sync): prevent race condition when adding new subscriptions
When a pullAllSessions was already running, the reloadTimer triggered
by adding sessions would be skipped by the source-level concurrency
lock, causing newly added sessions to wait until the next scheduled
interval (up to 60 minutes) before syncing.

Fix: trigger individual per-session pulls via triggerPull(sourceId,
sessionId) which bypasses the source-level lock, ensuring immediate
sync for newly added sessions regardless of concurrent pulls.

Also includes: connection pre-check on data source add, removal of
duplicate "browse remote sessions" button, hiding "other" session
types, and full resync fix for deleted local sessions.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 10:20:39 +08:00
diguaandCursor dd3cb10414 refactor(services): unify CLI Web and Electron service layer
Extract shared business logic from monolithic web.ts into reusable
services in @openchatlab/node-runtime (session, member, index, summary,
export), using SessionRuntimeAdapter to abstract platform differences.
Split web.ts into 12 domain-specific route modules under routes/web/.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 10:20:39 +08:00
diguaandCursor 9421662a52 feat(import): support unified directory import for Electron and Web
Add directory import support for multi-file formats (e.g. shuakami chunked-jsonl).
Users can select or drag-and-drop a directory via the "Import Folder" checkbox.

- Add `findEntryFileInDirectory()` to parser layer for format-agnostic entry file discovery
- Add `importDirectory` method to ImportAdapter interface
- Implement FetchImportAdapter.importDirectory with multi-file FormData upload
- Add `POST /_web/import-directory` CLI route with directory reconstruction
- Add `chat:importDirectory` IPC handler in Electron main process
- Enhance FileDropZone with `directory` prop and drag-and-drop directory support
- Refactor FetchImportAdapter to extract reusable `consumeSseStream` helper

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 10:20:39 +08:00
digua 04427a98d8 chore(cli): prepare npm release docs 2026-05-22 10:20:39 +08:00
digua 6fa92bc2e4 chore(mcp): prepare npm publish 2026-05-22 10:20:39 +08:00
digua 6c7e9f746f refactor(mcp): simplify MCP settings integration 2026-05-22 10:20:39 +08:00
diguaandCursor 584f581433 fix(mcp): pass nativeBinding to DatabaseManager for ABI compatibility
The MCP entry was loading better-sqlite3 from node_modules which may
have been compiled for a different Node.js ABI. Now passes the
pre-built native binding from apps/cli/native/ (maintained by
ensure-native.mjs), matching how other CLI commands handle this.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 10:20:39 +08:00
diguaandCursor d022bed48f refactor(mcp): extract MCP core into shared chatlab-mcp package
Move MCP Server logic (tool registration, resource registration, schema
conversion) from apps/cli/src/mcp.ts to packages/mcp-server so both CLI
and Desktop can share the same MCP implementation.

- New package: chatlab-mcp (packages/mcp-server) with McpDatabaseManager
  interface abstraction
- CLI mcp.ts slimmed to thin entry (~37 lines) calling startMcpServer()
- Desktop helper prototype at apps/desktop/helper/mcp.ts for dev-time
  MCP without GUI
- All 8 MCP tools and 3 resources unchanged

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 10:20:39 +08:00
digua e3370b52c2 fix(web): align dev server node runtime 2026-05-22 10:20:39 +08:00
digua eebb428dd3 release: v0.20.0 2026-05-19 23:59:11 +08:00
digua 0bd5bc9f38 fix(electron): auto-rebuild better-sqlite3 for Electron headers
Add @electron/rebuild devDependency and postinstall script to
apps/desktop so that better-sqlite3 is automatically recompiled
against Electron's Node.js headers after every pnpm install,
preventing NODE_MODULE_VERSION mismatch at runtime.
2026-05-19 22:47:00 +08:00
digua 08260499f8 feat: migrate localStorage to backend storage with declarative persist plugin
- Add backendPersist Pinia plugin for declarative preferences.json persistence
- Move Preferences types to @openchatlab/shared-types (single source of truth)
- Migrate sessionGapThreshold from localStorage to config.toml [ui]
- Migrate chatlab_filter_history from localStorage to preferences.json
- Fix stale localStorage locale read in i18n/index.ts
- Simplify usePreferencesSync (172 → 75 lines) by delegating to plugin

Adding a new backend-synced preference now only requires 3 changes:
1. shared-types interface  2. node-runtime DEFAULTS  3. store backendPersist.pick
2026-05-19 22:42:00 +08:00
digua 05394c2155 feat(cli): auto-detect and migrate Electron desktop data on first CLI run
When a desktop app user installs the CLI, automatically detect existing
Electron data directory (including custom paths via storage.json),
repoint config.toml, and migrate system data (ai, settings, cache, etc.)
to ~/.chatlab/. Block CLI execution with actionable instructions when
Electron was used but databases cannot be located.
2026-05-19 22:19:00 +08:00
digua 0aa30359ab fix(cli): resolve ESM module resolution for tsx dev mode
- Remove "type": "module" from apps/cli/package.json to avoid
  ESM/CJS interop issues with workspace packages in tsx dev mode
- Configure tsup to output .mjs files (always treated as ESM by Node.js)
- Rename bin entry from chatlab.js to chatlab.mjs
- Change chatlab web default port to 3100 (serve keeps 3110)
- Fix vite plugin: use pnpm instead of npx for tsx invocation
2026-05-19 22:13:00 +08:00
digua e363e8bd75 refactor(cli): unify all CLI text to English
All command descriptions, console output, option labels, comments
and error messages are now in English, consistent with AGENTS.md
rules and npm package positioning.
2026-05-19 21:59:00 +08:00
digua 09d4b1ddac feat(cli): add chatlab web command for one-click Web UI launch
- New `chatlab web` subcommand: starts HTTP API + serves Web SPA + auto-opens browser
- Options: --port, --host, --no-open
- Cross-platform `openBrowser()` using open/start/xdg-open
- Add `setWebMode()` in auth: static resources bypass token auth in web mode
- Add `build:full` and `prepare:web` scripts for dist-web preparation
2026-05-19 21:53:00 +08:00
digua b1427e2422 feat(cli): add tsup build pipeline for npm publishing
- Rename package to `chatlab-cli`, version 0.1.0
- Add tsup config with ESM output, bundle @openchatlab/* + stream-json
- Update bin/chatlab.js from stub to actual entry point
- Unify version reading via src/version.ts (CLI/MCP/HTTP API)
- Add publishing fields: type, files, engines, publishConfig, keywords
- Move @openchatlab/* to devDependencies (bundled into dist/)
- Add better-sqlite3 to dependencies, @node-rs/jieba to optionalDependencies
- Fix --web default path for bundled dist/ directory structure
2026-05-19 21:46:00 +08:00
digua 78e41a65b5 refactor: migrate CLI from packages/server to apps/cli
Move the CLI application from packages/server/ to apps/cli/ to align
with the monorepo convention (apps/ for deployable applications,
packages/ for shared libraries). Rename package to @openchatlab/chatlab.

Also fix a bug in ensureToken() that used raw string manipulation to
write config.toml, causing duplicate token fields that corrupted the
TOML file. This led to config parse failures and user_data_dir being
overwritten with defaults. Now uses writeConfigField() for safe writes.
2026-05-19 21:33:00 +08:00
digua 9db30879d3 fix(electron): decouple worker thread from electron module dependency
Worker thread crashed in packaged builds with "Cannot find module 'electron'"
because streamImport.ts transitively imported paths.ts (which requires electron)
through merger/tempCache.ts. Replaced with worker-local implementations that
receive tempDir via workerData, matching the existing dbDir/cacheDir pattern.
2026-05-19 21:13:59 +08:00
digua ba851f4ae9 fix(electron): fix data migration path mismatch after package extraction
The extraction of Electron code to apps/desktop/ changed the package name
from "ChatLab" to "@openchatlab/desktop", which caused app.getPath('userData')
to return a wrong path in dev mode. This made the migration system unable to
find existing databases, resulting in a fresh-app experience for upgrading users.

- Add productName "ChatLab" to desktop package.json to ensure correct userData path
- Add verifyDataPath() safety net: auto-correct config.toml when configured dir
  has no databases but old Electron path does
2026-05-19 20:39:25 +08:00
digua 1c6f4b3776 fix(electron): avoid install-app-deps during workspace install 2026-05-19 19:40:54 +08:00
digua c08a465116 chore(electron): remove Linux desktop build targets
Linux users will be served by the upcoming CLI package instead.
2026-05-19 19:17:59 +08:00
digua d058e8a60f fix(electron): fix CI build by pinning electron version and cleanup
- Pin electron to 35.7.5 (electron-builder requires fixed version)
- Remove redundant @electron/rebuild (built into electron-builder)
- Use electron-builder install-app-deps for postinstall
2026-05-19 19:14:11 +08:00
digua 9099b15ce6 chore(deps): upgrade vite toolchain 2026-05-19 18:39:14 +08:00
digua b12c07dc32 refactor: extract Electron shell to apps/desktop/
Move Electron-specific code (main, preload, shared) and configs
(electron.vite, electron-builder) into apps/desktop/ to prepare
for multi-platform support (Web Browser standalone).

- Create apps/desktop/ with dedicated package.json and tsconfig
- Split Electron deps (electron, electron-updater, better-sqlite3,
  etc.) from shared frontend deps in root package.json
- Declare better-sqlite3 and @node-rs/jieba in packages/node-runtime
- Add stream-json to packages/parser where it belongs
- Update all path aliases (@electron/* → apps/desktop/*) in tsconfig,
  vite configs, and relative imports in preload/main
- Keep slim root tsconfig.node.json as shared base for packages
- Update CI/CD release workflow for new directory layout
- Fix pre-existing type errors (pi-ai Model generic, SQLLabTab
  LLMChatStreamChunk, filter.test.ts empty methods)
2026-05-19 00:31:00 +08:00