@lobehub/lobehub 2.0.0-next.20 → 2.0.0-next.22

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 (40) hide show
  1. package/.github/workflows/claude-auto-testing.yml +73 -0
  2. package/.github/workflows/claude-translate-comments.yml +67 -0
  3. package/.github/workflows/release.yml +1 -1
  4. package/.github/workflows/test.yml +39 -2
  5. package/CHANGELOG.md +42 -0
  6. package/apps/desktop/package.json +1 -1
  7. package/apps/desktop/src/main/controllers/AuthCtr.ts +53 -39
  8. package/apps/desktop/src/main/controllers/MenuCtr.ts +5 -5
  9. package/apps/desktop/src/main/controllers/NotificationCtr.ts +29 -29
  10. package/apps/desktop/src/main/controllers/RemoteServerConfigCtr.ts +16 -16
  11. package/apps/desktop/src/main/controllers/ShortcutCtr.ts +2 -2
  12. package/apps/desktop/src/main/controllers/TrayMenuCtr.ts +18 -18
  13. package/apps/desktop/src/main/controllers/UpdaterCtr.ts +4 -4
  14. package/apps/desktop/src/main/controllers/__tests__/AuthCtr.test.ts +706 -0
  15. package/apps/desktop/src/main/controllers/__tests__/TrayMenuCtr.test.ts +5 -5
  16. package/apps/desktop/src/main/controllers/index.ts +4 -4
  17. package/changelog/v1.json +14 -0
  18. package/docs/development/database-schema.dbml +2 -1
  19. package/package.json +2 -2
  20. package/packages/database/migrations/0042_improve_agent_index.sql +1 -0
  21. package/packages/database/migrations/meta/0042_snapshot.json +7800 -0
  22. package/packages/database/migrations/meta/_journal.json +7 -0
  23. package/packages/database/src/core/migrations.json +8 -0
  24. package/packages/database/src/models/agent.ts +16 -13
  25. package/packages/database/src/models/session.ts +20 -9
  26. package/packages/database/src/models/user.ts +2 -1
  27. package/packages/database/src/schemas/agent.ts +4 -1
  28. package/packages/types/src/message/ui/params.ts +1 -1
  29. package/packages/utils/src/apiKey.test.ts +139 -0
  30. package/packages/utils/src/client/clipboard.ts +2 -2
  31. package/packages/utils/src/client/exportFile.ts +10 -10
  32. package/packages/utils/src/client/parserPlaceholder.ts +18 -18
  33. package/packages/utils/src/client/topic.ts +10 -10
  34. package/packages/utils/src/client/xor-obfuscation.ts +11 -11
  35. package/renovate.json +20 -3
  36. package/src/app/[variants]/oauth/consent/[uid]/Login.tsx +10 -1
  37. package/src/server/routers/lambda/message.ts +0 -2
  38. package/src/server/routers/lambda/user.ts +8 -6
  39. package/src/services/chat/index.ts +3 -3
  40. package/src/services/mcp.test.ts +777 -0
@@ -0,0 +1,73 @@
1
+ name: Claude Auto Testing Coverage
2
+ description: Automatically add unit tests to improve code coverage
3
+
4
+ on:
5
+ schedule:
6
+ # Run daily at 05:30 UTC (13:30 Beijing Time)
7
+ - cron: '30 5 * * *'
8
+ workflow_dispatch:
9
+ inputs:
10
+ target_module:
11
+ description: 'Specific module to add tests (e.g., packages/database, src/services/user)'
12
+ required: false
13
+ type: string
14
+
15
+ concurrency:
16
+ group: auto-testing
17
+ cancel-in-progress: false
18
+
19
+ jobs:
20
+ add-tests:
21
+ runs-on: ubuntu-latest
22
+ timeout-minutes: 45
23
+ permissions:
24
+ contents: write
25
+ pull-requests: write
26
+ id-token: write
27
+
28
+ steps:
29
+ - name: Checkout repository
30
+ uses: actions/checkout@v5
31
+ with:
32
+ fetch-depth: 1
33
+
34
+ - name: Setup Bun
35
+ uses: oven-sh/setup-bun@v2
36
+
37
+ - name: Install dependencies
38
+ run: bun install --frozen-lockfile
39
+
40
+ - name: Configure Git
41
+ run: |
42
+ git config --global user.name "claude-bot[bot]"
43
+ git config --global user.email "claude-bot[bot]@users.noreply.github.com"
44
+
45
+ - name: Copy testing prompt
46
+ run: |
47
+ mkdir -p /tmp/claude-prompts
48
+ cp .claude/prompts/auto-testing.md /tmp/claude-prompts/
49
+
50
+ - name: Run Claude Code for Auto Testing
51
+ uses: anthropics/claude-code-action@main
52
+ with:
53
+ github_token: ${{ secrets.GH_TOKEN }}
54
+ allowed_non_write_users: "*"
55
+ claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
56
+ claude_args: "--allowed-tools Bash,Read,Edit,Write,Glob,Grep"
57
+ prompt: |
58
+ Follow the auto testing guide located at:
59
+ ```bash
60
+ cat /tmp/claude-prompts/auto-testing.md
61
+ ```
62
+
63
+ ## Task Assignment
64
+
65
+ ${{ inputs.target_module && format('Process the specified module: {0}', inputs.target_module) || 'Automatically select one module from the target directories that needs test coverage' }}
66
+
67
+ ## Environment Information
68
+ - Repository: ${{ github.repository }}
69
+ - Branch: ${{ github.ref_name }}
70
+ - Target Module: ${{ inputs.target_module || 'Auto-select' }}
71
+ - Run ID: ${{ github.run_id }}
72
+
73
+ **Start the auto testing process now.**
@@ -0,0 +1,67 @@
1
+ name: Claude Translate Non-English Comments
2
+ description: Automatically detect and translate non-English comments to English in codebase
3
+
4
+ on:
5
+ schedule:
6
+ # Run daily at 02:00 UTC (10:00 Beijing Time)
7
+ - cron: '0 2 * * *'
8
+ workflow_dispatch:
9
+ inputs:
10
+ target_module:
11
+ description: 'Specific module to translate (e.g., packages/database, apps/desktop/src/modules/auth)'
12
+ required: false
13
+ type: string
14
+
15
+ concurrency:
16
+ group: translate-comments
17
+ cancel-in-progress: false
18
+
19
+ jobs:
20
+ translate-comments:
21
+ runs-on: ubuntu-latest
22
+ timeout-minutes: 30
23
+ permissions:
24
+ contents: write
25
+ pull-requests: write
26
+ id-token: write
27
+
28
+ steps:
29
+ - name: Checkout repository
30
+ uses: actions/checkout@v5
31
+ with:
32
+ fetch-depth: 1
33
+
34
+ - name: Configure Git
35
+ run: |
36
+ git config --global user.name "claude-bot[bot]"
37
+ git config --global user.email "claude-bot[bot]@users.noreply.github.com"
38
+
39
+ - name: Copy translation prompt
40
+ run: |
41
+ mkdir -p /tmp/claude-prompts
42
+ cp .claude/prompts/translate-comments.md /tmp/claude-prompts/
43
+
44
+ - name: Run Claude Code for Comment Translation
45
+ uses: anthropics/claude-code-action@main
46
+ with:
47
+ github_token: ${{ secrets.GH_TOKEN }}
48
+ allowed_non_write_users: "*"
49
+ claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
50
+ claude_args: "--allowed-tools Bash,Read,Edit,Glob,Grep"
51
+ prompt: |
52
+ Follow the translation guide located at:
53
+ ```bash
54
+ cat /tmp/claude-prompts/translate-comments.md
55
+ ```
56
+
57
+ ## Task Assignment
58
+
59
+ ${{ inputs.target_module && format('Process the specified module: {0}', inputs.target_module) || 'Automatically select one module from the target directories that has not been processed recently' }}
60
+
61
+ ## Environment Information
62
+ - Repository: ${{ github.repository }}
63
+ - Branch: ${{ github.ref_name }}
64
+ - Target Module: ${{ inputs.target_module || 'Auto-select' }}
65
+ - Run ID: ${{ github.run_id }}
66
+
67
+ **Start the translation process now.**
@@ -54,7 +54,7 @@ jobs:
54
54
  env:
55
55
  DATABASE_TEST_URL: postgresql://postgres:postgres@localhost:5432/postgres
56
56
  DATABASE_DRIVER: node
57
- KEY_VAULTS_SECRET: LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s=
57
+ KEY_VAULTS_SECRET: Kix2wcUONd4CX51E/ZPAd36BqM4wzJgKjPtz2sGztqQ=
58
58
  S3_PUBLIC_DOMAIN: https://example.com
59
59
  APP_URL: https://home.com
60
60
 
@@ -119,6 +119,43 @@ jobs:
119
119
  files: ./coverage/app/lcov.info
120
120
  flags: app
121
121
 
122
+ test-desktop:
123
+ name: Test Desktop App
124
+
125
+ runs-on: ubuntu-latest
126
+
127
+ steps:
128
+ - uses: actions/checkout@v5
129
+
130
+ - name: Setup Node.js
131
+ uses: actions/setup-node@v6
132
+ with:
133
+ node-version: 24
134
+ package-manager-cache: false
135
+
136
+ - name: Setup pnpm
137
+ uses: pnpm/action-setup@v2
138
+ with:
139
+ version: 10
140
+
141
+ - name: Install deps
142
+ run: pnpm install
143
+ working-directory: apps/desktop
144
+ env:
145
+ NODE_OPTIONS: --max-old-space-size=6144
146
+
147
+
148
+ - name: Test Desktop Client
149
+ run: pnpm test
150
+ working-directory: apps/desktop
151
+
152
+ - name: Upload Desktop App Coverage to Codecov
153
+ uses: codecov/codecov-action@v5
154
+ with:
155
+ token: ${{ secrets.CODECOV_TOKEN }}
156
+ files: ./apps/desktop/coverage/lcov.info
157
+ flags: desktop
158
+
122
159
  test-databsae:
123
160
  name: Test Database
124
161
 
@@ -156,7 +193,7 @@ jobs:
156
193
  - name: Test Client DB
157
194
  run: pnpm --filter @lobechat/database test:client-db
158
195
  env:
159
- KEY_VAULTS_SECRET: LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s=
196
+ KEY_VAULTS_SECRET: Kix2wcUONd4CX51E/ZPAd36BqM4wzJgKjPtz2sGztqQ=
160
197
  S3_PUBLIC_DOMAIN: https://example.com
161
198
  APP_URL: https://home.com
162
199
 
@@ -165,7 +202,7 @@ jobs:
165
202
  env:
166
203
  DATABASE_TEST_URL: postgresql://postgres:postgres@localhost:5432/postgres
167
204
  DATABASE_DRIVER: node
168
- KEY_VAULTS_SECRET: LA7n9k3JdEcbSgml2sxfw+4TV1AzaaFU5+R176aQz4s=
205
+ KEY_VAULTS_SECRET: Kix2wcUONd4CX51E/ZPAd36BqM4wzJgKjPtz2sGztqQ=
169
206
  S3_PUBLIC_DOMAIN: https://example.com
170
207
  APP_URL: https://home.com
171
208
 
package/CHANGELOG.md CHANGED
@@ -2,6 +2,48 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [Version 2.0.0-next.22](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.21...v2.0.0-next.22)
6
+
7
+ <sup>Released on **2025-11-04**</sup>
8
+
9
+ <br/>
10
+
11
+ <details>
12
+ <summary><kbd>Improvements and Fixes</kbd></summary>
13
+
14
+ </details>
15
+
16
+ <div align="right">
17
+
18
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
19
+
20
+ </div>
21
+
22
+ ## [Version 2.0.0-next.21](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.20...v2.0.0-next.21)
23
+
24
+ <sup>Released on **2025-11-04**</sup>
25
+
26
+ #### 🐛 Bug Fixes
27
+
28
+ - **misc**: Fix oidc auth timeout issue on the desktop.
29
+
30
+ <br/>
31
+
32
+ <details>
33
+ <summary><kbd>Improvements and Fixes</kbd></summary>
34
+
35
+ #### What's fixed
36
+
37
+ - **misc**: Fix oidc auth timeout issue on the desktop, closes [#10025](https://github.com/lobehub/lobe-chat/issues/10025) ([20666db](https://github.com/lobehub/lobe-chat/commit/20666db))
38
+
39
+ </details>
40
+
41
+ <div align="right">
42
+
43
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
44
+
45
+ </div>
46
+
5
47
  ## [Version 2.0.0-next.20](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.19...v2.0.0-next.20)
6
48
 
7
49
  <sup>Released on **2025-11-03**</sup>
@@ -72,7 +72,7 @@
72
72
  "tsx": "^4.19.3",
73
73
  "typescript": "^5.7.3",
74
74
  "undici": "^7.9.0",
75
- "vite": "^6.3.5",
75
+ "vite": "^7.1.12",
76
76
  "vitest": "^3.2.4"
77
77
  },
78
78
  "pnpm": {
@@ -14,39 +14,38 @@ const logger = createLogger('controllers:AuthCtr');
14
14
 
15
15
  /**
16
16
  * Authentication Controller
17
- * 使用中间页 + 轮询的方式实现 OAuth 授权流程
17
+ * Implements OAuth authorization flow using intermediate page + polling mechanism
18
18
  */
19
19
  export default class AuthCtr extends ControllerModule {
20
20
  /**
21
- * 远程服务器配置控制器
21
+ * Remote server configuration controller
22
22
  */
23
23
  private get remoteServerConfigCtr() {
24
24
  return this.app.getController(RemoteServerConfigCtr);
25
25
  }
26
26
 
27
27
  /**
28
- * 当前的 PKCE 参数
28
+ * Current PKCE parameters
29
29
  */
30
30
  private codeVerifier: string | null = null;
31
31
  private authRequestState: string | null = null;
32
32
 
33
33
  /**
34
- * 轮询相关参数
34
+ * Polling related parameters
35
35
  */
36
36
  // eslint-disable-next-line no-undef
37
37
  private pollingInterval: NodeJS.Timeout | null = null;
38
38
  private cachedRemoteUrl: string | null = null;
39
39
 
40
40
  /**
41
- * 自动刷新定时器
41
+ * Auto-refresh timer
42
42
  */
43
43
  // eslint-disable-next-line no-undef
44
44
  private autoRefreshTimer: NodeJS.Timeout | null = null;
45
45
 
46
46
  /**
47
- * 构造 redirect_uri,确保授权和令牌交换时使用相同的 URI
48
- * @param remoteUrl 远程服务器 URL
49
- * @param includeHandoffId 是否包含 handoff ID(仅在授权时需要)
47
+ * Construct redirect_uri, ensuring the same URI is used for authorization and token exchange
48
+ * @param remoteUrl Remote server URL
50
49
  */
51
50
  private constructRedirectUri(remoteUrl: string): string {
52
51
  const callbackUrl = new URL('/oidc/callback/desktop', remoteUrl);
@@ -59,9 +58,12 @@ export default class AuthCtr extends ControllerModule {
59
58
  */
60
59
  @ipcClientEvent('requestAuthorization')
61
60
  async requestAuthorization(config: DataSyncConfig) {
61
+ // Clear any old authorization state
62
+ this.clearAuthorizationState();
63
+
62
64
  const remoteUrl = await this.remoteServerConfigCtr.getRemoteServerUrl(config);
63
65
 
64
- // 缓存远程服务器 URL 用于后续轮询
66
+ // Cache remote server URL for subsequent polling
65
67
  this.cachedRemoteUrl = remoteUrl;
66
68
 
67
69
  logger.info(
@@ -115,7 +117,7 @@ export default class AuthCtr extends ControllerModule {
115
117
  }
116
118
 
117
119
  /**
118
- * 启动轮询机制获取凭证
120
+ * Start polling mechanism to retrieve credentials
119
121
  */
120
122
  private startPolling() {
121
123
  if (!this.authRequestState) {
@@ -133,7 +135,7 @@ export default class AuthCtr extends ControllerModule {
133
135
  // Check if polling has timed out
134
136
  if (Date.now() - startTime > maxPollTime) {
135
137
  logger.warn('Credential polling timed out');
136
- this.stopPolling();
138
+ this.clearAuthorizationState();
137
139
  this.broadcastAuthorizationFailed('Authorization timed out');
138
140
  return;
139
141
  }
@@ -167,14 +169,14 @@ export default class AuthCtr extends ControllerModule {
167
169
  }
168
170
  } catch (error) {
169
171
  logger.error('Error during credential polling:', error);
170
- this.stopPolling();
172
+ this.clearAuthorizationState();
171
173
  this.broadcastAuthorizationFailed('Polling error: ' + error.message);
172
174
  }
173
175
  }, pollInterval);
174
176
  }
175
177
 
176
178
  /**
177
- * 停止轮询
179
+ * Stop polling
178
180
  */
179
181
  private stopPolling() {
180
182
  if (this.pollingInterval) {
@@ -184,18 +186,30 @@ export default class AuthCtr extends ControllerModule {
184
186
  }
185
187
 
186
188
  /**
187
- * 启动自动刷新定时器
189
+ * Clear authorization state
190
+ * Called before starting a new authorization flow or after authorization failure/timeout
191
+ */
192
+ private clearAuthorizationState() {
193
+ logger.debug('Clearing authorization state');
194
+ this.stopPolling();
195
+ this.codeVerifier = null;
196
+ this.authRequestState = null;
197
+ this.cachedRemoteUrl = null;
198
+ }
199
+
200
+ /**
201
+ * Start auto-refresh timer
188
202
  */
189
203
  private startAutoRefresh() {
190
- // 先停止现有的定时器
204
+ // Stop existing timer first
191
205
  this.stopAutoRefresh();
192
206
 
193
- const checkInterval = 2 * 60 * 1000; // 2 分钟检查一次
207
+ const checkInterval = 2 * 60 * 1000; // Check every 2 minutes
194
208
  logger.debug('Starting auto-refresh timer');
195
209
 
196
210
  this.autoRefreshTimer = setInterval(async () => {
197
211
  try {
198
- // 检查 token 是否即将过期 (提前 5 分钟刷新)
212
+ // Check if token is expiring soon (refresh 5 minutes in advance)
199
213
  if (this.remoteServerConfigCtr.isTokenExpiringSoon()) {
200
214
  const expiresAt = this.remoteServerConfigCtr.getTokenExpiresAt();
201
215
  logger.info(
@@ -208,7 +222,7 @@ export default class AuthCtr extends ControllerModule {
208
222
  this.broadcastTokenRefreshed();
209
223
  } else {
210
224
  logger.error(`Auto-refresh failed: ${result.error}`);
211
- // 如果自动刷新失败,停止定时器并清除 token
225
+ // If auto-refresh fails, stop timer and clear token
212
226
  this.stopAutoRefresh();
213
227
  await this.remoteServerConfigCtr.clearTokens();
214
228
  await this.remoteServerConfigCtr.setRemoteServerConfig({ active: false });
@@ -222,7 +236,7 @@ export default class AuthCtr extends ControllerModule {
222
236
  }
223
237
 
224
238
  /**
225
- * 停止自动刷新定时器
239
+ * Stop auto-refresh timer
226
240
  */
227
241
  private stopAutoRefresh() {
228
242
  if (this.autoRefreshTimer) {
@@ -233,8 +247,8 @@ export default class AuthCtr extends ControllerModule {
233
247
  }
234
248
 
235
249
  /**
236
- * 轮询获取凭证
237
- * 直接发送 HTTP 请求到远程服务器
250
+ * Poll for credentials
251
+ * Sends HTTP request directly to remote server
238
252
  */
239
253
  private async pollForCredentials(): Promise<{ code: string; state: string } | null> {
240
254
  if (!this.authRequestState || !this.cachedRemoteUrl) {
@@ -242,17 +256,17 @@ export default class AuthCtr extends ControllerModule {
242
256
  }
243
257
 
244
258
  try {
245
- // 使用缓存的远程服务器 URL
259
+ // Use cached remote server URL
246
260
  const remoteUrl = this.cachedRemoteUrl;
247
261
 
248
- // 构造请求 URL
262
+ // Construct request URL
249
263
  const url = new URL('/oidc/handoff', remoteUrl);
250
264
  url.searchParams.set('id', this.authRequestState);
251
265
  url.searchParams.set('client', 'desktop');
252
266
 
253
267
  logger.debug(`Polling for credentials: ${url.toString()}`);
254
268
 
255
- // 直接发送 HTTP 请求
269
+ // Send HTTP request directly
256
270
  const response = await fetch(url.toString(), {
257
271
  headers: {
258
272
  'Content-Type': 'application/json',
@@ -260,9 +274,9 @@ export default class AuthCtr extends ControllerModule {
260
274
  method: 'GET',
261
275
  });
262
276
 
263
- // 检查响应状态
277
+ // Check response status
264
278
  if (response.status === 404) {
265
- // 凭证还未准备好,这是正常情况
279
+ // Credentials not ready yet, this is normal
266
280
  return null;
267
281
  }
268
282
 
@@ -270,7 +284,7 @@ export default class AuthCtr extends ControllerModule {
270
284
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
271
285
  }
272
286
 
273
- // 解析响应数据
287
+ // Parse response data
274
288
  const data = (await response.json()) as {
275
289
  data: {
276
290
  id: string;
@@ -511,7 +525,7 @@ export default class AuthCtr extends ControllerModule {
511
525
  }
512
526
 
513
527
  /**
514
- * 应用启动后初始化
528
+ * Initialize after app is ready
515
529
  */
516
530
  afterAppReady() {
517
531
  logger.debug('AuthCtr initialized, checking for existing tokens');
@@ -519,7 +533,7 @@ export default class AuthCtr extends ControllerModule {
519
533
  }
520
534
 
521
535
  /**
522
- * 清理所有定时器
536
+ * Clean up all timers
523
537
  */
524
538
  cleanup() {
525
539
  logger.debug('Cleaning up AuthCtr timers');
@@ -528,14 +542,14 @@ export default class AuthCtr extends ControllerModule {
528
542
  }
529
543
 
530
544
  /**
531
- * 初始化自动刷新功能
532
- * 在应用启动时检查是否有有效的 token,如果有就启动自动刷新定时器
545
+ * Initialize auto-refresh functionality
546
+ * Checks for valid token at app startup and starts auto-refresh timer if token exists
533
547
  */
534
548
  private async initializeAutoRefresh() {
535
549
  try {
536
550
  const config = await this.remoteServerConfigCtr.getRemoteServerConfig();
537
551
 
538
- // 检查是否配置了远程服务器且处于活动状态
552
+ // Check if remote server is configured and active
539
553
  if (!config.active || !config.remoteServerUrl) {
540
554
  logger.debug(
541
555
  'Remote server not active or configured, skipping auto-refresh initialization',
@@ -543,36 +557,36 @@ export default class AuthCtr extends ControllerModule {
543
557
  return;
544
558
  }
545
559
 
546
- // 检查是否有有效的访问令牌
560
+ // Check if valid access token exists
547
561
  const accessToken = await this.remoteServerConfigCtr.getAccessToken();
548
562
  if (!accessToken) {
549
563
  logger.debug('No access token found, skipping auto-refresh initialization');
550
564
  return;
551
565
  }
552
566
 
553
- // 检查是否有过期时间信息
567
+ // Check if token expiration time exists
554
568
  const expiresAt = this.remoteServerConfigCtr.getTokenExpiresAt();
555
569
  if (!expiresAt) {
556
570
  logger.debug('No token expiration time found, skipping auto-refresh initialization');
557
571
  return;
558
572
  }
559
573
 
560
- // 检查 token 是否已经过期
574
+ // Check if token has already expired
561
575
  const currentTime = Date.now();
562
576
  if (currentTime >= expiresAt) {
563
577
  logger.info('Token has expired, attempting to refresh it');
564
578
 
565
- // 尝试刷新 token
579
+ // Attempt to refresh token
566
580
  const refreshResult = await this.remoteServerConfigCtr.refreshAccessToken();
567
581
  if (refreshResult.success) {
568
582
  logger.info('Token refresh successful during initialization');
569
583
  this.broadcastTokenRefreshed();
570
- // 重新启动自动刷新定时器
584
+ // Restart auto-refresh timer
571
585
  this.startAutoRefresh();
572
586
  return;
573
587
  } else {
574
588
  logger.error(`Token refresh failed during initialization: ${refreshResult.error}`);
575
- // 只有在刷新失败时才清除 token 并要求重新授权
589
+ // Clear token and require re-authorization only on refresh failure
576
590
  await this.remoteServerConfigCtr.clearTokens();
577
591
  await this.remoteServerConfigCtr.setRemoteServerConfig({ active: false });
578
592
  this.broadcastAuthorizationRequired();
@@ -580,7 +594,7 @@ export default class AuthCtr extends ControllerModule {
580
594
  }
581
595
  }
582
596
 
583
- // 启动自动刷新定时器
597
+ // Start auto-refresh timer
584
598
  logger.info(
585
599
  `Token is valid, starting auto-refresh timer. Token expires at: ${new Date(expiresAt).toISOString()}`,
586
600
  );
@@ -2,16 +2,16 @@ import { ControllerModule, ipcClientEvent } from './index';
2
2
 
3
3
  export default class MenuController extends ControllerModule {
4
4
  /**
5
- * 刷新菜单
5
+ * Refresh menu
6
6
  */
7
7
  @ipcClientEvent('refreshAppMenu')
8
8
  refreshAppMenu() {
9
- // 注意:可能需要根据具体情况决定是否允许渲染进程刷新所有菜单
9
+ // Note: May need to decide whether to allow renderer process to refresh all menus based on specific circumstances
10
10
  return this.app.menuManager.refreshMenus();
11
11
  }
12
12
 
13
13
  /**
14
- * 显示上下文菜单
14
+ * Show context menu
15
15
  */
16
16
  @ipcClientEvent('showContextMenu')
17
17
  showContextMenu(params: { data?: any; type: string }) {
@@ -19,11 +19,11 @@ export default class MenuController extends ControllerModule {
19
19
  }
20
20
 
21
21
  /**
22
- * 设置开发菜单可见性
22
+ * Set development menu visibility
23
23
  */
24
24
  @ipcClientEvent('setDevMenuVisibility')
25
25
  setDevMenuVisibility(visible: boolean) {
26
- // 调用 MenuManager 的方法来重建应用菜单
26
+ // Call MenuManager method to rebuild application menu
27
27
  return this.app.menuManager.rebuildAppMenu({ showDevItems: visible });
28
28
  }
29
29
  }