@lobehub/chat 1.133.0 → 1.133.2
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.
- package/.cursor/rules/project-introduce.mdc +19 -25
- package/.cursor/rules/project-structure.mdc +102 -221
- package/.cursor/rules/{rules-attach.mdc → rules-index.mdc} +2 -11
- package/.cursor/rules/typescript.mdc +3 -53
- package/.vscode/settings.json +2 -1
- package/AGENTS.md +33 -54
- package/CHANGELOG.md +50 -0
- package/CLAUDE.md +1 -26
- package/changelog/v1.json +18 -0
- package/locales/ar/chat.json +5 -0
- package/locales/ar/models.json +7 -1
- package/locales/ar/tool.json +7 -0
- package/locales/bg-BG/chat.json +5 -0
- package/locales/bg-BG/models.json +6 -0
- package/locales/bg-BG/tool.json +7 -0
- package/locales/de-DE/chat.json +5 -0
- package/locales/de-DE/models.json +6 -0
- package/locales/de-DE/tool.json +7 -0
- package/locales/en-US/chat.json +5 -0
- package/locales/en-US/models.json +6 -0
- package/locales/en-US/tool.json +7 -0
- package/locales/es-ES/chat.json +5 -0
- package/locales/es-ES/models.json +6 -0
- package/locales/es-ES/tool.json +8 -1
- package/locales/fa-IR/chat.json +5 -0
- package/locales/fa-IR/models.json +7 -1
- package/locales/fa-IR/tool.json +7 -0
- package/locales/fr-FR/chat.json +5 -0
- package/locales/fr-FR/models.json +7 -1
- package/locales/fr-FR/tool.json +7 -0
- package/locales/it-IT/chat.json +5 -0
- package/locales/it-IT/models.json +6 -0
- package/locales/it-IT/tool.json +7 -0
- package/locales/ja-JP/chat.json +5 -0
- package/locales/ja-JP/models.json +6 -0
- package/locales/ja-JP/tool.json +7 -0
- package/locales/ko-KR/chat.json +5 -0
- package/locales/ko-KR/models.json +6 -0
- package/locales/ko-KR/tool.json +7 -0
- package/locales/nl-NL/chat.json +5 -0
- package/locales/nl-NL/models.json +6 -0
- package/locales/nl-NL/tool.json +7 -0
- package/locales/pl-PL/chat.json +5 -0
- package/locales/pl-PL/models.json +6 -0
- package/locales/pl-PL/tool.json +7 -0
- package/locales/pt-BR/chat.json +5 -0
- package/locales/pt-BR/models.json +6 -0
- package/locales/pt-BR/tool.json +7 -0
- package/locales/ru-RU/chat.json +5 -0
- package/locales/ru-RU/models.json +6 -0
- package/locales/ru-RU/tool.json +8 -1
- package/locales/tr-TR/chat.json +5 -0
- package/locales/tr-TR/models.json +7 -1
- package/locales/tr-TR/tool.json +7 -0
- package/locales/vi-VN/chat.json +5 -0
- package/locales/vi-VN/models.json +6 -0
- package/locales/vi-VN/tool.json +7 -0
- package/locales/zh-CN/chat.json +5 -0
- package/locales/zh-CN/models.json +6 -0
- package/locales/zh-TW/chat.json +5 -0
- package/locales/zh-TW/models.json +6 -0
- package/locales/zh-TW/tool.json +7 -0
- package/package.json +2 -2
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/default.tsx +2 -0
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatMinimap/index.tsx +335 -0
- package/src/app/[variants]/(main)/chat/(workspace)/_layout/Desktop/TopicPanel.tsx +4 -0
- package/src/features/Conversation/components/ChatItem/index.tsx +56 -2
- package/src/features/Conversation/components/VirtualizedList/VirtuosoContext.ts +88 -0
- package/src/features/Conversation/components/VirtualizedList/index.tsx +15 -1
- package/src/locales/default/chat.ts +5 -0
- package/.cursor/rules/backend-architecture.mdc +0 -176
- package/.cursor/rules/code-review.mdc +0 -58
- package/.cursor/rules/cursor-ux.mdc +0 -32
- package/.cursor/rules/define-database-model.mdc +0 -8
- package/.cursor/rules/system-role.mdc +0 -31
|
@@ -4,41 +4,35 @@ alwaysApply: true
|
|
|
4
4
|
|
|
5
5
|
## Project Description
|
|
6
6
|
|
|
7
|
-
You are developing an open-source, modern-design AI chat framework: lobe
|
|
7
|
+
You are developing an open-source, modern-design AI chat framework: lobehub(previous lobe-chat).
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
support platforms:
|
|
10
|
+
|
|
11
|
+
- web desktop/mobile
|
|
12
|
+
- desktop(electron)
|
|
13
|
+
- mobile app(react native). coming soon
|
|
14
|
+
|
|
15
|
+
logo emoji: 🤯
|
|
10
16
|
|
|
11
17
|
## Project Technologies Stack
|
|
12
18
|
|
|
13
19
|
read [package.json](mdc:package.json) to know all npm packages you can use.
|
|
14
20
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
- react 19, using hooks, functional components, react server components
|
|
20
|
-
- TypeScript programming language
|
|
21
|
-
- antd, `@lobehub/ui` for component framework
|
|
21
|
+
- Next.js 15
|
|
22
|
+
- react 19
|
|
23
|
+
- TypeScript
|
|
24
|
+
- `@lobehub/ui`, antd for component framework
|
|
22
25
|
- antd-style for css-in-js framework
|
|
23
|
-
- react-layout-kit for flex layout
|
|
24
|
-
- react-i18next for i18n
|
|
25
26
|
- lucide-react, `@ant-design/icons` for icons
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
- zustand for
|
|
29
|
-
- nuqs for
|
|
30
|
-
- SWR for
|
|
27
|
+
- react-layout-kit for flex layout component
|
|
28
|
+
- react-i18next for i18n
|
|
29
|
+
- zustand for state management
|
|
30
|
+
- nuqs for search params management
|
|
31
|
+
- SWR for data fetch
|
|
31
32
|
- aHooks for react hooks library
|
|
32
|
-
- dayjs for
|
|
33
|
+
- dayjs for time library
|
|
33
34
|
- lodash-es for utility library
|
|
34
|
-
- fast-deep-equal for deep comparison of JavaScript objects
|
|
35
|
-
- zod for data validation
|
|
36
35
|
- TRPC for type safe backend
|
|
37
36
|
- PGLite for client DB and PostgreSQL for backend DB
|
|
38
37
|
- Drizzle ORM
|
|
39
|
-
- Vitest for testing
|
|
40
|
-
- Prettier for code formatting
|
|
41
|
-
- ESLint for code linting
|
|
42
|
-
- Cursor AI for code editing and AI coding assistance
|
|
43
|
-
|
|
44
|
-
Note: All tools and libraries used are the latest versions. The application only needs to be compatible with the latest browsers;
|
|
38
|
+
- Vitest for testing
|
|
@@ -5,235 +5,116 @@ alwaysApply: false
|
|
|
5
5
|
|
|
6
6
|
# LobeChat Project Structure
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
note: some not very important files are not shown for simplicity.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## Complete Project Structure
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
lobe-chat/
|
|
14
|
-
├── apps/ # Applications directory
|
|
15
|
-
│ └── desktop/ # Electron desktop application
|
|
16
|
-
│ ├── src/ # Desktop app source code
|
|
17
|
-
│ └── resources/ # Desktop app resources
|
|
18
|
-
├── docs/ # Project documentation
|
|
19
|
-
│ ├── development/ # Development docs
|
|
20
|
-
│ ├── self-hosting/ # Self-hosting docs
|
|
21
|
-
│ └── usage/ # Usage guides
|
|
22
|
-
├── locales/ # Internationalization files (multiple locales)
|
|
23
|
-
│ ├── en-US/ # English (example)
|
|
24
|
-
│ └── zh-CN/ # Simplified Chinese (example)
|
|
25
|
-
├── packages/ # Monorepo packages directory
|
|
26
|
-
│ ├── const/ # Constants definition package
|
|
27
|
-
│ ├── database/ # Database related package
|
|
28
|
-
│ ├── electron-client-ipc/ # Electron renderer ↔ main IPC client
|
|
29
|
-
│ ├── electron-server-ipc/ # Electron main process IPC server
|
|
30
|
-
│ ├── model-bank/ # Built-in model presets/catalog exports
|
|
31
|
-
│ ├── model-runtime/ # AI model runtime package
|
|
32
|
-
│ ├── types/ # TypeScript type definitions
|
|
33
|
-
│ ├── utils/ # Utility functions package
|
|
34
|
-
│ ├── file-loaders/ # File processing packages
|
|
35
|
-
│ ├── prompts/ # AI prompt management
|
|
36
|
-
│ └── web-crawler/ # Web crawling functionality
|
|
37
|
-
├── public/ # Static assets
|
|
38
|
-
│ ├── icons/ # Application icons
|
|
39
|
-
│ ├── images/ # Image resources
|
|
40
|
-
│ └── screenshots/ # Application screenshots
|
|
41
|
-
├── scripts/ # Build and tool scripts
|
|
42
|
-
├── src/ # Main application source code (see below)
|
|
43
|
-
├── .cursor/ # Cursor AI configuration
|
|
44
|
-
├── docker-compose/ # Docker configuration
|
|
45
|
-
├── package.json # Project dependencies
|
|
46
|
-
├── pnpm-workspace.yaml # pnpm monorepo configuration
|
|
47
|
-
├── next.config.ts # Next.js configuration
|
|
48
|
-
├── drizzle.config.ts # Drizzle ORM configuration
|
|
49
|
-
└── tsconfig.json # TypeScript configuration
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## Core Source Directory (`src/`)
|
|
12
|
+
this project use common monorepo structure. The workspace packages name use `@lobechat/` namespace.
|
|
53
13
|
|
|
54
14
|
```plaintext
|
|
55
|
-
|
|
56
|
-
├──
|
|
57
|
-
│
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
│
|
|
61
|
-
│
|
|
62
|
-
|
|
63
|
-
│
|
|
64
|
-
│
|
|
65
|
-
│
|
|
66
|
-
│ │
|
|
67
|
-
│ │ │ ├──
|
|
68
|
-
│ │ │
|
|
69
|
-
│ │ └──
|
|
70
|
-
│
|
|
71
|
-
│
|
|
72
|
-
│ │
|
|
73
|
-
│ │ ├──
|
|
74
|
-
│ │
|
|
75
|
-
│
|
|
76
|
-
│
|
|
77
|
-
│ │
|
|
78
|
-
│ │
|
|
79
|
-
│
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
│
|
|
84
|
-
│ │
|
|
85
|
-
│ │
|
|
86
|
-
│
|
|
87
|
-
|
|
88
|
-
│ ├──
|
|
89
|
-
│ ├──
|
|
90
|
-
│
|
|
91
|
-
|
|
92
|
-
│ ├──
|
|
93
|
-
│ └──
|
|
94
|
-
├──
|
|
95
|
-
│ ├──
|
|
96
|
-
│ ├──
|
|
97
|
-
│
|
|
98
|
-
│
|
|
99
|
-
│ └──
|
|
100
|
-
├──
|
|
101
|
-
├──
|
|
102
|
-
│ ├──
|
|
103
|
-
│ └──
|
|
104
|
-
├──
|
|
105
|
-
│ ├──
|
|
106
|
-
│ ├──
|
|
107
|
-
│ └──
|
|
108
|
-
├──
|
|
109
|
-
│ └──
|
|
110
|
-
├──
|
|
111
|
-
|
|
112
|
-
│ ├──
|
|
113
|
-
│ ├──
|
|
114
|
-
│
|
|
115
|
-
├──
|
|
116
|
-
│ ├──
|
|
117
|
-
│ │ ├──
|
|
118
|
-
│ │ └──
|
|
119
|
-
│
|
|
120
|
-
│ ├──
|
|
121
|
-
│
|
|
122
|
-
├──
|
|
123
|
-
│
|
|
124
|
-
│
|
|
125
|
-
│
|
|
126
|
-
├──
|
|
127
|
-
├──
|
|
128
|
-
│
|
|
129
|
-
│
|
|
130
|
-
|
|
131
|
-
└──
|
|
132
|
-
├── client/ # Client-side utilities
|
|
133
|
-
└── server/ # Server-side utilities
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
## Key Monorepo Packages
|
|
137
|
-
|
|
138
|
-
```plaintext
|
|
139
|
-
packages/
|
|
140
|
-
├── const/ # Global constants and configurations
|
|
141
|
-
├── database/ # Database schemas and models
|
|
142
|
-
│ ├── src/models/ # Data models (CRUD operations)
|
|
143
|
-
│ ├── src/schemas/ # Drizzle database schemas
|
|
144
|
-
│ ├── src/repositories/ # Complex query layer
|
|
145
|
-
│ └── migrations/ # Database migration files
|
|
146
|
-
├── model-runtime/ # AI model runtime
|
|
147
|
-
│ └── src/
|
|
148
|
-
│ ├── openai/ # OpenAI provider integration
|
|
149
|
-
│ ├── anthropic/ # Anthropic provider integration
|
|
150
|
-
│ ├── google/ # Google AI provider integration
|
|
151
|
-
│ ├── ollama/ # Ollama local model integration
|
|
152
|
-
│ ├── types/ # Runtime type definitions
|
|
153
|
-
│ └── utils/ # Runtime utilities
|
|
154
|
-
├── types/ # Shared TypeScript type definitions
|
|
155
|
-
│ └── src/
|
|
156
|
-
│ ├── agent/ # Agent-related types
|
|
157
|
-
│ ├── message/ # Message and chat types
|
|
158
|
-
│ ├── user/ # User and session types
|
|
159
|
-
│ └── tool/ # Tool and plugin types
|
|
160
|
-
├── utils/ # Shared utility functions
|
|
161
|
-
│ └── src/
|
|
162
|
-
│ ├── client/ # Client-side utilities
|
|
163
|
-
│ ├── server/ # Server-side utilities
|
|
164
|
-
│ ├── fetch/ # HTTP request utilities
|
|
165
|
-
│ └── tokenizer/ # Token counting utilities
|
|
166
|
-
├── file-loaders/ # File loaders (PDF, DOCX, etc.)
|
|
167
|
-
├── prompts/ # AI prompt management
|
|
168
|
-
└── web-crawler/ # Web crawling functionality
|
|
15
|
+
lobe-chat/
|
|
16
|
+
├── apps/
|
|
17
|
+
│ └── desktop/
|
|
18
|
+
├── docs/
|
|
19
|
+
├── locales/
|
|
20
|
+
│ ├── en-US/
|
|
21
|
+
│ └── zh-CN/
|
|
22
|
+
├── packages/
|
|
23
|
+
│ ├── const/
|
|
24
|
+
│ ├── context-engine/
|
|
25
|
+
│ ├── database/
|
|
26
|
+
│ │ ├── src/
|
|
27
|
+
│ │ │ ├── models/
|
|
28
|
+
│ │ │ ├── schemas/
|
|
29
|
+
│ │ │ └── repositories/
|
|
30
|
+
│ ├── model-bank/
|
|
31
|
+
│ ├── model-runtime/
|
|
32
|
+
│ │ └── src/
|
|
33
|
+
│ │ ├── openai/
|
|
34
|
+
│ │ └── anthropic/
|
|
35
|
+
│ ├── types/
|
|
36
|
+
│ │ └── src/
|
|
37
|
+
│ │ ├── message/
|
|
38
|
+
│ │ └── user/
|
|
39
|
+
│ └── utils/
|
|
40
|
+
├── public/
|
|
41
|
+
├── scripts/
|
|
42
|
+
├── src/
|
|
43
|
+
│ ├── app/
|
|
44
|
+
│ │ ├── (backend)/
|
|
45
|
+
│ │ │ ├── api/
|
|
46
|
+
│ │ │ │ ├── auth/
|
|
47
|
+
│ │ │ │ └── webhooks/
|
|
48
|
+
│ │ │ ├── middleware/
|
|
49
|
+
│ │ │ ├── oidc/
|
|
50
|
+
│ │ │ ├── trpc/
|
|
51
|
+
│ │ │ └── webapi/
|
|
52
|
+
│ │ │ ├── chat/
|
|
53
|
+
│ │ │ └── tts/
|
|
54
|
+
│ │ ├── [variants]/
|
|
55
|
+
│ │ │ ├── (main)/
|
|
56
|
+
│ │ │ │ ├── chat/
|
|
57
|
+
│ │ │ │ └── settings/
|
|
58
|
+
│ │ │ └── @modal/
|
|
59
|
+
│ │ └── manifest.ts
|
|
60
|
+
│ ├── components/
|
|
61
|
+
│ ├── config/
|
|
62
|
+
│ ├── features/
|
|
63
|
+
│ │ └── ChatInput/
|
|
64
|
+
│ ├── hooks/
|
|
65
|
+
│ ├── layout/
|
|
66
|
+
│ │ ├── AuthProvider/
|
|
67
|
+
│ │ └── GlobalProvider/
|
|
68
|
+
│ ├── libs/
|
|
69
|
+
│ │ └── oidc-provider/
|
|
70
|
+
│ ├── locales/
|
|
71
|
+
│ │ └── default/
|
|
72
|
+
│ ├── server/
|
|
73
|
+
│ │ ├── modules/
|
|
74
|
+
│ │ ├── routers/
|
|
75
|
+
│ │ │ ├── async/
|
|
76
|
+
│ │ │ ├── desktop/
|
|
77
|
+
│ │ │ ├── edge/
|
|
78
|
+
│ │ │ └── lambda/
|
|
79
|
+
│ │ └── services/
|
|
80
|
+
│ ├── services/
|
|
81
|
+
│ │ ├── user/
|
|
82
|
+
│ │ │ ├── client.ts
|
|
83
|
+
│ │ │ └── server.ts
|
|
84
|
+
│ │ └── message/
|
|
85
|
+
│ ├── store/
|
|
86
|
+
│ │ ├── agent/
|
|
87
|
+
│ │ ├── chat/
|
|
88
|
+
│ │ └── user/
|
|
89
|
+
│ ├── styles/
|
|
90
|
+
│ └── utils/
|
|
91
|
+
└── package.json
|
|
169
92
|
```
|
|
170
93
|
|
|
171
94
|
## Architecture Map
|
|
172
95
|
|
|
173
|
-
-
|
|
174
|
-
-
|
|
175
|
-
-
|
|
176
|
-
-
|
|
177
|
-
-
|
|
178
|
-
-
|
|
179
|
-
-
|
|
96
|
+
- UI Components: `src/components`, `src/features`
|
|
97
|
+
- Global providers: `src/layout`
|
|
98
|
+
- Zustand stores: `src/store`
|
|
99
|
+
- Client Services: `src/services/`
|
|
100
|
+
- clientDB: `src/services/<domain>/client.ts`
|
|
101
|
+
- serverDB: `src/services/<domain>/server.ts`
|
|
102
|
+
- API Routers:
|
|
103
|
+
- `src/app/(backend)/webapi` (REST)
|
|
104
|
+
- `src/server/routers/{edge|lambda|async|desktop|tools}` (tRPC)
|
|
105
|
+
- Server:
|
|
106
|
+
- Services(can access serverDB): `src/server/services`
|
|
107
|
+
- Modules(can't access db): `src/server/modules` (Server only Third-party Service Module)
|
|
108
|
+
- Database:
|
|
109
|
+
- Schema (Drizzle): `packages/database/src/schemas`
|
|
110
|
+
- Model (CRUD): `packages/database/src/models`
|
|
111
|
+
- Repository (bff-queries): `packages/database/src/repositories`
|
|
112
|
+
- Third-party Integrations: `src/libs` — analytics, oidc etc.
|
|
180
113
|
|
|
181
114
|
## Data Flow Architecture
|
|
182
115
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
React Zustand Environment Local/Remote PGLite/
|
|
189
|
-
Components Store Adaptation Routing PostgreSQL
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
### Environment-Specific Routing
|
|
193
|
-
|
|
194
|
-
| Mode | UI | Service Route | Database |
|
|
195
|
-
| --------------- | -------- | ---------------------- | ------------------- |
|
|
196
|
-
| **Browser/PWA** | React | Direct Model Access | PGLite (Local) |
|
|
197
|
-
| **Server** | React | tRPC → Server Services | PostgreSQL (Remote) |
|
|
198
|
-
| **Desktop** | Electron | tRPC → Local Node.js | PGLite/PostgreSQL\* |
|
|
199
|
-
|
|
200
|
-
_\*Depends on cloud sync configuration_
|
|
201
|
-
|
|
202
|
-
### Key Characteristics
|
|
203
|
-
|
|
204
|
-
- **Type Safety**: End-to-end type safety via tRPC and Drizzle ORM
|
|
205
|
-
- **Local/Remote Dual Mode**: PGLite enables user data ownership and local control
|
|
206
|
-
|
|
207
|
-
## Quick Map
|
|
208
|
-
|
|
209
|
-
- App Routes: `src/app` — UI routes (App Router) and backend routes under `(backend)`
|
|
210
|
-
- Web API: `src/app/(backend)/webapi` — REST-like endpoints
|
|
211
|
-
- tRPC Routers: `src/server/routers` — typed RPC endpoints by runtime
|
|
212
|
-
- Client Services: `src/services` — environment-adaptive client-side business logic
|
|
213
|
-
- Server Services: `src/server/services` — platform-agnostic business logic
|
|
214
|
-
- Database: `packages/database` — schemas/models/repositories/migrations
|
|
215
|
-
- State: `src/store` — Zustand stores and slices
|
|
216
|
-
- Integrations: `src/libs` — analytics/auth/trpc/logging/runtime helpers
|
|
217
|
-
- Tools: `src/tools` — built-in tool system
|
|
218
|
-
|
|
219
|
-
## Common Tasks
|
|
220
|
-
|
|
221
|
-
- Add Web API route: `src/app/(backend)/webapi/<module>/route.ts`
|
|
222
|
-
- Add tRPC endpoint: `src/server/routers/{edge|lambda|desktop}/...`
|
|
223
|
-
- Add client/server service: `src/services/<domain>/{client|server}.ts` (client: PGLite; server: tRPC)
|
|
224
|
-
- Add server service: `src/server/services/<domain>`
|
|
225
|
-
- Add a new model/provider: `src/config/modelProviders/<provider>.ts` + `packages/model-bank/src/aiModels/<provider>.ts` + `packages/model-runtime/src/<provider>/index.ts`
|
|
226
|
-
- Add DB schema/model/repository: `packages/database/src/{schemas|models|repositories}`
|
|
227
|
-
- Add Zustand slice: `src/store/<domain>/slices`
|
|
228
|
-
|
|
229
|
-
## Env Modes
|
|
230
|
-
|
|
231
|
-
- `NEXT_PUBLIC_CLIENT_DB`: selects client DB mode (e.g., `pglite`) vs server-backed
|
|
232
|
-
- `NEXT_PUBLIC_IS_DESKTOP_APP`: enables desktop-specific routes and behavior
|
|
233
|
-
- `NEXT_PUBLIC_SERVICE_MODE`: controls service routing preference (client/server)
|
|
234
|
-
|
|
235
|
-
## Boundaries
|
|
236
|
-
|
|
237
|
-
- Keep client logic in `src/services`; server-only logic stays in `src/server/services`
|
|
238
|
-
- Don’t mix Web API (`webapi/`) with tRPC (`src/server/routers/`)
|
|
239
|
-
- Place business UI under `src/features`, global reusable UI under `src/components`
|
|
116
|
+
- **Browser/PWA**: React UI → Client Service → Direct Model Access → PGLite (Web WASM)
|
|
117
|
+
- **Server**: React UI → Client Service → tRPC Lambda → Server Services → PostgreSQL (Remote)
|
|
118
|
+
- **Desktop**:
|
|
119
|
+
- Cloud sync disabled: Electron UI → Client Service → tRPC Lambda → Local Server Services → PGLite (Node WASM)
|
|
120
|
+
- Cloud sync enabled: Electron UI → Client Service → tRPC Lambda → Cloud Server Services → PostgreSQL (Remote)
|
|
@@ -4,20 +4,12 @@ globs:
|
|
|
4
4
|
alwaysApply: true
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
#
|
|
7
|
+
# Available project rules index
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
## General
|
|
12
|
-
|
|
13
|
-
- `project-introduce.mdc` – Project description and tech stack
|
|
14
|
-
- `cursor-rules.mdc` – Cursor rules authoring and optimization guide
|
|
15
|
-
- `code-review.mdc` – How to code review
|
|
9
|
+
All following rules are saved under `.cursor/rules/` directory:
|
|
16
10
|
|
|
17
11
|
## Backend
|
|
18
12
|
|
|
19
|
-
- `backend-architecture.mdc` – Backend layer architecture and design guidelines
|
|
20
|
-
- `define-database-model.mdc` – Database model definition guidelines
|
|
21
13
|
- `drizzle-schema-style-guide.mdc` – Style guide for defining Drizzle ORM schemas
|
|
22
14
|
|
|
23
15
|
## Frontend
|
|
@@ -42,7 +34,6 @@ The following rules are available via `read_file` from the `.cursor/rules/` dire
|
|
|
42
34
|
|
|
43
35
|
## Debugging
|
|
44
36
|
|
|
45
|
-
- `debug.mdc` – General debugging guide
|
|
46
37
|
- `debug-usage.mdc` – Using the debug package and namespace conventions
|
|
47
38
|
|
|
48
39
|
## Testing
|
|
@@ -10,61 +10,11 @@ alwaysApply: false
|
|
|
10
10
|
|
|
11
11
|
- avoid explicit type annotations when TypeScript can infer types.
|
|
12
12
|
- avoid implicitly `any` variables; explicitly type when necessary (e.g., `let a: number` instead of `let a`).
|
|
13
|
-
- use the most accurate type possible (e.g., prefer `Record<PropertyKey, unknown>` over `object`).
|
|
13
|
+
- use the most accurate type possible (e.g., prefer `Record<PropertyKey, unknown>` over `object` and `any`).
|
|
14
14
|
- prefer `interface` over `type` for object shapes (e.g., React component props). Keep `type` for unions, intersections, and utility types.
|
|
15
15
|
- prefer `as const satisfies XyzInterface` over plain `as const` when suitable.
|
|
16
|
-
- prefer `@ts-expect-error` over `@ts-ignore`
|
|
17
|
-
-
|
|
18
|
-
|
|
19
|
-
- **Avoid unnecessary null checks**: Before adding `xxx !== null`, `?.`, `??`, or `!.`, read the type definition to confirm the necessary. **Example:**
|
|
20
|
-
|
|
21
|
-
```typescript
|
|
22
|
-
// ❌ Wrong: budget.spend and budget.maxBudget is number, not number | null
|
|
23
|
-
if (budget.spend !== null && budget.maxBudget !== null && budget.spend >= budget.maxBudget) {
|
|
24
|
-
// ...
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// ✅ Right
|
|
28
|
-
if (budget.spend >= budget.maxBudget) {
|
|
29
|
-
// ...
|
|
30
|
-
}
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
- **Avoid redundant runtime checks**: Don't add runtime validation for conditions already guaranteed by types or previous checks. Trust the type system and calling contract. **Example:**
|
|
34
|
-
|
|
35
|
-
```typescript
|
|
36
|
-
// ❌ Wrong: Adding impossible-to-fail checks
|
|
37
|
-
const due = await db.query.budgets.findMany({
|
|
38
|
-
where: and(isNotNull(budgets.budgetDuration)), // Already filtered non-null
|
|
39
|
-
});
|
|
40
|
-
const result = due.map(b => {
|
|
41
|
-
const nextReset = computeNextResetAt(b.budgetResetAt!, b.budgetDuration!);
|
|
42
|
-
if (!nextReset) { // This check is impossible to fail
|
|
43
|
-
throw new Error(`Unexpected null nextResetAt`);
|
|
44
|
-
}
|
|
45
|
-
return nextReset;
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
// ✅ Right: Trust the contract
|
|
49
|
-
const due = await db.query.budgets.findMany({
|
|
50
|
-
where: and(isNotNull(budgets.budgetDuration)),
|
|
51
|
-
});
|
|
52
|
-
const result = due.map(b => computeNextResetAt(b.budgetResetAt!, b.budgetDuration!));
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
- **Avoid meaningless null/undefined parameters**: Don't accept null/undefined for parameters that have no business meaning when null. Design strict function contracts. **Example:**
|
|
56
|
-
|
|
57
|
-
```typescript
|
|
58
|
-
// ❌ Wrong: Function accepts meaningless null input
|
|
59
|
-
function computeNextResetAt(currentResetAt: Date, durationStr: string | null): Date | null {
|
|
60
|
-
if (!durationStr) return null; // Why accept null if it just returns null?
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// ✅ Right: Strict contract, clear responsibility
|
|
64
|
-
function computeNextResetAt(currentResetAt: Date, durationStr: string): Date {
|
|
65
|
-
// Function has single clear purpose, caller ensures valid input
|
|
66
|
-
}
|
|
67
|
-
```
|
|
16
|
+
- prefer `@ts-expect-error` over `@ts-ignore` over `as any`
|
|
17
|
+
- Avoid meaningless null/undefined parameters; design strict function contracts.
|
|
68
18
|
|
|
69
19
|
## Imports and Modules
|
|
70
20
|
|
package/.vscode/settings.json
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
{ "rule": "prettier/prettier", "severity": "off" },
|
|
12
12
|
{ "rule": "react/jsx-sort-props", "severity": "off" },
|
|
13
13
|
{ "rule": "sort-keys-fix/sort-keys-fix", "severity": "off" },
|
|
14
|
+
{ "rule": "simple-import-sort/exports", "severity": "off" },
|
|
14
15
|
{ "rule": "typescript-sort-keys/interface", "severity": "off" }
|
|
15
16
|
],
|
|
16
17
|
"eslint.validate": [
|
|
@@ -81,7 +82,7 @@
|
|
|
81
82
|
|
|
82
83
|
"**/src/config/modelProviders/*.ts": "${filename} • provider",
|
|
83
84
|
"**/packages/model-bank/src/aiModels/*.ts": "${filename} • model",
|
|
84
|
-
"**/packages/model-runtime/src/*/index.ts": "${dirname} • runtime",
|
|
85
|
+
"**/packages/model-runtime/src/providers/*/index.ts": "${dirname} • runtime",
|
|
85
86
|
|
|
86
87
|
"**/src/server/services/*/index.ts": "${dirname} • server/service",
|
|
87
88
|
"**/src/server/routers/lambda/*.ts": "${filename} • lambda",
|
package/AGENTS.md
CHANGED
|
@@ -44,21 +44,7 @@ The project follows a well-organized monorepo structure:
|
|
|
44
44
|
|
|
45
45
|
#### TypeScript
|
|
46
46
|
|
|
47
|
-
- Follow strict TypeScript practices for type safety and code quality
|
|
48
|
-
- Use proper type annotations
|
|
49
47
|
- Prefer interfaces over types for object shapes
|
|
50
|
-
- Use generics for reusable components
|
|
51
|
-
|
|
52
|
-
#### React Components
|
|
53
|
-
|
|
54
|
-
- Use functional components with hooks
|
|
55
|
-
|
|
56
|
-
#### Database Schema
|
|
57
|
-
|
|
58
|
-
- Follow Drizzle ORM naming conventions
|
|
59
|
-
- Use plural snake_case for table names
|
|
60
|
-
- Implement proper foreign key relationships
|
|
61
|
-
- Follow the schema style guide
|
|
62
48
|
|
|
63
49
|
### Testing Strategy
|
|
64
50
|
|
|
@@ -67,64 +53,57 @@ The project follows a well-organized monorepo structure:
|
|
|
67
53
|
**Commands**:
|
|
68
54
|
|
|
69
55
|
- Web: `bunx vitest run --silent='passed-only' '[file-path-pattern]'`
|
|
70
|
-
- Packages: `cd packages/[package-name] && bunx vitest run --silent='passed-only' '[file-path-pattern]'`
|
|
56
|
+
- Packages: `cd packages/[package-name] && bunx vitest run --silent='passed-only' '[file-path-pattern]'` (each subpackage contains its own vitest.config.mts)
|
|
71
57
|
|
|
72
58
|
**Important Notes**:
|
|
73
59
|
|
|
74
60
|
- Wrap file paths in single quotes to avoid shell expansion
|
|
75
|
-
- Never run `bun run test` - this runs all tests and takes
|
|
76
|
-
- If a test fails twice, stop and ask for help
|
|
77
|
-
- Always add tests for new code
|
|
61
|
+
- Never run `bun run test` - this runs all tests and takes \~10 minutes
|
|
78
62
|
|
|
79
63
|
### Type Checking
|
|
80
64
|
|
|
81
65
|
- Use `bun run type-check` to check for type errors
|
|
82
|
-
- Ensure all TypeScript errors are resolved before committing
|
|
83
66
|
|
|
84
|
-
###
|
|
67
|
+
### i18n
|
|
85
68
|
|
|
86
|
-
- Add
|
|
87
|
-
- Translate
|
|
88
|
-
-
|
|
89
|
-
- Don't run `pnpm i18n` manually (handled by CI)
|
|
69
|
+
- **Keys**: Add to `src/locales/default/namespace.ts`
|
|
70
|
+
- **Dev**: Translate `locales/zh-CN/namespace.json` locale file only for preview
|
|
71
|
+
- DON'T run `pnpm i18n`, let CI auto handle it
|
|
90
72
|
|
|
91
|
-
##
|
|
73
|
+
## Project Rules Index
|
|
92
74
|
|
|
93
|
-
|
|
75
|
+
All following rules are saved under `.cursor/rules/` directory:
|
|
94
76
|
|
|
95
|
-
###
|
|
77
|
+
### Backend
|
|
96
78
|
|
|
97
|
-
- `
|
|
98
|
-
- `react-component.mdc` - Component patterns and UI library usage
|
|
99
|
-
- `drizzle-schema-style-guide.mdc` - Database schema conventions
|
|
100
|
-
- `define-database-model.mdc` - Model templates and CRUD patterns
|
|
101
|
-
- `i18n.mdc` - Internationalization workflow
|
|
79
|
+
- `drizzle-schema-style-guide.mdc` – Style guide for defining Drizzle ORM schemas
|
|
102
80
|
|
|
103
|
-
###
|
|
81
|
+
### Frontend
|
|
104
82
|
|
|
105
|
-
- `
|
|
106
|
-
- `
|
|
107
|
-
- `
|
|
83
|
+
- `react-component.mdc` – React component style guide and conventions
|
|
84
|
+
- `i18n.mdc` – Internationalization guide using react-i18next
|
|
85
|
+
- `typescript.mdc` – TypeScript code style guide
|
|
86
|
+
- `packages/react-layout-kit.mdc` – Usage guide for react-layout-kit
|
|
108
87
|
|
|
109
|
-
###
|
|
88
|
+
### State Management
|
|
110
89
|
|
|
111
|
-
- `
|
|
112
|
-
- `
|
|
90
|
+
- `zustand-action-patterns.mdc` – Recommended patterns for organizing Zustand actions
|
|
91
|
+
- `zustand-slice-organization.mdc` – Best practices for structuring Zustand slices
|
|
113
92
|
|
|
114
93
|
### Desktop (Electron)
|
|
115
94
|
|
|
116
|
-
- `desktop-feature-implementation.mdc`
|
|
117
|
-
- `desktop-
|
|
118
|
-
- `desktop-
|
|
119
|
-
- `desktop-
|
|
120
|
-
- `desktop-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
-
|
|
129
|
-
-
|
|
130
|
-
-
|
|
95
|
+
- `desktop-feature-implementation.mdc` – Implementing new Electron desktop features
|
|
96
|
+
- `desktop-controller-tests.mdc` – Desktop controller unit testing guide
|
|
97
|
+
- `desktop-local-tools-implement.mdc` – Workflow to add new desktop local tools
|
|
98
|
+
- `desktop-menu-configuration.mdc` – Desktop menu configuration guide
|
|
99
|
+
- `desktop-window-management.mdc` – Desktop window management guide
|
|
100
|
+
|
|
101
|
+
### Debugging
|
|
102
|
+
|
|
103
|
+
- `debug-usage.mdc` – Using the debug package and namespace conventions
|
|
104
|
+
|
|
105
|
+
### Testing
|
|
106
|
+
|
|
107
|
+
- `testing-guide/testing-guide.mdc` – Comprehensive testing guide for Vitest
|
|
108
|
+
- `testing-guide/electron-ipc-test.mdc` – Electron IPC interface testing strategy
|
|
109
|
+
- `testing-guide/db-model-test.mdc` – Database Model testing guide
|