@lobehub/lobehub 2.0.0-next.294 → 2.0.0-next.296

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 (249) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/apps/desktop/src/main/__mocks__/node-mac-permissions.ts +0 -1
  3. package/apps/desktop/src/main/__mocks__/setup.ts +0 -1
  4. package/apps/desktop/src/main/controllers/__tests__/SystemCtr.test.ts +1 -4
  5. package/apps/desktop/tsconfig.json +4 -10
  6. package/changelog/v1.json +18 -0
  7. package/e2e/scripts/setup.ts +45 -32
  8. package/locales/en-US/plugin.json +4 -0
  9. package/locales/zh-CN/plugin.json +4 -0
  10. package/package.json +1 -1
  11. package/packages/agent-runtime/src/core/__tests__/runtime.test.ts +5 -5
  12. package/packages/agent-runtime/src/utils/stepContextComputer.test.ts +5 -5
  13. package/packages/builtin-tool-gtd/src/client/Inspector/index.ts +0 -4
  14. package/packages/builtin-tool-gtd/src/client/Intervention/AddTodo.tsx +1 -1
  15. package/packages/builtin-tool-gtd/src/client/Render/TodoList/index.tsx +39 -10
  16. package/packages/builtin-tool-gtd/src/client/Render/index.ts +0 -2
  17. package/packages/builtin-tool-gtd/src/client/components/SortableTodoList/TodoItemRow.tsx +26 -12
  18. package/packages/builtin-tool-gtd/src/client/components/SortableTodoList/store/actions.ts +5 -5
  19. package/packages/builtin-tool-gtd/src/client/components/SortableTodoList/store/store.test.ts +14 -8
  20. package/packages/builtin-tool-gtd/src/executor/index.test.ts +48 -227
  21. package/packages/builtin-tool-gtd/src/executor/index.ts +15 -158
  22. package/packages/builtin-tool-gtd/src/manifest.ts +12 -42
  23. package/packages/builtin-tool-gtd/src/systemRole.ts +14 -8
  24. package/packages/builtin-tool-gtd/src/types.ts +47 -41
  25. package/packages/builtin-tool-memory/package.json +8 -0
  26. package/packages/builtin-tool-memory/src/client/Inspector/AddContextMemory/index.tsx +60 -0
  27. package/packages/builtin-tool-memory/src/client/Inspector/AddExperienceMemory/index.tsx +60 -0
  28. package/packages/builtin-tool-memory/src/client/Inspector/AddIdentityMemory/index.tsx +60 -0
  29. package/packages/builtin-tool-memory/src/client/Inspector/AddPreferenceMemory/index.tsx +60 -0
  30. package/packages/builtin-tool-memory/src/client/Inspector/RemoveIdentityMemory/index.tsx +60 -0
  31. package/packages/builtin-tool-memory/src/client/Inspector/SearchUserMemory/index.tsx +67 -0
  32. package/packages/builtin-tool-memory/src/client/Inspector/UpdateIdentityMemory/index.tsx +60 -0
  33. package/packages/builtin-tool-memory/src/client/Inspector/index.ts +35 -0
  34. package/packages/builtin-tool-memory/src/client/Intervention/AddExperienceMemory/index.tsx +17 -0
  35. package/packages/builtin-tool-memory/src/client/Intervention/index.ts +13 -0
  36. package/packages/builtin-tool-memory/src/client/Render/AddExperienceMemory/index.tsx +17 -0
  37. package/packages/builtin-tool-memory/src/client/Render/SearchUserMemory/index.tsx +217 -0
  38. package/packages/builtin-tool-memory/src/client/Render/index.ts +15 -0
  39. package/packages/builtin-tool-memory/src/client/Streaming/AddExperienceMemory/index.tsx +17 -0
  40. package/packages/builtin-tool-memory/src/client/Streaming/index.ts +18 -0
  41. package/packages/builtin-tool-memory/src/client/components/ExperienceMemoryCard.tsx +231 -0
  42. package/packages/builtin-tool-memory/src/client/components/index.ts +1 -0
  43. package/packages/builtin-tool-memory/src/client/index.ts +27 -0
  44. package/packages/builtin-tool-memory/src/executor/index.ts +9 -1
  45. package/packages/builtin-tool-memory/src/types.ts +61 -0
  46. package/packages/context-engine/src/providers/GTDTodoInjector.ts +15 -7
  47. package/packages/conversation-flow/src/__tests__/fixtures/outputs/assistantGroup/tools-with-branches.json +4 -0
  48. package/packages/conversation-flow/src/transformation/FlatListBuilder.ts +1 -0
  49. package/packages/database/src/models/__tests__/knowledgeBase.test.ts +1 -1
  50. package/packages/database/src/repositories/knowledge/index.ts +1 -4
  51. package/packages/prompts/src/prompts/gtd/index.test.ts +32 -16
  52. package/packages/prompts/src/prompts/gtd/index.ts +9 -5
  53. package/packages/types/src/discover/assistants.ts +2 -2
  54. package/packages/types/src/stepContext.ts +4 -1
  55. package/scripts/migrate-spa-navigation.ts +129 -0
  56. package/src/app/(backend)/api/workflows/memory-user-memory/pipelines/chat-topic/process-topics/route.ts +112 -109
  57. package/src/app/(backend)/api/workflows/memory-user-memory/pipelines/chat-topic/process-user-topics/route.ts +125 -113
  58. package/src/app/(backend)/api/workflows/memory-user-memory/pipelines/chat-topic/process-users/route.ts +74 -65
  59. package/src/app/[variants]/(auth)/auth-error/page.tsx +1 -1
  60. package/src/app/[variants]/(auth)/login/[[...login]]/page.tsx +1 -1
  61. package/src/app/[variants]/(auth)/next-auth/error/AuthErrorPage.tsx +1 -1
  62. package/src/app/[variants]/(auth)/next-auth/signin/AuthSignInBox.tsx +1 -1
  63. package/src/app/[variants]/(auth)/oauth/callback/error/page.tsx +1 -1
  64. package/src/app/[variants]/(auth)/oauth/callback/success/page.tsx +1 -1
  65. package/src/app/[variants]/(auth)/oauth/consent/[uid]/page.tsx +1 -1
  66. package/src/app/[variants]/(auth)/reset-password/layout.tsx +1 -1
  67. package/src/app/[variants]/(auth)/reset-password/page.tsx +2 -2
  68. package/src/app/[variants]/(auth)/signin/layout.tsx +1 -1
  69. package/src/app/[variants]/(auth)/signin/useSignIn.ts +1 -1
  70. package/src/app/[variants]/(auth)/signup/[[...signup]]/BetterAuthSignUpForm.tsx +2 -2
  71. package/src/app/[variants]/(auth)/signup/[[...signup]]/page.tsx +1 -1
  72. package/src/app/[variants]/(auth)/signup/[[...signup]]/useSignUp.tsx +1 -1
  73. package/src/app/[variants]/(auth)/verify-email/layout.tsx +1 -1
  74. package/src/app/[variants]/(auth)/verify-email/page.tsx +2 -2
  75. package/src/app/[variants]/(main)/_layout/index.tsx +1 -1
  76. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Cron/CronTopicGroup.tsx +1 -1
  77. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Header/AddTopicButon.tsx +1 -1
  78. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Header/Nav.tsx +1 -1
  79. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Topic/AllTopicsDrawer/index.tsx +1 -1
  80. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Topic/hooks/useThreadNavigation.ts +1 -1
  81. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Topic/hooks/useTopicNavigation.ts +1 -1
  82. package/src/app/[variants]/(main)/agent/features/TelemetryNotification.tsx +2 -3
  83. package/src/app/[variants]/(main)/community/(detail)/assistant/features/Details/Nav.tsx +9 -9
  84. package/src/app/[variants]/(main)/community/(detail)/assistant/features/Details/Versions/index.tsx +2 -3
  85. package/src/app/[variants]/(main)/community/(detail)/features/MakedownRender.tsx +1 -2
  86. package/src/app/[variants]/(main)/community/(detail)/features/ShareButton.tsx +2 -3
  87. package/src/app/[variants]/(main)/community/(detail)/features/Toc/Heading.tsx +2 -3
  88. package/src/app/[variants]/(main)/community/(detail)/mcp/features/Details/Versions/index.tsx +2 -2
  89. package/src/app/[variants]/(main)/community/(detail)/model/features/Details/Nav.tsx +12 -11
  90. package/src/app/[variants]/(main)/community/(detail)/model/features/Details/Parameter/ParameterItem.tsx +2 -3
  91. package/src/app/[variants]/(main)/community/(detail)/provider/features/Details/Nav.tsx +11 -10
  92. package/src/app/[variants]/(main)/community/(detail)/provider/features/Header.tsx +10 -9
  93. package/src/app/[variants]/(main)/community/(list)/(home)/index.tsx +1 -1
  94. package/src/app/[variants]/(main)/community/(list)/assistant/features/Category/useCategory.tsx +1 -1
  95. package/src/app/[variants]/(main)/community/(list)/features/SortButton/index.tsx +2 -3
  96. package/src/app/[variants]/(main)/community/_layout/Sidebar/Header/Nav.tsx +1 -1
  97. package/src/app/[variants]/(main)/community/features/CreateButton/Inner.tsx +1 -1
  98. package/src/app/[variants]/(main)/community/features/CreateButton/index.tsx +1 -1
  99. package/src/app/[variants]/(main)/community/features/Search.tsx +1 -2
  100. package/src/app/[variants]/(main)/community/features/Title.tsx +5 -5
  101. package/src/app/[variants]/(main)/group/_layout/Sidebar/Header/Nav.tsx +1 -1
  102. package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/AllTopicsDrawer/index.tsx +1 -1
  103. package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/hooks/useThreadNavigation.ts +1 -1
  104. package/src/app/[variants]/(main)/group/features/Conversation/Header/ShareButton/index.tsx +1 -1
  105. package/src/app/[variants]/(main)/group/features/TelemetryNotification.tsx +2 -3
  106. package/src/app/[variants]/(main)/home/_layout/Body/Agent/AllAgentsDrawer/index.tsx +1 -1
  107. package/src/app/[variants]/(main)/hooks/useActiveTabKey.ts +6 -11
  108. package/src/app/[variants]/(main)/image/NotSupportClient.tsx +4 -3
  109. package/src/app/[variants]/(main)/image/_layout/ConfigPanel/components/ImageUpload.tsx +1 -1
  110. package/src/app/[variants]/(main)/image/_layout/ConfigPanel/components/MultiImagesUpload/ImageManageModal.tsx +1 -1
  111. package/src/app/[variants]/(main)/image/_layout/ConfigPanel/components/MultiImagesUpload/index.tsx +1 -1
  112. package/src/app/[variants]/(main)/memory/(home)/features/RoleTagCloud/index.tsx +1 -1
  113. package/src/app/[variants]/(main)/memory/_layout/Sidebar/Header/Nav.tsx +1 -1
  114. package/src/app/[variants]/(main)/memory/features/SourceLink.tsx +1 -1
  115. package/src/app/[variants]/(main)/page/_layout/Body/AllPagesDrawer/index.tsx +1 -1
  116. package/src/app/[variants]/(main)/resource/features/DndContextWrapper.tsx +4 -2
  117. package/src/app/[variants]/(main)/resource/library/_layout/Header/LibraryHead.tsx +30 -35
  118. package/src/app/[variants]/(main)/resource/library/_layout/Header/index.tsx +9 -11
  119. package/src/app/[variants]/(main)/settings/about/features/ItemCard.tsx +2 -3
  120. package/src/app/[variants]/(main)/settings/about/features/ItemLink.tsx +2 -3
  121. package/src/app/[variants]/(main)/settings/about/features/Version.tsx +6 -7
  122. package/src/app/[variants]/(main)/settings/features/SettingsContent.tsx +1 -1
  123. package/src/app/[variants]/(main)/settings/features/UpgradeAlert.tsx +4 -4
  124. package/src/app/[variants]/(main)/settings/provider/(list)/Footer.tsx +2 -2
  125. package/src/app/[variants]/(main)/settings/provider/detail/index.tsx +1 -1
  126. package/src/app/[variants]/(main)/settings/provider/detail/ollama/CheckError.tsx +1 -1
  127. package/src/app/[variants]/(main)/settings/provider/features/ProviderConfig/index.tsx +12 -6
  128. package/src/app/[variants]/(main)/settings/security/index.tsx +1 -1
  129. package/src/app/[variants]/(main)/settings/stats/features/overview/ShareButton/ShareModal.tsx +1 -1
  130. package/src/app/[variants]/(main)/settings/stats/features/rankings/AssistantsRank.tsx +1 -1
  131. package/src/app/[variants]/(main)/settings/stats/features/rankings/TopicsRank.tsx +1 -1
  132. package/src/app/[variants]/(mobile)/_layout/index.tsx +1 -1
  133. package/src/app/[variants]/(mobile)/chat/settings/features/AgentInfoDescription/index.tsx +1 -1
  134. package/src/app/[variants]/(mobile)/chat/settings/features/SettingButton.tsx +1 -1
  135. package/src/app/[variants]/(mobile)/router/index.tsx +1 -1
  136. package/src/app/[variants]/page.tsx +1 -1
  137. package/src/app/[variants]/router/index.tsx +1 -1
  138. package/src/components/404/index.tsx +4 -4
  139. package/src/components/Analytics/index.tsx +1 -1
  140. package/src/components/BrandWatermark/index.tsx +4 -4
  141. package/src/components/Branding/ProductLogo/Custom.tsx +1 -1
  142. package/src/components/Error/index.tsx +3 -4
  143. package/src/components/GoBack/index.tsx +2 -2
  144. package/src/components/LabsModal/LabCard.tsx +1 -1
  145. package/src/components/Link.tsx +25 -5
  146. package/src/components/OllamaSetupGuide/index.tsx +5 -4
  147. package/src/components/WebFavicon/index.tsx +1 -1
  148. package/src/components/client/ClientResponsiveContent/index.tsx +1 -1
  149. package/src/components/client/ClientResponsiveLayout.tsx +1 -1
  150. package/src/components/mdx/Image.tsx +1 -1
  151. package/src/components/mdx/Link.tsx +26 -9
  152. package/src/features/AlertBanner/CloudBanner.tsx +2 -3
  153. package/src/features/ChatInput/ActionBar/Model/ControlsForm.tsx +8 -7
  154. package/src/features/ChatInput/ActionBar/Params/Controls.tsx +1 -3
  155. package/src/features/ChatInput/ActionBar/Token/index.tsx +1 -1
  156. package/src/features/ChatInput/Mobile/index.tsx +1 -1
  157. package/src/features/Conversation/ChatItem/components/MessageContent/index.tsx +1 -1
  158. package/src/features/Conversation/Error/OllamaBizError/index.tsx +1 -1
  159. package/src/features/Conversation/Error/OllamaSetupGuide/Desktop.tsx +1 -2
  160. package/src/features/Conversation/Error/index.tsx +1 -1
  161. package/src/features/Conversation/Messages/AssistantGroup/Tool/Actions/Settings.tsx +1 -1
  162. package/src/features/Conversation/Messages/AssistantGroup/Tool/Actions/index.tsx +11 -17
  163. package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/LoadingPlaceholder/index.tsx +13 -3
  164. package/src/features/Conversation/Messages/AssistantGroup/Tool/Detail/Render/CustomRender.tsx +43 -0
  165. package/src/features/Conversation/Messages/AssistantGroup/Tool/Detail/Render/FallbacktArgumentRender.tsx +59 -0
  166. package/src/features/Conversation/Messages/AssistantGroup/Tool/Detail/Render/index.tsx +46 -0
  167. package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/index.tsx +13 -19
  168. package/src/features/Conversation/Messages/AssistantGroup/Tool/index.tsx +18 -18
  169. package/src/features/Conversation/Messages/AssistantGroup/index.tsx +1 -1
  170. package/src/features/Conversation/Messages/Tool/Tool/index.tsx +11 -10
  171. package/src/features/Conversation/Messages/components/SearchGrounding.tsx +1 -1
  172. package/src/features/Conversation/TodoProgress/index.tsx +56 -23
  173. package/src/features/DataImporter/Error.tsx +3 -3
  174. package/src/features/DevPanel/CacheViewer/cacheProvider.tsx +2 -1
  175. package/src/features/DevPanel/MetadataViewer/Og.tsx +1 -1
  176. package/src/features/DevPanel/features/FloatPanel.tsx +1 -1
  177. package/src/features/DevPanel/features/Table/TooltipContent.tsx +3 -4
  178. package/src/features/DevPanel/index.tsx +1 -1
  179. package/src/features/EditorCanvas/InlineToolbar.tsx +1 -6
  180. package/src/features/FileViewer/NotSupport/index.tsx +2 -3
  181. package/src/features/Follow/index.tsx +8 -9
  182. package/src/features/LibraryModal/AddFilesToKnowledgeBase/SelectForm.tsx +2 -2
  183. package/src/features/MCP/Scores.tsx +1 -1
  184. package/src/features/MCPPluginDetail/Nav.tsx +8 -8
  185. package/src/features/MCPPluginDetail/Overview/TagList.tsx +1 -1
  186. package/src/features/MobileTabBar/index.tsx +2 -1
  187. package/src/features/OllamaSetupGuide/Desktop.tsx +1 -2
  188. package/src/features/PWAInstall/Install.tsx +1 -1
  189. package/src/features/PWAInstall/index.tsx +1 -1
  190. package/src/features/PluginStore/McpList/index.tsx +1 -1
  191. package/src/features/PluginStore/PluginList/Detail/Header.tsx +6 -6
  192. package/src/features/PluginsUI/Render/DefaultType/index.tsx +1 -1
  193. package/src/features/PluginsUI/Render/MCPType/index.tsx +1 -1
  194. package/src/features/Portal/Artifacts/Body/Renderer/index.tsx +1 -1
  195. package/src/features/ResourceManager/components/ChunkDrawer/index.tsx +1 -1
  196. package/src/features/ResourceManager/components/Explorer/Header/index.tsx +57 -4
  197. package/src/features/ResourceManager/components/Explorer/ListView/ListItem/index.tsx +6 -4
  198. package/src/features/ResourceManager/components/Explorer/ListView/Skeleton.tsx +26 -26
  199. package/src/features/ResourceManager/components/Explorer/ListView/index.tsx +16 -5
  200. package/src/features/ResourceManager/components/Explorer/ToolBar/BatchActionsDropdown.tsx +147 -149
  201. package/src/features/ResourceManager/components/LibraryHierarchy/styles.ts +5 -4
  202. package/src/features/ResourceManager/index.tsx +1 -1
  203. package/src/features/Setting/Footer.tsx +4 -5
  204. package/src/features/User/UserPanel/PanelContent.tsx +1 -1
  205. package/src/hooks/useActiveTabKey.ts +6 -4
  206. package/src/hooks/useIsSingleMode.test.ts +10 -24
  207. package/src/hooks/useIsSingleMode.ts +4 -2
  208. package/src/hooks/useIsSubSlug.ts +2 -1
  209. package/src/hooks/useQuery.ts +5 -5
  210. package/src/layout/GlobalProvider/AppTheme.tsx +2 -2
  211. package/src/layout/GlobalProvider/StyleRegistry.tsx +1 -1
  212. package/src/layout/GlobalProvider/useUserStateRedirect.ts +13 -25
  213. package/src/libs/next/Image.tsx +13 -0
  214. package/src/libs/next/Link.tsx +13 -0
  215. package/src/libs/next/dynamic.tsx +13 -0
  216. package/src/libs/next/index.ts +22 -0
  217. package/src/libs/next/navigation.ts +22 -0
  218. package/src/libs/router/Link.tsx +30 -0
  219. package/src/libs/router/index.ts +18 -0
  220. package/src/libs/router/navigation.ts +72 -0
  221. package/src/locales/default/plugin.ts +1 -0
  222. package/src/server/modules/AgentRuntime/AgentStateManager.ts +5 -1
  223. package/src/store/chat/slices/message/selectors/dbMessage.test.ts +11 -11
  224. package/src/store/chat/slices/portal/selectors.test.ts +5 -15
  225. package/src/store/file/slices/resource/action.ts +4 -2
  226. package/src/store/page/index.ts +1 -1
  227. package/src/store/page/slices/crud/index.ts +1 -1
  228. package/src/tools/inspectors.ts +2 -0
  229. package/src/tools/interventions.ts +2 -0
  230. package/src/tools/renders.ts +3 -1
  231. package/src/tools/streamings.ts +2 -0
  232. package/packages/builtin-tool-gtd/src/client/Inspector/CompleteTodos/index.tsx +0 -52
  233. package/packages/builtin-tool-gtd/src/client/Inspector/RemoveTodos/index.tsx +0 -52
  234. package/src/app/[variants]/(main)/hooks/usePathname.ts +0 -10
  235. package/src/app/[variants]/(main)/hooks/useQuery.ts +0 -12
  236. package/src/app/[variants]/(main)/hooks/useRouter.ts +0 -22
  237. package/src/app/[variants]/(main)/hooks/useSearchParams.ts +0 -11
  238. package/src/features/Conversation/Messages/AssistantGroup/Tool/Render/CustomRender.tsx +0 -113
  239. package/src/features/Conversation/Messages/Tool/Tool/Render.tsx +0 -47
  240. /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/AbortResponse.tsx +0 -0
  241. /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/Arguments/index.tsx +0 -0
  242. /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/ErrorResponse.tsx +0 -0
  243. /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/Intervention/ApprovalActions.tsx +0 -0
  244. /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/Intervention/Fallback.tsx +0 -0
  245. /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/Intervention/KeyValueEditor.tsx +0 -0
  246. /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/Intervention/ModeSelector.tsx +0 -0
  247. /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/Intervention/index.tsx +0 -0
  248. /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/PluginSettings.tsx +0 -0
  249. /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/RejectedResponse.tsx +0 -0
@@ -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) => ({ completed: false, 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].completed).toBe(false);
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].completed).toBe(false);
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 toggle item completed state', () => {
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].completed).toBe(false);
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].completed).toBe(true);
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].completed).toBe(false);
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([{ completed: false, text: 'Updated' }]);
371
+ expect(onSave).toHaveBeenCalledWith([{ status: 'todo', text: 'Updated' }]);
366
372
  });
367
373
 
368
374
  it('should set saveStatus to saving during save', async () => {
@@ -22,7 +22,7 @@ describe('GTDExecutor', () => {
22
22
  expect(result.content).toContain('Call mom');
23
23
  expect(result.state?.todos.items).toHaveLength(2);
24
24
  expect(result.state?.todos.items[0].text).toBe('Buy milk');
25
- expect(result.state?.todos.items[0].completed).toBe(false);
25
+ expect(result.state?.todos.items[0].status).toBe('todo');
26
26
  expect(result.state?.todos.items[1].text).toBe('Call mom');
27
27
  });
28
28
 
@@ -32,8 +32,8 @@ describe('GTDExecutor', () => {
32
32
  const result = await gtdExecutor.createTodos(
33
33
  {
34
34
  items: [
35
- { text: 'Buy milk', completed: false },
36
- { text: 'Call mom', completed: true },
35
+ { text: 'Buy milk', status: 'todo' },
36
+ { text: 'Call mom', status: 'completed' },
37
37
  ],
38
38
  },
39
39
  ctx,
@@ -43,15 +43,15 @@ describe('GTDExecutor', () => {
43
43
  expect(result.content).toContain('Added 2 items');
44
44
  expect(result.state?.todos.items).toHaveLength(2);
45
45
  expect(result.state?.todos.items[0].text).toBe('Buy milk');
46
- expect(result.state?.todos.items[0].completed).toBe(false);
46
+ expect(result.state?.todos.items[0].status).toBe('todo');
47
47
  expect(result.state?.todos.items[1].text).toBe('Call mom');
48
- expect(result.state?.todos.items[1].completed).toBe(true);
48
+ expect(result.state?.todos.items[1].status).toBe('completed');
49
49
  });
50
50
 
51
51
  it('should append items to existing todo list', async () => {
52
52
  const ctx = createMockContext({
53
53
  todos: {
54
- items: [{ text: 'Existing task', completed: false }],
54
+ items: [{ text: 'Existing task', status: 'todo' }],
55
55
  updatedAt: '2024-01-01T00:00:00.000Z',
56
56
  },
57
57
  });
@@ -89,7 +89,7 @@ describe('GTDExecutor', () => {
89
89
  const result = await gtdExecutor.createTodos(
90
90
  {
91
91
  adds: ['AI task'],
92
- items: [{ text: 'User edited task', completed: true }],
92
+ items: [{ text: 'User edited task', status: 'completed' }],
93
93
  },
94
94
  ctx,
95
95
  );
@@ -97,7 +97,7 @@ describe('GTDExecutor', () => {
97
97
  expect(result.success).toBe(true);
98
98
  expect(result.state?.todos.items).toHaveLength(1);
99
99
  expect(result.state?.todos.items[0].text).toBe('User edited task');
100
- expect(result.state?.todos.items[0].completed).toBe(true);
100
+ expect(result.state?.todos.items[0].status).toBe('completed');
101
101
  });
102
102
  });
103
103
 
@@ -105,7 +105,7 @@ describe('GTDExecutor', () => {
105
105
  it('should add new items via operations', async () => {
106
106
  const ctx = createMockContext({
107
107
  todos: {
108
- items: [{ text: 'Existing task', completed: false }],
108
+ items: [{ text: 'Existing task', status: 'todo' }],
109
109
  updatedAt: '2024-01-01T00:00:00.000Z',
110
110
  },
111
111
  });
@@ -125,7 +125,7 @@ describe('GTDExecutor', () => {
125
125
  it('should update item text via operations', async () => {
126
126
  const ctx = createMockContext({
127
127
  todos: {
128
- items: [{ text: 'Old task', completed: false }],
128
+ items: [{ text: 'Old task', status: 'todo' }],
129
129
  updatedAt: '2024-01-01T00:00:00.000Z',
130
130
  },
131
131
  });
@@ -144,7 +144,7 @@ describe('GTDExecutor', () => {
144
144
  it('should complete items via operations', async () => {
145
145
  const ctx = createMockContext({
146
146
  todos: {
147
- items: [{ text: 'Task', completed: false }],
147
+ items: [{ text: 'Task', status: 'todo' }],
148
148
  updatedAt: '2024-01-01T00:00:00.000Z',
149
149
  },
150
150
  });
@@ -157,15 +157,15 @@ describe('GTDExecutor', () => {
157
157
  );
158
158
 
159
159
  expect(result.success).toBe(true);
160
- expect(result.state?.todos.items[0].completed).toBe(true);
160
+ expect(result.state?.todos.items[0].status).toBe('completed');
161
161
  });
162
162
 
163
163
  it('should remove items via operations', async () => {
164
164
  const ctx = createMockContext({
165
165
  todos: {
166
166
  items: [
167
- { text: 'Task 1', completed: false },
168
- { text: 'Task 2', completed: false },
167
+ { text: 'Task 1', status: 'todo' },
168
+ { text: 'Task 2', status: 'todo' },
169
169
  ],
170
170
  updatedAt: '2024-01-01T00:00:00.000Z',
171
171
  },
@@ -198,11 +198,11 @@ describe('GTDExecutor', () => {
198
198
  createdItems: ['Task A', 'Task B', 'Task C', 'Task D', 'Task E'],
199
199
  todos: {
200
200
  items: [
201
- { completed: false, text: 'Task A' },
202
- { completed: false, text: 'Task B' },
203
- { completed: false, text: 'Task C' },
204
- { completed: false, text: 'Task D' },
205
- { completed: false, text: 'Task E' },
201
+ { status: 'todo', text: 'Task A' },
202
+ { status: 'todo', text: 'Task B' },
203
+ { status: 'todo', text: 'Task C' },
204
+ { status: 'todo', text: 'Task D' },
205
+ { status: 'todo', text: 'Task E' },
206
206
  ],
207
207
  updatedAt: '2025-01-01T00:00:00.000Z',
208
208
  },
@@ -211,8 +211,8 @@ describe('GTDExecutor', () => {
211
211
  const result = await gtdExecutor.updateTodos(
212
212
  {
213
213
  operations: [
214
- { completed: true, index: 5, newText: '', text: '', type: 'complete' }, // out of range
215
- { completed: true, index: 2, newText: '', text: '', type: 'complete' }, // valid
214
+ { index: 5, type: 'complete' }, // out of range
215
+ { index: 2, type: 'complete' }, // valid
216
216
  ],
217
217
  },
218
218
  ctx,
@@ -223,146 +223,12 @@ describe('GTDExecutor', () => {
223
223
  expect(result.state?.todos.items).toHaveLength(5);
224
224
  // Index 5 is out of range (0-4), so should be skipped
225
225
  // Index 2 should be completed
226
- expect(result.state?.todos.items[2].completed).toBe(true);
226
+ expect(result.state?.todos.items[2].status).toBe('completed');
227
227
  // Other items should remain uncompleted
228
- expect(result.state?.todos.items[0].completed).toBe(false);
229
- expect(result.state?.todos.items[1].completed).toBe(false);
230
- expect(result.state?.todos.items[3].completed).toBe(false);
231
- expect(result.state?.todos.items[4].completed).toBe(false);
232
- });
233
- });
234
-
235
- describe('completeTodos', () => {
236
- it('should mark items as done by indices', async () => {
237
- const ctx = createMockContext({
238
- todos: {
239
- items: [
240
- { text: 'Task 1', completed: false },
241
- { text: 'Task 2', completed: false },
242
- { text: 'Task 3', completed: false },
243
- ],
244
- updatedAt: '2024-01-01T00:00:00.000Z',
245
- },
246
- });
247
-
248
- const result = await gtdExecutor.completeTodos({ indices: [0, 2] }, ctx);
249
-
250
- expect(result.success).toBe(true);
251
- expect(result.content).toContain('Completed 2 items');
252
- expect(result.state?.todos.items[0].completed).toBe(true);
253
- expect(result.state?.todos.items[1].completed).toBe(false);
254
- expect(result.state?.todos.items[2].completed).toBe(true);
255
- });
256
-
257
- it('should return error when no indices provided', async () => {
258
- const ctx = createMockContext();
259
-
260
- const result = await gtdExecutor.completeTodos({ indices: [] }, ctx);
261
-
262
- expect(result.success).toBe(false);
263
- expect(result.content).toContain('No indices provided');
264
- });
265
-
266
- it('should handle empty todo list', async () => {
267
- const ctx = createMockContext({
268
- todos: { items: [], updatedAt: '2024-01-01T00:00:00.000Z' },
269
- });
270
-
271
- const result = await gtdExecutor.completeTodos({ indices: [0] }, ctx);
272
-
273
- expect(result.success).toBe(true);
274
- expect(result.content).toContain('No todos to complete');
275
- });
276
-
277
- it('should return error when all indices are invalid', async () => {
278
- const ctx = createMockContext({
279
- todos: {
280
- items: [{ text: 'Task 1', completed: false }],
281
- updatedAt: '2024-01-01T00:00:00.000Z',
282
- },
283
- });
284
-
285
- const result = await gtdExecutor.completeTodos({ indices: [5, 10] }, ctx);
286
-
287
- expect(result.success).toBe(false);
288
- expect(result.content).toContain('Invalid indices');
289
- });
290
-
291
- it('should complete valid indices and warn about invalid ones', async () => {
292
- const ctx = createMockContext({
293
- todos: {
294
- items: [
295
- { text: 'Task 1', completed: false },
296
- { text: 'Task 2', completed: false },
297
- ],
298
- updatedAt: '2024-01-01T00:00:00.000Z',
299
- },
300
- });
301
-
302
- const result = await gtdExecutor.completeTodos({ indices: [0, 99] }, ctx);
303
-
304
- expect(result.success).toBe(true);
305
- expect(result.content).toContain('Completed 1 item');
306
- expect(result.content).toContain('Ignored invalid indices');
307
- expect(result.state?.todos.items[0].completed).toBe(true);
308
- expect(result.state?.todos.items[1].completed).toBe(false);
309
- });
310
-
311
- it('should handle single item completion with correct grammar', async () => {
312
- const ctx = createMockContext({
313
- todos: {
314
- items: [{ text: 'Task 1', completed: false }],
315
- updatedAt: '2024-01-01T00:00:00.000Z',
316
- },
317
- });
318
-
319
- const result = await gtdExecutor.completeTodos({ indices: [0] }, ctx);
320
-
321
- expect(result.success).toBe(true);
322
- expect(result.content).toContain('Completed 1 item');
323
- expect(result.content).not.toContain('items');
324
- });
325
- });
326
-
327
- describe('removeTodos', () => {
328
- it('should remove items by indices', async () => {
329
- const ctx = createMockContext({
330
- todos: {
331
- items: [
332
- { text: 'Task 1', completed: false },
333
- { text: 'Task 2', completed: false },
334
- { text: 'Task 3', completed: false },
335
- ],
336
- updatedAt: '2024-01-01T00:00:00.000Z',
337
- },
338
- });
339
-
340
- const result = await gtdExecutor.removeTodos({ indices: [0, 2] }, ctx);
341
-
342
- expect(result.success).toBe(true);
343
- expect(result.content).toContain('Removed 2 items');
344
- expect(result.state?.todos.items).toHaveLength(1);
345
- expect(result.state?.todos.items[0].text).toBe('Task 2');
346
- });
347
-
348
- it('should return error when no indices provided', async () => {
349
- const ctx = createMockContext();
350
-
351
- const result = await gtdExecutor.removeTodos({ indices: [] }, ctx);
352
-
353
- expect(result.success).toBe(false);
354
- expect(result.content).toContain('No indices provided');
355
- });
356
-
357
- it('should handle empty todo list', async () => {
358
- const ctx = createMockContext({
359
- todos: { items: [], updatedAt: '2024-01-01T00:00:00.000Z' },
360
- });
361
-
362
- const result = await gtdExecutor.removeTodos({ indices: [0] }, ctx);
363
-
364
- expect(result.success).toBe(true);
365
- expect(result.content).toContain('No todos to remove');
228
+ expect(result.state?.todos.items[0].status).toBe('todo');
229
+ expect(result.state?.todos.items[1].status).toBe('todo');
230
+ expect(result.state?.todos.items[3].status).toBe('todo');
231
+ expect(result.state?.todos.items[4].status).toBe('todo');
366
232
  });
367
233
  });
368
234
 
@@ -371,8 +237,8 @@ describe('GTDExecutor', () => {
371
237
  const ctx = createMockContext({
372
238
  todos: {
373
239
  items: [
374
- { text: 'Task 1', completed: false },
375
- { text: 'Task 2', completed: true },
240
+ { text: 'Task 1', status: 'todo' },
241
+ { text: 'Task 2', status: 'completed' },
376
242
  ],
377
243
  updatedAt: '2024-01-01T00:00:00.000Z',
378
244
  },
@@ -389,9 +255,9 @@ describe('GTDExecutor', () => {
389
255
  const ctx = createMockContext({
390
256
  todos: {
391
257
  items: [
392
- { text: 'Task 1', completed: false },
393
- { text: 'Task 2', completed: true },
394
- { text: 'Task 3', completed: true },
258
+ { text: 'Task 1', status: 'todo' },
259
+ { text: 'Task 2', status: 'completed' },
260
+ { text: 'Task 3', status: 'completed' },
395
261
  ],
396
262
  updatedAt: '2024-01-01T00:00:00.000Z',
397
263
  },
@@ -421,7 +287,7 @@ describe('GTDExecutor', () => {
421
287
  it('should handle no completed items to clear', async () => {
422
288
  const ctx = createMockContext({
423
289
  todos: {
424
- items: [{ text: 'Task 1', completed: false }],
290
+ items: [{ text: 'Task 1', status: 'todo' }],
425
291
  updatedAt: '2024-01-01T00:00:00.000Z',
426
292
  },
427
293
  });
@@ -442,13 +308,13 @@ describe('GTDExecutor', () => {
442
308
  operationId: 'test-operation-id',
443
309
  pluginState: {
444
310
  todos: {
445
- items: [{ text: 'Old task from pluginState', completed: false }],
311
+ items: [{ text: 'Old task from pluginState', status: 'todo' }],
446
312
  updatedAt: '2024-01-01T00:00:00.000Z',
447
313
  },
448
314
  },
449
315
  stepContext: {
450
316
  todos: {
451
- items: [{ text: 'New task from stepContext', completed: true }],
317
+ items: [{ text: 'New task from stepContext', status: 'completed' }],
452
318
  updatedAt: '2024-06-01T00:00:00.000Z',
453
319
  },
454
320
  },
@@ -461,7 +327,7 @@ describe('GTDExecutor', () => {
461
327
  expect(result.state?.todos.items).toHaveLength(2);
462
328
  // First item should be from stepContext, not pluginState
463
329
  expect(result.state?.todos.items[0].text).toBe('New task from stepContext');
464
- expect(result.state?.todos.items[0].completed).toBe(true);
330
+ expect(result.state?.todos.items[0].status).toBe('completed');
465
331
  expect(result.state?.todos.items[1].text).toBe('Another task');
466
332
  });
467
333
 
@@ -471,7 +337,7 @@ describe('GTDExecutor', () => {
471
337
  operationId: 'test-operation-id',
472
338
  pluginState: {
473
339
  todos: {
474
- items: [{ text: 'Task from pluginState', completed: false }],
340
+ items: [{ text: 'Task from pluginState', status: 'todo' }],
475
341
  updatedAt: '2024-01-01T00:00:00.000Z',
476
342
  },
477
343
  },
@@ -502,50 +368,6 @@ describe('GTDExecutor', () => {
502
368
  expect(result.state?.todos.items[0].text).toBe('First task');
503
369
  });
504
370
 
505
- it('should work with stepContext.todos for completeTodos', async () => {
506
- const ctx: BuiltinToolContext = {
507
- messageId: 'test-message-id',
508
- operationId: 'test-operation-id',
509
- stepContext: {
510
- todos: {
511
- items: [
512
- { text: 'Task 1', completed: false },
513
- { text: 'Task 2', completed: false },
514
- ],
515
- updatedAt: '2024-06-01T00:00:00.000Z',
516
- },
517
- },
518
- };
519
-
520
- const result = await gtdExecutor.completeTodos({ indices: [0] }, ctx);
521
-
522
- expect(result.success).toBe(true);
523
- expect(result.state?.todos.items[0].completed).toBe(true);
524
- expect(result.state?.todos.items[1].completed).toBe(false);
525
- });
526
-
527
- it('should work with stepContext.todos for removeTodos', async () => {
528
- const ctx: BuiltinToolContext = {
529
- messageId: 'test-message-id',
530
- operationId: 'test-operation-id',
531
- stepContext: {
532
- todos: {
533
- items: [
534
- { text: 'Task 1', completed: false },
535
- { text: 'Task 2', completed: false },
536
- ],
537
- updatedAt: '2024-06-01T00:00:00.000Z',
538
- },
539
- },
540
- };
541
-
542
- const result = await gtdExecutor.removeTodos({ indices: [0] }, ctx);
543
-
544
- expect(result.success).toBe(true);
545
- expect(result.state?.todos.items).toHaveLength(1);
546
- expect(result.state?.todos.items[0].text).toBe('Task 2');
547
- });
548
-
549
371
  it('should work with stepContext.todos for clearTodos', async () => {
550
372
  const ctx: BuiltinToolContext = {
551
373
  messageId: 'test-message-id',
@@ -553,8 +375,8 @@ describe('GTDExecutor', () => {
553
375
  stepContext: {
554
376
  todos: {
555
377
  items: [
556
- { text: 'Task 1', completed: true },
557
- { text: 'Task 2', completed: false },
378
+ { text: 'Task 1', status: 'completed' },
379
+ { text: 'Task 2', status: 'todo' },
558
380
  ],
559
381
  updatedAt: '2024-06-01T00:00:00.000Z',
560
382
  },
@@ -574,27 +396,26 @@ describe('GTDExecutor', () => {
574
396
  expect(gtdExecutor.identifier).toBe('lobe-gtd');
575
397
  });
576
398
 
577
- it('should support all MVP APIs', () => {
399
+ it('should support all APIs', () => {
578
400
  expect(gtdExecutor.hasApi('createTodos')).toBe(true);
579
401
  expect(gtdExecutor.hasApi('updateTodos')).toBe(true);
580
- expect(gtdExecutor.hasApi('completeTodos')).toBe(true);
581
- expect(gtdExecutor.hasApi('removeTodos')).toBe(true);
582
402
  expect(gtdExecutor.hasApi('clearTodos')).toBe(true);
583
- });
584
-
585
- it('should not support non-MVP APIs', () => {
586
- expect(gtdExecutor.hasApi('createPlan')).toBe(false);
587
- expect(gtdExecutor.hasApi('updatePlan')).toBe(false);
403
+ expect(gtdExecutor.hasApi('createPlan')).toBe(true);
404
+ expect(gtdExecutor.hasApi('updatePlan')).toBe(true);
405
+ expect(gtdExecutor.hasApi('execTask')).toBe(true);
406
+ expect(gtdExecutor.hasApi('execTasks')).toBe(true);
588
407
  });
589
408
 
590
409
  it('should return correct API names', () => {
591
410
  const apiNames = gtdExecutor.getApiNames();
592
411
  expect(apiNames).toContain('createTodos');
593
412
  expect(apiNames).toContain('updateTodos');
594
- expect(apiNames).toContain('completeTodos');
595
- expect(apiNames).toContain('removeTodos');
596
413
  expect(apiNames).toContain('clearTodos');
597
- expect(apiNames).toHaveLength(5);
414
+ expect(apiNames).toContain('createPlan');
415
+ expect(apiNames).toContain('updatePlan');
416
+ expect(apiNames).toContain('execTask');
417
+ expect(apiNames).toContain('execTasks');
418
+ expect(apiNames).toHaveLength(7);
598
419
  });
599
420
  });
600
421
  });