@lobehub/lobehub 2.0.0-next.164 → 2.0.0-next.166

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 (102) hide show
  1. package/.cursor/rules/desktop-feature-implementation.mdc +31 -34
  2. package/.cursor/rules/desktop-local-tools-implement.mdc +3 -3
  3. package/.cursor/rules/desktop-window-management.mdc +56 -66
  4. package/CHANGELOG.md +50 -0
  5. package/Dockerfile +44 -52
  6. package/README.md +6 -6
  7. package/README.zh-CN.md +6 -6
  8. package/apps/desktop/Development.md +42 -46
  9. package/apps/desktop/README.md +37 -1
  10. package/apps/desktop/README.zh-CN.md +26 -1
  11. package/apps/desktop/electron.vite.config.ts +1 -0
  12. package/apps/desktop/src/main/controllers/AuthCtr.ts +4 -3
  13. package/apps/desktop/src/main/controllers/BrowserWindowsCtr.ts +33 -20
  14. package/apps/desktop/src/main/controllers/DevtoolsCtr.ts +4 -2
  15. package/apps/desktop/src/main/controllers/LocalFileCtr.ts +14 -13
  16. package/apps/desktop/src/main/controllers/MenuCtr.ts +5 -4
  17. package/apps/desktop/src/main/controllers/NetworkProxyCtr.ts +18 -19
  18. package/apps/desktop/src/main/controllers/NotificationCtr.ts +4 -3
  19. package/apps/desktop/src/main/controllers/RemoteServerConfigCtr.ts +5 -4
  20. package/apps/desktop/src/main/controllers/RemoteServerSyncCtr.ts +3 -2
  21. package/apps/desktop/src/main/controllers/ShellCommandCtr.ts +5 -4
  22. package/apps/desktop/src/main/controllers/ShortcutCtr.ts +4 -3
  23. package/apps/desktop/src/main/controllers/SystemCtr.ts +7 -37
  24. package/apps/desktop/src/main/controllers/SystemServerCtr.ts +38 -0
  25. package/apps/desktop/src/main/controllers/TrayMenuCtr.ts +5 -4
  26. package/apps/desktop/src/main/controllers/UpdaterCtr.ts +6 -5
  27. package/apps/desktop/src/main/controllers/UploadFileCtr.ts +3 -25
  28. package/apps/desktop/src/main/controllers/UploadFileServerCtr.ts +33 -0
  29. package/apps/desktop/src/main/controllers/__tests__/AuthCtr.test.ts +9 -1
  30. package/apps/desktop/src/main/controllers/__tests__/BrowserWindowsCtr.test.ts +29 -9
  31. package/apps/desktop/src/main/controllers/__tests__/DevtoolsCtr.test.ts +12 -3
  32. package/apps/desktop/src/main/controllers/__tests__/LocalFileCtr.test.ts +7 -0
  33. package/apps/desktop/src/main/controllers/__tests__/MenuCtr.test.ts +10 -0
  34. package/apps/desktop/src/main/controllers/__tests__/NetworkProxyCtr.test.ts +10 -0
  35. package/apps/desktop/src/main/controllers/__tests__/NotificationCtr.test.ts +8 -0
  36. package/apps/desktop/src/main/controllers/__tests__/RemoteServerConfigCtr.test.ts +8 -0
  37. package/apps/desktop/src/main/controllers/__tests__/RemoteServerSyncCtr.test.ts +1 -0
  38. package/apps/desktop/src/main/controllers/__tests__/ShellCommandCtr.test.ts +10 -0
  39. package/apps/desktop/src/main/controllers/__tests__/ShortcutCtr.test.ts +11 -0
  40. package/apps/desktop/src/main/controllers/__tests__/SystemCtr.test.ts +43 -73
  41. package/apps/desktop/src/main/controllers/__tests__/SystemServerCtr.test.ts +75 -0
  42. package/apps/desktop/src/main/controllers/__tests__/TrayMenuCtr.test.ts +24 -13
  43. package/apps/desktop/src/main/controllers/__tests__/UpdaterCtr.test.ts +13 -2
  44. package/apps/desktop/src/main/controllers/__tests__/UploadFileCtr.test.ts +29 -108
  45. package/apps/desktop/src/main/controllers/__tests__/UploadFileServerCtr.test.ts +55 -0
  46. package/apps/desktop/src/main/controllers/_template.ts +2 -2
  47. package/apps/desktop/src/main/controllers/index.ts +5 -29
  48. package/apps/desktop/src/main/controllers/registry.ts +52 -0
  49. package/apps/desktop/src/main/core/App.ts +15 -47
  50. package/apps/desktop/src/main/core/__tests__/App.test.ts +5 -4
  51. package/apps/desktop/src/main/core/infrastructure/IoCContainer.ts +0 -5
  52. package/apps/desktop/src/main/core/infrastructure/__tests__/IoCContainer.test.ts +0 -50
  53. package/apps/desktop/src/main/exports.d.ts +8 -0
  54. package/apps/desktop/src/main/exports.ts +2 -0
  55. package/apps/desktop/src/main/global.d.ts +3 -0
  56. package/apps/desktop/src/main/modules/fileSearch/__tests__/macOS.integration.test.ts +17 -8
  57. package/apps/desktop/src/main/package.json +10 -0
  58. package/apps/desktop/src/main/services/fileSrv.ts +1 -1
  59. package/apps/desktop/src/main/utils/ipc/__tests__/base.test.ts +91 -0
  60. package/apps/desktop/src/main/utils/ipc/base.ts +170 -0
  61. package/apps/desktop/src/main/utils/ipc/index.ts +11 -0
  62. package/apps/desktop/src/main/utils/ipc/utility.ts +20 -0
  63. package/apps/desktop/src/preload/electronApi.ts +4 -1
  64. package/apps/desktop/src/preload/invoke.test.ts +13 -16
  65. package/apps/desktop/src/preload/invoke.ts +2 -5
  66. package/apps/desktop/src/preload/routeInterceptor.test.ts +13 -13
  67. package/apps/desktop/src/preload/routeInterceptor.ts +4 -4
  68. package/apps/desktop/tsconfig.json +15 -5
  69. package/changelog/v1.json +10 -0
  70. package/package.json +4 -3
  71. package/packages/electron-client-ipc/src/index.ts +1 -1
  72. package/packages/electron-client-ipc/src/ipc.test.ts +62 -0
  73. package/packages/electron-client-ipc/src/ipc.ts +63 -0
  74. package/packages/electron-client-ipc/src/streamInvoke.ts +7 -1
  75. package/packages/electron-client-ipc/src/types/dispatch.ts +1 -10
  76. package/packages/electron-client-ipc/vitest.config.mts +10 -0
  77. package/packages/electron-server-ipc/src/ipcClient.ts +1 -2
  78. package/packages/electron-server-ipc/src/ipcServer.ts +1 -2
  79. package/packages/electron-server-ipc/src/types/index.ts +1 -5
  80. package/pnpm-workspace.yaml +1 -1
  81. package/scripts/i18nWorkflow/const.ts +2 -2
  82. package/scripts/i18nWorkflow/i18nConfig.ts +7 -0
  83. package/scripts/i18nWorkflow/utils.ts +1 -1
  84. package/src/app/[variants]/(main)/discover/(detail)/provider/features/Sidebar/ActionButton/ProviderConfig.tsx +2 -2
  85. package/src/locales/default/setting.ts +1 -0
  86. package/src/server/modules/ElectronIPCClient/index.ts +59 -13
  87. package/src/services/electron/__tests__/devtools.test.ts +10 -6
  88. package/src/services/electron/autoUpdate.ts +5 -5
  89. package/src/services/electron/desktopNotification.ts +4 -7
  90. package/src/services/electron/devtools.ts +2 -2
  91. package/src/services/electron/file.ts +3 -2
  92. package/src/services/electron/localFileService.ts +17 -16
  93. package/src/services/electron/remoteServer.ts +7 -6
  94. package/src/services/electron/settings.ts +9 -11
  95. package/src/services/electron/system.ts +8 -6
  96. package/src/store/chat/slices/plugin/actions/pluginTypes.ts +1 -1
  97. package/src/store/global/actions/general.ts +8 -10
  98. package/src/utils/electron/desktopRemoteRPCFetch.ts +3 -2
  99. package/src/utils/electron/ipc.ts +12 -0
  100. package/tsconfig.json +5 -0
  101. package/apps/desktop/src/main/types/ipcClientEvent.ts +0 -3
  102. package/packages/electron-client-ipc/src/dispatch.ts +0 -41
@@ -1,4 +1,6 @@
1
- import { ElectronAppState, dispatch } from '@lobechat/electron-client-ipc';
1
+ import { ElectronAppState } from '@lobechat/electron-client-ipc';
2
+
3
+ import { ensureElectronIpc } from '@/utils/electron/ipc';
2
4
 
3
5
  /**
4
6
  * Service class for interacting with Electron's system-level information and actions.
@@ -11,23 +13,23 @@ class ElectronSystemService {
11
13
  */
12
14
  async getAppState(): Promise<ElectronAppState> {
13
15
  // Calls the underlying IPC function to get data from the main process
14
- return dispatch('getDesktopAppState');
16
+ return ensureElectronIpc().system.getAppState();
15
17
  }
16
18
 
17
19
  async closeWindow(): Promise<void> {
18
- return dispatch('closeWindow');
20
+ return ensureElectronIpc().windows.closeWindow();
19
21
  }
20
22
 
21
23
  async maximizeWindow(): Promise<void> {
22
- return dispatch('maximizeWindow');
24
+ return ensureElectronIpc().windows.maximizeWindow();
23
25
  }
24
26
 
25
27
  async minimizeWindow(): Promise<void> {
26
- return dispatch('minimizeWindow');
28
+ return ensureElectronIpc().windows.minimizeWindow();
27
29
  }
28
30
 
29
31
  showContextMenu = async (type: string, data?: any) => {
30
- return dispatch('showContextMenu', { data, type });
32
+ return ensureElectronIpc().menu.showContextMenu({ data, type });
31
33
  };
32
34
  }
33
35
 
@@ -101,7 +101,7 @@ export const pluginTypes: StateCreator<
101
101
 
102
102
  let data: MCPToolCallResult | undefined;
103
103
 
104
- // Get message to extract sessionId/topicId
104
+ // Get message to extract agentId/topicId
105
105
  const message = dbMessageSelectors.getDbMessageById(id)(get());
106
106
 
107
107
  // Get abort controller from operation
@@ -39,11 +39,10 @@ export const generalActionSlice: StateCreator<
39
39
  if (!isDesktop) return;
40
40
 
41
41
  try {
42
- const { dispatch } = await import('@lobechat/electron-client-ipc');
43
-
42
+ const { ensureElectronIpc } = await import('@/utils/electron/ipc');
44
43
  const url = `/chat?session=${sessionId}&mode=single`;
45
44
 
46
- const result = await dispatch('createMultiInstanceWindow', {
45
+ const result = await ensureElectronIpc().windows.createMultiInstanceWindow({
47
46
  path: url,
48
47
  templateId: 'chatSingle',
49
48
  uniqueId: `chat_${sessionId}`,
@@ -61,11 +60,10 @@ export const generalActionSlice: StateCreator<
61
60
  if (!isDesktop) return;
62
61
 
63
62
  try {
64
- const { dispatch } = await import('@lobechat/electron-client-ipc');
65
-
63
+ const { ensureElectronIpc } = await import('@/utils/electron/ipc');
66
64
  const url = `/chat?session=${sessionId}&topic=${topicId}&mode=single`;
67
65
 
68
- const result = await dispatch('createMultiInstanceWindow', {
66
+ const result = await ensureElectronIpc().windows.createMultiInstanceWindow({
69
67
  path: url,
70
68
  templateId: 'chatSingle',
71
69
  uniqueId: `chat_${sessionId}_${topicId}`,
@@ -87,9 +85,9 @@ export const generalActionSlice: StateCreator<
87
85
  if (isDesktop && !skipBroadcast) {
88
86
  (async () => {
89
87
  try {
90
- const { dispatch } = await import('@lobechat/electron-client-ipc');
88
+ const { ensureElectronIpc } = await import('@/utils/electron/ipc');
91
89
 
92
- await dispatch('updateLocale', locale);
90
+ await ensureElectronIpc().system.updateLocale(locale);
93
91
  } catch (error) {
94
92
  console.error('Failed to update locale in main process:', error);
95
93
  }
@@ -104,8 +102,8 @@ export const generalActionSlice: StateCreator<
104
102
  if (isDesktop && !skipBroadcast) {
105
103
  (async () => {
106
104
  try {
107
- const { dispatch } = await import('@lobechat/electron-client-ipc');
108
- await dispatch('updateThemeMode', themeMode);
105
+ const { ensureElectronIpc } = await import('@/utils/electron/ipc');
106
+ await ensureElectronIpc().system.updateThemeModeHandler(themeMode);
109
107
  } catch (error) {
110
108
  console.error('Failed to update theme in main process:', error);
111
109
  }
@@ -1,10 +1,11 @@
1
1
  import { isDesktop } from '@lobechat/const';
2
- import { ProxyTRPCRequestParams, dispatch, streamInvoke } from '@lobechat/electron-client-ipc';
2
+ import { ProxyTRPCRequestParams, streamInvoke } from '@lobechat/electron-client-ipc';
3
3
  import { getRequestBody, headersToRecord } from '@lobechat/fetch-sse';
4
4
  import debug from 'debug';
5
5
 
6
6
  import { getElectronStoreState } from '@/store/electron';
7
7
  import { electronSyncSelectors } from '@/store/electron/selectors';
8
+ import { ensureElectronIpc } from '@/utils/electron/ipc';
8
9
 
9
10
  const log = debug('utils:desktopRemoteRPCFetch');
10
11
 
@@ -30,7 +31,7 @@ export const desktopRemoteRPCFetch = async (input: string, init?: RequestInit) =
30
31
  urlPath,
31
32
  };
32
33
 
33
- const ipcResult = await dispatch('proxyTRPCRequest', params);
34
+ const ipcResult = await ensureElectronIpc().remoteServerSync.proxyTRPCRequest(params);
34
35
 
35
36
  log(`Received ${url} IPC proxy response:`, { status: ipcResult.status });
36
37
  const response = new Response(ipcResult.body, {
@@ -0,0 +1,12 @@
1
+ import { getElectronIpc } from '@lobechat/electron-client-ipc';
2
+ import type { DesktopIpcServices } from '@lobehub/desktop-ipc-typings';
3
+
4
+ export const ensureElectronIpc = (): DesktopIpcServices => {
5
+ const ipc = getElectronIpc();
6
+ if (!ipc) {
7
+ throw new Error(
8
+ 'electronAPI.invoke not found. Ensure the preload exposes invoke via window.electronAPI.invoke',
9
+ );
10
+ }
11
+ return ipc;
12
+ };
package/tsconfig.json CHANGED
@@ -47,5 +47,10 @@
47
47
  ".next/types/**/*.ts",
48
48
  "next-env.d.ts",
49
49
  ".next/dev/types/**/*.ts"
50
+ ],
51
+ "references": [
52
+ {
53
+ "path": "./apps/desktop"
54
+ }
50
55
  ]
51
56
  }
@@ -1,3 +0,0 @@
1
- export interface IpcClientEventSender {
2
- identifier: string;
3
- }
@@ -1,41 +0,0 @@
1
- import { DispatchInvoke, type ProxyTRPCRequestParams } from './types';
2
-
3
- interface StreamerCallbacks {
4
- onData: (chunk: Uint8Array) => void;
5
- onEnd: () => void;
6
- onError: (error: Error) => void;
7
- onResponse: (response: {
8
- headers: Record<string, string>;
9
- status: number;
10
- statusText: string;
11
- }) => void;
12
- }
13
-
14
- interface IElectronAPI {
15
- invoke: DispatchInvoke;
16
- onStreamInvoke: (params: ProxyTRPCRequestParams, callbacks: StreamerCallbacks) => () => void;
17
- }
18
-
19
- declare global {
20
- interface Window {
21
- electronAPI: IElectronAPI;
22
- }
23
- }
24
-
25
- /**
26
- * client 端请求 main 端 event 数据的方法
27
- */
28
- export const dispatch: DispatchInvoke = async (event, ...data) => {
29
- if (!window.electronAPI || !window.electronAPI.invoke)
30
- throw new Error(`electronAPI.invoke not found. Please expose \`ipcRenderer.invoke\` to \`window.electronAPI.invoke\` in the preload:
31
-
32
- import { contextBridge, ipcRenderer } from 'electron';
33
-
34
- const invoke = async (event, ...data) =>
35
- ipcRenderer.invoke(event, ...data);
36
-
37
- contextBridge.exposeInMainWorld('electronAPI', { invoke });
38
- `);
39
-
40
- return window.electronAPI.invoke(event, ...data);
41
- };