@yancyyu/openhermit 1.5.8 → 1.5.9

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 (105) hide show
  1. package/README.md +10 -1
  2. package/dist-renderer/assets/{ProjectEditorOverlay-BNoDw9T1.js → ProjectEditorOverlay-C5D83Zxv.js} +1 -1
  3. package/dist-renderer/assets/{TeamGraphOverlay-CfGRKQIu.js → TeamGraphOverlay-ajzuM1-u.js} +1 -1
  4. package/dist-renderer/assets/{_basePickBy-Ct8Hm5_h.js → _basePickBy-C9H2zmVj.js} +1 -1
  5. package/dist-renderer/assets/{_baseUniq-BofrAFBx.js → _baseUniq-CpGZGemc.js} +1 -1
  6. package/dist-renderer/assets/{arc-AbJgatzR.js → arc-CbGBDw-m.js} +1 -1
  7. package/dist-renderer/assets/{architectureDiagram-VXUJARFQ-gpniCJVk.js → architectureDiagram-VXUJARFQ-nuKXUIpb.js} +1 -1
  8. package/dist-renderer/assets/{blockDiagram-VD42YOAC-aBbbmONC.js → blockDiagram-VD42YOAC-DHUUE7Jc.js} +1 -1
  9. package/dist-renderer/assets/{c4Diagram-YG6GDRKO-DJio1IsU.js → c4Diagram-YG6GDRKO-OILHhqLM.js} +1 -1
  10. package/dist-renderer/assets/channel-DpUKLLrj.js +1 -0
  11. package/dist-renderer/assets/{chunk-4BX2VUAB-D1_HKao2.js → chunk-4BX2VUAB-dqNpZaQ8.js} +1 -1
  12. package/dist-renderer/assets/{chunk-55IACEB6-NAmVxF4k.js → chunk-55IACEB6-BCoSJQM-.js} +1 -1
  13. package/dist-renderer/assets/{chunk-B4BG7PRW-Ce829laz.js → chunk-B4BG7PRW-BLbg8yVR.js} +1 -1
  14. package/dist-renderer/assets/{chunk-DI55MBZ5-Ct2Le12y.js → chunk-DI55MBZ5-CUUWOs1Q.js} +1 -1
  15. package/dist-renderer/assets/{chunk-FMBD7UC4-Cie3DzKk.js → chunk-FMBD7UC4-D9geTN5P.js} +1 -1
  16. package/dist-renderer/assets/{chunk-QN33PNHL-4f5Yb50e.js → chunk-QN33PNHL-BGT8-BRX.js} +1 -1
  17. package/dist-renderer/assets/{chunk-QZHKN3VN-D9ranl9c.js → chunk-QZHKN3VN-CC8ebGaM.js} +1 -1
  18. package/dist-renderer/assets/{chunk-TZMSLE5B-bdGZWlEy.js → chunk-TZMSLE5B-CajekcT6.js} +1 -1
  19. package/dist-renderer/assets/classDiagram-2ON5EDUG-LL85aSlz.js +1 -0
  20. package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-LL85aSlz.js +1 -0
  21. package/dist-renderer/assets/clone-BHWsFzFA.js +1 -0
  22. package/dist-renderer/assets/{cose-bilkent-S5V4N54A-C6tvfcVi.js → cose-bilkent-S5V4N54A-C_x7hSy3.js} +1 -1
  23. package/dist-renderer/assets/{dagre-6UL2VRFP-B-4qcZam.js → dagre-6UL2VRFP-C4Y1k4DZ.js} +1 -1
  24. package/dist-renderer/assets/{diagram-PSM6KHXK-CwT3TLjx.js → diagram-PSM6KHXK-oRIeULoh.js} +1 -1
  25. package/dist-renderer/assets/{diagram-QEK2KX5R-BWH6-ZFd.js → diagram-QEK2KX5R-DwSqw5HF.js} +1 -1
  26. package/dist-renderer/assets/{diagram-S2PKOQOG-DfpPnfi1.js → diagram-S2PKOQOG-DqjGYje2.js} +1 -1
  27. package/dist-renderer/assets/{erDiagram-Q2GNP2WA-BFbEFR4x.js → erDiagram-Q2GNP2WA-CEV5bBgg.js} +1 -1
  28. package/dist-renderer/assets/{flowDiagram-NV44I4VS-Dg3cf5hW.js → flowDiagram-NV44I4VS-BQQkrRyu.js} +1 -1
  29. package/dist-renderer/assets/{ganttDiagram-JELNMOA3-B21y55W5.js → ganttDiagram-JELNMOA3-CLy4WR1G.js} +1 -1
  30. package/dist-renderer/assets/{gitGraphDiagram-V2S2FVAM-BDV3BJzn.js → gitGraphDiagram-V2S2FVAM-6W3ioQu_.js} +1 -1
  31. package/dist-renderer/assets/{graph-BfaZ4hZt.js → graph-BnLKQvhH.js} +1 -1
  32. package/dist-renderer/assets/{index-CCqtDawH.js → index-B4aiRxoU.js} +1 -1
  33. package/dist-renderer/assets/{index-pMg_LlsS.js → index-B8lKqPVq.js} +1 -1
  34. package/dist-renderer/assets/{index-CZltVMDP.js → index-BRuhNKyU.js} +12 -12
  35. package/dist-renderer/assets/{index-BMXHMpkG.js → index-BufvLVIl.js} +1 -1
  36. package/dist-renderer/assets/{index-Ct0-y9TF.js → index-C1xShqKH.js} +1 -1
  37. package/dist-renderer/assets/{index-CVMSpK8C.js → index-zIOLLI7O.js} +1 -1
  38. package/dist-renderer/assets/{infoDiagram-HS3SLOUP-DvMlS0CL.js → infoDiagram-HS3SLOUP-BoBweEEY.js} +1 -1
  39. package/dist-renderer/assets/{journeyDiagram-XKPGCS4Q-DIyMluRv.js → journeyDiagram-XKPGCS4Q-DLL0V5oP.js} +1 -1
  40. package/dist-renderer/assets/{kanban-definition-3W4ZIXB7-CVOx8f-7.js → kanban-definition-3W4ZIXB7-HsFtEDG3.js} +1 -1
  41. package/dist-renderer/assets/{layout-BPKIXUf4.js → layout-ClIooAAq.js} +1 -1
  42. package/dist-renderer/assets/{linear-CScZGLr2.js → linear-r3RJcj8y.js} +1 -1
  43. package/dist-renderer/assets/{mindmap-definition-VGOIOE7T-CmDQ7Wo6.js → mindmap-definition-VGOIOE7T-BA_P1U4V.js} +1 -1
  44. package/dist-renderer/assets/{pieDiagram-ADFJNKIX-DbVClin-.js → pieDiagram-ADFJNKIX-CzPAfkTB.js} +1 -1
  45. package/dist-renderer/assets/{quadrantDiagram-AYHSOK5B-CAB0MYcW.js → quadrantDiagram-AYHSOK5B-PvdPWzFJ.js} +1 -1
  46. package/dist-renderer/assets/{requirementDiagram-UZGBJVZJ-w2Lfpg3T.js → requirementDiagram-UZGBJVZJ-CHqIL_Od.js} +1 -1
  47. package/dist-renderer/assets/{sankeyDiagram-TZEHDZUN-kvG1QoKY.js → sankeyDiagram-TZEHDZUN-ConzpACM.js} +1 -1
  48. package/dist-renderer/assets/{sequenceDiagram-WL72ISMW-DCVBQ23J.js → sequenceDiagram-WL72ISMW-Zryq4oxP.js} +1 -1
  49. package/dist-renderer/assets/{stateDiagram-FKZM4ZOC-ItZ0JBvq.js → stateDiagram-FKZM4ZOC-BA9V7NHF.js} +1 -1
  50. package/dist-renderer/assets/{stateDiagram-v2-4FDKWEC3-Hpmw4dMm.js → stateDiagram-v2-4FDKWEC3-CGnaujD-.js} +1 -1
  51. package/dist-renderer/assets/{timeline-definition-IT6M3QCI-BzSFaAjV.js → timeline-definition-IT6M3QCI-DPs2ZjMm.js} +1 -1
  52. package/dist-renderer/assets/{treemap-GDKQZRPO-fSz4hQn0.js → treemap-GDKQZRPO-B0lzrLxb.js} +1 -1
  53. package/dist-renderer/assets/{xychartDiagram-PRI3JC2R-CT1kaGlv.js → xychartDiagram-PRI3JC2R-CINGmMxX.js} +1 -1
  54. package/dist-renderer/index.html +1 -1
  55. package/package.json +2 -1
  56. package/src/main/server.ts +993 -764
  57. package/src/main/services/UpdateService.ts +4 -1
  58. package/src/main/services/ccConnect/CcConnectBridge.ts +1 -8
  59. package/src/main/services/ccConnect/CcConnectClient.ts +7 -2
  60. package/src/main/services/teams-mvp/TeamProvisioningService.ts +14 -4
  61. package/src/main/services/teams-mvp/TeamWorkspaceService.ts +11 -6
  62. package/src/renderer/App.tsx +18 -7
  63. package/src/renderer/api/httpClient.ts +136 -42
  64. package/src/renderer/components/chat/ChatHistory.tsx +11 -8
  65. package/src/renderer/components/dashboard/DashboardView.tsx +4 -2
  66. package/src/renderer/components/extensions/ExtensionStoreView.tsx +2 -7
  67. package/src/renderer/components/layout/Sidebar.tsx +3 -1
  68. package/src/renderer/components/schedules/SchedulesView.tsx +15 -13
  69. package/src/renderer/components/settings/SettingsTabs.tsx +2 -1
  70. package/src/renderer/components/settings/hooks/useSettingsHandlers.ts +4 -5
  71. package/src/renderer/components/settings/sections/AdvancedSection.tsx +19 -4
  72. package/src/renderer/components/settings/sections/CliStatusSection.tsx +63 -59
  73. package/src/renderer/components/settings/sections/GeneralSection.tsx +5 -11
  74. package/src/renderer/components/settings/sections/HarnessSection.tsx +30 -15
  75. package/src/renderer/components/settings/sections/PlatformsSection.tsx +110 -51
  76. package/src/renderer/components/sidebar/SidebarSessions.tsx +100 -67
  77. package/src/renderer/components/sidebar/WorkspaceBrowser.tsx +26 -43
  78. package/src/renderer/components/team/CcSessionsSection.tsx +34 -14
  79. package/src/renderer/components/team/TeamDetailView.tsx +150 -148
  80. package/src/renderer/components/team/TeamEmptyState.tsx +27 -16
  81. package/src/renderer/components/team/TeamListView.tsx +4 -2
  82. package/src/renderer/components/team/activity/ActivityItem.tsx +6 -1
  83. package/src/renderer/components/team/dialogs/CreateTeamDialog.tsx +282 -75
  84. package/src/renderer/components/team/dialogs/EditTeamDialog.tsx +2 -1
  85. package/src/renderer/components/team/dialogs/PlatformManualForm.tsx +64 -21
  86. package/src/renderer/components/team/dialogs/PlatformSetupQR.tsx +68 -19
  87. package/src/renderer/components/team/dialogs/ProjectPathSelector.tsx +20 -16
  88. package/src/renderer/components/team/dialogs/platformMeta.ts +66 -11
  89. package/src/renderer/components/team/editor/EditorFileTree.tsx +9 -7
  90. package/src/renderer/components/team/kanban/KanbanBoard.tsx +7 -10
  91. package/src/renderer/components/team/kanban/KanbanTaskCard.tsx +1 -3
  92. package/src/renderer/components/team/members/MemberDetailDialog.tsx +1 -5
  93. package/src/renderer/components/team/messages/MessageComposer.tsx +3 -1
  94. package/src/renderer/components/team/messages/MessagesPanel.tsx +34 -26
  95. package/src/renderer/components/team/schedule/CcCronScheduleDialog.tsx +1 -3
  96. package/src/renderer/components/team/schedule/ScheduleSection.tsx +9 -10
  97. package/src/renderer/store/slices/scheduleSlice.ts +4 -1
  98. package/src/renderer/store/slices/teamSlice.ts +3 -1
  99. package/src/shared/types/api.ts +70 -21
  100. package/src/shared/utils/leadDetection.ts +5 -1
  101. package/tsconfig.json +26 -0
  102. package/dist-renderer/assets/channel-CZ8sd5Xf.js +0 -1
  103. package/dist-renderer/assets/classDiagram-2ON5EDUG-CMcfSKj5.js +0 -1
  104. package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-CMcfSKj5.js +0 -1
  105. package/dist-renderer/assets/clone-CMuwA8RV.js +0 -1
@@ -2421,169 +2421,169 @@ export const TeamDetailView = ({
2421
2421
  members={activeMembers}
2422
2422
  />
2423
2423
  }
2424
- onRequestReview={(taskId) => {
2425
- void (async () => {
2426
- try {
2427
- await requestReview(teamName, taskId);
2428
- } catch {
2429
- // error via store
2430
- }
2431
- })();
2432
- }}
2433
- onApprove={(taskId) => {
2434
- void (async () => {
2435
- try {
2436
- await updateKanban(teamName, taskId, {
2437
- op: 'set_column',
2438
- column: 'approved',
2439
- });
2440
- } catch {
2441
- // error via store
2442
- }
2443
- })();
2444
- }}
2445
- onRequestChanges={(taskId) => {
2446
- setRequestChangesTaskId(taskId);
2447
- }}
2448
- onMoveBackToDone={(taskId) => {
2449
- void (async () => {
2424
+ onRequestReview={(taskId) => {
2425
+ void (async () => {
2426
+ try {
2427
+ await requestReview(teamName, taskId);
2428
+ } catch {
2429
+ // error via store
2430
+ }
2431
+ })();
2432
+ }}
2433
+ onApprove={(taskId) => {
2434
+ void (async () => {
2435
+ try {
2436
+ await updateKanban(teamName, taskId, {
2437
+ op: 'set_column',
2438
+ column: 'approved',
2439
+ });
2440
+ } catch {
2441
+ // error via store
2442
+ }
2443
+ })();
2444
+ }}
2445
+ onRequestChanges={(taskId) => {
2446
+ setRequestChangesTaskId(taskId);
2447
+ }}
2448
+ onMoveBackToDone={(taskId) => {
2449
+ void (async () => {
2450
+ try {
2451
+ await updateKanban(teamName, taskId, { op: 'remove' });
2452
+ await updateTaskStatus(teamName, taskId, 'completed');
2453
+ } catch {
2454
+ // error via store
2455
+ }
2456
+ })();
2457
+ }}
2458
+ onStartTask={(taskId) => {
2459
+ void (async () => {
2460
+ const scheduleId = getScheduleIdFromBoardTaskId(taskId);
2461
+ if (scheduleId) {
2450
2462
  try {
2451
- await updateKanban(teamName, taskId, { op: 'remove' });
2452
- await updateTaskStatus(teamName, taskId, 'completed');
2463
+ await triggerScheduleNow(scheduleId);
2464
+ await fetchRunHistory(scheduleId);
2453
2465
  } catch {
2454
2466
  // error via store
2455
2467
  }
2456
- })();
2457
- }}
2458
- onStartTask={(taskId) => {
2459
- void (async () => {
2460
- const scheduleId = getScheduleIdFromBoardTaskId(taskId);
2461
- if (scheduleId) {
2468
+ return;
2469
+ }
2470
+ try {
2471
+ const result = await startTaskByUser(teamName, taskId);
2472
+ if (data?.isAlive) {
2473
+ const task = data.tasks.find((t) => t.id === taskId);
2462
2474
  try {
2463
- await triggerScheduleNow(scheduleId);
2464
- await fetchRunHistory(scheduleId);
2465
- } catch {
2466
- // error via store
2467
- }
2468
- return;
2469
- }
2470
- try {
2471
- const result = await startTaskByUser(teamName, taskId);
2472
- if (data?.isAlive) {
2473
- const task = data.tasks.find((t) => t.id === taskId);
2474
- try {
2475
- if (result.notifiedOwner && task?.owner) {
2476
- await api.teams.processSend(
2477
- teamName,
2478
- `Task ${formatTaskDisplayLabel(task)} "${task.subject}" has started. Please begin working on it.`
2479
- );
2480
- } else if (!result.notifiedOwner) {
2481
- const desc = task?.description?.trim()
2482
- ? `\nDescription: ${task.description.trim()}`
2483
- : '';
2484
- await api.teams.processSend(
2485
- teamName,
2486
- `Task #${deriveTaskDisplayId(taskId)} "${task?.subject ?? ''}" has been moved to IN PROGRESS but has no assignee.${desc}\nPlease assign it to an available team member, or take it yourself if everyone is busy.`
2487
- );
2488
- }
2489
- } catch {
2490
- // best-effort
2491
- }
2492
- }
2493
- } catch {
2494
- // error via store
2495
- }
2496
- })();
2497
- }}
2498
- onCompleteTask={(taskId) => {
2499
- void (async () => {
2500
- if (isScheduleBoardTaskId(taskId)) {
2501
- return;
2502
- }
2503
- try {
2504
- await updateTaskStatus(teamName, taskId, 'completed');
2505
- } catch {
2506
- // error via store
2507
- }
2508
- })();
2509
- }}
2510
- onCancelTask={(taskId) => {
2511
- void (async () => {
2512
- if (isScheduleBoardTaskId(taskId)) {
2513
- return;
2514
- }
2515
- try {
2516
- const task = data?.tasks.find((t) => t.id === taskId);
2517
- await updateTaskStatus(teamName, taskId, 'pending');
2518
-
2519
- // Notify assignee directly via inbox — they'll see it immediately
2520
- if (task?.owner) {
2521
- try {
2522
- await api.teams.sendMessage(teamName, {
2523
- member: task.owner,
2524
- text: `Task ${formatTaskDisplayLabel(task)} "${task.subject}" has been CANCELLED by the user and moved back to TODO. Stop working on it immediately.`,
2525
- summary: `Task ${formatTaskDisplayLabel(task)} cancelled`,
2526
- });
2527
- } catch {
2528
- // best-effort
2529
- }
2530
- }
2531
-
2532
- // Also notify team lead so they can reassign/coordinate
2533
- if (data?.isAlive) {
2534
- try {
2535
- const ownerSuffix = task?.owner
2536
- ? ` ${task.owner} has been notified to stop.`
2475
+ if (result.notifiedOwner && task?.owner) {
2476
+ await api.teams.processSend(
2477
+ teamName,
2478
+ `Task ${formatTaskDisplayLabel(task)} "${task.subject}" has started. Please begin working on it.`
2479
+ );
2480
+ } else if (!result.notifiedOwner) {
2481
+ const desc = task?.description?.trim()
2482
+ ? `\nDescription: ${task.description.trim()}`
2537
2483
  : '';
2538
2484
  await api.teams.processSend(
2539
2485
  teamName,
2540
- `Task #${deriveTaskDisplayId(taskId)} "${task?.subject ?? ''}" has been cancelled and moved back to TODO.${ownerSuffix}`
2486
+ `Task #${deriveTaskDisplayId(taskId)} "${task?.subject ?? ''}" has been moved to IN PROGRESS but has no assignee.${desc}\nPlease assign it to an available team member, or take it yourself if everyone is busy.`
2541
2487
  );
2542
- } catch {
2543
- // best-effort
2544
2488
  }
2489
+ } catch {
2490
+ // best-effort
2545
2491
  }
2546
- } catch {
2547
- // error via store
2548
- }
2549
- })();
2550
- }}
2551
- onColumnOrderChange={(columnId, orderedTaskIds) => {
2552
- void (async () => {
2553
- try {
2554
- await updateKanbanColumnOrder(teamName, columnId, orderedTaskIds);
2555
- } catch {
2556
- // error via store
2557
2492
  }
2558
- })();
2559
- }}
2560
- onScrollToTask={(taskId) => {
2561
- const el = document.querySelector(`[data-task-id="${taskId}"]`);
2562
- if (el) {
2563
- el.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
2564
- el.classList.remove('kanban-card-focus-pulse');
2565
- void (el as HTMLElement).offsetWidth;
2566
- el.classList.add('kanban-card-focus-pulse');
2567
- el.addEventListener(
2568
- 'animationend',
2569
- () => el.classList.remove('kanban-card-focus-pulse'),
2570
- { once: true }
2571
- );
2493
+ } catch {
2494
+ // error via store
2572
2495
  }
2573
- }}
2574
- onTaskClick={(task) => {
2575
- if (isScheduleBoardTaskId(task.id)) {
2496
+ })();
2497
+ }}
2498
+ onCompleteTask={(taskId) => {
2499
+ void (async () => {
2500
+ if (isScheduleBoardTaskId(taskId)) {
2576
2501
  return;
2577
2502
  }
2578
- setSelectedTask(task);
2579
- }}
2580
- onViewChanges={handleViewChanges}
2581
- onAddTask={(startImmediately) =>
2582
- openCreateTaskDialog('', '', '', startImmediately)
2503
+ try {
2504
+ await updateTaskStatus(teamName, taskId, 'completed');
2505
+ } catch {
2506
+ // error via store
2507
+ }
2508
+ })();
2509
+ }}
2510
+ onCancelTask={(taskId) => {
2511
+ void (async () => {
2512
+ if (isScheduleBoardTaskId(taskId)) {
2513
+ return;
2514
+ }
2515
+ try {
2516
+ const task = data?.tasks.find((t) => t.id === taskId);
2517
+ await updateTaskStatus(teamName, taskId, 'pending');
2518
+
2519
+ // Notify assignee directly via inbox — they'll see it immediately
2520
+ if (task?.owner) {
2521
+ try {
2522
+ await api.teams.sendMessage(teamName, {
2523
+ member: task.owner,
2524
+ text: `Task ${formatTaskDisplayLabel(task)} "${task.subject}" has been CANCELLED by the user and moved back to TODO. Stop working on it immediately.`,
2525
+ summary: `Task ${formatTaskDisplayLabel(task)} cancelled`,
2526
+ });
2527
+ } catch {
2528
+ // best-effort
2529
+ }
2530
+ }
2531
+
2532
+ // Also notify team lead so they can reassign/coordinate
2533
+ if (data?.isAlive) {
2534
+ try {
2535
+ const ownerSuffix = task?.owner
2536
+ ? ` ${task.owner} has been notified to stop.`
2537
+ : '';
2538
+ await api.teams.processSend(
2539
+ teamName,
2540
+ `Task #${deriveTaskDisplayId(taskId)} "${task?.subject ?? ''}" has been cancelled and moved back to TODO.${ownerSuffix}`
2541
+ );
2542
+ } catch {
2543
+ // best-effort
2544
+ }
2545
+ }
2546
+ } catch {
2547
+ // error via store
2548
+ }
2549
+ })();
2550
+ }}
2551
+ onColumnOrderChange={(columnId, orderedTaskIds) => {
2552
+ void (async () => {
2553
+ try {
2554
+ await updateKanbanColumnOrder(teamName, columnId, orderedTaskIds);
2555
+ } catch {
2556
+ // error via store
2557
+ }
2558
+ })();
2559
+ }}
2560
+ onScrollToTask={(taskId) => {
2561
+ const el = document.querySelector(`[data-task-id="${taskId}"]`);
2562
+ if (el) {
2563
+ el.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
2564
+ el.classList.remove('kanban-card-focus-pulse');
2565
+ void (el as HTMLElement).offsetWidth;
2566
+ el.classList.add('kanban-card-focus-pulse');
2567
+ el.addEventListener(
2568
+ 'animationend',
2569
+ () => el.classList.remove('kanban-card-focus-pulse'),
2570
+ { once: true }
2571
+ );
2583
2572
  }
2584
- onDeleteTask={handleDeleteTask}
2585
- deletedTaskCount={deletedTasks.length}
2586
- onOpenTrash={() => setTrashOpen(true)}
2573
+ }}
2574
+ onTaskClick={(task) => {
2575
+ if (isScheduleBoardTaskId(task.id)) {
2576
+ return;
2577
+ }
2578
+ setSelectedTask(task);
2579
+ }}
2580
+ onViewChanges={handleViewChanges}
2581
+ onAddTask={(startImmediately) =>
2582
+ openCreateTaskDialog('', '', '', startImmediately)
2583
+ }
2584
+ onDeleteTask={handleDeleteTask}
2585
+ deletedTaskCount={deletedTasks.length}
2586
+ onOpenTrash={() => setTrashOpen(true)}
2587
2587
  />
2588
2588
  </div>
2589
2589
  </CollapsibleTeamSection>
@@ -2729,7 +2729,9 @@ export const TeamDetailView = ({
2729
2729
  currentColor={data.config.color ?? ''}
2730
2730
  currentAgentType={data.config.agentType ?? data.harness ?? 'cursor'}
2731
2731
  currentWorkDir={data.workDir ?? data.config.projectPath ?? ''}
2732
- currentPermissionMode={data.config.permissionMode ?? data.permissionMode ?? 'default'}
2732
+ currentPermissionMode={
2733
+ data.config.permissionMode ?? data.permissionMode ?? 'default'
2734
+ }
2733
2735
  currentLanguage={
2734
2736
  data.config.language ??
2735
2737
  (typeof rawTeamSettings.language === 'string' ? rawTeamSettings.language : 'zh')
@@ -75,9 +75,7 @@ export const TeamEmptyState = ({
75
75
  </Button>
76
76
 
77
77
  {!canCreate && (
78
- <p className="text-xs text-[var(--color-text-muted)]">
79
- 只有本地桌面模式支持创建团队。
80
- </p>
78
+ <p className="text-xs text-[var(--color-text-muted)]">只有本地桌面模式支持创建团队。</p>
81
79
  )}
82
80
  </div>
83
81
  );
@@ -85,18 +83,31 @@ export const TeamEmptyState = ({
85
83
 
86
84
  function getHarnessIcon(type: CcAgentType): string {
87
85
  switch (type) {
88
- case 'claudecode': return '🤖';
89
- case 'codex': return '🔬';
90
- case 'cursor': return '💻';
91
- case 'gemini': return '💎';
92
- case 'iflow': return '🌊';
93
- case 'kimi': return '🌙';
94
- case 'devin': return '🧑‍💻';
95
- case 'opencode': return '🔓';
96
- case 'qoder': return '⚡';
97
- case 'pi': return '🥧';
98
- case 'acp': return '🔗';
99
- case 'tmux': return '🖥️';
100
- default: return '📦';
86
+ case 'claudecode':
87
+ return '🤖';
88
+ case 'codex':
89
+ return '🔬';
90
+ case 'cursor':
91
+ return '💻';
92
+ case 'gemini':
93
+ return '💎';
94
+ case 'iflow':
95
+ return '🌊';
96
+ case 'kimi':
97
+ return '🌙';
98
+ case 'devin':
99
+ return '🧑‍💻';
100
+ case 'opencode':
101
+ return '🔓';
102
+ case 'qoder':
103
+ return '⚡';
104
+ case 'pi':
105
+ return '🥧';
106
+ case 'acp':
107
+ return '🔗';
108
+ case 'tmux':
109
+ return '🖥️';
110
+ default:
111
+ return '📦';
101
112
  }
102
113
  }
@@ -515,7 +515,8 @@ export const TeamListView = (): React.JSX.Element => {
515
515
  (teamName: string, isDraft: boolean, e: React.MouseEvent) => {
516
516
  e.stopPropagation();
517
517
  void (async () => {
518
- const teamDisplayName = teams.find((team) => team.teamName === teamName)?.displayName || teamName;
518
+ const teamDisplayName =
519
+ teams.find((team) => team.teamName === teamName)?.displayName || teamName;
519
520
  if (isDraft) {
520
521
  const confirmed = await confirm({
521
522
  title: '删除草稿',
@@ -566,7 +567,8 @@ export const TeamListView = (): React.JSX.Element => {
566
567
  (teamName: string, e: React.MouseEvent) => {
567
568
  e.stopPropagation();
568
569
  void (async () => {
569
- const teamDisplayName = teams.find((team) => team.teamName === teamName)?.displayName || teamName;
570
+ const teamDisplayName =
571
+ teams.find((team) => team.teamName === teamName)?.displayName || teamName;
570
572
  const confirmed = await confirm({
571
573
  title: '永久删除',
572
574
  message: `确定永久删除团队“${teamDisplayName}”吗?所有数据都将丢失。`,
@@ -211,7 +211,12 @@ const SessionSourceBadge = ({ message }: { message: InboxMessage }): React.JSX.E
211
211
  return null;
212
212
  }
213
213
  const label =
214
- session?.title || session?.chatName || session?.userName || session?.key || session?.platform || 'Session';
214
+ session?.title ||
215
+ session?.chatName ||
216
+ session?.userName ||
217
+ session?.key ||
218
+ session?.platform ||
219
+ 'Session';
215
220
  const platform = session?.platform ? `${session.platform} · ` : '';
216
221
  return (
217
222
  <span