@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,78 @@
1
+ ---
2
+ name: zustand
3
+ description: Zustand state management guide. Use when working with store code (src/store/**), implementing actions, managing state, or creating slices. Triggers on Zustand store development, state management questions, or action implementation.
4
+ ---
5
+
6
+ # LobeChat Zustand State Management
7
+
8
+ ## Action Type Hierarchy
9
+
10
+ ### 1. Public Actions
11
+ Main interfaces for UI components:
12
+ - Naming: Verb form (`createTopic`, `sendMessage`)
13
+ - Responsibilities: Parameter validation, flow orchestration
14
+
15
+ ### 2. Internal Actions (`internal_*`)
16
+ Core business logic implementation:
17
+ - Naming: `internal_` prefix (`internal_createTopic`)
18
+ - Responsibilities: Optimistic updates, service calls, error handling
19
+ - Should not be called directly by UI
20
+
21
+ ### 3. Dispatch Methods (`internal_dispatch*`)
22
+ State update handlers:
23
+ - Naming: `internal_dispatch` + entity (`internal_dispatchTopic`)
24
+ - Responsibilities: Calling reducers, updating store
25
+
26
+ ## When to Use Reducer vs Simple `set`
27
+
28
+ **Use Reducer Pattern:**
29
+ - Managing object lists/maps (`messagesMap`, `topicMaps`)
30
+ - Optimistic updates
31
+ - Complex state transitions
32
+
33
+ **Use Simple `set`:**
34
+ - Toggling booleans
35
+ - Updating simple values
36
+ - Setting single state fields
37
+
38
+ ## Optimistic Update Pattern
39
+
40
+ ```typescript
41
+ internal_createTopic: async (params) => {
42
+ const tmpId = Date.now().toString();
43
+
44
+ // 1. Immediately update frontend (optimistic)
45
+ get().internal_dispatchTopic(
46
+ { type: 'addTopic', value: { ...params, id: tmpId } },
47
+ 'internal_createTopic'
48
+ );
49
+
50
+ // 2. Call backend service
51
+ const topicId = await topicService.createTopic(params);
52
+
53
+ // 3. Refresh for consistency
54
+ await get().refreshTopic();
55
+ return topicId;
56
+ },
57
+ ```
58
+
59
+ **Delete operations**: Don't use optimistic updates (destructive, complex recovery)
60
+
61
+ ## Naming Conventions
62
+
63
+ **Actions:**
64
+ - Public: `createTopic`, `sendMessage`
65
+ - Internal: `internal_createTopic`, `internal_updateMessageContent`
66
+ - Dispatch: `internal_dispatchTopic`
67
+ - Toggle: `internal_toggleMessageLoading`
68
+
69
+ **State:**
70
+ - ID arrays: `messageLoadingIds`, `topicEditingIds`
71
+ - Maps: `topicMaps`, `messagesMap`
72
+ - Active: `activeTopicId`
73
+ - Init flags: `topicsInit`
74
+
75
+ ## Detailed Guides
76
+
77
+ - Action patterns: `references/action-patterns.md`
78
+ - Slice organization: `references/slice-organization.md`
@@ -0,0 +1,125 @@
1
+ # Zustand Action Patterns
2
+
3
+ ## Optimistic Update Implementation
4
+
5
+ ### Standard Flow
6
+
7
+ ```typescript
8
+ internal_updateMessageContent: async (id, content, extra) => {
9
+ const { internal_dispatchMessage, refreshMessages } = get();
10
+
11
+ // 1. Immediately update frontend
12
+ internal_dispatchMessage({
13
+ id,
14
+ type: 'updateMessage',
15
+ value: { content },
16
+ });
17
+
18
+ // 2. Call backend
19
+ await messageService.updateMessage(id, { content });
20
+
21
+ // 3. Refresh for consistency
22
+ await refreshMessages();
23
+ },
24
+ ```
25
+
26
+ ### Create Operations
27
+
28
+ ```typescript
29
+ internal_createMessage: async (message, context) => {
30
+ let tempId = context?.tempMessageId;
31
+ if (!tempId) {
32
+ tempId = internal_createTmpMessage(message);
33
+ internal_toggleMessageLoading(true, tempId);
34
+ }
35
+
36
+ try {
37
+ const id = await messageService.createMessage(message);
38
+ await refreshMessages();
39
+ internal_toggleMessageLoading(false, tempId);
40
+ return id;
41
+ } catch (e) {
42
+ internal_toggleMessageLoading(false, tempId);
43
+ internal_dispatchMessage({
44
+ id: tempId,
45
+ type: 'updateMessage',
46
+ value: { error: { type: ChatErrorType.CreateMessageError } },
47
+ });
48
+ }
49
+ },
50
+ ```
51
+
52
+ ### Delete Operations (No Optimistic Update)
53
+
54
+ ```typescript
55
+ internal_removeGenerationTopic: async (id: string) => {
56
+ get().internal_updateGenerationTopicLoading(id, true);
57
+
58
+ try {
59
+ await generationTopicService.deleteTopic(id);
60
+ await get().refreshGenerationTopics();
61
+ } finally {
62
+ get().internal_updateGenerationTopicLoading(id, false);
63
+ }
64
+ },
65
+ ```
66
+
67
+ ## Loading State Management
68
+
69
+ ```typescript
70
+ // Define in initialState.ts
71
+ export interface ChatMessageState {
72
+ messageEditingIds: string[];
73
+ }
74
+
75
+ // Manage in action
76
+ toggleMessageEditing: (id, editing) => {
77
+ set(
78
+ { messageEditingIds: toggleBooleanList(get().messageEditingIds, id, editing) },
79
+ false,
80
+ 'toggleMessageEditing'
81
+ );
82
+ }
83
+ ```
84
+
85
+ ## SWR Integration
86
+
87
+ ```typescript
88
+ useFetchMessages: (enable, sessionId, activeTopicId) =>
89
+ useClientDataSWR<ChatMessage[]>(
90
+ enable ? [SWR_USE_FETCH_MESSAGES, sessionId, activeTopicId] : null,
91
+ async ([, sessionId, topicId]) => messageService.getMessages(sessionId, topicId),
92
+ {
93
+ onSuccess: (messages) => {
94
+ const nextMap = { ...get().messagesMap, [messageMapKey(sessionId, activeTopicId)]: messages };
95
+ if (get().messagesInit && isEqual(nextMap, get().messagesMap)) return;
96
+ set({ messagesInit: true, messagesMap: nextMap }, false, n('useFetchMessages'));
97
+ },
98
+ }
99
+ ),
100
+
101
+ // Cache invalidation
102
+ refreshMessages: async () => {
103
+ await mutate([SWR_USE_FETCH_MESSAGES, get().activeId, get().activeTopicId]);
104
+ };
105
+ ```
106
+
107
+ ## Reducer Pattern
108
+
109
+ ```typescript
110
+ export const messagesReducer = (state: ChatMessage[], payload: MessageDispatch): ChatMessage[] => {
111
+ switch (payload.type) {
112
+ case 'updateMessage': {
113
+ return produce(state, (draftState) => {
114
+ const index = draftState.findIndex((i) => i.id === payload.id);
115
+ if (index < 0) return;
116
+ draftState[index] = merge(draftState[index], {
117
+ ...payload.value,
118
+ updatedAt: Date.now(),
119
+ });
120
+ });
121
+ }
122
+ // ...other cases
123
+ }
124
+ };
125
+ ```
@@ -0,0 +1,125 @@
1
+ # Zustand Slice Organization
2
+
3
+ ## Top-Level Store Structure
4
+
5
+ Key aggregation files:
6
+ - `src/store/chat/initialState.ts`: Aggregate all slice initial states
7
+ - `src/store/chat/store.ts`: Define top-level `ChatStore`, combine all slice actions
8
+ - `src/store/chat/selectors.ts`: Export all slice selectors
9
+ - `src/store/chat/helpers.ts`: Chat helper functions
10
+
11
+ ## Store Aggregation Pattern
12
+
13
+ ```typescript
14
+ // src/store/chat/initialState.ts
15
+ import { ChatTopicState, initialTopicState } from './slices/topic/initialState';
16
+ import { ChatMessageState, initialMessageState } from './slices/message/initialState';
17
+
18
+ export type ChatStoreState = ChatTopicState & ChatMessageState & ...
19
+
20
+ export const initialState: ChatStoreState = {
21
+ ...initialMessageState,
22
+ ...initialTopicState,
23
+ ...
24
+ };
25
+
26
+ // src/store/chat/store.ts
27
+ export interface ChatStoreAction
28
+ extends ChatMessageAction, ChatTopicAction, ...
29
+
30
+ const createStore: StateCreator<ChatStore, [['zustand/devtools', never]]> = (...params) => ({
31
+ ...initialState,
32
+ ...chatMessage(...params),
33
+ ...chatTopic(...params),
34
+ });
35
+
36
+ export const useChatStore = createWithEqualityFn<ChatStore>()(
37
+ subscribeWithSelector(devtools(createStore)),
38
+ shallow
39
+ );
40
+ ```
41
+
42
+ ## Single Slice Structure
43
+
44
+ ```plaintext
45
+ src/store/chat/slices/
46
+ └── [sliceName]/
47
+ ├── action.ts # Define actions (or actions/ directory)
48
+ ├── initialState.ts # State structure and initial values
49
+ ├── reducer.ts # (Optional) Reducer pattern
50
+ ├── selectors.ts # Define selectors
51
+ └── index.ts # (Optional) Re-exports
52
+ ```
53
+
54
+ ### initialState.ts
55
+
56
+ ```typescript
57
+ export interface ChatTopicState {
58
+ activeTopicId?: string;
59
+ topicMaps: Record<string, ChatTopic[]>;
60
+ topicsInit: boolean;
61
+ topicLoadingIds: string[];
62
+ }
63
+
64
+ export const initialTopicState: ChatTopicState = {
65
+ activeTopicId: undefined,
66
+ topicMaps: {},
67
+ topicsInit: false,
68
+ topicLoadingIds: [],
69
+ };
70
+ ```
71
+
72
+ ### selectors.ts
73
+
74
+ ```typescript
75
+ const currentTopics = (s: ChatStoreState): ChatTopic[] | undefined => s.topicMaps[s.activeId];
76
+
77
+ const getTopicById = (id: string) => (s: ChatStoreState): ChatTopic | undefined =>
78
+ currentTopics(s)?.find((topic) => topic.id === id);
79
+
80
+ // Core pattern: Use xxxSelectors aggregate
81
+ export const topicSelectors = {
82
+ currentTopics,
83
+ getTopicById,
84
+ };
85
+ ```
86
+
87
+ ## Complex Actions Sub-directory
88
+
89
+ ```plaintext
90
+ src/store/chat/slices/aiChat/
91
+ ├── actions/
92
+ │ ├── generateAIChat.ts
93
+ │ ├── rag.ts
94
+ │ ├── memory.ts
95
+ │ └── index.ts
96
+ ├── initialState.ts
97
+ └── selectors.ts
98
+ ```
99
+
100
+ ## State Design Patterns
101
+
102
+ ### Map Structure for Associated Data
103
+ ```typescript
104
+ topicMaps: Record<string, ChatTopic[]>;
105
+ messagesMap: Record<string, ChatMessage[]>;
106
+ ```
107
+
108
+ ### Arrays for Loading State
109
+ ```typescript
110
+ messageLoadingIds: string[]
111
+ topicLoadingIds: string[]
112
+ ```
113
+
114
+ ### Optional Fields for Active Items
115
+ ```typescript
116
+ activeId: string
117
+ activeTopicId?: string
118
+ ```
119
+
120
+ ## Best Practices
121
+
122
+ 1. **Slice division**: By functional domain (message, topic, aiChat)
123
+ 2. **File naming**: camelCase for directories, consistent patterns
124
+ 3. **State structure**: Flat, avoid deep nesting
125
+ 4. **Type safety**: Clear TypeScript interfaces for each slice
package/AGENTS.md CHANGED
@@ -4,12 +4,10 @@ This document serves as a comprehensive guide for all team members when developi
4
4
 
5
5
  ## Project Description
6
6
 
7
- You are developing an open-source, modern-design AI Agent Workspace: LobeHub(previous LobeChat).
7
+ You are developing an open-source, modern-design AI Agent Workspace: LobeHub (previously LobeChat).
8
8
 
9
9
  ## Tech Stack
10
10
 
11
- Built with modern technologies:
12
-
13
11
  - **Frontend**: Next.js 16, React 19, TypeScript
14
12
  - **UI Components**: Ant Design, @lobehub/ui, antd-style
15
13
  - **State Management**: Zustand, SWR
@@ -19,24 +17,33 @@ Built with modern technologies:
19
17
 
20
18
  ## Directory Structure
21
19
 
22
- The project follows a well-organized monorepo structure:
23
-
24
- - `apps/` - Main applications
25
- - `packages/` - Shared packages and libraries
26
- - `src/` - Main source code
27
- - `docs/` - Documentation
28
- - `.cursor/rules/` - Development rules and guidelines
29
- - PR titles starting with `✨ feat/` or `🐛 fix` will trigger the release workflow upon merge. Only use these prefixes for significant user-facing feature changes or bug fixes
20
+ ```
21
+ lobe-chat/
22
+ ├── apps/desktop/ # Electron desktop app
23
+ ├── packages/ # Shared packages (@lobechat/*)
24
+ │ ├── database/ # Database schemas, models, repositories
25
+ │ ├── agent-runtime/ # Agent runtime
26
+ │ └── ...
27
+ ├── src/
28
+ │ ├── app/ # Next.js app router
29
+ │ ├── store/ # Zustand stores
30
+ │ ├── services/ # Client services
31
+ │ ├── server/ # Server services and routers
32
+ │ └── ...
33
+ ├── .agents/skills/ # AI development skills
34
+ └── e2e/ # E2E tests (Cucumber + Playwright)
35
+ ```
30
36
 
31
37
  ## Development Workflow
32
38
 
33
39
  ### Git Workflow
34
40
 
35
- - The current release branch is `next` instead of `main` until v2.0.0 is officially released
41
+ - The current release branch is `next` until v2.0.0 is officially released
36
42
  - Use rebase for git pull
37
43
  - Git commit messages should prefix with gitmoji
38
44
  - Git branch name format: `username/feat/feature-name`
39
45
  - Use `.github/PULL_REQUEST_TEMPLATE.md` for PR descriptions
46
+ - PR titles with `✨ feat/` or `🐛 fix` trigger releases
40
47
 
41
48
  ### Package Management
42
49
 
@@ -52,17 +59,18 @@ The project follows a well-organized monorepo structure:
52
59
 
53
60
  ### Testing Strategy
54
61
 
55
- **Required Rule**: `testing-guide/testing-guide.mdc`
62
+ ```bash
63
+ # Web tests
64
+ bunx vitest run --silent='passed-only' '[file-path-pattern]'
56
65
 
57
- **Commands**:
58
-
59
- - Web: `bunx vitest run --silent='passed-only' '[file-path-pattern]'`
60
- - Packages: `cd packages/[package-name] && bunx vitest run --silent='passed-only' '[file-path-pattern]'` (each subpackage contains its own vitest.config.mts)
66
+ # Package tests (e.g., database)
67
+ cd packages/[package-name] && bunx vitest run --silent='passed-only' '[file-path-pattern]'
68
+ ```
61
69
 
62
70
  **Important Notes**:
63
71
 
64
72
  - Wrap file paths in single quotes to avoid shell expansion
65
- - Never run `bun run test` - this runs all tests and takes \~10 minutes
73
+ - Never run `bun run test` - this runs all tests and takes ~10 minutes
66
74
 
67
75
  ### Type Checking
68
76
 
@@ -78,40 +86,19 @@ The project follows a well-organized monorepo structure:
78
86
 
79
87
  Follow [Linear rules in CLAUDE.md](CLAUDE.md#linear-issue-management-ignore-if-not-installed-linear-mcp) when working with Linear issues.
80
88
 
81
- ## Project Rules Index
82
-
83
- All following rules are saved under `.cursor/rules/` directory:
84
-
85
- ### Backend
86
-
87
- - `drizzle-schema-style-guide.mdc` Style guide for defining Drizzle ORM schemas
88
-
89
- ### Frontend
90
-
91
- - `react.mdc` – React component style guide and conventions
92
- - `i18n.mdc` Internationalization guide using react-i18next
93
- - `typescript.mdc` – TypeScript code style guide
94
- - `packages/react-layout-kit.mdc` Usage guide for Flexbox and Center components from @lobehub/ui
95
-
96
- ### State Management
97
-
98
- - `zustand-action-patterns.mdc` – Recommended patterns for organizing Zustand actions
99
- - `zustand-slice-organization.mdc` – Best practices for structuring Zustand slices
100
-
101
- ### Desktop (Electron)
102
-
103
- - `desktop-feature-implementation.mdc` – Implementing new Electron desktop features
104
- - `desktop-controller-tests.mdc` – Desktop controller unit testing guide
105
- - `desktop-local-tools-implement.mdc` – Workflow to add new desktop local tools
106
- - `desktop-menu-configuration.mdc` – Desktop menu configuration guide
107
- - `desktop-window-management.mdc` – Desktop window management guide
108
-
109
- ### Debugging
110
-
111
- - `debug-usage.mdc` – Using the debug package and namespace conventions
112
-
113
- ### Testing
114
-
115
- - `testing-guide/testing-guide.mdc` – Comprehensive testing guide for Vitest
116
- - `testing-guide/electron-ipc-test.mdc` – Electron IPC interface testing strategy
117
- - `testing-guide/db-model-test.mdc` – Database Model testing guide
89
+ ## Skills (Auto-loaded)
90
+
91
+ All AI development skills are available in `.agents/skills/` directory:
92
+
93
+ | Category | Skills |
94
+ |----------|--------|
95
+ | Frontend | `react`, `typescript`, `i18n`, `microcopy` |
96
+ | State | `zustand` |
97
+ | Backend | `drizzle` |
98
+ | Desktop | `desktop` |
99
+ | Testing | `testing` |
100
+ | UI | `modal`, `hotkey`, `recent-data` |
101
+ | Config | `add-provider-doc`, `add-setting-env` |
102
+ | Workflow | `linear`, `debug` |
103
+ | Performance | `vercel-react-best-practices` |
104
+ | Overview | `project-overview` |
package/CHANGELOG.md CHANGED
@@ -2,6 +2,66 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [Version 2.0.0-next.355](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.354...v2.0.0-next.355)
6
+
7
+ <sup>Released on **2026-01-23**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **home**: Use correct CreateGroupModal for session group creation.
12
+ - **misc**: Fix favorite refresh bug and group topic refresh issue.
13
+
14
+ <br/>
15
+
16
+ <details>
17
+ <summary><kbd>Improvements and Fixes</kbd></summary>
18
+
19
+ #### What's fixed
20
+
21
+ - **home**: Use correct CreateGroupModal for session group creation, closes [#11752](https://github.com/lobehub/lobe-chat/issues/11752) ([36bcc50](https://github.com/lobehub/lobe-chat/commit/36bcc50))
22
+ - **misc**: Fix favorite refresh bug and group topic refresh issue, closes [#11745](https://github.com/lobehub/lobe-chat/issues/11745) ([5d115ef](https://github.com/lobehub/lobe-chat/commit/5d115ef))
23
+
24
+ </details>
25
+
26
+ <div align="right">
27
+
28
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
29
+
30
+ </div>
31
+
32
+ ## [Version 2.0.0-next.354](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.353...v2.0.0-next.354)
33
+
34
+ <sup>Released on **2026-01-23**</sup>
35
+
36
+ #### ♻ Code Refactoring
37
+
38
+ - **misc**: Migrate AI Rules to Claude Code Skills.
39
+
40
+ #### 🐛 Bug Fixes
41
+
42
+ - **pdf**: Ensure worker config before Document render.
43
+
44
+ <br/>
45
+
46
+ <details>
47
+ <summary><kbd>Improvements and Fixes</kbd></summary>
48
+
49
+ #### Code refactoring
50
+
51
+ - **misc**: Migrate AI Rules to Claude Code Skills, closes [#11737](https://github.com/lobehub/lobe-chat/issues/11737) ([346fc46](https://github.com/lobehub/lobe-chat/commit/346fc46))
52
+
53
+ #### What's fixed
54
+
55
+ - **pdf**: Ensure worker config before Document render, closes [#11746](https://github.com/lobehub/lobe-chat/issues/11746) ([ad34072](https://github.com/lobehub/lobe-chat/commit/ad34072))
56
+
57
+ </details>
58
+
59
+ <div align="right">
60
+
61
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
62
+
63
+ </div>
64
+
5
65
  ## [Version 2.0.0-next.353](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.352...v2.0.0-next.353)
6
66
 
7
67
  <sup>Released on **2026-01-23**</sup>
package/CLAUDE.md CHANGED
@@ -1,72 +1,83 @@
1
1
  # CLAUDE.md
2
2
 
3
- This document serves as a shared guideline for all team members when using Claude Code in this opensource lobe-chat(also known as lobehub) repository.
3
+ Guidelines for using Claude Code in this LobeChat repository.
4
4
 
5
5
  ## Tech Stack
6
6
 
7
- read @.cursor/rules/project-introduce.mdc
8
-
9
- ## Directory Structure
10
-
11
- read @.cursor/rules/project-structure.mdc
7
+ - Next.js 16 + React 19 + TypeScript
8
+ - SPA inside Next.js with `react-router-dom`
9
+ - `@lobehub/ui`, antd for components; antd-style for CSS-in-JS
10
+ - react-i18next for i18n; zustand for state management
11
+ - SWR for data fetching; TRPC for type-safe backend
12
+ - Drizzle ORM with PostgreSQL; Vitest for testing
13
+
14
+ ## Project Structure
15
+
16
+ ```
17
+ lobe-chat/
18
+ ├── apps/desktop/ # Electron desktop app
19
+ ├── packages/ # Shared packages (@lobechat/*)
20
+ │ ├── database/ # Database schemas, models, repositories
21
+ │ ├── agent-runtime/ # Agent runtime
22
+ │ └── ...
23
+ ├── src/
24
+ │ ├── app/ # Next.js app router
25
+ │ ├── store/ # Zustand stores
26
+ │ ├── services/ # Client services
27
+ │ ├── server/ # Server services and routers
28
+ │ └── ...
29
+ └── e2e/ # E2E tests (Cucumber + Playwright)
30
+ ```
12
31
 
13
32
  ## Development
14
33
 
15
34
  ### Git Workflow
16
35
 
17
- - use rebase for git pull
18
- - git commit message should prefix with gitmoji
19
- - git branch name format template: <type>/<feature-name>
20
- - use .github/PULL_REQUEST_TEMPLATE.md to generate pull request description
21
- - PR titles starting with `✨ feat/` or `🐛 fix` will trigger the release workflow upon merge. Only use these prefixes for significant user-facing feature changes or bug fixes
36
+ - Use rebase for `git pull`
37
+ - Commit messages: prefix with gitmoji
38
+ - Branch format: `<type>/<feature-name>`
39
+ - PR titles with `✨ feat/` or `🐛 fix` trigger releases
22
40
 
23
41
  ### Package Management
24
42
 
25
- This repository adopts a monorepo structure.
26
-
27
- - Use `pnpm` as the primary package manager for dependency management
28
- - Use `bun` to run npm scripts
29
- - Use `bunx` to run executable npm packages
30
-
31
- ### TypeScript Code Style Guide
32
-
33
- see @.cursor/rules/typescript.mdc
34
-
35
- ### Code Comments
36
-
37
- - **Avoid meaningless comments**: Do not write comments that merely restate what the code does. Comments should explain _why_ something is done, not _what_ is being done. The code itself should be self-explanatory.
43
+ - `pnpm` for dependency management
44
+ - `bun` to run npm scripts
45
+ - `bunx` for executable npm packages
38
46
 
39
47
  ### Testing
40
48
 
41
- - **Required Rule**: read `.cursor/rules/testing-guide/testing-guide.mdc` before writing tests
42
- - **Command**:
43
- - web: `bunx vitest run --silent='passed-only' '[file-path-pattern]'`
44
- - packages(eg: database): `cd packages/database && bunx vitest run --silent='passed-only' '[file-path-pattern]'`
49
+ ```bash
50
+ # Run specific test (NEVER run `bun run test` - takes ~10 minutes)
51
+ bunx vitest run --silent='passed-only' '[file-path]'
45
52
 
46
- **Important**:
53
+ # Database package
54
+ cd packages/database && bunx vitest run --silent='passed-only' '[file]'
55
+ ```
47
56
 
48
- - wrap the file path in single quotes to avoid shell expansion
49
- - Never run `bun run test` etc to run tests, this will run all tests and cost about 10mins
50
- - If trying to fix the same test twice, but still failed, stop and ask for help.
51
- - **Prefer `vi.spyOn` over `vi.mock`**: When mocking modules or functions, prefer using `vi.spyOn` to mock specific functions rather than `vi.mock` to mock entire modules. This approach is more targeted, easier to maintain, and allows for better control over mock behavior in individual tests.
52
- - **Tests must pass type check**: After writing or modifying tests, run `bun run type-check` to ensure there are no type errors. Tests should pass both runtime execution and TypeScript type checking.
57
+ - Prefer `vi.spyOn` over `vi.mock`
58
+ - Tests must pass type check: `bun run type-check`
59
+ - After 2 failed fix attempts, stop and ask for help
53
60
 
54
- ### Typecheck
61
+ ### i18n
55
62
 
56
- - use `bun run type-check` to check type errors.
63
+ - Add keys to `src/locales/default/namespace.ts`
64
+ - For dev preview: translate `locales/zh-CN/` and `locales/en-US/`
65
+ - Don't run `pnpm i18n` - CI handles it
57
66
 
58
- ### i18n
67
+ ## Linear Issue Management
68
+
69
+ **Trigger conditions** - when ANY of these occur, apply Linear workflow:
59
70
 
60
- - **Keys**: Add to `src/locales/default/namespace.ts`
61
- - **Dev**: Translate `locales/zh-CN/namespace.json` and `locales/en-US/namespace.json` locales file only for dev preview
62
- - DON'T run `pnpm i18n`, let CI auto handle it
71
+ - User mentions issue ID like `LOBE-XXX`
72
+ - User says "linear", "link linear", "linear issue"
73
+ - Creating PR that references a Linear issue
63
74
 
64
- ## Linear Issue Management (search tools first; ignore if not installed)
75
+ **Workflow:**
65
76
 
66
- ClaudeCode may not inject MCP tools until they are discovered/used.\
67
- Before applying Linear workflows, **use tool search** to confirm `linear-server` exists (e.g. search `linear` / `mcp__linear-server__`). If not found, treat it as not installed.\
68
- Then read `@.cursor/rules/linear.mdc` when working with Linear issues.
77
+ 1. Use `ToolSearch` to confirm `linear-server` MCP exists (search `linear` or `mcp__linear-server__`)
78
+ 2. If found, read `.agents/skills/linear/SKILL.md` and follow the workflow
79
+ 3. If not found, skip Linear integration (treat as not installed)
69
80
 
70
- ## Rules Index
81
+ ## Skills (Auto-loaded by Claude)
71
82
 
72
- Some useful project rules are listed in @.cursor/rules/rules-index.mdc
83
+ Claude Code automatically loads relevant skills from `.agents/skills/`.