lobehub/package.json
Innei 687b36c81c
♻️ refactor: migrate frontend from Next.js App Router to Vite SPA (#12404)
* init plan

* 📝 docs: update SPA plan for dev mode Worker cross-origin handling

- Clarified the handling of Worker cross-origin issues in dev mode, emphasizing the need for `workerPatch` to wrap cross-origin URLs as blob URLs.
- Enhanced the explanation of the dev mode's resource URL rewriting process for better understanding.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 refactor: Phase 1 - 环境变量整治

- Fix Pyodide env var mismatch (NEXT_PUBLIC_PYPI_INDEX_URL → pythonEnv.NEXT_PUBLIC_PYODIDE_PIP_INDEX_URL)
- Consolidate python.ts to use pythonEnv instead of direct process.env
- Remove NEXT_PUBLIC_ prefix from server-side MARKET_BASE_URL (5 files)

* 🏗️ chore: Phase 2 - Vite 工程搭建

- Add vite.config.ts with dual build (desktop/mobile via MOBILE env)
- Add index.html SPA template with __SERVER_CONFIG__ placeholder
- Add entry.desktop.tsx and entry.mobile.tsx SPA entry points
- Add dev:spa, dev:spa:mobile, build:spa, build:spa:copy scripts
- Install @vitejs/plugin-react and linkedom

* ♻️ refactor: Phase 3 - 第一方包 Next.js 解耦

- Replace next/link with <a> in builtin-tool-web-browsing (4 files, external links)
- Replace next/image with <img> in builtin-tool-agent-builder/InstallPlugin.tsx
- Add Vite import.meta.env compat for isDesktop in const/version.ts, builtin-tool-gtd, builtin-tool-group-management

* ♻️ refactor: Phase 4a - Auth 页面改用直接 next/navigation 和 next/link

- 9 auth files: @/libs/next/navigation → next/navigation
- 5 auth files: @/libs/next/Link → next/link
- Auth pages remain in Next.js App Router, need direct Next.js imports

* ♻️ refactor: Phase 4b - Next.js 抽象层替换为 react-router-dom/vanilla React

- navigation.ts: useRouter/usePathname/useSearchParams/useParams → react-router-dom
- navigation.ts: redirect/notFound → custom error throws
- navigation.ts: useServerInsertedHTML → no-op for SPA
- Link.tsx: next/link → react-router-dom Link adapter (href→to, external→<a>)
- Image.tsx: next/image → <img> wrapper with fill/style support
- dynamic.tsx: next/dynamic → React.lazy + Suspense wrapper

*  feat: Phase 5 - 新建 SPAGlobalProvider

- Create SPAServerConfig type (analyticsConfig, clientEnv, theme, featureFlags, locale)
- Add window.__SERVER_CONFIG__ and __MOBILE__ to global.d.ts
- Create SPAGlobalProvider (client-only Provider tree mirroring GlobalProvider)
- Includes AuthProvider for user session support
- Update entry.desktop.tsx and entry.mobile.tsx to wrap with SPAGlobalProvider

* ♻️ refactor: add SPA catch-all route handler with Vite dev proxy

- Create (spa)/[[...path]]/route.ts for serving SPA HTML
- Dev mode: proxy Vite dev server, rewrite asset URLs, inject Worker patch
- Prod mode: read pre-built HTML templates
- Build SPAServerConfig with analytics, theme, clientEnv, featureFlags
- Update middleware to pass SPA routes through to catch-all

* ♻️ refactor: skip auth checks for SPA routes in middleware

SPA pages are all public (no sensitive data in HTML).
Auth is handled client-side by SPAGlobalProvider's AuthProvider.
Only Next.js auth routes and API endpoints go through session checks.

* ♻️ refactor: replace Next.js-specific analytics with vanilla JS

- Google.tsx: replace @next/third-parties/google with direct gtag script
- ReactScan.tsx: replace react-scan/monitoring/next with generic script
- Desktop.tsx: replace next/script with native script injection

* ♻️ refactor: migrate @t3-oss/env-nextjs to @t3-oss/env-core

Replace framework-specific env validation with framework-agnostic version.
Add clientPrefix where client schemas exist.

* ♻️ refactor: replace next-mdx-remote/rsc with react-markdown

Use client-side react-markdown for MDX rendering instead of
Next.js RSC-dependent next-mdx-remote.

* 🔧 chore: update build scripts and Dockerfile for SPA integration

- build:docker now includes SPA build + copy steps
- dev defaults to Vite SPA, dev:next for Next.js backend
- Dockerfile copies public/spa/ assets for production
- Add public/spa/ to .gitignore (build artifact)

* 🗑️ chore: remove old Next.js route segment files and serwist PWA

- Delete [variants] page.tsx, error.tsx, not-found.tsx, loading.tsx
- Delete root loading.tsx and empty [[...path]] directory
- Delete unused loaders directory
- Remove @serwist/next PWA wrapper from Next.js config

* plan2

*  feat: add locale detection script to index.html for SPA dev mode

* ♻️ refactor: remove locale and theme from SPAServerConfig

*  feat: add [locale] segment with force-static and SEO meta generation

* ♻️ refactor: remove theme/locale reads from SPAGlobalProvider

*  feat: set vite base to /spa/ for production builds

*  feat: auto-generate spaHtmlTemplates from vite build output

* 🔧 chore: register dev:next task in turbo.json for parallel dev startup

* ♻️ refactor: rename (spa) route group to spa segment, rewrite SPA routes via middleware

*  feat: add Vite-compatible i18n/locale modules with import.meta.glob and resolve aliases

* 🔧 fix: use custom Vite plugin for module redirects instead of resolve.alias

* very important

* build

* 🔧 chore: update build scripts and clean up Vite configuration by removing unused plugin and code

Signed-off-by: Innei <tukon479@gmail.com>

* 🗑️ refactor: remove all electron modifier scripts

Modifiers are no longer needed with Vite SPA renderer build.

*  feat: add Vite renderer entry to electron-vite config

Add renderer build configuration to electron-vite, replacing the old
Next.js shadow workspace build flow. Delete buildNextApp.mts and
moveNextExports.ts, update package.json scripts accordingly.

*  feat: add .desktop suffix files for eager i18n loading

Create 4 .desktop files that use import.meta.glob({ eager: true })
for synchronous locale access in Electron desktop builds, replacing
the async lazy-loading used in web SPA builds.

* 🔧 refactor: adapt Electron main process for Vite renderer

Replace nextExportDir with rendererDir, update protocol from
app://next to app://renderer, simplify file resolution to SPA
fallback pattern, update _next/ asset paths to /assets/.

* 🔧 chore: update electron-builder files config for Vite renderer

Replace dist/next references with dist/renderer, remove Next.js
specific exclusion rules no longer applicable to Vite output.

* 🗑️ chore: remove @ast-grep/napi dependency

No longer needed after removing electron modifier scripts.

* 🔧 refactor: unify isDesktop to __ELECTRON__ compile-time constant

Remove NEXT_PUBLIC_IS_DESKTOP_APP and VITE_IS_DESKTOP_APP env vars.
Unify isDesktop in @lobechat/const using __ELECTRON__ defined by Vite.
Re-export from builtin-tool packages. Scripts use DESKTOP_BUILD.

* update

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 refactor: use electron-vite ELECTRON_RENDERER_URL instead of hardcoded port 3015

Replace hardcoded http://localhost:3015 with process.env.ELECTRON_RENDERER_URL
injected by electron-vite dev server. Clean up stale Next.js references.

* 🐛 fix: use local renderer-entry shim to resolve Vite root path issue

HTML entry ../../src/entry.desktop.tsx resolves to /src/entry.desktop.tsx
in URL space, which Vite cannot find within apps/desktop/ root. Add a
local shim that imports across root via module resolver instead.

* 🔧 refactor: extract shared renderer Vite config into sharedRendererConfig

Deduplicate plugins (nodeModuleStub, platformResolve, tsconfigPaths) and
define (__MOBILE__, __ELECTRON__, process.env) between root vite.config.ts
and electron.vite.config.ts renderer section.

* 🔧 refactor: move all renderer plugins and optimizeDeps into shared config

sharedRendererPlugins now includes react, codeInspectorPlugin alongside
nodeModuleStub, platformResolve, tsconfigPaths. Add sharedOptimizeDeps
for pre-bundling list. Both root and electron configs consume shared only.

* 🐛 fix: set electron renderer root to monorepo root for correct glob resolution

import.meta.glob with absolute paths (e.g. /node_modules/antd/...) resolved
within apps/desktop/ instead of monorepo root. Change renderer root to ROOT_DIR,
add electronDesktopHtmlPlugin middleware to rewrite / to /apps/desktop/index.html,
and remove the now-unnecessary renderer-entry.ts shim.

* desktop vite !!

Signed-off-by: Innei <tukon479@gmail.com>

* sync import !!

Signed-off-by: Innei <tukon479@gmail.com>

* clean ci!!

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 refactor: update SPA path structure and clean up dependencies

- Changed the path in .gitignore and related files from [locale] to [variants] for SPA templates.
- Updated index.html to set body height to 100%.
- Cleaned up package.json by removing unused dependencies and reorganizing devDependencies.
- Refactored RendererUrlManager to use a constant for SPA entry HTML path.
- Removed obsolete route.ts file from the SPA structure.
- Adjusted proxy configuration to reflect the new SPA path structure.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 chore: update build script to include mobile SPA build

- Modified the build script in package.json to add the mobile SPA build step.
- Ensured the build process accommodates both desktop and mobile SPA versions.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 chore: update build scripts and improve file encoding consistency

- Modified the build script in package.json to ensure the SPA copy step runs after the build.
- Updated file encoding in generateSpaTemplates.mts from 'utf-8' to 'utf8' for consistency.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 fix: correct Blob import syntax and update global server config type

- Fixed the Blob import syntax in route.ts to ensure proper module loading.
- Updated the global server configuration type in global.d.ts for improved type safety.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 test: update RendererUrlManager test to reflect new file path

- Modified the mock implementation in RendererUrlManager.test.ts to check for the updated file path '/mock/export/out/apps/desktop/index.html'.
- Adjusted the expected resolved path in the test to match the new structure.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 refactor: remove catch-all example file and update imports

- Deleted the catch-all example file `catch-all.eg.ts` to streamline the codebase.
- Updated import paths in `ClientResponsiveLayout.tsx` and `ClientResponsiveContent/index.tsx` to use the new dynamic import location.
- Added type declarations for HTML templates in `spaHtmlTemplates.d.ts`.
- Adjusted `tsconfig.json` to include the updated file structure.
- Enhanced type definitions in `global.d.ts` and fixed locale loading in `locale.vite.ts`.

Signed-off-by: Innei <tukon479@gmail.com>

* e2e

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 chore: remove unused build script for Vercel deployment

- Deleted the `build:vercel` script from package.json to streamline the build process.
- Ensured the remaining build scripts are organized and relevant.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 config: update Vite build input for mobile support

- Changed the build input path in vite.config.ts to conditionally use 'index.mobile.html' for mobile builds, enhancing support for mobile SPA versions.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 feat: add compatibility checks for import maps and cascade layers

- Implemented functions to check for browser support of import maps and CSS cascade layers.
- Redirected users to a compatibility page if their browser does not support the required features.
- Updated the build script in package.json to use the experimental analyze command for better performance.

Signed-off-by: Innei <tukon479@gmail.com>

* chore: rename

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 feat: refactor authentication layout and introduce global providers

- Created a new `RootLayout` component to streamline the layout structure.
- Removed the old layout file for variants and integrated necessary features into the new layout.
- Added `AuthGlobalProvider` to manage authentication context and server configurations.
- Introduced language and theme selection components for enhanced user experience.
- Updated various components to utilize the new context and improve modularity.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 config: exclude build artifacts from serverless functions

- Updated the `next.config.ts` to exclude SPA, desktop, and mobile build artifacts from serverless functions.
- Added paths for `public/spa/**`, `dist/**`, `apps/desktop/build/**`, and `packages/database/migrations/**` to the exclusion list.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 config: refine exclusion of build artifacts from serverless functions

- Updated `next.config.ts` to specify exclusion paths for desktop and mobile build artifacts.
- Changed exclusions from `dist/**` and `apps/desktop/build/**` to `dist/desktop/**`, `dist/mobile/**`, and `apps/desktop/**` for better clarity and organization.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 fix: update BrowserRouter basename for local development

- Modified the `ClientRouter` component to conditionally set the `basename` of `BrowserRouter` based on the `__DEBUG_PROXY__` variable, improving local development experience.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 feat: implement mobile SPA workflow and S3 asset management

- Added a new workflow for building and uploading mobile SPA assets to S3, including environment variable configurations in `.env.example`.
- Updated `package.json` to include a new script for the mobile SPA workflow.
- Enhanced the Vite configuration to support dynamic CDN base paths.
- Refactored the template generation script to handle mobile HTML templates more effectively.
- Introduced new modules for uploading assets to S3 and generating mobile HTML templates.

Signed-off-by: Innei <tukon479@gmail.com>

* 🐛 fix: extract origin from MOBILE_S3_PUBLIC_DOMAIN to prevent double key prefix

* 🔧 fix: update mobile HTML template to use the latest asset versions

- Modified the mobile HTML template to reference the updated JavaScript asset version for improved functionality.
- Ensured consistency in the template structure while maintaining existing styles and scripts.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 chore: update dependencies and refine service worker integration

- Removed outdated dependencies related to Serwist from package.json and tsconfig.json.
- Added vite-plugin-pwa to enhance PWA capabilities in the Vite configuration.
- Updated service worker registration logic in the PWA installation component.
- Introduced a new local development proxy route for debugging purposes.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 chore: refactor development scripts and remove Turbo configuration

- Updated the `dev` script in `package.json` to use a new startup sequence script for improved development workflow.
- Removed the outdated `turbo.json` configuration file as it is no longer needed.
- Introduced `devStartupSequence.mts` to manage the startup of Next.js and Vite processes concurrently.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 feat: update entry points and introduce debug proxy for local development

- Changed the main entry point in `index.html` from `entry.desktop.tsx` to `entry.web.tsx` for improved web compatibility.
- Added an `initialize.ts` file to enable `immer`'s `enableMapSet` functionality.
- Introduced a new `__DEBUG_PROXY__` variable in global types to support local development proxy features.
- Implemented a debug proxy route to facilitate local development with dynamic HTML injection and script handling.
- Removed outdated mobile routing components to streamline the codebase.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 refactor: replace BrowserRouter with RouterProvider for improved routing

- Updated entry points for desktop, mobile, and web to utilize RouterProvider and createAppRouter for better routing management.
- Removed the deprecated renderRoutes function in favor of a more streamlined router configuration.
- Enhanced router setup to support error boundaries and dynamic routing.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 refactor: remove direct access handling for SPA routes in proxy configuration

- Eliminated the handling of direct access to pre-rendered SPA pages in the proxy configuration.
- Simplified the request processing logic by removing checks for SPA routes, streamlining the middleware response flow.

Signed-off-by: Innei <tukon479@gmail.com>

* update

* 🔧 refactor: enhance Worker instantiation logic in mobile HTML template

* 🐛 fix: remove duplicate waitForPageWorkspaceReady calls in page CRUD e2e steps

* 🔧 refactor: simplify createTracePayload function by using btoa for base64 encoding

* 🔧 refactor: specify locales in import.meta.glob for dayjs and antd

* 🔧 refactor: replace Node.js Buffer with web-compatible btoa for base64 encoding in file upload

* 🐛 fix: disable consistent-type-imports rule for mdx files to prevent eslint crash

* 🔧 refactor: add height style to root div for consistent layout

* 🔧 refactor: replace btoa with Buffer for base64 encoding in trace and file upload handling

* 🔧 refactor: extract nextjsOnlyRoutes to a separate file for better organization

* 🔧 refactor: enable Immer MapSet plugin in tests for better state management

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 refactor: integrate sharedRollupOutput configuration and increase cache size for better performance

Signed-off-by: Innei <tukon479@gmail.com>

* 🗑️ chore: remove obsolete desktop.routes.test.ts file as it is no longer needed

Signed-off-by: Innei <tukon479@gmail.com>

* 🐛 fix: use cross-env for env vars in npm scripts (Windows CI)

Co-authored-by: Cursor <cursoragent@cursor.com>

* 🔧 chore: update Dockerfile for web-only build and adjust npm scripts to use pnpm

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 chore: enhance Dockerfile prebuild process with environment checks and add new dependencies

- Updated Dockerfile to include environment checks before removing desktop-only code.
- Added new dependencies in package.json: @aws-sdk/client-bedrock-runtime, @opentelemetry/auto-instrumentations-node, @opentelemetry/resources, @opentelemetry/sdk-metrics, and ajv.
- Configured Rollup to exclude @aws-sdk/client-bedrock-runtime from the SPA bundle.
- Introduced dockerPrebuild.mts script for environment variable validation and information logging.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 chore: enhance Vite and Electron configurations with environment loading and trace encoding improvements

- Updated Vite and Electron configurations to load environment variables using loadEnv.
- Modified trace encoding in utils to use TextEncoder for better compatibility.
- Adjusted sharedRendererConfig to expose only necessary public environment variables.

Signed-off-by: Innei <tukon479@gmail.com>

* 🗑️ chore: remove plans directory (migrated to discussion)

* ♻️ refactor: inject NEXT_PUBLIC_* env per key in Vite define

Co-authored-by: Cursor <cursoragent@cursor.com>

*  feat: add loading screen with animation to enhance user experience

- Introduced a loading screen with a brand logo and animations for better visual feedback during loading times.
- Implemented CSS styles for the loading screen and animations in index.html.
- Removed the loading screen from the DOM once the layout is ready using useLayoutEffect in SPAGlobalProvider.

Signed-off-by: Innei <tukon479@gmail.com>

* 🗑️ chore: remove unnecessary external dependency from Vite configuration

- Eliminated the external dependency '@aws-sdk/client-bedrock-runtime' from the Vite configuration to streamline the build process for the SPA bundle.

Signed-off-by: Innei <tukon479@gmail.com>

*  feat: add web app manifest link in index.html and enable PWA support in Vite configuration

- Added a link to the web app manifest in index.html to enhance PWA capabilities.
- Enabled manifest support in Vite configuration for improved service worker functionality.

Signed-off-by: Innei <tukon479@gmail.com>

* 🔧 chore: update link rel attributes for improved SEO and consistency

- Modified link rel attributes in multiple components to remove 'noreferrer' and standardize to 'nofollow'.
- Adjusted imports in PageContent components for better organization.

Signed-off-by: Innei <tukon479@gmail.com>

* update provider

*  feat: enhance loading experience and update package dependencies

- Added a loading screen with animations and a brand logo in index.html for improved user feedback during loading times.
- Introduced CSS styles for the loading screen and animations.
- Updated package.json files across multiple packages to include "@lobechat/const" as a dependency.

Signed-off-by: Innei <tukon479@gmail.com>

* fix: update proxy

Signed-off-by: Innei <tukon479@gmail.com>

* 🗑️ chore: remove GlobalLayout and Locale components

- Deleted GlobalLayout and Locale components from the GlobalProvider directory to streamline the codebase.
- This removal is part of a refactor to simplify the layout structure and improve maintainability.

Signed-off-by: Innei <tukon479@gmail.com>

* chore: clean up console logs and improve component structure

- Removed unnecessary console log statements from AgentForkTag components in both agent and community directories to enhance code cleanliness.
- Refactored UserAgentList component for better readability by restructuring the useUserDetailContext hook and adjusting the layout of Flexbox components.

Signed-off-by: Innei <tukon479@gmail.com>

* chore: remove console log from MemoryAnalysis component

* chore: update mobile HTML template with new asset links

- Replaced the previous asset links in the mobile HTML template with updated versions to ensure the latest resources are utilized.
- Adjusted the link rel attributes for module preloading to enhance performance and loading efficiency.

Signed-off-by: Innei <tukon479@gmail.com>

* fix: correct variable assignment in createClientTaskThread integration test

- Updated the assignment of the second parent message in the createClientTaskThread integration test to improve clarity and ensure proper data handling.
- Changed the variable name from 'secondParentMsg' to 'inserted' for better context before extracting the first message from the inserted results.

Signed-off-by: Innei <tukon479@gmail.com>

* refactor: simplify authentication check in define-config

- Removed the dependency on the isDesktop variable in the authentication check to streamline the logic.
- Enhanced the clarity of the redirection process for protected routes by focusing solely on the isLoggedIn status.

Signed-off-by: Innei <tukon479@gmail.com>

*  feat(dev): enhance local development setup with debug proxy instructions

- Added detailed instructions for starting the development environment in CLAUDE.md, including commands for SPA and full-stack modes.
- Updated README.md and README.zh-CN.md to reflect new commands and the debug proxy URL for local development.
- Introduced a Vite plugin to print the debug proxy URL upon server start, facilitating easier local development against the production backend.
- Corrected the debug proxy route in entry.web.tsx and define-config.ts for consistency.

This improves the developer experience by providing clear guidance and tools for local development.

Signed-off-by: Innei <tukon479@gmail.com>

* optimize perf

* optimize perf

* optimize perf

* remove speedy plugin

* add dayjs vendor

* Revert "remove speedy plugin"

This reverts commit bf986afeb1.

---------

Signed-off-by: Innei <tukon479@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-28 00:01:01 +08:00

505 lines
20 KiB
JSON

{
"name": "@lobehub/lobehub",
"version": "2.1.33",
"description": "LobeHub - an open-source,comprehensive AI Agent framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
"keywords": [
"framework",
"chatbot",
"chatgpt",
"nextjs",
"vercel-ai",
"openai",
"azure-openai",
"visual-model",
"tts",
"stt"
],
"homepage": "https://github.com/lobehub/lobe-chat",
"bugs": {
"url": "https://github.com/lobehub/lobe-chat/issues/new/choose"
},
"repository": {
"type": "git",
"url": "https://github.com/lobehub/lobe-chat.git"
},
"license": "MIT",
"author": "LobeHub <i@lobehub.com>",
"sideEffects": false,
"workspaces": [
"packages/*",
"packages/business/*",
"e2e",
"apps/desktop/src/main"
],
"scripts": {
"build": "bun run build:spa && bun run build:spa:copy && bun run build:next",
"build:analyze": "cross-env NODE_OPTIONS=--max-old-space-size=81920 next experimental-analyze",
"build:docker": "pnpm run build:spa && pnpm run build:spa:mobile && pnpm run build:spa:copy && cross-env NODE_OPTIONS=--max-old-space-size=8192 DOCKER=true next build && pnpm run build-sitemap",
"build:next": "cross-env NODE_OPTIONS=--max-old-space-size=8192 next build",
"build:spa": "rm -rf public/spa && cross-env NODE_OPTIONS=--max-old-space-size=8192 vite build",
"build:spa:copy": "mkdir -p public/spa && cp -r dist/desktop/assets public/spa/ && ([ -d dist/mobile/assets ] && cp -r dist/mobile/assets public/spa/ || true) && tsx scripts/generateSpaTemplates.mts",
"build:spa:mobile": "cross-env NODE_OPTIONS=--max-old-space-size=8192 MOBILE=true vite build",
"build-migrate-db": "bun run db:migrate",
"build-sitemap": "tsx ./scripts/buildSitemapIndex/index.ts",
"clean:node_modules": "bash -lc 'set -e; echo \"Removing all node_modules...\"; rm -rf node_modules; pnpm -r exec rm -rf node_modules; rm -rf apps/desktop/node_modules; echo \"All node_modules removed.\"'",
"db:generate": "drizzle-kit generate && npm run workflow:dbml",
"db:migrate": "cross-env MIGRATION_DB=1 tsx ./scripts/migrateServerDB/index.ts",
"db:studio": "drizzle-kit studio",
"db:visualize": "dbdocs build docs/development/database-schema.dbml --project lobe-chat",
"desktop:build:all": "npm run desktop:build:main",
"desktop:build:main": "npm run build:main --prefix=./apps/desktop",
"desktop:build-channel": "tsx scripts/electronWorkflow/buildDesktopChannel.ts",
"desktop:main:build": "npm run desktop:main:build --prefix=./apps/desktop",
"desktop:package:app": "npm run desktop:build:all && npm run desktop:package:app:platform",
"desktop:package:app:platform": "tsx scripts/electronWorkflow/buildElectron.ts",
"desktop:package:local": "npm run desktop:build:all && npm run package:local --prefix=./apps/desktop",
"desktop:package:local:reuse": "npm run package:local:reuse --prefix=./apps/desktop",
"dev": "tsx scripts/devStartupSequence.mts",
"dev:bun": "bun --bun next dev -p 3010",
"dev:docker": "docker compose -f docker-compose/dev/docker-compose.yml up -d --wait postgresql redis rustfs searxng",
"dev:docker:down": "docker compose -f docker-compose/dev/docker-compose.yml down",
"dev:docker:reset": "docker compose -f docker-compose/dev/docker-compose.yml down -v && rm -rf docker-compose/dev/data && npm run dev:docker && pnpm db:migrate",
"dev:next": "next dev -p 3010",
"dev:spa": "vite --port 9876",
"dev:spa:mobile": "cross-env MOBILE=true vite --port 3012",
"docs:cdn": "npm run workflow:docs-cdn && npm run lint:mdx",
"docs:i18n": "lobe-i18n md && npm run lint:mdx",
"docs:seo": "lobe-seo && npm run lint:mdx",
"e2e": "cd e2e && npm run test",
"e2e:install": "playwright install",
"e2e:ui": "playwright test --ui",
"hotfix:branch": "tsx ./scripts/hotfixWorkflow/index.ts",
"i18n": "npm run workflow:i18n && lobe-i18n && prettier -c --write \"locales/**\"",
"i18n:unused": "tsx ./scripts/i18nWorkflow/analyzeUnusedKeys.ts",
"i18n:unused-clean": "tsx ./scripts/i18nWorkflow/cleanUnusedKeys.ts",
"lint": "npm run lint:ts && npm run lint:style && npm run type-check && npm run lint:circular",
"lint:circular": "npm run lint:circular:main && npm run lint:circular:packages",
"lint:circular:main": "dpdm src/**/*.ts --no-warning --no-tree --exit-code circular:1 --no-progress -T true --skip-dynamic-imports circular",
"lint:circular:packages": "dpdm packages/**/src/**/*.ts --no-warning --no-tree --exit-code circular:1 --no-progress -T true --skip-dynamic-imports circular",
"lint:console": "tsx scripts/checkConsoleLog.mts",
"lint:md": "remark . --silent --output",
"lint:mdx": "npm run workflow:mdx && remark \"docs/**/*.mdx\" -r ./.remarkrc.mdx.mjs --silent --output && eslint \"docs/**/*.mdx\" --quiet --fix",
"lint:style": "stylelint \"{src,tests}/**/*.{js,jsx,ts,tsx}\" --fix",
"lint:ts": "bash scripts/lint-ts.sh",
"lint:ts:prune": "eslint \"{src,tests,packages}/**/*.{js,jsx,ts,tsx}\" --prune-suppressions --concurrency=auto",
"lint:ts:suppress": "eslint \"{src,tests}/**/*.{js,jsx,ts,tsx}\" --suppress-all --concurrency=auto",
"lint:unused": "knip --include files,exports,types,enumMembers,duplicates",
"prepare": "husky",
"prettier": "prettier -c --write \"**/**\"",
"pull": "git pull",
"qstash": "pnpx @upstash/qstash-cli@latest dev",
"reinstall": "rm -rf .next && rm -rf node_modules && rm -rf ./packages/*/node_modules && pnpm -r exec rm -rf node_modules && pnpm install",
"reinstall:desktop": "rm -rf pnpm-lock.yaml && rm -rf node_modules && pnpm -r exec rm -rf node_modules && pnpm install --node-linker=hoisted",
"release": "semantic-release",
"release:branch": "tsx ./scripts/releaseWorkflow/index.ts",
"self-hosting:docker": "docker build -t lobehub:local .",
"self-hosting:docker-cn": "docker build -t lobehub-local --build-arg USE_CN_MIRROR=true .",
"start": "next start -p 3210",
"stylelint": "stylelint \"src/**/*.{js,jsx,ts,tsx}\" --fix",
"test": "npm run test-app && npm run test-server",
"test:e2e": "pnpm --filter @lobechat/e2e-tests test",
"test:e2e:smoke": "pnpm --filter @lobechat/e2e-tests test:smoke",
"test:update": "vitest -u",
"test-app": "vitest run",
"test-app:coverage": "vitest --coverage --silent='passed-only'",
"tunnel:cloudflare": "cloudflared tunnel --url http://localhost:3010",
"tunnel:ngrok": "ngrok http http://localhost:3011",
"type-check": "tsgo --noEmit",
"type-check:tsc": "tsc --noEmit",
"workflow:cdn": "tsx ./scripts/cdnWorkflow/index.ts",
"workflow:changelog": "tsx ./scripts/changelogWorkflow/index.ts",
"workflow:countCharters": "tsx scripts/countEnWord.ts",
"workflow:dbml": "tsx ./scripts/dbmlWorkflow/index.ts",
"workflow:docs": "tsx ./scripts/docsWorkflow/index.ts",
"workflow:docs-cdn": "tsx ./scripts/docsWorkflow/autoCDN.ts",
"workflow:i18n": "tsx ./scripts/i18nWorkflow/index.ts",
"workflow:mdx": "tsx ./scripts/mdxWorkflow/index.ts",
"workflow:mobile-spa": "tsx scripts/mobileSpaWorkflow/index.ts",
"workflow:readme": "tsx ./scripts/readmeWorkflow/index.ts",
"workflow:set-desktop-version": "tsx ./scripts/electronWorkflow/setDesktopVersion.ts"
},
"lint-staged": {
"*.md": [
"remark --silent --output --",
"prettier --write --no-error-on-unmatched-pattern"
],
"*.mdx": [
"remark -r ./.remarkrc.mdx.mjs --silent --output --",
"eslint --quiet --fix --prune-suppressions",
"git add eslint-suppressions.json"
],
"*.json": [
"prettier --write --no-error-on-unmatched-pattern"
],
"*.{mjs,cjs}": [
"eslint --fix --prune-suppressions",
"git add eslint-suppressions.json",
"prettier --write"
],
"*.{js,jsx}": [
"eslint --fix --prune-suppressions",
"git add eslint-suppressions.json",
"stylelint --fix",
"prettier --write"
],
"*.{ts,tsx}": [
"stylelint --fix",
"eslint --fix --prune-suppressions",
"git add eslint-suppressions.json",
"prettier --parser=typescript --write"
],
"*.{yml,yaml}": [
"eslint --fix"
]
},
"overrides": {
"pdfjs-dist": "5.4.530",
"stylelint-config-clean-order": "7.0.0"
},
"dependencies": {
"@ant-design/icons": "^6.1.0",
"@ant-design/pro-components": "^2.8.10",
"@anthropic-ai/sdk": "^0.73.0",
"@atlaskit/pragmatic-drag-and-drop": "^1.7.7",
"@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.1.0",
"@aws-sdk/client-bedrock-runtime": "^3.941.0",
"@aws-sdk/client-s3": "~3.932.0",
"@aws-sdk/s3-request-presigner": "~3.932.0",
"@azure-rest/ai-inference": "1.0.0-beta.5",
"@azure/core-auth": "^1.10.1",
"@better-auth/expo": "1.4.6",
"@better-auth/passkey": "1.4.6",
"@cfworker/json-schema": "^4.1.1",
"@codesandbox/sandpack-react": "^2.20.0",
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/utilities": "^3.2.2",
"@emoji-mart/data": "^1.2.1",
"@emoji-mart/react": "^1.1.1",
"@emotion/react": "^11.14.0",
"@fal-ai/client": "^1.8.4",
"@formkit/auto-animate": "^0.9.0",
"@google/genai": "^1.38.0",
"@henrygd/queue": "^1.2.0",
"@huggingface/inference": "^4.13.10",
"@icons-pack/react-simple-icons": "^13.8.0",
"@khmyznikov/pwa-install": "0.3.9",
"@langchain/community": "^0.3.59",
"@lobechat/agent-runtime": "workspace:*",
"@lobechat/builtin-agents": "workspace:*",
"@lobechat/builtin-skills": "workspace:*",
"@lobechat/builtin-tool-agent-builder": "workspace:*",
"@lobechat/builtin-tool-calculator": "workspace:*",
"@lobechat/builtin-tool-cloud-sandbox": "workspace:*",
"@lobechat/builtin-tool-group-agent-builder": "workspace:*",
"@lobechat/builtin-tool-group-management": "workspace:*",
"@lobechat/builtin-tool-gtd": "workspace:*",
"@lobechat/builtin-tool-knowledge-base": "workspace:*",
"@lobechat/builtin-tool-local-system": "workspace:*",
"@lobechat/builtin-tool-memory": "workspace:*",
"@lobechat/builtin-tool-notebook": "workspace:*",
"@lobechat/builtin-tool-page-agent": "workspace:*",
"@lobechat/builtin-tool-skill-store": "workspace:*",
"@lobechat/builtin-tool-skills": "workspace:*",
"@lobechat/builtin-tool-tools": "workspace:*",
"@lobechat/builtin-tool-web-browsing": "workspace:*",
"@lobechat/builtin-tools": "workspace:*",
"@lobechat/business-config": "workspace:*",
"@lobechat/business-const": "workspace:*",
"@lobechat/config": "workspace:*",
"@lobechat/const": "workspace:*",
"@lobechat/context-engine": "workspace:*",
"@lobechat/conversation-flow": "workspace:*",
"@lobechat/database": "workspace:*",
"@lobechat/desktop-bridge": "workspace:*",
"@lobechat/edge-config": "workspace:*",
"@lobechat/editor-runtime": "workspace:*",
"@lobechat/electron-client-ipc": "workspace:*",
"@lobechat/electron-server-ipc": "workspace:*",
"@lobechat/eval-dataset-parser": "workspace:*",
"@lobechat/eval-rubric": "workspace:*",
"@lobechat/fetch-sse": "workspace:*",
"@lobechat/file-loaders": "workspace:*",
"@lobechat/memory-user-memory": "workspace:*",
"@lobechat/model-runtime": "workspace:*",
"@lobechat/observability-otel": "workspace:*",
"@lobechat/prompts": "workspace:*",
"@lobechat/python-interpreter": "workspace:*",
"@lobechat/ssrf-safe-fetch": "workspace:*",
"@lobechat/utils": "workspace:*",
"@lobechat/web-crawler": "workspace:*",
"@lobehub/analytics": "^1.6.0",
"@lobehub/charts": "^4.0.3",
"@lobehub/chat-plugin-sdk": "^1.32.4",
"@lobehub/chat-plugins-gateway": "^1.9.0",
"@lobehub/desktop-ipc-typings": "workspace:*",
"@lobehub/editor": "^3.16.1",
"@lobehub/icons": "^4.1.0",
"@lobehub/market-sdk": "^0.30.3",
"@lobehub/tts": "^4.0.2",
"@lobehub/ui": "^4.38.1",
"@modelcontextprotocol/sdk": "^1.26.0",
"@napi-rs/canvas": "^0.1.88",
"@neondatabase/serverless": "^1.0.2",
"@next/third-parties": "^16.1.5",
"@opentelemetry/auto-instrumentations-node": "^0.67.0",
"@opentelemetry/exporter-jaeger": "^2.5.0",
"@opentelemetry/resources": "^2.2.0",
"@opentelemetry/sdk-metrics": "^2.2.0",
"@opentelemetry/winston-transport": "^0.19.0",
"@react-pdf/renderer": "^4.3.2",
"@react-three/drei": "^10.7.7",
"@react-three/fiber": "^9.5.0",
"@saintno/comfyui-sdk": "^0.2.49",
"@t3-oss/env-core": "^0.13.10",
"@t3-oss/env-nextjs": "^0.13.10",
"@tanstack/react-query": "^5.90.20",
"@trpc/client": "^11.8.1",
"@trpc/next": "^11.8.1",
"@trpc/react-query": "^11.8.1",
"@trpc/server": "^11.8.1",
"@upstash/qstash": "^2.8.4",
"@upstash/workflow": "^0.2.23",
"@vercel/analytics": "^1.6.1",
"@vercel/edge-config": "^1.4.3",
"@vercel/functions": "^3.3.6",
"@vercel/speed-insights": "^1.3.1",
"@virtuoso.dev/masonry": "^1.4.0",
"@xterm/xterm": "^5.5.0",
"@zumer/snapdom": "^1.9.14",
"ahooks": "^3.9.6",
"antd": "^6.2.1",
"antd-style": "4.1.0",
"async-retry": "^1.3.3",
"bcryptjs": "^3.0.3",
"better-auth": "1.4.6",
"better-auth-harmony": "^1.2.5",
"better-call": "1.1.8",
"brotli-wasm": "^3.0.1",
"chroma-js": "^3.2.0",
"class-variance-authority": "^0.7.1",
"cmdk": "^1.1.1",
"cookie": "^1.1.1",
"countries-and-timezones": "^3.8.0",
"dayjs": "^1.11.19",
"debug": "^4.4.3",
"dexie": "^3.2.7",
"diff": "^8.0.3",
"drizzle-orm": "^0.45.1",
"drizzle-zod": "^0.5.1",
"epub2": "^3.0.2",
"es-toolkit": "^1.44.0",
"fast-deep-equal": "^3.1.3",
"fflate": "^0.8.2",
"ffmpeg-static": "^5.3.0",
"file-type": "^21.3.0",
"gray-matter": "^4.0.3",
"html-to-text": "^9.0.5",
"i18next": "^25.8.0",
"i18next-browser-languagedetector": "^8.2.0",
"i18next-resources-to-backend": "^1.2.1",
"immer": "^11.1.3",
"ioredis": "^5.9.2",
"jose": "^6.1.3",
"js-sha256": "^0.11.1",
"jsonl-parse-stringify": "^1.0.3",
"klavis": "^2.15.0",
"langchain": "^0.3.37",
"langfuse": "^3.38.6",
"langfuse-core": "^3.38.6",
"lucide-react": "^0.562.0",
"mammoth": "^1.11.0",
"marked": "^17.0.1",
"mdast-util-to-markdown": "^2.1.2",
"model-bank": "workspace:*",
"motion": "^12.29.0",
"nanoid": "^5.1.6",
"next": "^16.1.5",
"next-mdx-remote": "^6.0.0",
"next-themes": "^0.4.6",
"nextjs-toploader": "^3.9.17",
"node-machine-id": "^1.1.12",
"nodemailer": "^7.0.12",
"numeral": "^2.0.6",
"nuqs": "^2.8.6",
"officeparser": "5.1.1",
"ogl": "^1.0.11",
"oidc-provider": "^9.6.0",
"ollama": "^0.6.3",
"openai": "^4.104.0",
"openapi-fetch": "^0.14.1",
"partial-json": "^0.1.7",
"path-browserify-esm": "^1.0.6",
"pathe": "^2.0.3",
"pdf-parse": "^1.1.4",
"pdfjs-dist": "5.4.530",
"pdfkit": "^0.17.2",
"pg": "^8.17.2",
"plaiceholder": "^3.0.0",
"polished": "^4.3.1",
"posthog-js": "~1.278.0",
"pure-rand": "^7.0.1",
"pwa-install-handler": "^2.6.3",
"query-string": "^9.3.1",
"random-words": "^2.0.1",
"rc-util": "^5.44.4",
"react": "^19.2.3",
"react-confetti": "^6.4.0",
"react-dom": "^19.2.3",
"react-fast-marquee": "^1.6.5",
"react-hotkeys-hook": "^5.2.3",
"react-i18next": "^16.5.3",
"react-lazy-load": "^4.0.1",
"react-markdown": "^10.1.0",
"react-pdf": "^10.3.0",
"react-responsive": "^10.0.1",
"react-rnd": "^10.5.2",
"react-router-dom": "^7.13.0",
"react-scan": "^0.4.3",
"react-virtuoso": "^4.18.1",
"react-wrap-balancer": "^1.1.1",
"remark": "^15.0.1",
"remark-gfm": "^4.0.1",
"remark-html": "^16.0.1",
"remove-markdown": "^0.6.3",
"resend": "6.8.0",
"resolve-accept-language": "^3.1.15",
"rtl-detect": "^1.1.2",
"semver": "^7.7.3",
"sharp": "^0.34.5",
"shiki": "^3.21.0",
"stripe": "^17.7.0",
"superjson": "^2.2.6",
"svix": "^1.84.1",
"swr": "^2.3.8",
"systemjs": "^6.15.1",
"three": "^0.181.2",
"tokenx": "^1.3.0",
"ts-md5": "^2.0.1",
"ua-parser-js": "^1.0.41",
"undici": "^7.19.1",
"unist-builder": "^4.0.0",
"url-join": "^5.0.0",
"use-merge-value": "^1.2.0",
"uuid": "^13.0.0",
"virtua": "^0.48.3",
"word-extractor": "^1.0.4",
"ws": "^8.19.0",
"xast-util-to-xml": "^4.0.0",
"xastscript": "^4.0.0",
"yaml": "^2.8.2",
"zod": "^3.25.76",
"zod-to-json-schema": "^3.25.1",
"zustand": "5.0.4",
"zustand-utils": "^2.1.1"
},
"devDependencies": {
"@commitlint/cli": "^19.8.1",
"@edge-runtime/vm": "^5.0.0",
"@huggingface/tasks": "^0.19.80",
"@inquirer/prompts": "^8.2.0",
"@lobechat/types": "workspace:*",
"@lobehub/i18n-cli": "^1.26.0",
"@lobehub/lint": "2.1.3",
"@lobehub/market-types": "^1.12.3",
"@lobehub/seo-cli": "^1.7.0",
"@peculiar/webcrypto": "^1.5.0",
"@playwright/test": "^1.58.0",
"@prettier/sync": "^0.6.1",
"@semantic-release/exec": "^6.0.3",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
"@testing-library/user-event": "^14.6.1",
"@types/async-retry": "^1.4.9",
"@types/chroma-js": "^3.1.2",
"@types/crypto-js": "^4.2.2",
"@types/debug": "^4.1.12",
"@types/fs-extra": "^11.0.4",
"@types/ip": "^1.1.3",
"@types/json-schema": "^7.0.15",
"@types/node": "^24.10.9",
"@types/nodemailer": "^7.0.5",
"@types/numeral": "^2.0.5",
"@types/oidc-provider": "^9.5.0",
"@types/pdfkit": "^0.17.4",
"@types/pg": "^8.16.0",
"@types/react": "19.2.13",
"@types/react-dom": "^19.2.3",
"@types/rtl-detect": "^1.0.3",
"@types/semver": "^7.7.1",
"@types/systemjs": "^6.15.4",
"@types/three": "^0.181.0",
"@types/ua-parser-js": "^0.7.39",
"@types/unist": "^3.0.3",
"@types/ws": "^8.18.1",
"@types/xast": "^2.0.4",
"@typescript/native-preview": "7.0.0-dev.20260207.1",
"@vitejs/plugin-react": "^5.1.4",
"@vitest/coverage-v8": "^3.2.4",
"ajv": "^8.17.1",
"ajv-keywords": "^5.1.0",
"code-inspector-plugin": "1.3.3",
"commitlint": "^19.8.1",
"consola": "^3.4.2",
"cross-env": "^10.1.0",
"crypto-js": "^4.2.0",
"dbdocs": "^0.16.2",
"dotenv": "^17.2.3",
"dotenv-expand": "^12.0.3",
"dpdm-fast": "^1.0.14",
"drizzle-dbml-generator": "^0.10.0",
"drizzle-kit": "^0.31.8",
"eslint": "10.0.0",
"eslint-plugin-mdx": "^3.6.2",
"fake-indexeddb": "^6.2.5",
"fs-extra": "^11.3.3",
"glob": "^13.0.0",
"happy-dom": "^20.3.7",
"husky": "^9.1.7",
"import-in-the-middle": "^2.0.5",
"just-diff": "^6.0.2",
"knip": "^5.82.1",
"linkedom": "^0.18.12",
"lint-staged": "^16.2.7",
"markdown-table": "^3.0.4",
"mcp-hello-world": "^1.1.2",
"mime": "^4.1.0",
"node-fetch": "^3.3.2",
"node-gyp": "^11.5.0",
"openapi-typescript": "^7.10.1",
"p-map": "^7.0.4",
"prettier": "^3.8.1",
"remark-cli": "^12.0.1",
"remark-frontmatter": "^5.0.0",
"remark-mdx": "^3.1.1",
"remark-parse": "^11.0.0",
"require-in-the-middle": "^8.0.1",
"semantic-release": "^21.1.2",
"stylelint": "^16.12.0",
"tsx": "^4.21.0",
"type-fest": "^5.4.1",
"typescript": "^5.9.3",
"unified": "^11.0.5",
"unist-util-visit": "^5.1.0",
"vite": "^7.3.1",
"vite-plugin-node-polyfills": "^0.25.0",
"vite-plugin-pwa": "^1.2.0",
"vite-tsconfig-paths": "^6.1.1",
"vitest": "^3.2.4"
},
"packageManager": "pnpm@10.20.0",
"publishConfig": {
"access": "public",
"registry": "https://registry.npmjs.org"
},
"pnpm": {
"onlyBuiltDependencies": [
"ffmpeg-static"
],
"overrides": {
"@types/react": "19.2.13",
"better-auth": "1.4.6",
"better-call": "1.1.8",
"drizzle-orm": "^0.45.1"
}
}
}