@lobehub/chat 1.82.10 → 1.83.1
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/.env.desktop +1 -2
- package/.github/workflows/{release-desktop.yml → desktop-pr-build.yml} +59 -137
- package/.github/workflows/release-desktop-beta.yml +194 -0
- package/CHANGELOG.md +42 -0
- package/apps/desktop/.i18nrc.js +31 -0
- package/apps/desktop/Development.md +47 -0
- package/apps/desktop/README.md +6 -0
- package/apps/desktop/build/Icon-beta.icns +0 -0
- package/apps/desktop/build/Icon-nightly.icns +0 -0
- package/apps/desktop/build/Icon.icns +0 -0
- package/apps/desktop/build/entitlements.mac.plist +12 -0
- package/apps/desktop/build/favicon.ico +0 -0
- package/apps/desktop/build/icon-beta.png +0 -0
- package/apps/desktop/build/icon-dev.png +0 -0
- package/apps/desktop/build/icon-nightly.ico +0 -0
- package/apps/desktop/build/icon-nightly.png +0 -0
- package/apps/desktop/build/icon.ico +0 -0
- package/apps/desktop/build/icon.png +0 -0
- package/apps/desktop/dev-app-update.yml +6 -0
- package/apps/desktop/electron-builder.js +92 -0
- package/apps/desktop/electron.vite.config.ts +40 -0
- package/apps/desktop/package.json +72 -0
- package/apps/desktop/pnpm-workspace.yaml +5 -0
- package/apps/desktop/resources/error.html +136 -0
- package/apps/desktop/resources/locales/ar/common.json +32 -0
- package/apps/desktop/resources/locales/ar/dialog.json +31 -0
- package/apps/desktop/resources/locales/ar/menu.json +70 -0
- package/apps/desktop/resources/locales/bg-BG/common.json +32 -0
- package/apps/desktop/resources/locales/bg-BG/dialog.json +31 -0
- package/apps/desktop/resources/locales/bg-BG/menu.json +70 -0
- package/apps/desktop/resources/locales/de-DE/common.json +32 -0
- package/apps/desktop/resources/locales/de-DE/dialog.json +31 -0
- package/apps/desktop/resources/locales/de-DE/menu.json +70 -0
- package/apps/desktop/resources/locales/en-US/common.json +32 -0
- package/apps/desktop/resources/locales/en-US/dialog.json +31 -0
- package/apps/desktop/resources/locales/en-US/menu.json +70 -0
- package/apps/desktop/resources/locales/es-ES/common.json +32 -0
- package/apps/desktop/resources/locales/es-ES/dialog.json +31 -0
- package/apps/desktop/resources/locales/es-ES/menu.json +70 -0
- package/apps/desktop/resources/locales/fa-IR/common.json +32 -0
- package/apps/desktop/resources/locales/fa-IR/dialog.json +31 -0
- package/apps/desktop/resources/locales/fa-IR/menu.json +70 -0
- package/apps/desktop/resources/locales/fr-FR/common.json +32 -0
- package/apps/desktop/resources/locales/fr-FR/dialog.json +31 -0
- package/apps/desktop/resources/locales/fr-FR/menu.json +70 -0
- package/apps/desktop/resources/locales/it-IT/common.json +32 -0
- package/apps/desktop/resources/locales/it-IT/dialog.json +31 -0
- package/apps/desktop/resources/locales/it-IT/menu.json +70 -0
- package/apps/desktop/resources/locales/ja-JP/common.json +32 -0
- package/apps/desktop/resources/locales/ja-JP/dialog.json +31 -0
- package/apps/desktop/resources/locales/ja-JP/menu.json +70 -0
- package/apps/desktop/resources/locales/ko-KR/common.json +32 -0
- package/apps/desktop/resources/locales/ko-KR/dialog.json +31 -0
- package/apps/desktop/resources/locales/ko-KR/menu.json +70 -0
- package/apps/desktop/resources/locales/nl-NL/common.json +32 -0
- package/apps/desktop/resources/locales/nl-NL/dialog.json +31 -0
- package/apps/desktop/resources/locales/nl-NL/menu.json +70 -0
- package/apps/desktop/resources/locales/pl-PL/common.json +32 -0
- package/apps/desktop/resources/locales/pl-PL/dialog.json +31 -0
- package/apps/desktop/resources/locales/pl-PL/menu.json +70 -0
- package/apps/desktop/resources/locales/pt-BR/common.json +32 -0
- package/apps/desktop/resources/locales/pt-BR/dialog.json +31 -0
- package/apps/desktop/resources/locales/pt-BR/menu.json +70 -0
- package/apps/desktop/resources/locales/ru-RU/common.json +32 -0
- package/apps/desktop/resources/locales/ru-RU/dialog.json +31 -0
- package/apps/desktop/resources/locales/ru-RU/menu.json +70 -0
- package/apps/desktop/resources/locales/tr-TR/common.json +32 -0
- package/apps/desktop/resources/locales/tr-TR/dialog.json +31 -0
- package/apps/desktop/resources/locales/tr-TR/menu.json +70 -0
- package/apps/desktop/resources/locales/vi-VN/common.json +32 -0
- package/apps/desktop/resources/locales/vi-VN/dialog.json +31 -0
- package/apps/desktop/resources/locales/vi-VN/menu.json +70 -0
- package/apps/desktop/resources/locales/zh-CN/common.json +32 -0
- package/apps/desktop/resources/locales/zh-CN/dialog.json +31 -0
- package/apps/desktop/resources/locales/zh-CN/menu.json +70 -0
- package/apps/desktop/resources/locales/zh-TW/common.json +32 -0
- package/apps/desktop/resources/locales/zh-TW/dialog.json +31 -0
- package/apps/desktop/resources/locales/zh-TW/menu.json +70 -0
- package/apps/desktop/resources/splash.html +88 -0
- package/apps/desktop/scripts/i18nWorkflow/const.ts +18 -0
- package/apps/desktop/scripts/i18nWorkflow/genDefaultLocale.ts +35 -0
- package/apps/desktop/scripts/i18nWorkflow/genDiff.ts +57 -0
- package/apps/desktop/scripts/i18nWorkflow/index.ts +35 -0
- package/apps/desktop/scripts/i18nWorkflow/utils.ts +54 -0
- package/apps/desktop/scripts/pglite-server.ts +14 -0
- package/apps/desktop/src/common/routes.ts +78 -0
- package/apps/desktop/src/main/appBrowsers.ts +47 -0
- package/apps/desktop/src/main/const/dir.ts +29 -0
- package/apps/desktop/src/main/const/env.ts +3 -0
- package/apps/desktop/src/main/const/store.ts +22 -0
- package/apps/desktop/src/main/controllers/AuthCtr.ts +390 -0
- package/apps/desktop/src/main/controllers/BrowserWindowsCtr.ts +95 -0
- package/apps/desktop/src/main/controllers/DevtoolsCtr.ts +9 -0
- package/apps/desktop/src/main/controllers/LocalFileCtr.ts +380 -0
- package/apps/desktop/src/main/controllers/MenuCtr.ts +29 -0
- package/apps/desktop/src/main/controllers/RemoteServerConfigCtr.ts +335 -0
- package/apps/desktop/src/main/controllers/RemoteServerSyncCtr.ts +321 -0
- package/apps/desktop/src/main/controllers/ShortcutCtr.ts +19 -0
- package/apps/desktop/src/main/controllers/SystemCtr.ts +93 -0
- package/apps/desktop/src/main/controllers/UpdaterCtr.ts +43 -0
- package/apps/desktop/src/main/controllers/UploadFileCtr.ts +34 -0
- package/apps/desktop/src/main/controllers/_template.ts +9 -0
- package/apps/desktop/src/main/controllers/index.ts +58 -0
- package/apps/desktop/src/main/core/App.ts +370 -0
- package/apps/desktop/src/main/core/Browser.ts +345 -0
- package/apps/desktop/src/main/core/BrowserManager.ts +154 -0
- package/apps/desktop/src/main/core/I18nManager.ts +185 -0
- package/apps/desktop/src/main/core/IoCContainer.ts +12 -0
- package/apps/desktop/src/main/core/MenuManager.ts +64 -0
- package/apps/desktop/src/main/core/ShortcutManager.ts +173 -0
- package/apps/desktop/src/main/core/StoreManager.ts +89 -0
- package/apps/desktop/src/main/core/UpdaterManager.ts +321 -0
- package/apps/desktop/src/main/index.ts +5 -0
- package/apps/desktop/src/main/locales/default/common.ts +34 -0
- package/apps/desktop/src/main/locales/default/dialog.ts +33 -0
- package/apps/desktop/src/main/locales/default/index.ts +11 -0
- package/apps/desktop/src/main/locales/default/menu.ts +72 -0
- package/apps/desktop/src/main/locales/resources.ts +35 -0
- package/apps/desktop/src/main/menus/impls/BaseMenuPlatform.ts +10 -0
- package/apps/desktop/src/main/menus/impls/linux.ts +243 -0
- package/apps/desktop/src/main/menus/impls/macOS.ts +360 -0
- package/apps/desktop/src/main/menus/impls/windows.ts +226 -0
- package/apps/desktop/src/main/menus/index.ts +34 -0
- package/apps/desktop/src/main/menus/types.ts +28 -0
- package/apps/desktop/src/main/modules/fileSearch/impl/macOS.ts +577 -0
- package/apps/desktop/src/main/modules/fileSearch/index.ts +23 -0
- package/apps/desktop/src/main/modules/fileSearch/type.ts +27 -0
- package/apps/desktop/src/main/modules/updater/configs.ts +22 -0
- package/apps/desktop/src/main/modules/updater/utils.ts +33 -0
- package/apps/desktop/src/main/services/fileSearchSrv.ts +35 -0
- package/apps/desktop/src/main/services/fileSrv.ts +255 -0
- package/apps/desktop/src/main/services/index.ts +9 -0
- package/apps/desktop/src/main/shortcuts/config.ts +18 -0
- package/apps/desktop/src/main/shortcuts/index.ts +1 -0
- package/apps/desktop/src/main/types/fileSearch.ts +51 -0
- package/apps/desktop/src/main/types/store.ts +14 -0
- package/apps/desktop/src/main/utils/file-system.ts +15 -0
- package/apps/desktop/src/main/utils/logger.ts +44 -0
- package/apps/desktop/src/main/utils/next-electron-rsc.ts +383 -0
- package/apps/desktop/src/preload/electronApi.ts +18 -0
- package/apps/desktop/src/preload/index.ts +14 -0
- package/apps/desktop/src/preload/invoke.ts +10 -0
- package/apps/desktop/src/preload/routeInterceptor.ts +162 -0
- package/apps/desktop/tsconfig.json +21 -0
- package/changelog/v1.json +14 -0
- package/package.json +1 -1
- package/packages/electron-client-ipc/src/events/remoteServer.ts +11 -4
- package/packages/electron-client-ipc/src/types/dataSync.ts +15 -0
- package/packages/electron-client-ipc/src/types/index.ts +2 -1
- package/packages/electron-client-ipc/src/types/proxyTRPCRequest.ts +21 -0
- package/packages/electron-server-ipc/src/const.ts +3 -3
- package/packages/electron-server-ipc/src/ipcClient.test.ts +7 -6
- package/packages/electron-server-ipc/src/ipcClient.ts +17 -8
- package/packages/electron-server-ipc/src/ipcServer.ts +7 -3
- package/scripts/electronWorkflow/setDesktopVersion.ts +60 -43
- package/src/app/[variants]/(main)/_layout/Desktop/index.tsx +1 -1
- package/src/components/Analytics/Desktop.tsx +19 -0
- package/src/components/Analytics/index.tsx +3 -0
- package/src/database/core/db-adaptor.ts +4 -1
- package/src/database/core/electron.ts +317 -0
- package/src/{app/[variants]/(main)/_layout/Desktop/ElectronTitlebar/Connection/Mode.tsx → features/ElectronTitlebar/Connection/ConnectionMode.tsx} +24 -21
- package/src/{app/[variants]/(main)/_layout/Desktop → features}/ElectronTitlebar/Connection/Option.tsx +3 -5
- package/src/{app/[variants]/(main)/_layout/Desktop/ElectronTitlebar/Connection/Sync.tsx → features/ElectronTitlebar/Connection/RemoteStatus.tsx} +10 -7
- package/src/{app/[variants]/(main)/_layout/Desktop → features}/ElectronTitlebar/Connection/index.tsx +4 -4
- package/src/{app/[variants]/(main)/_layout/Desktop → features}/ElectronTitlebar/UpdateModal.tsx +2 -1
- package/src/libs/trpc/client/async.ts +6 -0
- package/src/libs/trpc/client/edge.ts +6 -0
- package/src/libs/trpc/client/helpers/desktopRemoteRPCFetch.ts +72 -0
- package/src/libs/trpc/client/index.ts +1 -0
- package/src/libs/trpc/client/lambda.ts +10 -1
- package/src/libs/trpc/client/tools.ts +6 -0
- package/src/server/globalConfig/index.ts +0 -3
- package/src/server/modules/ElectronIPCClient/index.ts +3 -1
- package/src/server/routers/desktop/index.ts +2 -0
- package/src/server/routers/desktop/mcp.ts +47 -0
- package/src/server/routers/lambda/user.ts +38 -23
- package/src/server/routers/tools/mcp.ts +0 -6
- package/src/services/electron/remoteServer.ts +4 -4
- package/src/services/mcp.ts +17 -7
- package/src/services/upload.ts +9 -0
- package/src/store/chat/slices/aiChat/actions/generateAIChat.ts +11 -2
- package/src/store/chat/slices/builtinTool/actions/localFile.ts +110 -53
- package/src/store/electron/actions/sync.ts +20 -19
- package/src/store/electron/initialState.ts +3 -3
- package/src/store/electron/selectors/sync.ts +6 -3
- package/src/store/electron/store.ts +2 -0
- package/src/store/file/slices/upload/action.ts +11 -3
- package/src/store/tool/selectors/tool.ts +10 -1
- package/src/utils/fetch/headers.ts +27 -0
- package/src/utils/fetch/index.ts +2 -0
- package/src/utils/fetch/request.ts +28 -0
- package/packages/electron-client-ipc/src/types/remoteServer.ts +0 -8
- /package/src/{app/[variants]/(main)/_layout/Desktop → features}/ElectronTitlebar/Connection/Waiting.tsx +0 -0
- /package/src/{app/[variants]/(main)/_layout/Desktop → features}/ElectronTitlebar/UpdateNotification.tsx +0 -0
- /package/src/{app/[variants]/(main)/_layout/Desktop → features}/ElectronTitlebar/index.tsx +0 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
export type ProxyTRPCRequestParams = {
|
2
|
+
/** Request body (can be string, ArrayBuffer, or null/undefined) */
|
3
|
+
body?: string | ArrayBuffer;
|
4
|
+
/** Request headers */
|
5
|
+
headers: Record<string, string>;
|
6
|
+
/** The HTTP method (e.g., 'GET', 'POST') */
|
7
|
+
method: string;
|
8
|
+
/** The path and query string of the request (e.g., '/trpc/lambda/...') */
|
9
|
+
urlPath: string;
|
10
|
+
};
|
11
|
+
|
12
|
+
export interface ProxyTRPCRequestResult {
|
13
|
+
/** Response body (likely as ArrayBuffer or string) */
|
14
|
+
body: ArrayBuffer | string;
|
15
|
+
/** Response headers */
|
16
|
+
headers: Record<string, string>;
|
17
|
+
/** Response status code */
|
18
|
+
status: number;
|
19
|
+
/** Response status text */
|
20
|
+
statusText: string;
|
21
|
+
}
|
@@ -1,5 +1,5 @@
|
|
1
|
-
export const SOCK_FILE =
|
1
|
+
export const SOCK_FILE = (id: string) => `${id}-electron-ipc.sock`;
|
2
2
|
|
3
|
-
export const SOCK_INFO_FILE =
|
3
|
+
export const SOCK_INFO_FILE = (id: string) => `${id}-electron-ipc-info.json`;
|
4
4
|
|
5
|
-
export const WINDOW_PIPE_FILE =
|
5
|
+
export const WINDOW_PIPE_FILE = (id: string) => `\\\\.\\pipe\\${id}-electron-ipc`;
|
@@ -12,6 +12,7 @@ vi.mock('node:net');
|
|
12
12
|
vi.mock('node:os');
|
13
13
|
vi.mock('node:path');
|
14
14
|
|
15
|
+
const appId = 'lobehub';
|
15
16
|
describe('ElectronIpcClient', () => {
|
16
17
|
// Mock data
|
17
18
|
const mockTempDir = '/mock/temp/dir';
|
@@ -54,7 +55,7 @@ describe('ElectronIpcClient', () => {
|
|
54
55
|
vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify(mockSocketInfo));
|
55
56
|
|
56
57
|
// Execute
|
57
|
-
new ElectronIpcClient();
|
58
|
+
new ElectronIpcClient(appId);
|
58
59
|
|
59
60
|
// Verify
|
60
61
|
expect(fs.existsSync).toHaveBeenCalledWith(mockSocketInfoPath);
|
@@ -66,7 +67,7 @@ describe('ElectronIpcClient', () => {
|
|
66
67
|
vi.mocked(fs.existsSync).mockReturnValue(false);
|
67
68
|
|
68
69
|
// Execute
|
69
|
-
new ElectronIpcClient();
|
70
|
+
new ElectronIpcClient(appId);
|
70
71
|
|
71
72
|
// Verify
|
72
73
|
expect(fs.existsSync).toHaveBeenCalledWith(mockSocketInfoPath);
|
@@ -75,7 +76,7 @@ describe('ElectronIpcClient', () => {
|
|
75
76
|
// Test platform-specific behavior
|
76
77
|
const originalPlatform = process.platform;
|
77
78
|
Object.defineProperty(process, 'platform', { value: 'win32' });
|
78
|
-
new ElectronIpcClient();
|
79
|
+
new ElectronIpcClient(appId);
|
79
80
|
Object.defineProperty(process, 'platform', { value: originalPlatform });
|
80
81
|
});
|
81
82
|
|
@@ -86,7 +87,7 @@ describe('ElectronIpcClient', () => {
|
|
86
87
|
});
|
87
88
|
|
88
89
|
// Execute
|
89
|
-
new ElectronIpcClient();
|
90
|
+
new ElectronIpcClient(appId);
|
90
91
|
|
91
92
|
// Verify
|
92
93
|
expect(console.error).toHaveBeenCalledWith(
|
@@ -103,7 +104,7 @@ describe('ElectronIpcClient', () => {
|
|
103
104
|
// Setup a client with a known socket path
|
104
105
|
vi.mocked(fs.existsSync).mockReturnValue(true);
|
105
106
|
vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify(mockSocketInfo));
|
106
|
-
client = new ElectronIpcClient();
|
107
|
+
client = new ElectronIpcClient(appId);
|
107
108
|
|
108
109
|
// Reset socket mocks for each test
|
109
110
|
mockSocket.on.mockReset();
|
@@ -170,7 +171,7 @@ describe('ElectronIpcClient', () => {
|
|
170
171
|
// Setup a client with a known socket path
|
171
172
|
vi.mocked(fs.existsSync).mockReturnValue(true);
|
172
173
|
vi.mocked(fs.readFileSync).mockReturnValue(JSON.stringify(mockSocketInfo));
|
173
|
-
client = new ElectronIpcClient();
|
174
|
+
client = new ElectronIpcClient(appId);
|
174
175
|
|
175
176
|
// Setup socket.on
|
176
177
|
mockSocket.on.mockImplementation((event, callback) => {
|
@@ -20,18 +20,28 @@ export class ElectronIpcClient {
|
|
20
20
|
private connectionAttempts: number = 0;
|
21
21
|
private maxConnectionAttempts: number = 5;
|
22
22
|
private dataBuffer: string = '';
|
23
|
+
private readonly appId: string;
|
23
24
|
|
24
|
-
constructor() {
|
25
|
-
log('Initializing client');
|
25
|
+
constructor(appId: string) {
|
26
|
+
log('Initializing client', appId);
|
27
|
+
this.appId = appId;
|
26
28
|
this.initialize();
|
27
29
|
}
|
28
30
|
|
29
31
|
// 初始化客户端
|
30
32
|
private initialize() {
|
31
33
|
try {
|
32
|
-
// 从临时文件读取套接字路径
|
33
34
|
const tempDir = os.tmpdir();
|
34
|
-
|
35
|
+
|
36
|
+
// Windows 平台强制使用命名管道
|
37
|
+
if (process.platform === 'win32') {
|
38
|
+
this.socketPath = WINDOW_PIPE_FILE(this.appId);
|
39
|
+
log('Using named pipe for Windows: %s', this.socketPath);
|
40
|
+
return;
|
41
|
+
}
|
42
|
+
|
43
|
+
// 其他平台尝试读取 sock info 文件
|
44
|
+
const socketInfoPath = path.join(tempDir, SOCK_INFO_FILE(this.appId));
|
35
45
|
|
36
46
|
log('Looking for socket info at: %s', socketInfoPath);
|
37
47
|
if (fs.existsSync(socketInfoPath)) {
|
@@ -39,10 +49,9 @@ export class ElectronIpcClient {
|
|
39
49
|
this.socketPath = socketInfo.socketPath;
|
40
50
|
log('Found socket path: %s', this.socketPath);
|
41
51
|
} else {
|
42
|
-
//
|
43
|
-
this.socketPath =
|
44
|
-
|
45
|
-
log('Socket info not found, using default path: %s', this.socketPath);
|
52
|
+
// 如果找不到套接字信息,使用默认 sock 文件路径
|
53
|
+
this.socketPath = path.join(tempDir, SOCK_FILE(this.appId));
|
54
|
+
log('Socket info not found, using default sock path: %s', this.socketPath);
|
46
55
|
}
|
47
56
|
} catch (err) {
|
48
57
|
console.error('Failed to initialize IPC client:', err);
|
@@ -13,12 +13,16 @@ const log = debug('electron-server-ipc:server');
|
|
13
13
|
export class ElectronIPCServer {
|
14
14
|
private server: net.Server;
|
15
15
|
private socketPath: string;
|
16
|
+
private appId: string;
|
16
17
|
private eventHandler: ElectronIPCEventHandler;
|
17
18
|
|
18
|
-
constructor(eventHandler: ElectronIPCEventHandler) {
|
19
|
+
constructor(appId: string, eventHandler: ElectronIPCEventHandler) {
|
20
|
+
this.appId = appId;
|
19
21
|
const isWindows = process.platform === 'win32';
|
20
22
|
// 创建唯一的套接字路径,避免冲突
|
21
|
-
this.socketPath = isWindows
|
23
|
+
this.socketPath = isWindows
|
24
|
+
? WINDOW_PIPE_FILE(appId)
|
25
|
+
: path.join(os.tmpdir(), SOCK_FILE(appId));
|
22
26
|
|
23
27
|
// 如果是 Unix 套接字,确保文件不存在
|
24
28
|
if (!isWindows && fs.existsSync(this.socketPath)) {
|
@@ -47,7 +51,7 @@ export class ElectronIPCServer {
|
|
47
51
|
|
48
52
|
// 将套接字路径写入临时文件,供 Next.js 服务端读取
|
49
53
|
const tempDir = os.tmpdir();
|
50
|
-
const socketInfoPath = path.join(tempDir, SOCK_INFO_FILE);
|
54
|
+
const socketInfoPath = path.join(tempDir, SOCK_INFO_FILE(this.appId));
|
51
55
|
log('Writing socket info to: %s', socketInfoPath);
|
52
56
|
fs.writeFileSync(socketInfoPath, JSON.stringify({ socketPath: this.socketPath }), 'utf8');
|
53
57
|
|
@@ -2,12 +2,24 @@
|
|
2
2
|
import fs from 'fs-extra';
|
3
3
|
import path from 'node:path';
|
4
4
|
|
5
|
+
type ReleaseType = 'stable' | 'beta' | 'nightly';
|
6
|
+
|
5
7
|
// 获取脚本的命令行参数
|
6
8
|
const version = process.argv[2];
|
7
|
-
const
|
9
|
+
const releaseType = process.argv[3] as ReleaseType;
|
10
|
+
|
11
|
+
// 验证参数
|
12
|
+
if (!version || !releaseType) {
|
13
|
+
console.error(
|
14
|
+
'Missing parameters. Usage: bun run setDesktopVersion.ts <version> <stable|beta|nightly>',
|
15
|
+
);
|
16
|
+
process.exit(1);
|
17
|
+
}
|
8
18
|
|
9
|
-
if (!
|
10
|
-
console.error(
|
19
|
+
if (!['stable', 'beta', 'nightly'].includes(releaseType)) {
|
20
|
+
console.error(
|
21
|
+
`Invalid release type: ${releaseType}. Must be one of 'stable', 'beta', 'nightly'.`,
|
22
|
+
);
|
11
23
|
process.exit(1);
|
12
24
|
}
|
13
25
|
|
@@ -16,81 +28,86 @@ const rootDir = path.resolve(__dirname, '../..');
|
|
16
28
|
|
17
29
|
// 桌面应用 package.json 的路径
|
18
30
|
const desktopPackageJsonPath = path.join(rootDir, 'apps/desktop/package.json');
|
31
|
+
const buildDir = path.join(rootDir, 'apps/desktop/build');
|
19
32
|
|
20
33
|
// 更新应用图标
|
21
|
-
function updateAppIcon() {
|
34
|
+
function updateAppIcon(type: 'beta' | 'nightly') {
|
35
|
+
console.log(`📦 Updating app icon for ${type} version...`);
|
22
36
|
try {
|
23
|
-
const
|
24
|
-
|
25
|
-
// 定义需要处理的图标映射,考虑到大小写敏感性
|
37
|
+
const iconSuffix = type === 'beta' ? 'beta' : 'nightly';
|
26
38
|
const iconMappings = [
|
27
|
-
|
28
|
-
{ ext: '.
|
29
|
-
{ ext: '.
|
39
|
+
{ ext: '.png', source: `icon-${iconSuffix}.png`, target: 'icon.png' },
|
40
|
+
{ ext: '.icns', source: `Icon-${iconSuffix}.icns`, target: 'Icon.icns' },
|
41
|
+
{ ext: '.ico', source: `icon-${iconSuffix}.ico`, target: 'icon.ico' },
|
30
42
|
];
|
31
43
|
|
32
|
-
// 处理每种图标格式
|
33
44
|
for (const mapping of iconMappings) {
|
34
|
-
const sourceFile = path.join(buildDir, mapping.
|
35
|
-
const targetFile = path.join(buildDir, mapping.
|
45
|
+
const sourceFile = path.join(buildDir, mapping.source);
|
46
|
+
const targetFile = path.join(buildDir, mapping.target);
|
36
47
|
|
37
|
-
// 检查源文件是否存在
|
38
48
|
if (fs.existsSync(sourceFile)) {
|
39
|
-
// 只有当源文件和目标文件不同,才进行复制
|
40
49
|
if (sourceFile !== targetFile) {
|
41
50
|
fs.copyFileSync(sourceFile, targetFile);
|
42
|
-
console.log(`
|
51
|
+
console.log(` ✅ Copied ${mapping.source} to ${mapping.target}`);
|
43
52
|
}
|
44
53
|
} else {
|
45
|
-
console.warn(`Warning: Source icon not found: ${sourceFile}`);
|
54
|
+
console.warn(` ⚠️ Warning: Source icon not found: ${sourceFile}`);
|
46
55
|
}
|
47
56
|
}
|
48
57
|
} catch (error) {
|
49
|
-
console.error('Error updating icons:', error);
|
50
|
-
//
|
58
|
+
console.error(' ❌ Error updating icons:', error);
|
59
|
+
// 不终止程序,继续处理 package.json
|
51
60
|
}
|
52
61
|
}
|
53
62
|
|
54
|
-
function
|
63
|
+
function updatePackageJson() {
|
64
|
+
console.log(`⚙️ Updating ${desktopPackageJsonPath} for ${releaseType} version ${version}...`);
|
55
65
|
try {
|
56
|
-
// 确保文件存在
|
57
66
|
if (!fs.existsSync(desktopPackageJsonPath)) {
|
58
|
-
console.error(
|
67
|
+
console.error(`❌ Error: File not found ${desktopPackageJsonPath}`);
|
59
68
|
process.exit(1);
|
60
69
|
}
|
61
70
|
|
62
|
-
// 读取 package.json 文件
|
63
71
|
const packageJson = fs.readJSONSync(desktopPackageJsonPath);
|
64
72
|
|
65
|
-
//
|
73
|
+
// 始终更新版本号
|
66
74
|
packageJson.version = version;
|
67
|
-
packageJson.productName = 'LobeHub';
|
68
|
-
packageJson.name = 'lobehub-desktop';
|
69
|
-
|
70
|
-
// 如果是 PR 构建,设置为 Nightly 版本
|
71
|
-
if (isPr) {
|
72
|
-
// 修改包名,添加 -nightly 后缀
|
73
|
-
if (!packageJson.name.endsWith('-nightly')) {
|
74
|
-
packageJson.name = `${packageJson.name}-nightly`;
|
75
|
-
}
|
76
75
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
76
|
+
// 根据 releaseType 修改其他字段
|
77
|
+
switch (releaseType) {
|
78
|
+
case 'stable': {
|
79
|
+
packageJson.productName = 'LobeHub';
|
80
|
+
packageJson.name = 'lobehub-desktop';
|
81
|
+
console.log('🌟 Setting as Stable version.');
|
82
|
+
break;
|
83
|
+
}
|
84
|
+
case 'beta': {
|
85
|
+
packageJson.productName = 'LobeHub-Beta'; // Or 'LobeHub-Beta' if preferred
|
86
|
+
packageJson.name = 'lobehub-desktop-beta'; // Or 'lobehub-desktop' if preferred
|
87
|
+
console.log('🧪 Setting as Beta version.');
|
88
|
+
updateAppIcon('beta');
|
89
|
+
break;
|
90
|
+
}
|
91
|
+
case 'nightly': {
|
92
|
+
packageJson.productName = 'LobeHub-Nightly'; // Or 'LobeHub-Nightly'
|
93
|
+
packageJson.name = 'lobehub-desktop-nightly'; // Or 'lobehub-desktop-nightly'
|
94
|
+
console.log('🌙 Setting as Nightly version.');
|
95
|
+
updateAppIcon('nightly');
|
96
|
+
break;
|
97
|
+
}
|
84
98
|
}
|
85
99
|
|
86
100
|
// 写回文件
|
87
101
|
fs.writeJsonSync(desktopPackageJsonPath, packageJson, { spaces: 2 });
|
88
102
|
|
89
|
-
console.log(
|
103
|
+
console.log(
|
104
|
+
`✅ Desktop app package.json updated successfully for ${releaseType} version ${version}.`,
|
105
|
+
);
|
90
106
|
} catch (error) {
|
91
|
-
console.error('Error updating
|
107
|
+
console.error('❌ Error updating package.json:', error);
|
92
108
|
process.exit(1);
|
93
109
|
}
|
94
110
|
}
|
95
111
|
|
96
|
-
|
112
|
+
// 执行更新
|
113
|
+
updatePackageJson();
|
@@ -9,12 +9,12 @@ import { Flexbox } from 'react-layout-kit';
|
|
9
9
|
|
10
10
|
import { isDesktop } from '@/const/version';
|
11
11
|
import { BANNER_HEIGHT } from '@/features/AlertBanner/CloudBanner';
|
12
|
+
import TitleBar, { TITLE_BAR_HEIGHT } from '@/features/ElectronTitlebar';
|
12
13
|
import HotkeyHelperPanel from '@/features/HotkeyHelperPanel';
|
13
14
|
import { usePlatform } from '@/hooks/usePlatform';
|
14
15
|
import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig';
|
15
16
|
import { HotkeyScopeEnum } from '@/types/hotkey';
|
16
17
|
|
17
|
-
import TitleBar, { TITLE_BAR_HEIGHT } from './ElectronTitlebar';
|
18
18
|
import RegisterHotkeys from './RegisterHotkeys';
|
19
19
|
import SideBar from './SideBar';
|
20
20
|
|
@@ -0,0 +1,19 @@
|
|
1
|
+
'use client';
|
2
|
+
|
3
|
+
import Script from 'next/script';
|
4
|
+
import { memo } from 'react';
|
5
|
+
import urlJoin from 'url-join';
|
6
|
+
|
7
|
+
const DesktopAnalytics = memo(
|
8
|
+
() =>
|
9
|
+
process.env.NEXT_PUBLIC_DESKTOP_PROJECT_ID &&
|
10
|
+
process.env.NEXT_PUBLIC_DESKTOP_UMAMI_BASE_URL && (
|
11
|
+
<Script
|
12
|
+
data-website-id={process.env.NEXT_PUBLIC_DESKTOP_PROJECT_ID}
|
13
|
+
defer
|
14
|
+
src={urlJoin(process.env.NEXT_PUBLIC_DESKTOP_UMAMI_BASE_URL, 'script.js')}
|
15
|
+
/>
|
16
|
+
),
|
17
|
+
);
|
18
|
+
|
19
|
+
export default DesktopAnalytics;
|
@@ -1,7 +1,9 @@
|
|
1
1
|
import dynamic from 'next/dynamic';
|
2
2
|
|
3
3
|
import { analyticsEnv } from '@/config/analytics';
|
4
|
+
import { isDesktop } from '@/const/version';
|
4
5
|
|
6
|
+
import Desktop from './Desktop';
|
5
7
|
import Google from './Google';
|
6
8
|
import Vercel from './Vercel';
|
7
9
|
|
@@ -41,6 +43,7 @@ const Analytics = () => {
|
|
41
43
|
{!!analyticsEnv.REACT_SCAN_MONITOR_API_KEY && (
|
42
44
|
<ReactScan apiKey={analyticsEnv.REACT_SCAN_MONITOR_API_KEY} />
|
43
45
|
)}
|
46
|
+
{isDesktop && <Desktop />}
|
44
47
|
</>
|
45
48
|
);
|
46
49
|
};
|
@@ -1,6 +1,9 @@
|
|
1
|
+
import { isDesktop } from '@/const/version';
|
1
2
|
import { getDBInstance } from '@/database/core/web-server';
|
2
3
|
import { LobeChatDatabase } from '@/database/type';
|
3
4
|
|
5
|
+
import { getPgliteInstance } from './electron';
|
6
|
+
|
4
7
|
/**
|
5
8
|
* 懒加载数据库实例
|
6
9
|
* 避免每次模块导入时都初始化数据库
|
@@ -13,7 +16,7 @@ export const getServerDB = async (): Promise<LobeChatDatabase> => {
|
|
13
16
|
|
14
17
|
try {
|
15
18
|
// 根据环境选择合适的数据库实例
|
16
|
-
cachedDB = getDBInstance();
|
19
|
+
cachedDB = isDesktop ? await getPgliteInstance() : getDBInstance();
|
17
20
|
return cachedDB;
|
18
21
|
} catch (error) {
|
19
22
|
console.error('❌ Failed to initialize database:', error);
|