@lobehub/chat 1.82.10 → 1.83.0

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 (195) hide show
  1. package/.env.desktop +1 -2
  2. package/.github/workflows/{release-desktop.yml → desktop-pr-build.yml} +59 -137
  3. package/.github/workflows/release-desktop-beta.yml +196 -0
  4. package/CHANGELOG.md +25 -0
  5. package/apps/desktop/.i18nrc.js +31 -0
  6. package/apps/desktop/Development.md +47 -0
  7. package/apps/desktop/README.md +6 -0
  8. package/apps/desktop/build/Icon-beta.icns +0 -0
  9. package/apps/desktop/build/Icon-nightly.icns +0 -0
  10. package/apps/desktop/build/Icon.icns +0 -0
  11. package/apps/desktop/build/entitlements.mac.plist +12 -0
  12. package/apps/desktop/build/favicon.ico +0 -0
  13. package/apps/desktop/build/icon-beta.png +0 -0
  14. package/apps/desktop/build/icon-dev.png +0 -0
  15. package/apps/desktop/build/icon-nightly.ico +0 -0
  16. package/apps/desktop/build/icon-nightly.png +0 -0
  17. package/apps/desktop/build/icon.ico +0 -0
  18. package/apps/desktop/build/icon.png +0 -0
  19. package/apps/desktop/dev-app-update.yml +6 -0
  20. package/apps/desktop/electron-builder.js +92 -0
  21. package/apps/desktop/electron.vite.config.ts +40 -0
  22. package/apps/desktop/package.json +72 -0
  23. package/apps/desktop/pnpm-workspace.yaml +5 -0
  24. package/apps/desktop/resources/error.html +136 -0
  25. package/apps/desktop/resources/locales/ar/common.json +32 -0
  26. package/apps/desktop/resources/locales/ar/dialog.json +31 -0
  27. package/apps/desktop/resources/locales/ar/menu.json +70 -0
  28. package/apps/desktop/resources/locales/bg-BG/common.json +32 -0
  29. package/apps/desktop/resources/locales/bg-BG/dialog.json +31 -0
  30. package/apps/desktop/resources/locales/bg-BG/menu.json +70 -0
  31. package/apps/desktop/resources/locales/de-DE/common.json +32 -0
  32. package/apps/desktop/resources/locales/de-DE/dialog.json +31 -0
  33. package/apps/desktop/resources/locales/de-DE/menu.json +70 -0
  34. package/apps/desktop/resources/locales/en-US/common.json +32 -0
  35. package/apps/desktop/resources/locales/en-US/dialog.json +31 -0
  36. package/apps/desktop/resources/locales/en-US/menu.json +70 -0
  37. package/apps/desktop/resources/locales/es-ES/common.json +32 -0
  38. package/apps/desktop/resources/locales/es-ES/dialog.json +31 -0
  39. package/apps/desktop/resources/locales/es-ES/menu.json +70 -0
  40. package/apps/desktop/resources/locales/fa-IR/common.json +32 -0
  41. package/apps/desktop/resources/locales/fa-IR/dialog.json +31 -0
  42. package/apps/desktop/resources/locales/fa-IR/menu.json +70 -0
  43. package/apps/desktop/resources/locales/fr-FR/common.json +32 -0
  44. package/apps/desktop/resources/locales/fr-FR/dialog.json +31 -0
  45. package/apps/desktop/resources/locales/fr-FR/menu.json +70 -0
  46. package/apps/desktop/resources/locales/it-IT/common.json +32 -0
  47. package/apps/desktop/resources/locales/it-IT/dialog.json +31 -0
  48. package/apps/desktop/resources/locales/it-IT/menu.json +70 -0
  49. package/apps/desktop/resources/locales/ja-JP/common.json +32 -0
  50. package/apps/desktop/resources/locales/ja-JP/dialog.json +31 -0
  51. package/apps/desktop/resources/locales/ja-JP/menu.json +70 -0
  52. package/apps/desktop/resources/locales/ko-KR/common.json +32 -0
  53. package/apps/desktop/resources/locales/ko-KR/dialog.json +31 -0
  54. package/apps/desktop/resources/locales/ko-KR/menu.json +70 -0
  55. package/apps/desktop/resources/locales/nl-NL/common.json +32 -0
  56. package/apps/desktop/resources/locales/nl-NL/dialog.json +31 -0
  57. package/apps/desktop/resources/locales/nl-NL/menu.json +70 -0
  58. package/apps/desktop/resources/locales/pl-PL/common.json +32 -0
  59. package/apps/desktop/resources/locales/pl-PL/dialog.json +31 -0
  60. package/apps/desktop/resources/locales/pl-PL/menu.json +70 -0
  61. package/apps/desktop/resources/locales/pt-BR/common.json +32 -0
  62. package/apps/desktop/resources/locales/pt-BR/dialog.json +31 -0
  63. package/apps/desktop/resources/locales/pt-BR/menu.json +70 -0
  64. package/apps/desktop/resources/locales/ru-RU/common.json +32 -0
  65. package/apps/desktop/resources/locales/ru-RU/dialog.json +31 -0
  66. package/apps/desktop/resources/locales/ru-RU/menu.json +70 -0
  67. package/apps/desktop/resources/locales/tr-TR/common.json +32 -0
  68. package/apps/desktop/resources/locales/tr-TR/dialog.json +31 -0
  69. package/apps/desktop/resources/locales/tr-TR/menu.json +70 -0
  70. package/apps/desktop/resources/locales/vi-VN/common.json +32 -0
  71. package/apps/desktop/resources/locales/vi-VN/dialog.json +31 -0
  72. package/apps/desktop/resources/locales/vi-VN/menu.json +70 -0
  73. package/apps/desktop/resources/locales/zh-CN/common.json +32 -0
  74. package/apps/desktop/resources/locales/zh-CN/dialog.json +31 -0
  75. package/apps/desktop/resources/locales/zh-CN/menu.json +70 -0
  76. package/apps/desktop/resources/locales/zh-TW/common.json +32 -0
  77. package/apps/desktop/resources/locales/zh-TW/dialog.json +31 -0
  78. package/apps/desktop/resources/locales/zh-TW/menu.json +70 -0
  79. package/apps/desktop/resources/splash.html +88 -0
  80. package/apps/desktop/scripts/i18nWorkflow/const.ts +18 -0
  81. package/apps/desktop/scripts/i18nWorkflow/genDefaultLocale.ts +35 -0
  82. package/apps/desktop/scripts/i18nWorkflow/genDiff.ts +57 -0
  83. package/apps/desktop/scripts/i18nWorkflow/index.ts +35 -0
  84. package/apps/desktop/scripts/i18nWorkflow/utils.ts +54 -0
  85. package/apps/desktop/scripts/pglite-server.ts +14 -0
  86. package/apps/desktop/src/common/routes.ts +78 -0
  87. package/apps/desktop/src/main/appBrowsers.ts +47 -0
  88. package/apps/desktop/src/main/const/dir.ts +29 -0
  89. package/apps/desktop/src/main/const/env.ts +3 -0
  90. package/apps/desktop/src/main/const/store.ts +22 -0
  91. package/apps/desktop/src/main/controllers/AuthCtr.ts +390 -0
  92. package/apps/desktop/src/main/controllers/BrowserWindowsCtr.ts +95 -0
  93. package/apps/desktop/src/main/controllers/DevtoolsCtr.ts +9 -0
  94. package/apps/desktop/src/main/controllers/LocalFileCtr.ts +380 -0
  95. package/apps/desktop/src/main/controllers/MenuCtr.ts +29 -0
  96. package/apps/desktop/src/main/controllers/RemoteServerConfigCtr.ts +335 -0
  97. package/apps/desktop/src/main/controllers/RemoteServerSyncCtr.ts +321 -0
  98. package/apps/desktop/src/main/controllers/ShortcutCtr.ts +19 -0
  99. package/apps/desktop/src/main/controllers/SystemCtr.ts +93 -0
  100. package/apps/desktop/src/main/controllers/UpdaterCtr.ts +43 -0
  101. package/apps/desktop/src/main/controllers/UploadFileCtr.ts +34 -0
  102. package/apps/desktop/src/main/controllers/_template.ts +9 -0
  103. package/apps/desktop/src/main/controllers/index.ts +58 -0
  104. package/apps/desktop/src/main/core/App.ts +370 -0
  105. package/apps/desktop/src/main/core/Browser.ts +345 -0
  106. package/apps/desktop/src/main/core/BrowserManager.ts +154 -0
  107. package/apps/desktop/src/main/core/I18nManager.ts +185 -0
  108. package/apps/desktop/src/main/core/IoCContainer.ts +12 -0
  109. package/apps/desktop/src/main/core/MenuManager.ts +64 -0
  110. package/apps/desktop/src/main/core/ShortcutManager.ts +173 -0
  111. package/apps/desktop/src/main/core/StoreManager.ts +89 -0
  112. package/apps/desktop/src/main/core/UpdaterManager.ts +321 -0
  113. package/apps/desktop/src/main/index.ts +5 -0
  114. package/apps/desktop/src/main/locales/default/common.ts +34 -0
  115. package/apps/desktop/src/main/locales/default/dialog.ts +33 -0
  116. package/apps/desktop/src/main/locales/default/index.ts +11 -0
  117. package/apps/desktop/src/main/locales/default/menu.ts +72 -0
  118. package/apps/desktop/src/main/locales/resources.ts +35 -0
  119. package/apps/desktop/src/main/menus/impls/BaseMenuPlatform.ts +10 -0
  120. package/apps/desktop/src/main/menus/impls/linux.ts +243 -0
  121. package/apps/desktop/src/main/menus/impls/macOS.ts +360 -0
  122. package/apps/desktop/src/main/menus/impls/windows.ts +226 -0
  123. package/apps/desktop/src/main/menus/index.ts +34 -0
  124. package/apps/desktop/src/main/menus/types.ts +28 -0
  125. package/apps/desktop/src/main/modules/fileSearch/impl/macOS.ts +577 -0
  126. package/apps/desktop/src/main/modules/fileSearch/index.ts +23 -0
  127. package/apps/desktop/src/main/modules/fileSearch/type.ts +27 -0
  128. package/apps/desktop/src/main/modules/updater/configs.ts +22 -0
  129. package/apps/desktop/src/main/modules/updater/utils.ts +33 -0
  130. package/apps/desktop/src/main/services/fileSearchSrv.ts +35 -0
  131. package/apps/desktop/src/main/services/fileSrv.ts +255 -0
  132. package/apps/desktop/src/main/services/index.ts +9 -0
  133. package/apps/desktop/src/main/shortcuts/config.ts +18 -0
  134. package/apps/desktop/src/main/shortcuts/index.ts +1 -0
  135. package/apps/desktop/src/main/types/fileSearch.ts +51 -0
  136. package/apps/desktop/src/main/types/store.ts +14 -0
  137. package/apps/desktop/src/main/utils/file-system.ts +15 -0
  138. package/apps/desktop/src/main/utils/logger.ts +44 -0
  139. package/apps/desktop/src/main/utils/next-electron-rsc.ts +383 -0
  140. package/apps/desktop/src/preload/electronApi.ts +18 -0
  141. package/apps/desktop/src/preload/index.ts +14 -0
  142. package/apps/desktop/src/preload/invoke.ts +10 -0
  143. package/apps/desktop/src/preload/routeInterceptor.ts +162 -0
  144. package/apps/desktop/tsconfig.json +21 -0
  145. package/changelog/v1.json +9 -0
  146. package/package.json +1 -1
  147. package/packages/electron-client-ipc/src/events/remoteServer.ts +11 -4
  148. package/packages/electron-client-ipc/src/types/dataSync.ts +15 -0
  149. package/packages/electron-client-ipc/src/types/index.ts +2 -1
  150. package/packages/electron-client-ipc/src/types/proxyTRPCRequest.ts +21 -0
  151. package/packages/electron-server-ipc/src/const.ts +3 -3
  152. package/packages/electron-server-ipc/src/ipcClient.test.ts +7 -6
  153. package/packages/electron-server-ipc/src/ipcClient.ts +17 -8
  154. package/packages/electron-server-ipc/src/ipcServer.ts +7 -3
  155. package/scripts/electronWorkflow/setDesktopVersion.ts +60 -43
  156. package/src/app/[variants]/(main)/_layout/Desktop/index.tsx +1 -1
  157. package/src/components/Analytics/Desktop.tsx +19 -0
  158. package/src/components/Analytics/index.tsx +3 -0
  159. package/src/database/core/db-adaptor.ts +4 -1
  160. package/src/database/core/electron.ts +317 -0
  161. package/src/{app/[variants]/(main)/_layout/Desktop/ElectronTitlebar/Connection/Mode.tsx → features/ElectronTitlebar/Connection/ConnectionMode.tsx} +24 -21
  162. package/src/{app/[variants]/(main)/_layout/Desktop → features}/ElectronTitlebar/Connection/Option.tsx +3 -5
  163. package/src/{app/[variants]/(main)/_layout/Desktop/ElectronTitlebar/Connection/Sync.tsx → features/ElectronTitlebar/Connection/RemoteStatus.tsx} +10 -7
  164. package/src/{app/[variants]/(main)/_layout/Desktop → features}/ElectronTitlebar/Connection/index.tsx +4 -4
  165. package/src/{app/[variants]/(main)/_layout/Desktop → features}/ElectronTitlebar/UpdateModal.tsx +2 -1
  166. package/src/libs/trpc/client/async.ts +6 -0
  167. package/src/libs/trpc/client/edge.ts +6 -0
  168. package/src/libs/trpc/client/helpers/desktopRemoteRPCFetch.ts +72 -0
  169. package/src/libs/trpc/client/index.ts +1 -0
  170. package/src/libs/trpc/client/lambda.ts +10 -1
  171. package/src/libs/trpc/client/tools.ts +6 -0
  172. package/src/server/globalConfig/index.ts +0 -3
  173. package/src/server/modules/ElectronIPCClient/index.ts +3 -1
  174. package/src/server/routers/desktop/index.ts +2 -0
  175. package/src/server/routers/desktop/mcp.ts +47 -0
  176. package/src/server/routers/lambda/user.ts +38 -23
  177. package/src/server/routers/tools/mcp.ts +0 -6
  178. package/src/services/electron/remoteServer.ts +4 -4
  179. package/src/services/mcp.ts +17 -7
  180. package/src/services/upload.ts +9 -0
  181. package/src/store/chat/slices/aiChat/actions/generateAIChat.ts +11 -2
  182. package/src/store/chat/slices/builtinTool/actions/localFile.ts +110 -53
  183. package/src/store/electron/actions/sync.ts +20 -19
  184. package/src/store/electron/initialState.ts +3 -3
  185. package/src/store/electron/selectors/sync.ts +6 -3
  186. package/src/store/electron/store.ts +2 -0
  187. package/src/store/file/slices/upload/action.ts +11 -3
  188. package/src/store/tool/selectors/tool.ts +10 -1
  189. package/src/utils/fetch/headers.ts +27 -0
  190. package/src/utils/fetch/index.ts +2 -0
  191. package/src/utils/fetch/request.ts +28 -0
  192. package/packages/electron-client-ipc/src/types/remoteServer.ts +0 -8
  193. /package/src/{app/[variants]/(main)/_layout/Desktop → features}/ElectronTitlebar/Connection/Waiting.tsx +0 -0
  194. /package/src/{app/[variants]/(main)/_layout/Desktop → features}/ElectronTitlebar/UpdateNotification.tsx +0 -0
  195. /package/src/{app/[variants]/(main)/_layout/Desktop → features}/ElectronTitlebar/index.tsx +0 -0
@@ -0,0 +1,31 @@
1
+ {
2
+ "about": {
3
+ "button": "确定",
4
+ "detail": "一个基于大语言模型的聊天应用",
5
+ "message": "{{appName}} {{appVersion}}",
6
+ "title": "关于"
7
+ },
8
+ "confirm": {
9
+ "cancel": "取消",
10
+ "no": "否",
11
+ "title": "确认",
12
+ "yes": "是"
13
+ },
14
+ "error": {
15
+ "button": "确定",
16
+ "detail": "操作过程中发生错误,请稍后重试",
17
+ "message": "发生错误",
18
+ "title": "错误"
19
+ },
20
+ "update": {
21
+ "downloadAndInstall": "下载并安装",
22
+ "downloadComplete": "下载完成",
23
+ "downloadCompleteMessage": "更新包已下载完成,是否立即安装?",
24
+ "installLater": "稍后安装",
25
+ "installNow": "立即安装",
26
+ "later": "稍后提醒",
27
+ "newVersion": "发现新版本",
28
+ "newVersionAvailable": "发现新版本: {{version}}",
29
+ "skipThisVersion": "跳过此版本"
30
+ }
31
+ }
@@ -0,0 +1,70 @@
1
+ {
2
+ "common": {
3
+ "checkUpdates": "检查更新..."
4
+ },
5
+ "dev": {
6
+ "devPanel": "开发者面板",
7
+ "devTools": "开发者工具",
8
+ "forceReload": "强制重新加载",
9
+ "openStore": "打开存储文件",
10
+ "refreshMenu": "刷新菜单",
11
+ "reload": "重新加载",
12
+ "title": "开发"
13
+ },
14
+ "edit": {
15
+ "copy": "复制",
16
+ "cut": "剪切",
17
+ "paste": "粘贴",
18
+ "redo": "重做",
19
+ "selectAll": "全选",
20
+ "speech": "语音",
21
+ "startSpeaking": "开始朗读",
22
+ "stopSpeaking": "停止朗读",
23
+ "title": "编辑",
24
+ "undo": "撤销"
25
+ },
26
+ "file": {
27
+ "preferences": "首选项",
28
+ "quit": "退出",
29
+ "title": "文件"
30
+ },
31
+ "help": {
32
+ "about": "关于",
33
+ "githubRepo": "GitHub 仓库",
34
+ "reportIssue": "报告问题",
35
+ "title": "帮助",
36
+ "visitWebsite": "访问官网"
37
+ },
38
+ "macOS": {
39
+ "about": "关于 {{appName}}",
40
+ "devTools": "LobeHub 开发者工具",
41
+ "hide": "隐藏 {{appName}}",
42
+ "hideOthers": "隐藏其他",
43
+ "preferences": "偏好设置...",
44
+ "services": "服务",
45
+ "unhide": "全部显示"
46
+ },
47
+ "tray": {
48
+ "open": "打开 {{appName}}",
49
+ "quit": "退出",
50
+ "show": "显示 {{appName}}"
51
+ },
52
+ "view": {
53
+ "forceReload": "强制重新加载",
54
+ "reload": "重新加载",
55
+ "resetZoom": "重置缩放",
56
+ "title": "视图",
57
+ "toggleFullscreen": "切换全屏",
58
+ "zoomIn": "放大",
59
+ "zoomOut": "缩小"
60
+ },
61
+ "window": {
62
+ "bringAllToFront": "前置所有窗口",
63
+ "close": "关闭",
64
+ "front": "前置所有窗口",
65
+ "minimize": "最小化",
66
+ "title": "窗口",
67
+ "toggleFullscreen": "切换全屏",
68
+ "zoom": "缩放"
69
+ }
70
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "actions": {
3
+ "add": "新增",
4
+ "back": "返回",
5
+ "cancel": "取消",
6
+ "close": "關閉",
7
+ "confirm": "確認",
8
+ "delete": "刪除",
9
+ "edit": "編輯",
10
+ "more": "更多",
11
+ "next": "下一步",
12
+ "ok": "確定",
13
+ "previous": "上一步",
14
+ "refresh": "刷新",
15
+ "remove": "移除",
16
+ "retry": "重試",
17
+ "save": "儲存",
18
+ "search": "搜尋",
19
+ "submit": "提交"
20
+ },
21
+ "app": {
22
+ "description": "你的 AI 助手協作平台",
23
+ "name": "LobeHub"
24
+ },
25
+ "status": {
26
+ "error": "錯誤",
27
+ "info": "資訊",
28
+ "loading": "載入中",
29
+ "success": "成功",
30
+ "warning": "警告"
31
+ }
32
+ }
@@ -0,0 +1,31 @@
1
+ {
2
+ "about": {
3
+ "button": "確定",
4
+ "detail": "一個基於大語言模型的聊天應用",
5
+ "message": "{{appName}} {{appVersion}}",
6
+ "title": "關於"
7
+ },
8
+ "confirm": {
9
+ "cancel": "取消",
10
+ "no": "否",
11
+ "title": "確認",
12
+ "yes": "是"
13
+ },
14
+ "error": {
15
+ "button": "確定",
16
+ "detail": "操作過程中發生錯誤,請稍後重試",
17
+ "message": "發生錯誤",
18
+ "title": "錯誤"
19
+ },
20
+ "update": {
21
+ "downloadAndInstall": "下載並安裝",
22
+ "downloadComplete": "下載完成",
23
+ "downloadCompleteMessage": "更新包已下載完成,是否立即安裝?",
24
+ "installLater": "稍後安裝",
25
+ "installNow": "立即安裝",
26
+ "later": "稍後提醒",
27
+ "newVersion": "發現新版本",
28
+ "newVersionAvailable": "發現新版本: {{version}}",
29
+ "skipThisVersion": "跳過此版本"
30
+ }
31
+ }
@@ -0,0 +1,70 @@
1
+ {
2
+ "common": {
3
+ "checkUpdates": "檢查更新..."
4
+ },
5
+ "dev": {
6
+ "devPanel": "開發者面板",
7
+ "devTools": "開發者工具",
8
+ "forceReload": "強制重新載入",
9
+ "openStore": "打開儲存檔案",
10
+ "refreshMenu": "刷新選單",
11
+ "reload": "重新載入",
12
+ "title": "開發"
13
+ },
14
+ "edit": {
15
+ "copy": "複製",
16
+ "cut": "剪下",
17
+ "paste": "貼上",
18
+ "redo": "重做",
19
+ "selectAll": "全選",
20
+ "speech": "語音",
21
+ "startSpeaking": "開始朗讀",
22
+ "stopSpeaking": "停止朗讀",
23
+ "title": "編輯",
24
+ "undo": "撤銷"
25
+ },
26
+ "file": {
27
+ "preferences": "偏好設定",
28
+ "quit": "退出",
29
+ "title": "檔案"
30
+ },
31
+ "help": {
32
+ "about": "關於",
33
+ "githubRepo": "GitHub 倉庫",
34
+ "reportIssue": "報告問題",
35
+ "title": "幫助",
36
+ "visitWebsite": "訪問網站"
37
+ },
38
+ "macOS": {
39
+ "about": "關於 {{appName}}",
40
+ "devTools": "LobeHub 開發者工具",
41
+ "hide": "隱藏 {{appName}}",
42
+ "hideOthers": "隱藏其他",
43
+ "preferences": "偏好設定...",
44
+ "services": "服務",
45
+ "unhide": "全部顯示"
46
+ },
47
+ "tray": {
48
+ "open": "打開 {{appName}}",
49
+ "quit": "退出",
50
+ "show": "顯示 {{appName}}"
51
+ },
52
+ "view": {
53
+ "forceReload": "強制重新載入",
54
+ "reload": "重新載入",
55
+ "resetZoom": "重置縮放",
56
+ "title": "視圖",
57
+ "toggleFullscreen": "切換全螢幕",
58
+ "zoomIn": "放大",
59
+ "zoomOut": "縮小"
60
+ },
61
+ "window": {
62
+ "bringAllToFront": "前置所有視窗",
63
+ "close": "關閉",
64
+ "front": "前置所有視窗",
65
+ "minimize": "最小化",
66
+ "title": "視窗",
67
+ "toggleFullscreen": "切換全螢幕",
68
+ "zoom": "縮放"
69
+ }
70
+ }
@@ -0,0 +1,88 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>LobeHub</title>
7
+ <style>
8
+ body {
9
+ -webkit-app-region: drag;
10
+ margin: 0;
11
+ padding: 0;
12
+ height: 100vh;
13
+ display: flex;
14
+ justify-content: center;
15
+ align-items: center;
16
+ font-family:
17
+ -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
18
+ color: #1f1f1f;
19
+ overflow: hidden;
20
+ }
21
+
22
+ /* 添加暗色模式支持 */
23
+ @media (prefers-color-scheme: dark) {
24
+ body {
25
+ color: #f5f5f5;
26
+ }
27
+ }
28
+
29
+ .container {
30
+ text-align: center;
31
+ }
32
+
33
+ .lobe-brand-loading {
34
+ width: 120px;
35
+ height: auto;
36
+ }
37
+
38
+ .lobe-brand-loading path {
39
+ fill: currentcolor;
40
+ fill-opacity: 0%;
41
+ stroke: currentcolor;
42
+ stroke-dasharray: 1000;
43
+ stroke-dashoffset: 1000;
44
+ stroke-width: 0.25em;
45
+
46
+ animation:
47
+ draw 2s cubic-bezier(0.4, 0, 0.2, 1) infinite,
48
+ fill 2s cubic-bezier(0.4, 0, 0.2, 1) infinite;
49
+ }
50
+
51
+ @keyframes draw {
52
+ 0% {
53
+ stroke-dashoffset: 1000;
54
+ }
55
+
56
+ 100% {
57
+ stroke-dashoffset: 0;
58
+ }
59
+ }
60
+
61
+ @keyframes fill {
62
+ 30% {
63
+ fill-opacity: 5%;
64
+ }
65
+
66
+ 100% {
67
+ fill-opacity: 100%;
68
+ }
69
+ }
70
+ </style>
71
+ </head>
72
+ <body>
73
+ <div class="container">
74
+ <svg
75
+ class="lobe-brand-loading"
76
+ fill="currentColor"
77
+ fillRule="evenodd"
78
+ viewBox="0 0 940 320"
79
+ xmlns="http://www.w3.org/2000/svg"
80
+ >
81
+ <title>LobeHub</title>
82
+ <path
83
+ d="M15 240.035V87.172h39.24V205.75h66.192v34.285H15zM183.731 242c-11.759 0-22.196-2.621-31.313-7.862-9.116-5.241-16.317-12.447-21.601-21.619-5.153-9.317-7.729-19.945-7.729-31.883 0-11.937 2.576-22.492 7.729-31.664 5.164-8.963 12.159-15.98 20.982-21.05l.619-.351c9.117-5.241 19.554-7.861 31.313-7.861s22.196 2.62 31.313 7.861c9.248 5.096 16.449 12.229 21.601 21.401 5.153 9.172 7.729 19.727 7.729 31.664 0 11.938-2.576 22.566-7.729 31.883-5.152 9.172-12.353 16.378-21.601 21.619-9.117 5.241-19.554 7.862-31.313 7.862zm0-32.975c4.36 0 8.191-1.092 11.494-3.275 3.436-2.184 6.144-5.387 8.126-9.609 1.982-4.367 2.973-9.536 2.973-15.505 0-5.968-.991-10.991-2.973-15.067-1.906-4.06-4.483-7.177-7.733-9.352l-.393-.257c-3.303-2.184-7.134-3.276-11.494-3.276-4.228 0-8.059 1.092-11.495 3.276-3.303 2.184-6.011 5.387-8.125 9.609-1.982 4.076-2.973 9.099-2.973 15.067 0 5.969.991 11.138 2.973 15.505 2.114 4.222 4.822 7.425 8.125 9.609 3.436 2.183 7.267 3.275 11.495 3.275zM295.508 78l-.001 54.042a34.071 34.071 0 016.541-5.781c6.474-4.367 14.269-6.551 23.385-6.551 9.777 0 18.629 2.475 26.557 7.424 7.872 4.835 14.105 11.684 18.7 20.546l.325.637c4.756 9.026 7.135 19.799 7.135 32.319 0 12.666-2.379 23.585-7.135 32.757-4.624 9.026-10.966 16.087-19.025 21.182-7.928 4.95-16.78 7.425-26.557 7.425-9.644 0-17.704-2.184-24.178-6.551-2.825-1.946-5.336-4.355-7.532-7.226l.001 11.812h-35.87V78h37.654zm21.998 74.684c-4.228 0-8.059 1.092-11.494 3.276-3.303 2.184-6.012 5.387-8.126 9.609-1.982 4.076-2.972 9.099-2.972 15.067 0 5.969.99 11.138 2.972 15.505 2.114 4.222 4.823 7.425 8.126 9.609 3.435 2.183 7.266 3.275 11.494 3.275s7.994-1.092 11.297-3.275c3.435-2.184 6.143-5.387 8.125-9.609 2.114-4.367 3.171-9.536 3.171-15.505 0-5.968-1.057-10.991-3.171-15.067-1.906-4.06-4.483-7.177-7.732-9.352l-.393-.257c-3.303-2.184-7.069-3.276-11.297-3.276zm105.335 38.653l.084.337a27.857 27.857 0 002.057 5.559c2.246 4.222 5.417 7.498 9.513 9.827 4.096 2.184 8.984 3.276 14.665 3.276 5.285 0 9.777-.801 13.477-2.403 3.579-1.632 7.1-4.025 10.564-7.182l.732-.679 19.818 22.711c-5.153 6.26-11.494 11.064-19.025 14.413-7.531 3.203-16.449 4.804-26.755 4.804-12.683 0-23.782-2.621-33.294-7.862-9.381-5.386-16.713-12.665-21.998-21.837-5.153-9.317-7.729-19.872-7.729-31.665 0-11.792 2.51-22.274 7.53-31.446 5.036-9.105 11.902-16.195 20.596-21.268l.61-.351c8.984-5.241 19.091-7.861 30.322-7.861 10.311 0 19.743 2.286 28.294 6.859l.64.347c8.72 4.659 15.656 11.574 20.809 20.746 5.153 9.172 7.729 20.309 7.729 33.411 0 1.294-.052 2.761-.156 4.4l-.042.623-.17 2.353c-.075 1.01-.151 1.973-.227 2.888h-78.044zm21.365-42.147c-4.492 0-8.456 1.092-11.891 3.276-3.303 2.184-5.879 5.314-7.729 9.39a26.04 26.04 0 00-1.117 2.79 30.164 30.164 0 00-1.121 4.499l-.058.354h43.96l-.015-.106c-.401-2.638-1.122-5.055-2.163-7.252l-.246-.503c-1.776-3.774-4.282-6.742-7.519-8.906l-.409-.266c-3.303-2.184-7.2-3.276-11.692-3.276zm111.695-62.018l-.001 57.432h53.51V87.172h39.24v152.863h-39.24v-59.617H555.9l.001 59.617h-39.24V87.172h39.24zM715.766 242c-8.72 0-16.581-1.893-23.583-5.678-6.87-3.785-12.287-9.681-16.251-17.688-3.832-8.153-5.747-18.417-5.747-30.791v-66.168h37.654v59.398c0 9.172 1.519 15.723 4.558 19.654 3.171 3.931 7.597 5.896 13.278 5.896 3.7 0 7.069-.946 10.108-2.839 3.038-1.892 5.483-4.877 7.332-8.953 1.85-4.222 2.775-9.609 2.775-16.16v-56.996h37.654v118.36h-35.871l.004-12.38c-2.642 3.197-5.682 5.868-9.12 8.012-7.002 4.222-14.599 6.333-22.791 6.333zM841.489 78l-.001 54.041a34.1 34.1 0 016.541-5.78c6.474-4.367 14.269-6.551 23.385-6.551 9.777 0 18.629 2.475 26.556 7.424 7.873 4.835 14.106 11.684 18.701 20.546l.325.637c4.756 9.026 7.134 19.799 7.134 32.319 0 12.666-2.378 23.585-7.134 32.757-4.624 9.026-10.966 16.087-19.026 21.182-7.927 4.95-16.779 7.425-26.556 7.425-9.645 0-17.704-2.184-24.178-6.551-2.825-1.946-5.336-4.354-7.531-7.224v11.81h-35.87V78h37.654zm21.998 74.684c-4.228 0-8.059 1.092-11.495 3.276-3.303 2.184-6.011 5.387-8.125 9.609-1.982 4.076-2.973 9.099-2.973 15.067 0 5.969.991 11.138 2.973 15.505 2.114 4.222 4.822 7.425 8.125 9.609 3.436 2.183 7.267 3.275 11.495 3.275 4.228 0 7.993-1.092 11.296-3.275 3.435-2.184 6.144-5.387 8.126-9.609 2.114-4.367 3.171-9.536 3.171-15.505 0-5.968-1.057-10.991-3.171-15.067-1.906-4.06-4.484-7.177-7.733-9.352l-.393-.257c-3.303-2.184-7.068-3.276-11.296-3.276z"
84
+ />
85
+ </svg>
86
+ </div>
87
+ </body>
88
+ </html>
@@ -0,0 +1,18 @@
1
+ import { readdirSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+
4
+ import i18nConfig from '../../.i18nrc';
5
+
6
+ export const root = resolve(__dirname, '../..');
7
+ export const localesDir = resolve(root, i18nConfig.output);
8
+ export const localeDir = (locale: string) => resolve(localesDir, locale);
9
+ export const localeDirJsonList = (locale: string) =>
10
+ readdirSync(localeDir(locale)).filter((name) => name.includes('.json'));
11
+ export const srcLocalesDir = resolve(root, './src/main/locales');
12
+ export const entryLocaleJsonFilepath = (file: string) =>
13
+ resolve(localesDir, i18nConfig.entryLocale, file);
14
+ export const outputLocaleJsonFilepath = (locale: string, file: string) =>
15
+ resolve(localesDir, locale, file);
16
+ export const srcDefaultLocales = resolve(root, srcLocalesDir, 'default');
17
+
18
+ export { default as i18nConfig } from '../../.i18nrc';
@@ -0,0 +1,35 @@
1
+ import { consola } from 'consola';
2
+ import { colors } from 'consola/utils';
3
+ import { existsSync, mkdirSync } from 'node:fs';
4
+ import { dirname } from 'node:path';
5
+
6
+ import { entryLocaleJsonFilepath, i18nConfig, localeDir, srcDefaultLocales } from './const';
7
+ import { tagWhite, writeJSON } from './utils';
8
+
9
+ export const genDefaultLocale = () => {
10
+ consola.info(`默认语言为 ${i18nConfig.entryLocale}...`);
11
+
12
+ // 确保入口语言目录存在
13
+ const entryLocaleDir = localeDir(i18nConfig.entryLocale);
14
+ if (!existsSync(entryLocaleDir)) {
15
+ mkdirSync(entryLocaleDir, { recursive: true });
16
+ consola.info(`创建目录:${entryLocaleDir}`);
17
+ }
18
+
19
+ const resources = require(srcDefaultLocales);
20
+ const data = Object.entries(resources.default);
21
+ consola.start(`生成默认语言 JSON 文件,发现 ${data.length} 个命名空间...`);
22
+
23
+ for (const [ns, value] of data) {
24
+ const filepath = entryLocaleJsonFilepath(`${ns}.json`);
25
+
26
+ // 确保目录存在
27
+ const dir = dirname(filepath);
28
+ if (!existsSync(dir)) {
29
+ mkdirSync(dir, { recursive: true });
30
+ }
31
+
32
+ writeJSON(filepath, value);
33
+ consola.success(tagWhite(ns), colors.gray(filepath));
34
+ }
35
+ };
@@ -0,0 +1,57 @@
1
+ import { consola } from 'consola';
2
+ import { colors } from 'consola/utils';
3
+ import { diff } from 'just-diff';
4
+ import { unset } from 'lodash';
5
+ import { existsSync } from 'node:fs';
6
+
7
+ import {
8
+ entryLocaleJsonFilepath,
9
+ i18nConfig,
10
+ outputLocaleJsonFilepath,
11
+ srcDefaultLocales,
12
+ } from './const';
13
+ import { readJSON, tagWhite, writeJSON } from './utils';
14
+
15
+ export const genDiff = () => {
16
+ consola.start(`对比开发与生产环境中的本地化文件...`);
17
+
18
+ const resources = require(srcDefaultLocales);
19
+ const data = Object.entries(resources.default);
20
+
21
+ for (const [ns, devJSON] of data) {
22
+ const filepath = entryLocaleJsonFilepath(`${ns}.json`);
23
+ if (!existsSync(filepath)) {
24
+ consola.info(`文件不存在,跳过:${filepath}`);
25
+ continue;
26
+ }
27
+
28
+ const prodJSON = readJSON(filepath);
29
+
30
+ const diffResult = diff(prodJSON, devJSON as any);
31
+ const remove = diffResult.filter((item) => item.op === 'remove');
32
+ if (remove.length === 0) {
33
+ consola.success(tagWhite(ns), colors.gray(filepath));
34
+ continue;
35
+ }
36
+
37
+ const clearLocals = [];
38
+
39
+ for (const locale of [i18nConfig.entryLocale, ...i18nConfig.outputLocales]) {
40
+ const localeFilepath = outputLocaleJsonFilepath(locale, `${ns}.json`);
41
+ if (!existsSync(localeFilepath)) continue;
42
+ const localeJSON = readJSON(localeFilepath);
43
+
44
+ for (const item of remove) {
45
+ unset(localeJSON, item.path);
46
+ }
47
+
48
+ writeJSON(localeFilepath, localeJSON);
49
+ clearLocals.push(locale);
50
+ }
51
+
52
+ if (clearLocals.length > 0) {
53
+ consola.info('清理了以下语言的过期项目:', clearLocals.join(', '));
54
+ }
55
+ consola.success(tagWhite(ns), colors.gray(filepath));
56
+ }
57
+ };
@@ -0,0 +1,35 @@
1
+ import { existsSync, mkdirSync } from 'node:fs';
2
+
3
+ import { i18nConfig, localeDir } from './const';
4
+ import { genDefaultLocale } from './genDefaultLocale';
5
+ import { genDiff } from './genDiff';
6
+ import { split } from './utils';
7
+
8
+ // 确保所有语言目录存在
9
+ const ensureLocalesDirs = () => {
10
+ [i18nConfig.entryLocale, ...i18nConfig.outputLocales].forEach((locale) => {
11
+ const dir = localeDir(locale);
12
+ if (!existsSync(dir)) {
13
+ mkdirSync(dir, { recursive: true });
14
+ }
15
+ });
16
+ };
17
+
18
+ // 运行工作流
19
+ const run = async () => {
20
+ // 确保目录存在
21
+ ensureLocalesDirs();
22
+
23
+ // 差异分析
24
+ split('差异分析');
25
+ genDiff();
26
+
27
+ // 生成默认语言文件
28
+ split('生成默认语言文件');
29
+ genDefaultLocale();
30
+
31
+ // 生成国际化文件
32
+ split('生成国际化文件');
33
+ };
34
+
35
+ run();
@@ -0,0 +1,54 @@
1
+ import { consola } from 'consola';
2
+ import { colors } from 'consola/utils';
3
+ import { readFileSync, writeFileSync } from 'node:fs';
4
+ import { resolve } from 'node:path';
5
+
6
+ import i18nConfig from '../../.i18nrc';
7
+
8
+ export const readJSON = (filePath: string) => {
9
+ const data = readFileSync(filePath, 'utf8');
10
+ return JSON.parse(data);
11
+ };
12
+
13
+ export const writeJSON = (filePath: string, data: any) => {
14
+ const jsonStr = JSON.stringify(data, null, 2);
15
+ writeFileSync(filePath, jsonStr, 'utf8');
16
+ };
17
+
18
+ export const genResourcesContent = (locales: string[]) => {
19
+ let index = '';
20
+ let indexObj = '';
21
+
22
+ for (const locale of locales) {
23
+ index += `import ${locale} from "./${locale}";\n`;
24
+ indexObj += ` "${locale.replace('_', '-')}": ${locale},\n`;
25
+ }
26
+
27
+ return `${index}
28
+ const resources = {
29
+ ${indexObj}} as const;
30
+ export default resources;
31
+ export const defaultResources = ${i18nConfig.entryLocale};
32
+ export type Resources = typeof resources;
33
+ export type DefaultResources = typeof defaultResources;
34
+ export type Namespaces = keyof DefaultResources;
35
+ export type Locales = keyof Resources;
36
+ `;
37
+ };
38
+
39
+ export const genNamespaceList = (files: string[], locale: string) => {
40
+ return files.map((file) => ({
41
+ name: file.replace('.json', ''),
42
+ path: resolve(i18nConfig.output, locale, file),
43
+ }));
44
+ };
45
+
46
+ export const tagBlue = (text: string) => colors.bgBlueBright(colors.black(` ${text} `));
47
+ export const tagYellow = (text: string) => colors.bgYellowBright(colors.black(` ${text} `));
48
+ export const tagGreen = (text: string) => colors.bgGreenBright(colors.black(` ${text} `));
49
+ export const tagWhite = (text: string) => colors.bgWhiteBright(colors.black(` ${text} `));
50
+
51
+ export const split = (name: string) => {
52
+ consola.log('');
53
+ consola.log(colors.gray(`========================== ${name} ==============================`));
54
+ };
@@ -0,0 +1,14 @@
1
+ import { PGlite } from "@electric-sql/pglite";
2
+ import { createServer } from "pglite-server";
3
+
4
+ // 创建或连接到您现有的 PGlite 数据库
5
+ const db = new PGlite("/Users/arvinxx/Library/Application Support/lobehub-desktop/lobehub-local-db");
6
+ await db.waitReady;
7
+
8
+ // 创建服务器并监听端口
9
+ const PORT = 6543;
10
+ const pgServer = createServer(db);
11
+
12
+ pgServer.listen(PORT, () => {
13
+ console.log(`PGlite 服务器已启动,监听端口 ${PORT}`);
14
+ });
@@ -0,0 +1,78 @@
1
+ /**
2
+ * 路由拦截类型,描述拦截路由和目标窗口的映射关系
3
+ */
4
+ export interface RouteInterceptConfig {
5
+ /**
6
+ * 是否始终在新窗口中打开,即使目标窗口已经存在
7
+ */
8
+ alwaysOpenNew?: boolean;
9
+
10
+ /**
11
+ * 描述
12
+ */
13
+ description: string;
14
+
15
+ /**
16
+ * 是否启用拦截
17
+ */
18
+ enabled: boolean;
19
+
20
+ /**
21
+ * 路由模式前缀,例如 '/settings'
22
+ */
23
+ pathPrefix: string;
24
+
25
+ /**
26
+ * 目标窗口标识符
27
+ */
28
+ targetWindow: string;
29
+ }
30
+
31
+ /**
32
+ * 拦截路由配置列表
33
+ * 定义了所有需要特殊处理的路由
34
+ */
35
+ export const interceptRoutes: RouteInterceptConfig[] = [
36
+ {
37
+ description: '设置页面',
38
+ enabled: true,
39
+ pathPrefix: '/settings',
40
+ targetWindow: 'settings',
41
+ },
42
+ {
43
+ description: '开发者工具',
44
+ enabled: true,
45
+ pathPrefix: '/desktop/devtools',
46
+ targetWindow: 'devtools',
47
+ },
48
+ // 未来可能的其他路由
49
+ // {
50
+ // description: '帮助中心',
51
+ // enabled: true,
52
+ // pathPrefix: '/help',
53
+ // targetWindow: 'help',
54
+ // },
55
+ ];
56
+
57
+ /**
58
+ * 通过路径查找匹配的路由拦截配置
59
+ * @param path 需要检查的路径
60
+ * @returns 匹配的拦截配置,如果没有匹配则返回 undefined
61
+ */
62
+ export const findMatchingRoute = (path: string): RouteInterceptConfig | undefined => {
63
+ return interceptRoutes.find((route) => route.enabled && path.startsWith(route.pathPrefix));
64
+ };
65
+
66
+ /**
67
+ * 从完整路径中提取子路径
68
+ * @param fullPath 完整路径,如 '/settings/agent'
69
+ * @param pathPrefix 路径前缀,如 '/settings'
70
+ * @returns 子路径,如 'agent'
71
+ */
72
+ export const extractSubPath = (fullPath: string, pathPrefix: string): string | undefined => {
73
+ if (fullPath.length <= pathPrefix.length) return undefined;
74
+
75
+ // 去除前导斜杠
76
+ const subPath = fullPath.slice(Math.max(0, pathPrefix.length + 1));
77
+ return subPath || undefined;
78
+ };
@@ -0,0 +1,47 @@
1
+ import type { BrowserWindowOpts } from './core/Browser';
2
+
3
+ export const BrowsersIdentifiers = {
4
+ chat: 'chat',
5
+ devtools: 'devtools',
6
+ settings: 'settings',
7
+ };
8
+
9
+ export const appBrowsers = {
10
+ chat: {
11
+ autoHideMenuBar: true,
12
+ height: 800,
13
+ identifier: 'chat',
14
+ keepAlive: true,
15
+ minWidth: 400,
16
+ path: '/chat',
17
+ showOnInit: true,
18
+ titleBarStyle: 'hidden',
19
+ vibrancy: 'under-window',
20
+ width: 1200,
21
+ },
22
+ devtools: {
23
+ autoHideMenuBar: true,
24
+ fullscreenable: false,
25
+ height: 600,
26
+ identifier: 'devtools',
27
+ maximizable: false,
28
+ minWidth: 400,
29
+ path: '/desktop/devtools',
30
+ titleBarStyle: 'hiddenInset',
31
+ vibrancy: 'under-window',
32
+ width: 1000,
33
+ },
34
+ settings: {
35
+ autoHideMenuBar: true,
36
+ height: 800,
37
+ identifier: 'settings',
38
+ keepAlive: true,
39
+ minWidth: 600,
40
+ path: '/settings',
41
+ titleBarStyle: 'hidden',
42
+ vibrancy: 'under-window',
43
+ width: 1000,
44
+ },
45
+ } satisfies Record<string, BrowserWindowOpts>;
46
+
47
+ export type AppBrowsersIdentifiers = keyof typeof appBrowsers;