@lobehub/lobehub 2.0.0-next.295 → 2.0.0-next.297
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/CHANGELOG.md +50 -0
- package/changelog/v1.json +18 -0
- package/locales/en-US/plugin.json +4 -0
- package/locales/zh-CN/plugin.json +4 -0
- package/package.json +2 -2
- package/packages/agent-runtime/src/core/__tests__/runtime.test.ts +5 -5
- package/packages/agent-runtime/src/utils/stepContextComputer.test.ts +5 -5
- package/packages/builtin-tool-gtd/src/client/Inspector/index.ts +0 -4
- package/packages/builtin-tool-gtd/src/client/Intervention/AddTodo.tsx +1 -1
- package/packages/builtin-tool-gtd/src/client/Render/TodoList/index.tsx +39 -10
- package/packages/builtin-tool-gtd/src/client/Render/index.ts +0 -2
- package/packages/builtin-tool-gtd/src/client/components/SortableTodoList/TodoItemRow.tsx +26 -12
- package/packages/builtin-tool-gtd/src/client/components/SortableTodoList/store/actions.ts +5 -5
- package/packages/builtin-tool-gtd/src/client/components/SortableTodoList/store/store.test.ts +14 -8
- package/packages/builtin-tool-gtd/src/executor/index.test.ts +48 -227
- package/packages/builtin-tool-gtd/src/executor/index.ts +15 -158
- package/packages/builtin-tool-gtd/src/manifest.ts +12 -42
- package/packages/builtin-tool-gtd/src/systemRole.ts +14 -8
- package/packages/builtin-tool-gtd/src/types.ts +47 -41
- package/packages/builtin-tool-memory/package.json +8 -0
- package/packages/builtin-tool-memory/src/client/Inspector/AddContextMemory/index.tsx +60 -0
- package/packages/builtin-tool-memory/src/client/Inspector/AddExperienceMemory/index.tsx +60 -0
- package/packages/builtin-tool-memory/src/client/Inspector/AddIdentityMemory/index.tsx +60 -0
- package/packages/builtin-tool-memory/src/client/Inspector/AddPreferenceMemory/index.tsx +60 -0
- package/packages/builtin-tool-memory/src/client/Inspector/RemoveIdentityMemory/index.tsx +60 -0
- package/packages/builtin-tool-memory/src/client/Inspector/SearchUserMemory/index.tsx +67 -0
- package/packages/builtin-tool-memory/src/client/Inspector/UpdateIdentityMemory/index.tsx +60 -0
- package/packages/builtin-tool-memory/src/client/Inspector/index.ts +35 -0
- package/packages/builtin-tool-memory/src/client/Intervention/AddExperienceMemory/index.tsx +17 -0
- package/packages/builtin-tool-memory/src/client/Intervention/index.ts +13 -0
- package/packages/builtin-tool-memory/src/client/Render/AddExperienceMemory/index.tsx +17 -0
- package/packages/builtin-tool-memory/src/client/Render/SearchUserMemory/index.tsx +217 -0
- package/packages/builtin-tool-memory/src/client/Render/index.ts +15 -0
- package/packages/builtin-tool-memory/src/client/Streaming/AddExperienceMemory/index.tsx +17 -0
- package/packages/builtin-tool-memory/src/client/Streaming/index.ts +18 -0
- package/packages/builtin-tool-memory/src/client/components/ExperienceMemoryCard.tsx +231 -0
- package/packages/builtin-tool-memory/src/client/components/index.ts +1 -0
- package/packages/builtin-tool-memory/src/client/index.ts +27 -0
- package/packages/builtin-tool-memory/src/executor/index.ts +9 -1
- package/packages/builtin-tool-memory/src/types.ts +61 -0
- package/packages/context-engine/src/providers/GTDTodoInjector.ts +15 -7
- package/packages/conversation-flow/src/__tests__/fixtures/outputs/assistantGroup/tools-with-branches.json +4 -0
- package/packages/conversation-flow/src/transformation/FlatListBuilder.ts +1 -0
- package/packages/prompts/src/prompts/gtd/index.test.ts +32 -16
- package/packages/prompts/src/prompts/gtd/index.ts +9 -5
- package/packages/types/package.json +1 -1
- package/packages/types/src/discover/assistants.ts +4 -0
- package/packages/types/src/discover/groupAgents.ts +196 -0
- package/packages/types/src/discover/index.ts +5 -1
- package/packages/types/src/stepContext.ts +4 -1
- package/src/app/[variants]/(main)/community/(detail)/assistant/features/Details/Versions/index.tsx +2 -2
- package/src/app/[variants]/(main)/community/(detail)/group_agent/features/DetailProvider.tsx +19 -0
- package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/Members/index.tsx +137 -0
- package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/Nav.tsx +88 -0
- package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/Overview/index.tsx +213 -0
- package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/Related/index.tsx +85 -0
- package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/SystemRole/TagList.tsx +20 -0
- package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/SystemRole/index.tsx +71 -0
- package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/Versions/index.tsx +119 -0
- package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Details/index.tsx +51 -0
- package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Header.tsx +253 -0
- package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Sidebar/ActionButton/AddGroupAgent.tsx +222 -0
- package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Sidebar/ActionButton/index.tsx +34 -0
- package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Sidebar/Summary/index.tsx +42 -0
- package/src/app/[variants]/(main)/community/(detail)/group_agent/features/Sidebar/index.tsx +41 -0
- package/src/app/[variants]/(main)/community/(detail)/group_agent/features/StatusPage/index.tsx +104 -0
- package/src/app/[variants]/(main)/community/(detail)/group_agent/index.tsx +103 -0
- package/src/app/[variants]/(main)/community/(detail)/group_agent/loading.tsx +1 -0
- package/src/app/[variants]/(main)/community/(detail)/user/features/DetailProvider.tsx +7 -1
- package/src/app/[variants]/(main)/community/(detail)/user/features/UserContent.tsx +2 -0
- package/src/app/[variants]/(main)/community/(detail)/user/features/UserGroupCard.tsx +186 -0
- package/src/app/[variants]/(main)/community/(detail)/user/features/UserGroupList.tsx +59 -0
- package/src/app/[variants]/(main)/community/(detail)/user/index.tsx +3 -1
- package/src/app/[variants]/(main)/community/(list)/assistant/features/List/Item.tsx +26 -8
- package/src/app/[variants]/(main)/community/(list)/assistant/index.tsx +1 -0
- package/src/app/[variants]/(main)/community/features/Search.tsx +1 -1
- package/src/app/[variants]/(main)/group/profile/features/GroupProfile/index.tsx +2 -0
- package/src/app/[variants]/(main)/group/profile/features/Header/AgentPublishButton/PublishResultModal.tsx +2 -1
- package/src/app/[variants]/(main)/group/profile/features/Header/GroupPublishButton/GroupForkConfirmModal.tsx +60 -0
- package/src/app/[variants]/(main)/group/profile/features/Header/GroupPublishButton/GroupPublishResultModal.tsx +62 -0
- package/src/app/[variants]/(main)/group/profile/features/Header/GroupPublishButton/PublishButton.tsx +122 -0
- package/src/app/[variants]/(main)/group/profile/features/Header/GroupPublishButton/index.tsx +46 -0
- package/src/app/[variants]/(main)/group/profile/features/Header/GroupPublishButton/types.ts +12 -0
- package/src/app/[variants]/(main)/group/profile/features/Header/GroupPublishButton/useMarketGroupPublish.ts +211 -0
- package/src/app/[variants]/(main)/group/profile/features/Header/GroupPublishButton/utils.ts +22 -0
- package/src/app/[variants]/(main)/resource/features/DndContextWrapper.tsx +4 -2
- package/src/app/[variants]/(main)/resource/library/_layout/Header/LibraryHead.tsx +30 -35
- package/src/app/[variants]/(main)/resource/library/_layout/Header/index.tsx +9 -11
- package/src/app/[variants]/router/desktopRouter.config.tsx +7 -0
- package/src/features/Conversation/Messages/AssistantGroup/Tool/Actions/index.tsx +11 -17
- package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/LoadingPlaceholder/index.tsx +13 -3
- package/src/features/Conversation/Messages/AssistantGroup/Tool/Detail/Render/CustomRender.tsx +43 -0
- package/src/features/Conversation/Messages/AssistantGroup/Tool/Detail/Render/FallbacktArgumentRender.tsx +59 -0
- package/src/features/Conversation/Messages/AssistantGroup/Tool/Detail/Render/index.tsx +46 -0
- package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/index.tsx +13 -19
- package/src/features/Conversation/Messages/AssistantGroup/Tool/index.tsx +17 -17
- package/src/features/Conversation/Messages/Tool/Tool/index.tsx +10 -9
- package/src/features/Conversation/TodoProgress/index.tsx +56 -23
- package/src/features/PluginsUI/Render/MCPType/index.tsx +1 -1
- package/src/features/ResourceManager/components/Explorer/Header/index.tsx +57 -4
- package/src/features/ResourceManager/components/Explorer/ListView/ListItem/index.tsx +6 -4
- package/src/features/ResourceManager/components/Explorer/ListView/index.tsx +16 -5
- package/src/features/ResourceManager/components/LibraryHierarchy/styles.ts +5 -4
- package/src/hooks/useActiveTabKey.ts +1 -2
- package/src/locales/default/plugin.ts +1 -0
- package/src/locales/default/setting.ts +12 -0
- package/src/server/routers/lambda/market/agentGroup.ts +296 -0
- package/src/server/routers/lambda/market/index.ts +134 -4
- package/src/server/services/discover/index.ts +123 -7
- package/src/services/discover.ts +55 -0
- package/src/store/chat/slices/message/selectors/dbMessage.test.ts +11 -11
- package/src/store/discover/slices/groupAgent/action.ts +80 -0
- package/src/store/discover/store.ts +3 -0
- package/src/store/file/slices/resource/action.ts +4 -2
- package/src/tools/inspectors.ts +2 -0
- package/src/tools/interventions.ts +2 -0
- package/src/tools/renders.ts +3 -1
- package/src/tools/streamings.ts +2 -0
- package/packages/builtin-tool-gtd/src/client/Inspector/CompleteTodos/index.tsx +0 -52
- package/packages/builtin-tool-gtd/src/client/Inspector/RemoveTodos/index.tsx +0 -52
- package/src/features/Conversation/Messages/AssistantGroup/Tool/Render/CustomRender.tsx +0 -113
- package/src/features/Conversation/Messages/Tool/Tool/Render.tsx +0 -47
- /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/AbortResponse.tsx +0 -0
- /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/Arguments/index.tsx +0 -0
- /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/ErrorResponse.tsx +0 -0
- /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/Intervention/ApprovalActions.tsx +0 -0
- /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/Intervention/Fallback.tsx +0 -0
- /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/Intervention/KeyValueEditor.tsx +0 -0
- /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/Intervention/ModeSelector.tsx +0 -0
- /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/Intervention/index.tsx +0 -0
- /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/PluginSettings.tsx +0 -0
- /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/RejectedResponse.tsx +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,56 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## [Version 2.0.0-next.297](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.296...v2.0.0-next.297)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2026-01-16**</sup>
|
|
8
|
+
|
|
9
|
+
#### ✨ Features
|
|
10
|
+
|
|
11
|
+
- **misc**: Add agent group publish into market & use market group agents in lobehub.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### What's improved
|
|
19
|
+
|
|
20
|
+
- **misc**: Add agent group publish into market & use market group agents in lobehub, closes [#11535](https://github.com/lobehub/lobe-chat/issues/11535) ([02b9e76](https://github.com/lobehub/lobe-chat/commit/02b9e76))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
## [Version 2.0.0-next.296](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.295...v2.0.0-next.296)
|
|
31
|
+
|
|
32
|
+
<sup>Released on **2026-01-16**</sup>
|
|
33
|
+
|
|
34
|
+
#### 💄 Styles
|
|
35
|
+
|
|
36
|
+
- **misc**: Improve todo list.
|
|
37
|
+
|
|
38
|
+
<br/>
|
|
39
|
+
|
|
40
|
+
<details>
|
|
41
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
42
|
+
|
|
43
|
+
#### Styles
|
|
44
|
+
|
|
45
|
+
- **misc**: Improve todo list, closes [#11533](https://github.com/lobehub/lobe-chat/issues/11533) ([a4b71e9](https://github.com/lobehub/lobe-chat/commit/a4b71e9))
|
|
46
|
+
|
|
47
|
+
</details>
|
|
48
|
+
|
|
49
|
+
<div align="right">
|
|
50
|
+
|
|
51
|
+
[](#readme-top)
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
|
|
5
55
|
## [Version 2.0.0-next.295](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.294...v2.0.0-next.295)
|
|
6
56
|
|
|
7
57
|
<sup>Released on **2026-01-15**</sup>
|
package/changelog/v1.json
CHANGED
|
@@ -1,4 +1,22 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"children": {
|
|
4
|
+
"features": [
|
|
5
|
+
"Add agent group publish into market & use market group agents in lobehub."
|
|
6
|
+
]
|
|
7
|
+
},
|
|
8
|
+
"date": "2026-01-16",
|
|
9
|
+
"version": "2.0.0-next.297"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"children": {
|
|
13
|
+
"improvements": [
|
|
14
|
+
"Improve todo list."
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
"date": "2026-01-16",
|
|
18
|
+
"version": "2.0.0-next.296"
|
|
19
|
+
},
|
|
2
20
|
{
|
|
3
21
|
"children": {
|
|
4
22
|
"improvements": [
|
|
@@ -173,6 +173,10 @@
|
|
|
173
173
|
"builtins.lobe-user-memory.apiName.removeIdentityMemory": "Delete identity memory",
|
|
174
174
|
"builtins.lobe-user-memory.apiName.searchUserMemory": "Search memory",
|
|
175
175
|
"builtins.lobe-user-memory.apiName.updateIdentityMemory": "Update identity memory",
|
|
176
|
+
"builtins.lobe-user-memory.inspector.noResults": "No results",
|
|
177
|
+
"builtins.lobe-user-memory.render.contexts": "Contexts",
|
|
178
|
+
"builtins.lobe-user-memory.render.experiences": "Experiences",
|
|
179
|
+
"builtins.lobe-user-memory.render.preferences": "Preferences",
|
|
176
180
|
"builtins.lobe-user-memory.title": "Memory",
|
|
177
181
|
"builtins.lobe-web-browsing.apiName.crawlMultiPages": "Read multiple pages",
|
|
178
182
|
"builtins.lobe-web-browsing.apiName.crawlSinglePage": "Read page content",
|
|
@@ -173,6 +173,10 @@
|
|
|
173
173
|
"builtins.lobe-user-memory.apiName.removeIdentityMemory": "删除身份记忆",
|
|
174
174
|
"builtins.lobe-user-memory.apiName.searchUserMemory": "搜索记忆",
|
|
175
175
|
"builtins.lobe-user-memory.apiName.updateIdentityMemory": "更新身份记忆",
|
|
176
|
+
"builtins.lobe-user-memory.inspector.noResults": "无结果",
|
|
177
|
+
"builtins.lobe-user-memory.render.contexts": "情境记忆",
|
|
178
|
+
"builtins.lobe-user-memory.render.experiences": "经验记忆",
|
|
179
|
+
"builtins.lobe-user-memory.render.preferences": "偏好记忆",
|
|
176
180
|
"builtins.lobe-user-memory.title": "记忆",
|
|
177
181
|
"builtins.lobe-web-browsing.apiName.crawlMultiPages": "读取多个页面内容",
|
|
178
182
|
"builtins.lobe-web-browsing.apiName.crawlSinglePage": "读取页面内容",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/lobehub",
|
|
3
|
-
"version": "2.0.0-next.
|
|
3
|
+
"version": "2.0.0-next.297",
|
|
4
4
|
"description": "LobeHub - an open-source,comprehensive AI Agent framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"framework",
|
|
@@ -204,7 +204,7 @@
|
|
|
204
204
|
"@lobehub/desktop-ipc-typings": "workspace:*",
|
|
205
205
|
"@lobehub/editor": "^3.11.0",
|
|
206
206
|
"@lobehub/icons": "^4.0.2",
|
|
207
|
-
"@lobehub/market-sdk": "0.
|
|
207
|
+
"@lobehub/market-sdk": "0.29.0",
|
|
208
208
|
"@lobehub/tts": "^4.0.2",
|
|
209
209
|
"@lobehub/ui": "^4.19.0",
|
|
210
210
|
"@modelcontextprotocol/sdk": "^1.25.1",
|
|
@@ -1607,8 +1607,8 @@ describe('AgentRuntime', () => {
|
|
|
1607
1607
|
const stepContext = {
|
|
1608
1608
|
todos: {
|
|
1609
1609
|
items: [
|
|
1610
|
-
{ text: 'Buy milk',
|
|
1611
|
-
{ text: 'Call mom',
|
|
1610
|
+
{ text: 'Buy milk', status: 'todo' as const },
|
|
1611
|
+
{ text: 'Call mom', status: 'completed' as const },
|
|
1612
1612
|
],
|
|
1613
1613
|
updatedAt: '2024-06-01T00:00:00.000Z',
|
|
1614
1614
|
},
|
|
@@ -1634,7 +1634,7 @@ describe('AgentRuntime', () => {
|
|
|
1634
1634
|
stepContext: expect.objectContaining({
|
|
1635
1635
|
todos: expect.objectContaining({
|
|
1636
1636
|
items: expect.arrayContaining([
|
|
1637
|
-
expect.objectContaining({ text: 'Buy milk',
|
|
1637
|
+
expect.objectContaining({ text: 'Buy milk', status: 'todo' }),
|
|
1638
1638
|
]),
|
|
1639
1639
|
}),
|
|
1640
1640
|
}),
|
|
@@ -1666,7 +1666,7 @@ describe('AgentRuntime', () => {
|
|
|
1666
1666
|
|
|
1667
1667
|
const stepContext = {
|
|
1668
1668
|
todos: {
|
|
1669
|
-
items: [{ text: 'Task 1',
|
|
1669
|
+
items: [{ text: 'Task 1', status: 'todo' as const }],
|
|
1670
1670
|
updatedAt: '2024-06-01T00:00:00.000Z',
|
|
1671
1671
|
},
|
|
1672
1672
|
};
|
|
@@ -1746,7 +1746,7 @@ describe('AgentRuntime', () => {
|
|
|
1746
1746
|
|
|
1747
1747
|
const stepContext = {
|
|
1748
1748
|
todos: {
|
|
1749
|
-
items: [{ text: 'Batch task',
|
|
1749
|
+
items: [{ text: 'Batch task', status: 'todo' as const }],
|
|
1750
1750
|
updatedAt: '2024-06-01T00:00:00.000Z',
|
|
1751
1751
|
},
|
|
1752
1752
|
};
|
|
@@ -7,8 +7,8 @@ describe('computeStepContext', () => {
|
|
|
7
7
|
it('should include todos when provided', () => {
|
|
8
8
|
const todos = {
|
|
9
9
|
items: [
|
|
10
|
-
{ text: 'Buy milk',
|
|
11
|
-
{ text: 'Call mom',
|
|
10
|
+
{ text: 'Buy milk', status: 'todo' as const },
|
|
11
|
+
{ text: 'Call mom', status: 'completed' as const },
|
|
12
12
|
],
|
|
13
13
|
updatedAt: '2024-06-01T00:00:00.000Z',
|
|
14
14
|
};
|
|
@@ -18,9 +18,9 @@ describe('computeStepContext', () => {
|
|
|
18
18
|
expect(result.todos).toBeDefined();
|
|
19
19
|
expect(result.todos?.items).toHaveLength(2);
|
|
20
20
|
expect(result.todos?.items[0].text).toBe('Buy milk');
|
|
21
|
-
expect(result.todos?.items[0].
|
|
21
|
+
expect(result.todos?.items[0].status).toBe('todo');
|
|
22
22
|
expect(result.todos?.items[1].text).toBe('Call mom');
|
|
23
|
-
expect(result.todos?.items[1].
|
|
23
|
+
expect(result.todos?.items[1].status).toBe('completed');
|
|
24
24
|
});
|
|
25
25
|
|
|
26
26
|
it('should not include todos key when undefined', () => {
|
|
@@ -42,7 +42,7 @@ describe('computeStepContext', () => {
|
|
|
42
42
|
// This should compile and work - object param allows future extensions
|
|
43
43
|
const result = computeStepContext({
|
|
44
44
|
todos: {
|
|
45
|
-
items: [{ text: 'Task',
|
|
45
|
+
items: [{ text: 'Task', status: 'todo' as const }],
|
|
46
46
|
updatedAt: '2024-01-01T00:00:00.000Z',
|
|
47
47
|
},
|
|
48
48
|
});
|
|
@@ -2,12 +2,10 @@ import { type BuiltinInspector } from '@lobechat/types';
|
|
|
2
2
|
|
|
3
3
|
import { GTDApiName } from '../../types';
|
|
4
4
|
import { ClearTodosInspector } from './ClearTodos';
|
|
5
|
-
import { CompleteTodosInspector } from './CompleteTodos';
|
|
6
5
|
import { CreatePlanInspector } from './CreatePlan';
|
|
7
6
|
import { CreateTodosInspector } from './CreateTodos';
|
|
8
7
|
import { ExecTaskInspector } from './ExecTask';
|
|
9
8
|
import { ExecTasksInspector } from './ExecTasks';
|
|
10
|
-
import { RemoveTodosInspector } from './RemoveTodos';
|
|
11
9
|
import { UpdatePlanInspector } from './UpdatePlan';
|
|
12
10
|
import { UpdateTodosInspector } from './UpdateTodos';
|
|
13
11
|
|
|
@@ -19,12 +17,10 @@ import { UpdateTodosInspector } from './UpdateTodos';
|
|
|
19
17
|
*/
|
|
20
18
|
export const GTDInspectors: Record<string, BuiltinInspector> = {
|
|
21
19
|
[GTDApiName.clearTodos]: ClearTodosInspector as BuiltinInspector,
|
|
22
|
-
[GTDApiName.completeTodos]: CompleteTodosInspector as BuiltinInspector,
|
|
23
20
|
[GTDApiName.createPlan]: CreatePlanInspector as BuiltinInspector,
|
|
24
21
|
[GTDApiName.createTodos]: CreateTodosInspector as BuiltinInspector,
|
|
25
22
|
[GTDApiName.execTask]: ExecTaskInspector as BuiltinInspector,
|
|
26
23
|
[GTDApiName.execTasks]: ExecTasksInspector as BuiltinInspector,
|
|
27
|
-
[GTDApiName.removeTodos]: RemoveTodosInspector as BuiltinInspector,
|
|
28
24
|
[GTDApiName.updatePlan]: UpdatePlanInspector as BuiltinInspector,
|
|
29
25
|
[GTDApiName.updateTodos]: UpdateTodosInspector as BuiltinInspector,
|
|
30
26
|
};
|
|
@@ -17,7 +17,7 @@ const AddTodoIntervention = memo<BuiltinInterventionProps<CreateTodosParams>>(
|
|
|
17
17
|
// - Initial AI input: { adds: string[] } (from AI)
|
|
18
18
|
// - After user edit: { items: TodoItem[] } (saved format)
|
|
19
19
|
const defaultItems: TodoItem[] =
|
|
20
|
-
args?.items || args?.adds?.map((text) => ({
|
|
20
|
+
args?.items || args?.adds?.map((text) => ({ status: 'todo', text })) || [];
|
|
21
21
|
|
|
22
22
|
const handleSave = useCallback(
|
|
23
23
|
async (items: TodoItem[]) => {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { type BuiltinRenderProps } from '@lobechat/types';
|
|
4
|
-
import { Block, Checkbox } from '@lobehub/ui';
|
|
5
|
-
import { createStaticStyles, cssVar } from 'antd-style';
|
|
4
|
+
import { Block, Checkbox, Icon } from '@lobehub/ui';
|
|
5
|
+
import { createStaticStyles, cssVar, cx } from 'antd-style';
|
|
6
|
+
import { CircleArrowRight } from 'lucide-react';
|
|
6
7
|
import { memo } from 'react';
|
|
7
8
|
|
|
8
|
-
import type { TodoItem, TodoList as TodoListType } from '../../../types';
|
|
9
|
+
import type { TodoItem, TodoList as TodoListType, TodoStatus } from '../../../types';
|
|
9
10
|
|
|
10
11
|
export interface TodoListRenderState {
|
|
11
12
|
todos?: TodoListType;
|
|
@@ -23,30 +24,58 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
23
24
|
border-block-end: none;
|
|
24
25
|
}
|
|
25
26
|
`,
|
|
26
|
-
|
|
27
|
+
processingRow: css`
|
|
28
|
+
display: flex;
|
|
29
|
+
gap: 7px;
|
|
30
|
+
align-items: center;
|
|
31
|
+
`,
|
|
32
|
+
textCompleted: css`
|
|
27
33
|
color: ${cssVar.colorTextQuaternary};
|
|
28
34
|
text-decoration: line-through;
|
|
29
35
|
`,
|
|
36
|
+
textProcessing: css`
|
|
37
|
+
color: ${cssVar.colorText};
|
|
38
|
+
`,
|
|
39
|
+
textTodo: css`
|
|
40
|
+
color: ${cssVar.colorTextSecondary};
|
|
41
|
+
`,
|
|
30
42
|
}));
|
|
31
43
|
|
|
32
44
|
interface ReadOnlyTodoItemProps {
|
|
33
|
-
|
|
45
|
+
status: TodoStatus;
|
|
34
46
|
text: string;
|
|
35
47
|
}
|
|
36
48
|
|
|
37
49
|
/**
|
|
38
50
|
* Read-only todo item row, matching the style of TodoItemRow in SortableTodoList
|
|
39
51
|
*/
|
|
40
|
-
const ReadOnlyTodoItem = memo<ReadOnlyTodoItemProps>(({ text,
|
|
52
|
+
const ReadOnlyTodoItem = memo<ReadOnlyTodoItemProps>(({ text, status }) => {
|
|
53
|
+
const isCompleted = status === 'completed';
|
|
54
|
+
const isProcessing = status === 'processing';
|
|
55
|
+
|
|
56
|
+
// Processing state uses CircleArrowRight icon
|
|
57
|
+
if (isProcessing) {
|
|
58
|
+
return (
|
|
59
|
+
<div className={cx(styles.itemRow, styles.processingRow)}>
|
|
60
|
+
<Icon icon={CircleArrowRight} size={17} style={{ color: cssVar.colorTextSecondary }} />
|
|
61
|
+
<span className={styles.textProcessing}>{text}</span>
|
|
62
|
+
</div>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Todo and completed states use Checkbox
|
|
41
67
|
return (
|
|
42
68
|
<Checkbox
|
|
43
69
|
backgroundColor={cssVar.colorSuccess}
|
|
44
|
-
checked={
|
|
45
|
-
classNames={{
|
|
70
|
+
checked={isCompleted}
|
|
71
|
+
classNames={{
|
|
72
|
+
text: cx(styles.textTodo, isCompleted && styles.textCompleted),
|
|
73
|
+
wrapper: styles.itemRow,
|
|
74
|
+
}}
|
|
46
75
|
shape={'circle'}
|
|
47
76
|
style={{ borderWidth: 1.5, cursor: 'default' }}
|
|
48
77
|
textProps={{
|
|
49
|
-
type:
|
|
78
|
+
type: isCompleted ? 'secondary' : undefined,
|
|
50
79
|
}}
|
|
51
80
|
>
|
|
52
81
|
{text}
|
|
@@ -73,7 +102,7 @@ const TodoListUI = memo<TodoListUIProps>(({ items }) => {
|
|
|
73
102
|
// Outer container with background - matches AddTodoIntervention
|
|
74
103
|
<Block variant={'outlined'} width="100%">
|
|
75
104
|
{items.map((item, index) => (
|
|
76
|
-
<ReadOnlyTodoItem
|
|
105
|
+
<ReadOnlyTodoItem key={index} status={item.status} text={item.text} />
|
|
77
106
|
))}
|
|
78
107
|
</Block>
|
|
79
108
|
);
|
|
@@ -14,9 +14,7 @@ import TodoListRender from './TodoList';
|
|
|
14
14
|
export const GTDRenders = {
|
|
15
15
|
// All todo operations render the same TodoList UI
|
|
16
16
|
[GTDApiName.clearTodos]: TodoListRender,
|
|
17
|
-
[GTDApiName.completeTodos]: TodoListRender,
|
|
18
17
|
[GTDApiName.createTodos]: TodoListRender,
|
|
19
|
-
[GTDApiName.removeTodos]: TodoListRender,
|
|
20
18
|
[GTDApiName.updateTodos]: TodoListRender,
|
|
21
19
|
|
|
22
20
|
// Plan operations render the PlanCard UI
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { ActionIcon, Checkbox, Flexbox, SortableList } from '@lobehub/ui';
|
|
3
|
+
import { ActionIcon, Checkbox, Flexbox, Icon, SortableList } from '@lobehub/ui';
|
|
4
4
|
import { Input, InputRef } from 'antd';
|
|
5
5
|
import { createStaticStyles, cssVar, cx } from 'antd-style';
|
|
6
|
-
import { Trash2 } from 'lucide-react';
|
|
6
|
+
import { CircleArrowRight, Trash2 } from 'lucide-react';
|
|
7
7
|
import { ChangeEvent, KeyboardEvent, memo, useCallback, useEffect, useRef } from 'react';
|
|
8
8
|
import { useTranslation } from 'react-i18next';
|
|
9
9
|
|
|
@@ -34,10 +34,13 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
`,
|
|
37
|
-
|
|
37
|
+
textCompleted: css`
|
|
38
38
|
color: ${cssVar.colorTextQuaternary};
|
|
39
39
|
text-decoration: line-through;
|
|
40
40
|
`,
|
|
41
|
+
textProcessing: css`
|
|
42
|
+
color: ${cssVar.colorWarningText};
|
|
43
|
+
`,
|
|
41
44
|
}));
|
|
42
45
|
|
|
43
46
|
interface TodoItemRowProps {
|
|
@@ -53,7 +56,9 @@ const TodoItemRow = memo<TodoItemRowProps>(({ id, placeholder }) => {
|
|
|
53
56
|
// Find item by stable id
|
|
54
57
|
const item = useTodoListStore((s) => s.items.find((item) => item.id === id));
|
|
55
58
|
const text = item?.text ?? '';
|
|
56
|
-
const
|
|
59
|
+
const status = item?.status ?? 'todo';
|
|
60
|
+
const isCompleted = status === 'completed';
|
|
61
|
+
const isProcessing = status === 'processing';
|
|
57
62
|
|
|
58
63
|
const focusedId = useTodoListStore((s) => s.focusedId);
|
|
59
64
|
const cursorPosition = useTodoListStore((s) => s.cursorPosition);
|
|
@@ -123,15 +128,24 @@ const TodoItemRow = memo<TodoItemRowProps>(({ id, placeholder }) => {
|
|
|
123
128
|
return (
|
|
124
129
|
<Flexbox align="center" className={styles.itemRow} gap={4} horizontal width="100%">
|
|
125
130
|
<SortableList.DragHandle className={cx(styles.dragHandle, 'drag-handle')} size="small" />
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
131
|
+
{isProcessing ? (
|
|
132
|
+
<Icon
|
|
133
|
+
icon={CircleArrowRight}
|
|
134
|
+
onClick={handleToggle}
|
|
135
|
+
size={16}
|
|
136
|
+
style={{ color: cssVar.colorInfo, cursor: 'pointer', flexShrink: 0 }}
|
|
137
|
+
/>
|
|
138
|
+
) : (
|
|
139
|
+
<Checkbox
|
|
140
|
+
backgroundColor={cssVar.colorSuccess}
|
|
141
|
+
checked={isCompleted}
|
|
142
|
+
onChange={handleToggle}
|
|
143
|
+
shape={'circle'}
|
|
144
|
+
style={{ borderWidth: 1.5 }}
|
|
145
|
+
/>
|
|
146
|
+
)}
|
|
133
147
|
<Input
|
|
134
|
-
className={cx(
|
|
148
|
+
className={cx(isCompleted && styles.textCompleted, isProcessing && styles.textProcessing)}
|
|
135
149
|
onChange={handleChange}
|
|
136
150
|
onFocus={handleFocus}
|
|
137
151
|
onKeyDown={handleKeyDown}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { debounce } from 'es-toolkit/compat';
|
|
2
2
|
|
|
3
|
-
import type
|
|
3
|
+
import { getNextTodoStatus, type TodoItem } from '../../../../types';
|
|
4
4
|
import { AUTO_SAVE_DELAY, AUTO_SAVE_MAX_WAIT, initialState } from './initialState';
|
|
5
5
|
import type { StoreInternals, TodoListItem, TodoListStore } from './types';
|
|
6
6
|
import { ADD_ITEM_ID } from './types';
|
|
@@ -37,7 +37,7 @@ export const createActions = (
|
|
|
37
37
|
|
|
38
38
|
try {
|
|
39
39
|
// Convert TodoListItem[] to TodoItem[] (remove id)
|
|
40
|
-
const todoItems: TodoItem[] = items.map(({
|
|
40
|
+
const todoItems: TodoItem[] = items.map(({ status, text }) => ({ status, text }));
|
|
41
41
|
console.log('[performSave] calling onSave with', todoItems.length, 'items');
|
|
42
42
|
await internals.onSave(todoItems);
|
|
43
43
|
console.log('[performSave] onSave completed');
|
|
@@ -69,7 +69,7 @@ export const createActions = (
|
|
|
69
69
|
if (!newItemText.trim()) return;
|
|
70
70
|
|
|
71
71
|
set({
|
|
72
|
-
items: [...items, {
|
|
72
|
+
items: [...items, { id: generateId(), status: 'todo', text: newItemText.trim() }],
|
|
73
73
|
newItemText: '',
|
|
74
74
|
});
|
|
75
75
|
markDirtyAndSave();
|
|
@@ -97,7 +97,7 @@ export const createActions = (
|
|
|
97
97
|
set({ saveStatus: 'saving' });
|
|
98
98
|
|
|
99
99
|
try {
|
|
100
|
-
const todoItems: TodoItem[] = items.map(({
|
|
100
|
+
const todoItems: TodoItem[] = items.map(({ status, text }) => ({ status, text }));
|
|
101
101
|
console.log('[saveNow] force saving', todoItems.length, 'items');
|
|
102
102
|
await internals.onSave(todoItems);
|
|
103
103
|
console.log('[saveNow] save completed');
|
|
@@ -160,7 +160,7 @@ export const createActions = (
|
|
|
160
160
|
const { items } = get();
|
|
161
161
|
set({
|
|
162
162
|
items: items.map((item) =>
|
|
163
|
-
item.id === id ? { ...item,
|
|
163
|
+
item.id === id ? { ...item, status: getNextTodoStatus(item.status) } : item,
|
|
164
164
|
),
|
|
165
165
|
});
|
|
166
166
|
markDirtyAndSave();
|
package/packages/builtin-tool-gtd/src/client/components/SortableTodoList/store/store.test.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { ADD_ITEM_ID } from './types';
|
|
|
8
8
|
|
|
9
9
|
// Helper to create TodoItem array from text strings
|
|
10
10
|
const toTodoItems = (...texts: string[]): TodoItem[] =>
|
|
11
|
-
texts.map((text) => ({
|
|
11
|
+
texts.map((text) => ({ status: 'todo', text }));
|
|
12
12
|
|
|
13
13
|
describe('TodoListStore', () => {
|
|
14
14
|
beforeEach(() => {
|
|
@@ -39,7 +39,7 @@ describe('TodoListStore', () => {
|
|
|
39
39
|
|
|
40
40
|
expect(state.items).toHaveLength(2);
|
|
41
41
|
expect(state.items[0].text).toBe('Task 1');
|
|
42
|
-
expect(state.items[0].
|
|
42
|
+
expect(state.items[0].status).toBe('todo');
|
|
43
43
|
expect(state.items[1].text).toBe('Task 2');
|
|
44
44
|
});
|
|
45
45
|
|
|
@@ -63,7 +63,7 @@ describe('TodoListStore', () => {
|
|
|
63
63
|
const state = store.getState();
|
|
64
64
|
expect(state.items).toHaveLength(1);
|
|
65
65
|
expect(state.items[0].text).toBe('New Task');
|
|
66
|
-
expect(state.items[0].
|
|
66
|
+
expect(state.items[0].status).toBe('todo');
|
|
67
67
|
expect(state.newItemText).toBe('');
|
|
68
68
|
});
|
|
69
69
|
|
|
@@ -152,23 +152,29 @@ describe('TodoListStore', () => {
|
|
|
152
152
|
});
|
|
153
153
|
|
|
154
154
|
describe('toggleItem', () => {
|
|
155
|
-
it('should
|
|
155
|
+
it('should cycle through status: todo → processing → completed → todo', () => {
|
|
156
156
|
const store = createTodoListStore(toTodoItems('Task 1'));
|
|
157
157
|
const itemId = store.getState().items[0].id;
|
|
158
158
|
|
|
159
|
-
expect(store.getState().items[0].
|
|
159
|
+
expect(store.getState().items[0].status).toBe('todo');
|
|
160
160
|
|
|
161
161
|
act(() => {
|
|
162
162
|
store.getState().toggleItem(itemId);
|
|
163
163
|
});
|
|
164
164
|
|
|
165
|
-
expect(store.getState().items[0].
|
|
165
|
+
expect(store.getState().items[0].status).toBe('processing');
|
|
166
166
|
|
|
167
167
|
act(() => {
|
|
168
168
|
store.getState().toggleItem(itemId);
|
|
169
169
|
});
|
|
170
170
|
|
|
171
|
-
expect(store.getState().items[0].
|
|
171
|
+
expect(store.getState().items[0].status).toBe('completed');
|
|
172
|
+
|
|
173
|
+
act(() => {
|
|
174
|
+
store.getState().toggleItem(itemId);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
expect(store.getState().items[0].status).toBe('todo');
|
|
172
178
|
});
|
|
173
179
|
|
|
174
180
|
it('should mark store as dirty after toggling item', () => {
|
|
@@ -362,7 +368,7 @@ describe('TodoListStore', () => {
|
|
|
362
368
|
|
|
363
369
|
expect(onSave).toHaveBeenCalledTimes(1);
|
|
364
370
|
// onSave receives TodoItem[] (without id), not TodoListItem[]
|
|
365
|
-
expect(onSave).toHaveBeenCalledWith([{
|
|
371
|
+
expect(onSave).toHaveBeenCalledWith([{ status: 'todo', text: 'Updated' }]);
|
|
366
372
|
});
|
|
367
373
|
|
|
368
374
|
it('should set saveStatus to saving during save', async () => {
|