Skip to content

Refactor: ChatLab Electron → Web Application#1

Open
WZhijun154 wants to merge 22 commits intomainfrom
refactor/web-app
Open

Refactor: ChatLab Electron → Web Application#1
WZhijun154 wants to merge 22 commits intomainfrom
refactor/web-app

Conversation

@WZhijun154
Copy link
Copy Markdown
Owner

@WZhijun154 WZhijun154 commented Mar 8, 2026

Refactor: ChatLab Electron → Web Application

This PR refactors ChatLab from an Electron desktop app into a standard web application with an Express backend and Vue 3 + Vite frontend.

Motivation

Remove the Electron dependency so ChatLab can run as a web app — deployable anywhere, no desktop install required.

Architecture Changes

Before: Electron main process ↔ IPC ↔ Renderer (Vue)
After: Express server (API) ↔ HTTP ↔ Vue 3 SPA (Vite)

What Changed

285 files changed — 21,988 insertions, 22,397 deletions

🗄️ Server (new server/ directory)

All Electron main process logic moved to an Express server:

Module Routes Description
Database server/database/core.ts SQLite via better-sqlite3 (was Electron main process)
Workers/Query server/services/ Query execution, worker modules
Chat /api/chat/* Session CRUD, chat operations
Import /api/import/* Chat import with file upload
Analysis /api/analysis/* Analysis data endpoints
Members /api/members/* Member management
Messages /api/messages/* Message queries
NLP /api/nlp/* NLP processing, stopwords
AI/LLM /api/llm/* LLM config, model management
AI Agent /api/agent/* Streaming agent API, desensitize rules
AI Conversations /api/ai-conversations/* AI conversation management
RAG/Embedding /api/embedding/* Embedding generation, vector search
Cache /api/cache/* Cache management
Network /api/network/* Network/proxy operations
Session Index /api/session-index/* Session indexing
Merge /api/merge/* Database merge operations
Migration /api/migration/* Database migrations

🖥️ Frontend (src/)

  • New src/api/ client layer — HTTP client replacing window.* preload APIs
  • All window.chatApi, window.mergeApi, window.aiApi, window.agentApi calls replaced with HTTP API client
  • All remaining window.* Electron API calls replaced
  • TitleBar component updated — removed Electron window controls, added web-native UI
  • Vite config updated with dev server proxy (/api → Express backend)

🗑️ Removed

  • electron/ directory (main process, preload scripts, IPC handlers)
  • electron-builder.yml
  • electron.vite.config.ts
  • All electron/preload/apis/* files
  • Electron-specific dependencies

✅ Tests

  • Server route tests: chat, import, analysis, members, messages, NLP, LLM, agent, AI conversations, embedding, cache, network, session-index, merge, migration
  • Database core tests
  • Integration tests (server/integration.test.ts)
  • API client tests (src/api/__tests__/)

How to Run

# Install dependencies
npm install

# Start dev server (Express + Vite)
npm run dev

# Build for production
npm run build

Stories Implemented

  1. US-001 Initialize project structure and package.json for web app
  2. US-002 Move database core module to server with better-sqlite3
  3. US-003 Move worker/query modules to server-side services
  4. US-004 Create chat session API routes
  5. US-005 Create chat import API routes with file upload
  6. US-006 Create analysis data API routes
  7. US-007 Create member management API routes
  8. US-008 Create message query API routes
  9. US-009 Move NLP module to server and create API routes
  10. US-010 Move AI/LLM modules to server and create LLM config API routes
  11. US-011 Move AI Agent to server and create streaming agent API
  12. US-012 Move RAG/Embedding modules to server and create API routes
  13. US-013 Create cache, network, and session-index API routes
  14. US-014 Create merge and database migration API routes
  15. US-015 Create frontend API client layer replacing Electron preload APIs
  16. US-016 Replace window.chatApi and window.mergeApi calls with HTTP API client
  17. US-017 Replace window.aiApi and window.agentApi calls with HTTP API client
  18. US-018 Replace remaining window.* API calls with HTTP API client
  19. US-019 Remove Electron-specific code and update TitleBar for web
  20. US-020 End-to-end integration: dev server, build, and smoke test

Built via antfarm multi-agent workflow (feature-dev pipeline)

- Remove all Electron dependencies (electron, electron-vite, electron-builder,
  @electron-toolkit/*, @electron/rebuild)
- Add Express, cors, multer and their type definitions
- Add concurrently, tsx, vue-tsc as dev dependencies
- Create server/index.ts with minimal Express app and /api/health endpoint
- Create server/index.test.ts with node:test health endpoint test
- Create vite.config.ts with Vue, TailwindCSS, Nuxt UI plugins and path aliases
- Create tsconfig.server.json targeting Node/ESNext
- Update tsconfig.json, tsconfig.node.json, tsconfig.web.json to remove
  Electron references
- Update scripts: dev (concurrently), build (tsc + vite), test, start
- Remove electron-builder.yml
- Created server/services/db-pool.ts with database connection pool management
  (cached read-only, writable, time-filter/system-filter utilities)
- Created server/services/import.ts with chat import database utilities
  (schema creation, indexing, dedup keys, temp database management)
- Created server/services/queries.ts as barrel re-export module
- Created server/services/queries/ with 11 sub-modules:
  basic.ts, sessions.ts, messages.ts, sql.ts, advanced.ts,
  session-index.ts, ai-tools.ts, filter.ts, export.ts, types.ts, helpers.ts
- All query functions accept sessionId and return same data shapes
- No worker_threads or electron imports in server/services/
- Added closeAllDatabases to queries.ts re-exports
- 24 tests covering getMemberActivity, getHourlyActivity, getTimeRange,
  plus getDailyActivity, getAvailableYears, getMessageTypeDistribution,
  getMessageLengthDistribution, getMembers, getMemberNameHistory,
  and no-worker_threads/no-electron import verification
- Created server/routes/chat.ts with Express Router for all session endpoints
- GET /api/sessions - list all sessions (returns AnalysisSession array)
- GET /api/sessions/:id - get single session (404 if not found)
- DELETE /api/sessions/:id - delete session (returns { success })
- PATCH /api/sessions/:id - rename session ({ name }) and/or update ownerId ({ ownerId })
- GET /api/sessions/:id/years - available years
- GET /api/sessions/:id/time-range - message time range
- GET /api/sessions/:id/schema - database schema
- POST /api/sessions/:id/sql - execute SQL query (returns { columns, rows, rowCount, duration, limited })
- Wired routes into server/index.ts via app.use('/api/sessions', chatRoutes)
- Added comprehensive tests in server/routes/chat.test.ts (18 tests)
- Copy parser module from electron/main/parser/ to server/parser/
- Fix relative import paths for server directory structure
- Fix stream-chain/stream-json CJS-to-ESM import compatibility
- Fix LogLevel type to include 'debug'
- Fix null/undefined type mismatch in discord exporter
- Create server/routes/import.ts with all import endpoints:
  - POST /api/import (upload and import chat file)
  - POST /api/import/detect-format (detect file format)
  - POST /api/import/scan-multi-chat (scan multi-chat file)
  - POST /api/import/with-options (import with format options)
  - POST /api/sessions/:id/incremental-import
  - POST /api/sessions/:id/analyze-incremental
- Use multer for multipart file upload handling
- Mount import routes in server/index.ts
- Write comprehensive tests (10 test cases covering all endpoints)
- All 82 tests pass, typecheck clean, build succeeds
…HTTP API client

- Rename src/api/ to src/services/ to fix Vite proxy conflict
  (imports from @/api resolved to /api/*.ts URLs which matched the
  Vite proxy rule "/api" → Express backend, causing 404s)
- Replace all window.chatApi references with imported chatApi from @/services
- Replace all window.mergeApi references with imported mergeApi from @/services
- Replace all window.sessionApi, window.aiApi, window.llmApi, window.agentApi,
  window.embeddingApi, window.nlpApi, window.networkApi, window.cacheApi
  references with imported modules from @/services
- Replace window.api.app, window.api.dialog, window.api.clipboard with
  new appApi, dialogApi, clipboardApi modules in src/services/app.ts
- Replace window.electron?.ipcRenderer calls with no-ops (web app)
- Replace window.electron?.webUtils in FileDropZone with browser File API
- Update src/stores/session.ts to use HTTP API client for all operations
- Update src/stores/llm.ts, embedding.ts, settings.ts, prompt.ts
- Replace @electron/preload/index and @electron/shared/types imports
  with @/services/* type imports
- Update ImportArea.vue to use File objects (browser File API) instead
  of Electron file paths
- Update IncrementalImportModal.vue to use File-based import
- Update ChatSelector.vue to accept File prop instead of filePath
- Add appApi.ts for web-compatible replacements of Electron app APIs
- Add mergeApi.parseServerFile() for server-side temp file parsing
- Update test glob in package.json to include __tests__/ directories
- Add 23 tests for session store API integration (all pass)
- All 399 tests pass, typecheck passes (pre-existing SessionTimeline.vue
  errors excluded)
- Updated server/index.ts to serve Vite build output (dist/client/) in
  production mode with SPA fallback for non-API routes
- Updated start script to set NODE_ENV=production via cross-env
- Updated README.md with web app setup, dev/build/start instructions,
  removed all Electron references and architecture docs
- Updated README.zh-CN.md with matching Chinese web app documentation
- Added 25 integration tests in server/integration.test.ts:
  - Health check (status, content type)
  - Session list (returns array)
  - Import flow (requires file upload)
  - LLM config (configs object, has-config boolean)
  - Cache info (info object, data-dir path)
  - Migration check (needsMigration boolean)
  - Embedding config, NLP pos-tags
  - Static file serving and SPA fallback
  - CORS headers
  - Package scripts (dev, start, build, no electron deps)
  - Vite config (proxy, build output)
  - No Electron references (directory, README)
  - Chart packages (exist, have Vue components, no Electron APIs)
- All 541 tests pass, build passes, typecheck passes
The app was stuck on 'Initializing...' because settingsStore.initLocale()
calls ensureDesensitizeRules() which hits GET /api/agent/desensitize-rules.
This route was missing, causing a 404 that prevented loadSessions() from
running.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant