@lobehub/lobehub 2.0.0-next.353 → 2.0.0-next.355

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/.agents/skills/add-provider-doc/SKILL.md +90 -0
  2. package/.agents/skills/add-setting-env/SKILL.md +106 -0
  3. package/.agents/skills/debug/SKILL.md +66 -0
  4. package/.agents/skills/desktop/SKILL.md +78 -0
  5. package/.agents/skills/desktop/references/feature-implementation.md +99 -0
  6. package/.agents/skills/desktop/references/local-tools.md +133 -0
  7. package/.agents/skills/desktop/references/menu-config.md +103 -0
  8. package/.agents/skills/desktop/references/window-management.md +143 -0
  9. package/.agents/skills/drizzle/SKILL.md +129 -0
  10. package/.agents/skills/drizzle/references/db-migrations.md +50 -0
  11. package/.agents/skills/hotkey/SKILL.md +90 -0
  12. package/{.cursor/rules/i18n.mdc → .agents/skills/i18n/SKILL.md} +14 -23
  13. package/.agents/skills/linear/SKILL.md +51 -0
  14. package/.agents/skills/microcopy/SKILL.md +83 -0
  15. package/.agents/skills/modal/SKILL.md +102 -0
  16. package/{.cursor/rules/project-structure.mdc → .agents/skills/project-overview/SKILL.md} +65 -37
  17. package/.agents/skills/react/SKILL.md +73 -0
  18. package/.agents/skills/react/references/layout-kit.md +100 -0
  19. package/.agents/skills/recent-data/SKILL.md +108 -0
  20. package/.agents/skills/testing/SKILL.md +89 -0
  21. package/.agents/skills/testing/references/agent-runtime-e2e.md +126 -0
  22. package/.agents/skills/testing/references/db-model-test.md +124 -0
  23. package/.agents/skills/testing/references/desktop-controller-test.md +124 -0
  24. package/.agents/skills/testing/references/electron-ipc-test.md +63 -0
  25. package/.agents/skills/testing/references/zustand-store-action-test.md +150 -0
  26. package/.agents/skills/typescript/SKILL.md +52 -0
  27. package/.agents/skills/zustand/SKILL.md +78 -0
  28. package/.agents/skills/zustand/references/action-patterns.md +125 -0
  29. package/.agents/skills/zustand/references/slice-organization.md +125 -0
  30. package/AGENTS.md +42 -55
  31. package/CHANGELOG.md +60 -0
  32. package/CLAUDE.md +57 -46
  33. package/GEMINI.md +47 -39
  34. package/changelog/v1.json +18 -0
  35. package/locales/en-US/plugin.json +3 -0
  36. package/locales/zh-CN/plugin.json +3 -0
  37. package/package.json +1 -1
  38. package/packages/builtin-tool-memory/src/client/Render/SearchUserMemory/index.tsx +3 -11
  39. package/packages/context-engine/src/engine/messages/MessagesEngine.ts +0 -13
  40. package/packages/context-engine/src/engine/messages/__tests__/MessagesEngine.test.ts +0 -25
  41. package/packages/database/src/models/__tests__/topics/topic.create.test.ts +3 -3
  42. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Topic/List/Item/index.tsx +1 -0
  43. package/src/app/[variants]/(main)/agent/features/Conversation/ConversationArea.tsx +4 -0
  44. package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/List/Item/index.tsx +1 -0
  45. package/src/app/[variants]/(main)/home/_layout/Body/Agent/List/AgentItem/index.tsx +1 -1
  46. package/src/app/[variants]/(main)/home/_layout/Body/Agent/List/InboxItem.tsx +19 -29
  47. package/src/app/[variants]/(main)/home/_layout/Body/Agent/List/List.tsx +1 -1
  48. package/src/app/[variants]/(main)/home/_layout/Body/Agent/ModalProvider.tsx +1 -1
  49. package/src/features/FileViewer/Renderer/PDF/index.tsx +2 -3
  50. package/src/features/ShareModal/SharePdf/PdfPreview.tsx +1 -2
  51. package/src/libs/pdfjs/index.tsx +25 -0
  52. package/src/locales/default/plugin.ts +3 -0
  53. package/src/server/modules/Mecha/ContextEngineering/__tests__/serverMessagesEngine.test.ts +0 -25
  54. package/src/services/chat/chat.test.ts +19 -19
  55. package/src/services/chat/index.ts +8 -3
  56. package/src/services/chat/mecha/agentConfigResolver.test.ts +72 -55
  57. package/src/services/chat/mecha/agentConfigResolver.ts +28 -4
  58. package/src/services/chat/mecha/contextEngineering.test.ts +21 -14
  59. package/src/services/chat/mecha/contextEngineering.ts +12 -0
  60. package/src/services/chat/types.ts +7 -1
  61. package/src/store/chat/agents/createAgentExecutors.ts +15 -4
  62. package/src/store/chat/slices/aiChat/actions/conversationLifecycle.ts +1 -0
  63. package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +6 -2
  64. package/src/store/test-coverage.md +5 -5
  65. package/.cursor/rules/add-provider-doc.mdc +0 -183
  66. package/.cursor/rules/add-setting-env.mdc +0 -175
  67. package/.cursor/rules/cursor-rules.mdc +0 -28
  68. package/.cursor/rules/db-migrations.mdc +0 -46
  69. package/.cursor/rules/debug-usage.mdc +0 -86
  70. package/.cursor/rules/desktop-controller-tests.mdc +0 -189
  71. package/.cursor/rules/desktop-feature-implementation.mdc +0 -155
  72. package/.cursor/rules/desktop-local-tools-implement.mdc +0 -81
  73. package/.cursor/rules/desktop-menu-configuration.mdc +0 -209
  74. package/.cursor/rules/desktop-window-management.mdc +0 -301
  75. package/.cursor/rules/drizzle-schema-style-guide.mdc +0 -218
  76. package/.cursor/rules/hotkey.mdc +0 -162
  77. package/.cursor/rules/linear.mdc +0 -53
  78. package/.cursor/rules/microcopy-cn.mdc +0 -158
  79. package/.cursor/rules/microcopy-en.mdc +0 -148
  80. package/.cursor/rules/modal-imperative.mdc +0 -162
  81. package/.cursor/rules/packages/react-layout-kit.mdc +0 -122
  82. package/.cursor/rules/project-introduce.mdc +0 -36
  83. package/.cursor/rules/react.mdc +0 -169
  84. package/.cursor/rules/recent-data-usage.mdc +0 -139
  85. package/.cursor/rules/rules-index.mdc +0 -44
  86. package/.cursor/rules/testing-guide/agent-runtime-e2e.mdc +0 -285
  87. package/.cursor/rules/testing-guide/db-model-test.mdc +0 -455
  88. package/.cursor/rules/testing-guide/electron-ipc-test.mdc +0 -80
  89. package/.cursor/rules/testing-guide/testing-guide.mdc +0 -534
  90. package/.cursor/rules/testing-guide/zustand-store-action-test.mdc +0 -574
  91. package/.cursor/rules/typescript.mdc +0 -55
  92. package/.cursor/rules/zustand-action-patterns.mdc +0 -328
  93. package/.cursor/rules/zustand-slice-organization.mdc +0 -308
  94. package/src/libs/pdfjs/pdf.worker.ts +0 -1
  95. package/src/libs/pdfjs/worker.ts +0 -12
  96. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/AGENTS.md +0 -0
  97. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/SKILL.md +0 -0
  98. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/advanced-event-handler-refs.md +0 -0
  99. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/advanced-use-latest.md +0 -0
  100. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/async-api-routes.md +0 -0
  101. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/async-defer-await.md +0 -0
  102. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/async-dependencies.md +0 -0
  103. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/async-parallel.md +0 -0
  104. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/async-suspense-boundaries.md +0 -0
  105. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/bundle-barrel-imports.md +0 -0
  106. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/bundle-conditional.md +0 -0
  107. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/bundle-defer-third-party.md +0 -0
  108. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/bundle-dynamic-imports.md +0 -0
  109. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/bundle-preload.md +0 -0
  110. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/client-event-listeners.md +0 -0
  111. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/client-localstorage-schema.md +0 -0
  112. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/client-passive-event-listeners.md +0 -0
  113. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/client-swr-dedup.md +0 -0
  114. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/js-batch-dom-css.md +0 -0
  115. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/js-cache-function-results.md +0 -0
  116. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/js-cache-property-access.md +0 -0
  117. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/js-cache-storage.md +0 -0
  118. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/js-combine-iterations.md +0 -0
  119. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/js-early-exit.md +0 -0
  120. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/js-hoist-regexp.md +0 -0
  121. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/js-index-maps.md +0 -0
  122. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/js-length-check-first.md +0 -0
  123. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/js-min-max-loop.md +0 -0
  124. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/js-set-map-lookups.md +0 -0
  125. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/js-tosorted-immutable.md +0 -0
  126. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/rendering-activity.md +0 -0
  127. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/rendering-animate-svg-wrapper.md +0 -0
  128. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/rendering-conditional-render.md +0 -0
  129. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/rendering-content-visibility.md +0 -0
  130. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/rendering-hoist-jsx.md +0 -0
  131. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/rendering-hydration-no-flicker.md +0 -0
  132. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/rendering-svg-precision.md +0 -0
  133. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/rerender-defer-reads.md +0 -0
  134. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/rerender-dependencies.md +0 -0
  135. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/rerender-derived-state.md +0 -0
  136. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/rerender-functional-setstate.md +0 -0
  137. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/rerender-lazy-state-init.md +0 -0
  138. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/rerender-memo.md +0 -0
  139. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/rerender-transitions.md +0 -0
  140. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/server-after-nonblocking.md +0 -0
  141. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/server-cache-lru.md +0 -0
  142. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/server-cache-react.md +0 -0
  143. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/server-parallel-fetching.md +0 -0
  144. /package/.agents/{vercel-react-best-practices → skills/vercel-react-best-practices}/rules/server-serialization.md +0 -0
@@ -0,0 +1,102 @@
1
+ ---
2
+ name: modal
3
+ description: Modal imperative API guide. Use when creating modal dialogs using createModal from @lobehub/ui. Triggers on modal component implementation or dialog creation tasks.
4
+ user-invocable: false
5
+ ---
6
+
7
+ # Modal Imperative API Guide
8
+
9
+ Use `createModal` from `@lobehub/ui` for imperative modal dialogs.
10
+
11
+ ## Why Imperative?
12
+
13
+ | Mode | Characteristics | Recommended |
14
+ |------|-----------------|-------------|
15
+ | Declarative | Need `open` state, render `<Modal />` | ❌ |
16
+ | Imperative | Call function directly, no state | ✅ |
17
+
18
+ ## File Structure
19
+
20
+ ```
21
+ features/
22
+ └── MyFeatureModal/
23
+ ├── index.tsx # Export createXxxModal
24
+ └── MyFeatureContent.tsx # Modal content
25
+ ```
26
+
27
+ ## Implementation
28
+
29
+ ### 1. Content Component (`MyFeatureContent.tsx`)
30
+
31
+ ```tsx
32
+ 'use client';
33
+
34
+ import { useModalContext } from '@lobehub/ui';
35
+ import { useTranslation } from 'react-i18next';
36
+
37
+ export const MyFeatureContent = () => {
38
+ const { t } = useTranslation('namespace');
39
+ const { close } = useModalContext(); // Optional: get close method
40
+
41
+ return <div>{/* Modal content */}</div>;
42
+ };
43
+ ```
44
+
45
+ ### 2. Export createModal (`index.tsx`)
46
+
47
+ ```tsx
48
+ 'use client';
49
+
50
+ import { createModal } from '@lobehub/ui';
51
+ import { t } from 'i18next'; // Note: use i18next, not react-i18next
52
+
53
+ import { MyFeatureContent } from './MyFeatureContent';
54
+
55
+ export const createMyFeatureModal = () =>
56
+ createModal({
57
+ allowFullscreen: true,
58
+ children: <MyFeatureContent />,
59
+ destroyOnHidden: false,
60
+ footer: null,
61
+ styles: { body: { overflow: 'hidden', padding: 0 } },
62
+ title: t('myFeature.title', { ns: 'setting' }),
63
+ width: 'min(80%, 800px)',
64
+ });
65
+ ```
66
+
67
+ ### 3. Usage
68
+
69
+ ```tsx
70
+ import { createMyFeatureModal } from '@/features/MyFeatureModal';
71
+
72
+ const handleOpen = useCallback(() => {
73
+ createMyFeatureModal();
74
+ }, []);
75
+
76
+ return <Button onClick={handleOpen}>Open</Button>;
77
+ ```
78
+
79
+ ## i18n Handling
80
+
81
+ - **Content component**: `useTranslation` hook (React context)
82
+ - **createModal params**: `import { t } from 'i18next'` (non-hook, imperative)
83
+
84
+ ## useModalContext Hook
85
+
86
+ ```tsx
87
+ const { close, setCanDismissByClickOutside } = useModalContext();
88
+ ```
89
+
90
+ ## Common Config
91
+
92
+ | Property | Type | Description |
93
+ |----------|------|-------------|
94
+ | `allowFullscreen` | `boolean` | Allow fullscreen mode |
95
+ | `destroyOnHidden` | `boolean` | Destroy content on close |
96
+ | `footer` | `ReactNode \| null` | Footer content |
97
+ | `width` | `string \| number` | Modal width |
98
+
99
+ ## Examples
100
+
101
+ - `src/features/SkillStore/index.tsx`
102
+ - `src/features/LibraryModal/CreateNew/index.tsx`
@@ -1,19 +1,50 @@
1
1
  ---
2
- alwaysApply: true
2
+ name: project-overview
3
+ description: Complete project architecture and structure guide. Use when exploring the codebase, understanding project organization, finding files, or needing comprehensive architectural context. Triggers on architecture questions, directory navigation, or project overview needs.
3
4
  ---
4
5
 
5
- # LobeChat Project Structure
6
+ # LobeChat Project Overview
6
7
 
7
- ## Complete Project Structure
8
+ ## Project Description
9
+
10
+ Open-source, modern-design AI Agent Workspace: **LobeHub** (previously LobeChat).
11
+
12
+ **Supported platforms:**
13
+ - Web desktop/mobile
14
+ - Desktop (Electron)
15
+ - Mobile app (React Native) - coming soon
16
+
17
+ **Logo emoji:** 🤯
18
+
19
+ ## Complete Tech Stack
8
20
 
9
- This project uses common monorepo structure. The workspace packages name use `@lobechat/` namespace.
21
+ | Category | Technology |
22
+ |----------|------------|
23
+ | Framework | Next.js 16 + React 19 |
24
+ | Routing | SPA inside Next.js with `react-router-dom` |
25
+ | Language | TypeScript |
26
+ | UI Components | `@lobehub/ui`, antd |
27
+ | CSS-in-JS | antd-style |
28
+ | Icons | lucide-react, `@ant-design/icons` |
29
+ | i18n | react-i18next |
30
+ | State | zustand |
31
+ | URL Params | nuqs |
32
+ | Data Fetching | SWR |
33
+ | React Hooks | aHooks |
34
+ | Date/Time | dayjs |
35
+ | Utilities | es-toolkit |
36
+ | API | TRPC (type-safe) |
37
+ | Database | Neon PostgreSQL + Drizzle ORM |
38
+ | Testing | Vitest |
10
39
 
11
- **note**: some not very important files are not shown for simplicity.
40
+ ## Complete Project Structure
41
+
42
+ Monorepo using `@lobechat/` namespace for workspace packages.
12
43
 
13
- ```plaintext
44
+ ```
14
45
  lobe-chat/
15
46
  ├── apps/
16
- │ └── desktop/
47
+ │ └── desktop/ # Electron desktop app
17
48
  ├── docs/
18
49
  │ ├── changelog/
19
50
  │ ├── development/
@@ -23,10 +54,10 @@ lobe-chat/
23
54
  │ ├── en-US/
24
55
  │ └── zh-CN/
25
56
  ├── packages/
26
- │ ├── agent-runtime/
57
+ │ ├── agent-runtime/ # Agent runtime
27
58
  │ ├── builtin-agents/
28
- │ ├── builtin-tool-*/ # builtin tool packages
29
- │ ├── business/ # cloud-only business logic packages
59
+ │ ├── builtin-tool-*/ # Builtin tool packages
60
+ │ ├── business/ # Cloud-only business logic
30
61
  │ │ ├── config/
31
62
  │ │ ├── const/
32
63
  │ │ └── model-runtime/
@@ -59,8 +90,6 @@ lobe-chat/
59
90
  │ ├── types/
60
91
  │ ├── utils/
61
92
  │ └── web-crawler/
62
- ├── public/
63
- ├── scripts/
64
93
  ├── src/
65
94
  │ ├── app/
66
95
  │ │ ├── (backend)/
@@ -78,7 +107,7 @@ lobe-chat/
78
107
  │ │ │ ├── onboarding/
79
108
  │ │ │ └── router/
80
109
  │ │ └── desktop/
81
- │ ├── business/ # cloud-only business logic (client/server)
110
+ │ ├── business/ # Cloud-only (client/server)
82
111
  │ │ ├── client/
83
112
  │ │ ├── locales/
84
113
  │ │ └── server/
@@ -117,33 +146,32 @@ lobe-chat/
117
146
  │ ├── tools/
118
147
  │ ├── types/
119
148
  │ └── utils/
120
- └── package.json
149
+ └── e2e/ # E2E tests (Cucumber + Playwright)
121
150
  ```
122
151
 
123
152
  ## Architecture Map
124
153
 
125
- - UI Components: `src/components`, `src/features`
126
- - Global providers: `src/layout`
127
- - Zustand stores: `src/store`
128
- - Client Services: `src/services/`
129
- - API Routers:
130
- - `src/app/(backend)/webapi` (REST)
131
- - `src/server/routers/{async|lambda|mobile|tools}` (tRPC)
132
- - Server:
133
- - Services (can access serverDB): `src/server/services`
134
- - Modules (can't access db): `src/server/modules`
135
- - Feature Flags: `src/server/featureFlags`
136
- - Global Config: `src/server/globalConfig`
137
- - Database:
138
- - Schema (Drizzle): `packages/database/src/schemas`
139
- - Model (CRUD): `packages/database/src/models`
140
- - Repository (bff-queries): `packages/database/src/repositories`
141
- - Third-party Integrations: `src/libs` — analytics, oidc etc.
142
- - Builtin Tools: `src/tools`, `packages/builtin-tool-*`
143
- - Business (cloud-only): Code specific to LobeHub cloud service, only expose empty interfaces for opens-source version.
144
- - `src/business/*`
145
- - `packages/business/*`
154
+ | Layer | Location |
155
+ |-------|----------|
156
+ | UI Components | `src/components`, `src/features` |
157
+ | Global Providers | `src/layout` |
158
+ | Zustand Stores | `src/store` |
159
+ | Client Services | `src/services/` |
160
+ | REST API | `src/app/(backend)/webapi` |
161
+ | tRPC Routers | `src/server/routers/{async\|lambda\|mobile\|tools}` |
162
+ | Server Services | `src/server/services` (can access DB) |
163
+ | Server Modules | `src/server/modules` (no DB access) |
164
+ | Feature Flags | `src/server/featureFlags` |
165
+ | Global Config | `src/server/globalConfig` |
166
+ | DB Schema | `packages/database/src/schemas` |
167
+ | DB Model | `packages/database/src/models` |
168
+ | DB Repository | `packages/database/src/repositories` |
169
+ | Third-party | `src/libs` (analytics, oidc, etc.) |
170
+ | Builtin Tools | `src/tools`, `packages/builtin-tool-*` |
171
+ | Cloud-only | `src/business/*`, `packages/business/*` |
146
172
 
147
- ## Data Flow Architecture
173
+ ## Data Flow
148
174
 
149
- React UI → Store Actions → Client Service → TRPC Lambda → Server Services -> DB Model → PostgreSQL (Remote)
175
+ ```
176
+ React UI → Store Actions → Client Service → TRPC Lambda → Server Services → DB Model → PostgreSQL
177
+ ```
@@ -0,0 +1,73 @@
1
+ ---
2
+ name: react
3
+ description: React component development guide. Use when working with React components (.tsx files), creating UI, using @lobehub/ui components, implementing routing, or building frontend features. Triggers on React component creation, modification, layout implementation, or navigation tasks.
4
+ ---
5
+
6
+ # React Component Writing Guide
7
+
8
+ - Use antd-style for complex styles; for simple cases, use inline `style` attribute
9
+ - Use `Flexbox` and `Center` from `@lobehub/ui` for layouts (see `references/layout-kit.md`)
10
+ - Component priority: `src/components` > installed packages > `@lobehub/ui` > antd
11
+ - Use selectors to access zustand store data
12
+
13
+ ## @lobehub/ui Components
14
+
15
+ If unsure about component usage, search existing code in this project. Most components extend antd with additional props.
16
+
17
+ Reference: `node_modules/@lobehub/ui/es/index.mjs` for all available components.
18
+
19
+ **Common Components:**
20
+ - General: ActionIcon, ActionIconGroup, Block, Button, Icon
21
+ - Data Display: Avatar, Collapse, Empty, Highlighter, Markdown, Tag, Tooltip
22
+ - Data Entry: CodeEditor, CopyButton, EditableText, Form, FormModal, Input, SearchBar, Select
23
+ - Feedback: Alert, Drawer, Modal
24
+ - Layout: Center, DraggablePanel, Flexbox, Grid, Header, MaskShadow
25
+ - Navigation: Burger, Dropdown, Menu, SideNav, Tabs
26
+
27
+ ## Routing Architecture
28
+
29
+ Hybrid routing: Next.js App Router (static pages) + React Router DOM (main SPA).
30
+
31
+ | Route Type | Use Case | Implementation |
32
+ |------------|----------|----------------|
33
+ | Next.js App Router | Auth pages (login, signup, oauth) | `src/app/[variants]/(auth)/` |
34
+ | React Router DOM | Main SPA (chat, settings) | `desktopRouter.config.tsx` |
35
+
36
+ ### Key Files
37
+ - Entry: `src/app/[variants]/page.tsx`
38
+ - Desktop router: `src/app/[variants]/router/desktopRouter.config.tsx`
39
+ - Mobile router: `src/app/[variants]/(mobile)/router/mobileRouter.config.tsx`
40
+ - Router utilities: `src/utils/router.tsx`
41
+
42
+ ### Router Utilities
43
+
44
+ ```tsx
45
+ import { dynamicElement, redirectElement, ErrorBoundary } from '@/utils/router';
46
+
47
+ element: dynamicElement(() => import('./chat'), 'Desktop > Chat');
48
+ element: redirectElement('/settings/profile');
49
+ errorElement: <ErrorBoundary resetPath="/chat" />;
50
+ ```
51
+
52
+ ### Navigation
53
+
54
+ **Important**: For SPA pages, use `Link` from `react-router-dom`, NOT `next/link`.
55
+
56
+ ```tsx
57
+ // ❌ Wrong
58
+ import Link from 'next/link';
59
+ <Link href="/">Home</Link>
60
+
61
+ // ✅ Correct
62
+ import { Link } from 'react-router-dom';
63
+ <Link to="/">Home</Link>
64
+
65
+ // In components
66
+ import { useNavigate } from 'react-router-dom';
67
+ const navigate = useNavigate();
68
+ navigate('/chat');
69
+
70
+ // From stores
71
+ const navigate = useGlobalStore.getState().navigate;
72
+ navigate?.('/settings');
73
+ ```
@@ -0,0 +1,100 @@
1
+ # Flexbox Layout Components Guide
2
+
3
+ `@lobehub/ui` provides `Flexbox` and `Center` components for creating flexible layouts.
4
+
5
+ ## Flexbox Component
6
+
7
+ Flexbox is the most commonly used layout component, similar to CSS `display: flex`.
8
+
9
+ ### Basic Usage
10
+
11
+ ```jsx
12
+ import { Flexbox } from '@lobehub/ui';
13
+
14
+ // Default vertical layout
15
+ <Flexbox>
16
+ <div>Child 1</div>
17
+ <div>Child 2</div>
18
+ </Flexbox>
19
+
20
+ // Horizontal layout
21
+ <Flexbox horizontal>
22
+ <div>Left</div>
23
+ <div>Right</div>
24
+ </Flexbox>
25
+ ```
26
+
27
+ ### Common Props
28
+
29
+ - `horizontal`: Boolean, set horizontal direction layout
30
+ - `flex`: Number or string, controls flex property
31
+ - `gap`: Number, spacing between children
32
+ - `align`: Alignment like 'center', 'flex-start', etc.
33
+ - `justify`: Main axis alignment like 'space-between', 'center', etc.
34
+ - `padding`: Padding value
35
+ - `paddingInline`: Horizontal padding
36
+ - `paddingBlock`: Vertical padding
37
+ - `width/height`: Set dimensions, typically '100%' or specific pixels
38
+ - `style`: Custom style object
39
+
40
+ ### Layout Example
41
+
42
+ ```jsx
43
+ // Classic three-column layout
44
+ <Flexbox horizontal height={'100%'} width={'100%'}>
45
+ {/* Left sidebar */}
46
+ <Flexbox
47
+ width={260}
48
+ style={{
49
+ borderRight: `1px solid ${theme.colorBorderSecondary}`,
50
+ height: '100%',
51
+ overflowY: 'auto',
52
+ }}
53
+ >
54
+ <SidebarContent />
55
+ </Flexbox>
56
+
57
+ {/* Center content */}
58
+ <Flexbox flex={1} style={{ height: '100%' }}>
59
+ <Flexbox flex={1} padding={24} style={{ overflowY: 'auto' }}>
60
+ <MainContent />
61
+ </Flexbox>
62
+
63
+ {/* Footer */}
64
+ <Flexbox
65
+ style={{
66
+ borderTop: `1px solid ${theme.colorBorderSecondary}`,
67
+ padding: '16px 24px',
68
+ }}
69
+ >
70
+ <Footer />
71
+ </Flexbox>
72
+ </Flexbox>
73
+ </Flexbox>
74
+ ```
75
+
76
+ ## Center Component
77
+
78
+ Center wraps Flexbox with horizontal and vertical centering.
79
+
80
+ ```jsx
81
+ import { Center } from '@lobehub/ui';
82
+
83
+ <Center width={'100%'} height={'100%'}>
84
+ <Content />
85
+ </Center>
86
+
87
+ // Icon centered
88
+ <Center className={styles.icon} flex={'none'} height={40} width={40}>
89
+ <Icon icon={icon} size={24} />
90
+ </Center>
91
+ ```
92
+
93
+ ## Best Practices
94
+
95
+ - Use `flex={1}` to fill available space
96
+ - Use `gap` instead of margin for spacing
97
+ - Nest Flexbox for complex layouts
98
+ - Set `overflow: 'auto'` for scrollable content
99
+ - Use `horizontal` for horizontal layout (default is vertical)
100
+ - Combine with `useTheme` hook for theme-responsive layouts
@@ -0,0 +1,108 @@
1
+ ---
2
+ name: recent-data
3
+ description: Guide for using Recent Data (topics, resources, pages). Use when working with recently accessed items, implementing recent lists, or accessing session store recent data. Triggers on recent data usage or implementation tasks.
4
+ user-invocable: false
5
+ ---
6
+
7
+ # Recent Data Usage Guide
8
+
9
+ Recent data (recentTopics, recentResources, recentPages) is stored in session store.
10
+
11
+ ## Initialization
12
+
13
+ In app top-level (e.g., `RecentHydration.tsx`):
14
+
15
+ ```tsx
16
+ import { useInitRecentTopic } from '@/hooks/useInitRecentTopic';
17
+ import { useInitRecentResource } from '@/hooks/useInitRecentResource';
18
+ import { useInitRecentPage } from '@/hooks/useInitRecentPage';
19
+
20
+ const App = () => {
21
+ useInitRecentTopic();
22
+ useInitRecentResource();
23
+ useInitRecentPage();
24
+ return <YourComponents />;
25
+ };
26
+ ```
27
+
28
+ ## Usage
29
+
30
+ ### Method 1: Read from Store (Recommended)
31
+
32
+ ```tsx
33
+ import { useSessionStore } from '@/store/session';
34
+ import { recentSelectors } from '@/store/session/selectors';
35
+
36
+ const Component = () => {
37
+ const recentTopics = useSessionStore(recentSelectors.recentTopics);
38
+ const isInit = useSessionStore(recentSelectors.isRecentTopicsInit);
39
+
40
+ if (!isInit) return <div>Loading...</div>;
41
+
42
+ return (
43
+ <div>
44
+ {recentTopics.map((topic) => (
45
+ <div key={topic.id}>{topic.title}</div>
46
+ ))}
47
+ </div>
48
+ );
49
+ };
50
+ ```
51
+
52
+ ### Method 2: Use Hook Return (Single component)
53
+
54
+ ```tsx
55
+ const { data: recentTopics, isLoading } = useInitRecentTopic();
56
+ ```
57
+
58
+ ## Available Selectors
59
+
60
+ ### Recent Topics
61
+
62
+ ```tsx
63
+ const recentTopics = useSessionStore(recentSelectors.recentTopics);
64
+ // Type: RecentTopic[]
65
+
66
+ const isInit = useSessionStore(recentSelectors.isRecentTopicsInit);
67
+ // Type: boolean
68
+ ```
69
+
70
+ **RecentTopic type:**
71
+ ```typescript
72
+ interface RecentTopic {
73
+ agent: { avatar: string | null; backgroundColor: string | null; id: string; title: string | null } | null;
74
+ id: string;
75
+ title: string | null;
76
+ updatedAt: Date;
77
+ }
78
+ ```
79
+
80
+ ### Recent Resources
81
+
82
+ ```tsx
83
+ const recentResources = useSessionStore(recentSelectors.recentResources);
84
+ // Type: FileListItem[]
85
+
86
+ const isInit = useSessionStore(recentSelectors.isRecentResourcesInit);
87
+ ```
88
+
89
+ ### Recent Pages
90
+
91
+ ```tsx
92
+ const recentPages = useSessionStore(recentSelectors.recentPages);
93
+ const isInit = useSessionStore(recentSelectors.isRecentPagesInit);
94
+ ```
95
+
96
+ ## Features
97
+
98
+ 1. **Auto login detection**: Only loads when user is logged in
99
+ 2. **Data caching**: Stored in store, no repeated loading
100
+ 3. **Auto refresh**: SWR refreshes on focus (5-minute interval)
101
+ 4. **Type safe**: Full TypeScript types
102
+
103
+ ## Best Practices
104
+
105
+ 1. Initialize all recent data at app top-level
106
+ 2. Use selectors to read from store
107
+ 3. For multi-component use, prefer Method 1
108
+ 4. Use selectors for render optimization
@@ -0,0 +1,89 @@
1
+ ---
2
+ name: testing
3
+ description: Testing guide using Vitest. Use when writing tests (.test.ts, .test.tsx), fixing failing tests, improving test coverage, or debugging test issues. Triggers on test creation, test debugging, mock setup, or test-related questions.
4
+ ---
5
+
6
+ # LobeChat Testing Guide
7
+
8
+ ## Quick Reference
9
+
10
+ **Commands:**
11
+ ```bash
12
+ # Run specific test file
13
+ bunx vitest run --silent='passed-only' '[file-path]'
14
+
15
+ # Database package (client)
16
+ cd packages/database && bunx vitest run --silent='passed-only' '[file]'
17
+
18
+ # Database package (server)
19
+ cd packages/database && TEST_SERVER_DB=1 bunx vitest run --silent='passed-only' '[file]'
20
+ ```
21
+
22
+ **Never run** `bun run test` - it runs all 3000+ tests (~10 minutes).
23
+
24
+ ## Test Categories
25
+
26
+ | Category | Location | Config |
27
+ |----------|----------|--------|
28
+ | Webapp | `src/**/*.test.ts(x)` | `vitest.config.ts` |
29
+ | Packages | `packages/*/**/*.test.ts` | `packages/*/vitest.config.ts` |
30
+ | Desktop | `apps/desktop/**/*.test.ts` | `apps/desktop/vitest.config.ts` |
31
+
32
+ ## Core Principles
33
+
34
+ 1. **Prefer `vi.spyOn` over `vi.mock`** - More targeted, easier to maintain
35
+ 2. **Tests must pass type check** - Run `bun run type-check` after writing tests
36
+ 3. **After 1-2 failed fix attempts, stop and ask for help**
37
+ 4. **Test behavior, not implementation details**
38
+
39
+ ## Basic Test Structure
40
+
41
+ ```typescript
42
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
43
+
44
+ beforeEach(() => {
45
+ vi.clearAllMocks();
46
+ });
47
+
48
+ afterEach(() => {
49
+ vi.restoreAllMocks();
50
+ });
51
+
52
+ describe('ModuleName', () => {
53
+ describe('functionName', () => {
54
+ it('should handle normal case', () => {
55
+ // Arrange → Act → Assert
56
+ });
57
+ });
58
+ });
59
+ ```
60
+
61
+ ## Mock Patterns
62
+
63
+ ```typescript
64
+ // ✅ Spy on direct dependencies
65
+ vi.spyOn(messageService, 'createMessage').mockResolvedValue('id');
66
+
67
+ // ✅ Use vi.stubGlobal for browser APIs
68
+ vi.stubGlobal('Image', mockImage);
69
+ vi.spyOn(URL, 'createObjectURL').mockReturnValue('blob:mock');
70
+
71
+ // ❌ Avoid mocking entire modules globally
72
+ vi.mock('@/services/chat'); // Too broad
73
+ ```
74
+
75
+ ## Detailed Guides
76
+
77
+ See `references/` for specific testing scenarios:
78
+ - **Database Model testing**: `references/db-model-test.md`
79
+ - **Electron IPC testing**: `references/electron-ipc-test.md`
80
+ - **Zustand Store Action testing**: `references/zustand-store-action-test.md`
81
+ - **Agent Runtime E2E testing**: `references/agent-runtime-e2e.md`
82
+ - **Desktop Controller testing**: `references/desktop-controller-test.md`
83
+
84
+ ## Common Issues
85
+
86
+ 1. **Module pollution**: Use `vi.resetModules()` when tests fail mysteriously
87
+ 2. **Mock not working**: Check setup position and use `vi.clearAllMocks()` in beforeEach
88
+ 3. **Test data pollution**: Clean database state in beforeEach/afterEach
89
+ 4. **Async issues**: Wrap state changes in `act()` for React hooks