@yancyyu/openhermit 1.6.38 → 1.6.40

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 (243) hide show
  1. package/dist-renderer/assets/ProjectEditorOverlay-CemDOX-3.js +58 -0
  2. package/dist-renderer/assets/{TeamGraphOverlay-ZEDfZyHb.js → TeamGraphOverlay-hPY770Db.js} +1 -1
  3. package/dist-renderer/assets/{_basePickBy-CIhniz70.js → _basePickBy-BHHrJT1i.js} +1 -1
  4. package/dist-renderer/assets/{_baseUniq-cKAW4Q8I.js → _baseUniq-CWErBtke.js} +1 -1
  5. package/dist-renderer/assets/{arc-YmNsoDXW.js → arc-C_o2_Uv8.js} +1 -1
  6. package/dist-renderer/assets/{architectureDiagram-VXUJARFQ-DHEls2sX.js → architectureDiagram-VXUJARFQ-DUW0LI3t.js} +1 -1
  7. package/dist-renderer/assets/{blockDiagram-VD42YOAC-Bpwf1Sbg.js → blockDiagram-VD42YOAC-CWbCE9hQ.js} +1 -1
  8. package/dist-renderer/assets/{c4Diagram-YG6GDRKO-B0IaQ4w5.js → c4Diagram-YG6GDRKO-BjLadrfV.js} +1 -1
  9. package/dist-renderer/assets/channel-DyP9YlCF.js +1 -0
  10. package/dist-renderer/assets/{chunk-4BX2VUAB-DLk-hcFc.js → chunk-4BX2VUAB-CPnvjZl9.js} +1 -1
  11. package/dist-renderer/assets/{chunk-55IACEB6-1XRmX_Zm.js → chunk-55IACEB6-OlL47yXQ.js} +1 -1
  12. package/dist-renderer/assets/{chunk-B4BG7PRW-1waH1DAD.js → chunk-B4BG7PRW-DTasjbm8.js} +1 -1
  13. package/dist-renderer/assets/{chunk-DI55MBZ5-BqpZBtrN.js → chunk-DI55MBZ5-C5_Xaqkk.js} +1 -1
  14. package/dist-renderer/assets/{chunk-FMBD7UC4-Bly7vVym.js → chunk-FMBD7UC4-NdoM4DMR.js} +1 -1
  15. package/dist-renderer/assets/{chunk-QN33PNHL-Ci2QWBAs.js → chunk-QN33PNHL-C8Fybejy.js} +1 -1
  16. package/dist-renderer/assets/{chunk-QZHKN3VN-YCqFW7d-.js → chunk-QZHKN3VN-E98TYFXJ.js} +1 -1
  17. package/dist-renderer/assets/{chunk-TZMSLE5B-B0xGXInl.js → chunk-TZMSLE5B-h4lFgkIq.js} +1 -1
  18. package/dist-renderer/assets/classDiagram-2ON5EDUG-BqffFTae.js +1 -0
  19. package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-BqffFTae.js +1 -0
  20. package/dist-renderer/assets/clone-MPcKWs2O.js +1 -0
  21. package/dist-renderer/assets/{cose-bilkent-S5V4N54A-DxcFNQKT.js → cose-bilkent-S5V4N54A-DtQ7fkrs.js} +1 -1
  22. package/dist-renderer/assets/{dagre-6UL2VRFP-DPo_RfZY.js → dagre-6UL2VRFP-CN-nL_z4.js} +1 -1
  23. package/dist-renderer/assets/{diagram-PSM6KHXK-U3hQsFe4.js → diagram-PSM6KHXK-DVJtqmm-.js} +1 -1
  24. package/dist-renderer/assets/{diagram-QEK2KX5R-OrwrAy0V.js → diagram-QEK2KX5R-DlxHxyXh.js} +1 -1
  25. package/dist-renderer/assets/{diagram-S2PKOQOG-CXATPWVw.js → diagram-S2PKOQOG-7dpzO6x6.js} +1 -1
  26. package/dist-renderer/assets/{erDiagram-Q2GNP2WA-B0e8AfMF.js → erDiagram-Q2GNP2WA-GP1TqsHi.js} +1 -1
  27. package/dist-renderer/assets/{flowDiagram-NV44I4VS-CXfzA4jJ.js → flowDiagram-NV44I4VS-C7ZLETuH.js} +1 -1
  28. package/dist-renderer/assets/{ganttDiagram-JELNMOA3-CMr08qVl.js → ganttDiagram-JELNMOA3-CvPB68dH.js} +1 -1
  29. package/dist-renderer/assets/{gitGraphDiagram-V2S2FVAM-vYFHpPmy.js → gitGraphDiagram-V2S2FVAM-B5yOm3w7.js} +1 -1
  30. package/dist-renderer/assets/{graph-DOe5j8dH.js → graph-smeyY1YZ.js} +1 -1
  31. package/dist-renderer/assets/{index-BySQS7AB.js → index-BJx8XvG1.js} +1 -1
  32. package/dist-renderer/assets/{index-C_okzZXP.js → index-CQaXUAua.js} +1 -1
  33. package/dist-renderer/assets/{index-VJ-MM9xa.js → index-CajRpxO2.js} +1 -1
  34. package/dist-renderer/assets/{index-V7dAKPqd.js → index-ChG4rE-E.js} +587 -705
  35. package/dist-renderer/assets/index-DUd0uw9C.css +32 -0
  36. package/dist-renderer/assets/{index-CzWxVCRL.js → index-IhmXZWqf.js} +1 -1
  37. package/dist-renderer/assets/{index-B2Dy7M2G.js → index-x_JkoDRH.js} +1 -1
  38. package/dist-renderer/assets/{infoDiagram-HS3SLOUP-D_WubR0B.js → infoDiagram-HS3SLOUP-D-hWRQGY.js} +1 -1
  39. package/dist-renderer/assets/{journeyDiagram-XKPGCS4Q-w9ca-1TI.js → journeyDiagram-XKPGCS4Q-Bb6W8rUG.js} +1 -1
  40. package/dist-renderer/assets/{kanban-definition-3W4ZIXB7-Jg9p6_pN.js → kanban-definition-3W4ZIXB7-CnHdUX0q.js} +1 -1
  41. package/dist-renderer/assets/{layout-B-z3y17c.js → layout-pqss_zkI.js} +1 -1
  42. package/dist-renderer/assets/{linear-D-RTX5UW.js → linear-B1mFITNh.js} +1 -1
  43. package/dist-renderer/assets/{mindmap-definition-VGOIOE7T-CDQmHOYP.js → mindmap-definition-VGOIOE7T-DTD9q7-D.js} +1 -1
  44. package/dist-renderer/assets/{pieDiagram-ADFJNKIX-D_odsQL7.js → pieDiagram-ADFJNKIX-Df3mhrn7.js} +1 -1
  45. package/dist-renderer/assets/{quadrantDiagram-AYHSOK5B-BRsmYWSA.js → quadrantDiagram-AYHSOK5B-B1FZ09vH.js} +1 -1
  46. package/dist-renderer/assets/{requirementDiagram-UZGBJVZJ-ChNE_BOV.js → requirementDiagram-UZGBJVZJ-aEO78thZ.js} +1 -1
  47. package/dist-renderer/assets/{sankeyDiagram-TZEHDZUN-C8FtpwKc.js → sankeyDiagram-TZEHDZUN-6Ui--jp-.js} +1 -1
  48. package/dist-renderer/assets/{sequenceDiagram-WL72ISMW-DmLCzNcc.js → sequenceDiagram-WL72ISMW-DF4Q1cAM.js} +1 -1
  49. package/dist-renderer/assets/splashScene-D0YB9uxm.js +17 -0
  50. package/dist-renderer/assets/{stateDiagram-FKZM4ZOC-WJBm4bhu.js → stateDiagram-FKZM4ZOC-BqA2BI8C.js} +1 -1
  51. package/dist-renderer/assets/stateDiagram-v2-4FDKWEC3-Cs2ZtUD2.js +1 -0
  52. package/dist-renderer/assets/{timeline-definition-IT6M3QCI-BXs_hOJs.js → timeline-definition-IT6M3QCI-DoOkw_A8.js} +1 -1
  53. package/dist-renderer/assets/{treemap-GDKQZRPO-o04MA0G9.js → treemap-GDKQZRPO-DUe26QdD.js} +1 -1
  54. package/dist-renderer/assets/{xychartDiagram-PRI3JC2R-Czj69XRd.js → xychartDiagram-PRI3JC2R-BKCnj5Xn.js} +1 -1
  55. package/dist-renderer/index.html +20 -53
  56. package/package.json +25 -18
  57. package/src/main/ipc/extensions.ts +2 -1
  58. package/src/main/server.ts +873 -221
  59. package/src/main/services/extensions/ExtensionFacadeService.ts +2 -5
  60. package/src/main/services/extensions/catalog/PluginCatalogService.ts +4 -2
  61. package/src/main/services/session-intelligence/ConversationTelemetryService.ts +1101 -0
  62. package/src/main/services/session-intelligence/LocalSessionScanner.ts +512 -0
  63. package/src/main/services/session-intelligence/SessionUsageParser.ts +4 -4
  64. package/src/main/services/system-manager/SystemManagerConfigService.ts +122 -0
  65. package/src/main/services/system-manager/SystemManagerPtyService.ts +233 -0
  66. package/src/main/services/system-manager/WorkflowPromptService.ts +75 -0
  67. package/src/main/services/teams-mvp/TaskDispatchService.ts +5 -6
  68. package/src/main/services/teams-mvp/TeamProvisioningService.ts +39 -2
  69. package/src/main/services/teams-mvp/TeamWorkspaceService.ts +22 -4
  70. package/src/main/utils/teamProjectResolution.ts +15 -0
  71. package/src/renderer/App.tsx +8 -4
  72. package/src/renderer/api/httpClient.ts +68 -18
  73. package/src/renderer/api/providers.ts +23 -2
  74. package/src/renderer/assets/participant-avatars/01.svg +3 -0
  75. package/src/renderer/assets/participant-avatars/02.svg +3 -0
  76. package/src/renderer/assets/participant-avatars/03.svg +3 -0
  77. package/src/renderer/assets/participant-avatars/04.svg +3 -0
  78. package/src/renderer/assets/participant-avatars/05.svg +3 -0
  79. package/src/renderer/assets/participant-avatars/06.svg +3 -0
  80. package/src/renderer/assets/participant-avatars/07.svg +3 -0
  81. package/src/renderer/assets/participant-avatars/08.svg +3 -0
  82. package/src/renderer/assets/participant-avatars/09.svg +3 -0
  83. package/src/renderer/assets/participant-avatars/10.svg +3 -0
  84. package/src/renderer/assets/participant-avatars/11.svg +3 -0
  85. package/src/renderer/assets/participant-avatars/12.svg +3 -0
  86. package/src/renderer/assets/participant-avatars/13.svg +3 -0
  87. package/src/renderer/components/chat/ChatHistoryItem.tsx +1 -1
  88. package/src/renderer/components/chat/items/SubagentItem.tsx +2 -2
  89. package/src/renderer/components/chat/viewers/MermaidDiagram.tsx +2 -2
  90. package/src/renderer/components/common/ErrorBoundary.tsx +1 -1
  91. package/src/renderer/components/common/TerminalPane.tsx +213 -0
  92. package/src/renderer/components/dashboard/CliStatusBanner.tsx +7 -7
  93. package/src/renderer/components/dashboard/DashboardView.tsx +9 -36
  94. package/src/renderer/components/extensions/ExtensionStoreView.tsx +7 -126
  95. package/src/renderer/components/extensions/ExtensionsSubTabTrigger.tsx +1 -1
  96. package/src/renderer/components/extensions/common/ExtensionToast.tsx +3 -3
  97. package/src/renderer/components/extensions/common/SourceBadge.tsx +1 -1
  98. package/src/renderer/components/extensions/mcp/McpLibraryEnableDialog.tsx +305 -0
  99. package/src/renderer/components/extensions/mcp/McpLibraryEntryDialog.tsx +418 -0
  100. package/src/renderer/components/extensions/mcp/McpLibraryPanel.tsx +404 -0
  101. package/src/renderer/components/extensions/plugins/CategoryChips.tsx +1 -1
  102. package/src/renderer/components/extensions/plugins/PluginCard.tsx +6 -6
  103. package/src/renderer/components/extensions/plugins/PluginDetailDialog.tsx +2 -2
  104. package/src/renderer/components/extensions/plugins/PluginsPanel.tsx +34 -21
  105. package/src/renderer/components/extensions/skills/SkillEditorDialog.tsx +1 -1
  106. package/src/renderer/components/extensions/skills/SkillsLibraryPanel.tsx +335 -0
  107. package/src/renderer/components/layout/PaneContent.tsx +8 -1
  108. package/src/renderer/components/layout/PaneResizeHandle.tsx +2 -2
  109. package/src/renderer/components/layout/Sidebar.tsx +13 -56
  110. package/src/renderer/components/layout/SortableTab.tsx +22 -33
  111. package/src/renderer/components/layout/TabBar.tsx +1 -1
  112. package/src/renderer/components/layout/TabContextMenu.tsx +1 -1
  113. package/src/renderer/components/report/sections/CostSection.tsx +2 -2
  114. package/src/renderer/components/report/sections/InsightsSection.tsx +1 -1
  115. package/src/renderer/components/runtime/ProviderRuntimeBackendSelector.tsx +2 -2
  116. package/src/renderer/components/runtime/ProviderRuntimeSettingsDialog.tsx +768 -157
  117. package/src/renderer/components/schedules/SchedulesView.tsx +51 -462
  118. package/src/renderer/components/schedules/calendar/CalendarDayView.tsx +173 -0
  119. package/src/renderer/components/schedules/calendar/CalendarEventBlock.tsx +113 -0
  120. package/src/renderer/components/schedules/calendar/CalendarHeader.tsx +148 -0
  121. package/src/renderer/components/schedules/calendar/CalendarMonthView.tsx +142 -0
  122. package/src/renderer/components/schedules/calendar/CalendarWeekView.tsx +219 -0
  123. package/src/renderer/components/schedules/calendar/ScheduleCalendarBoard.tsx +41 -0
  124. package/src/renderer/components/schedules/calendar/TeamGanttView.tsx +405 -0
  125. package/src/renderer/components/schedules/calendar/computeOccurrences.ts +234 -0
  126. package/src/renderer/components/schedules/calendar/index.ts +2 -0
  127. package/src/renderer/components/schedules/calendar/types.ts +44 -0
  128. package/src/renderer/components/search/CommandPalette.tsx +4 -4
  129. package/src/renderer/components/settings/SettingsTabs.tsx +50 -55
  130. package/src/renderer/components/settings/SettingsView.tsx +30 -35
  131. package/src/renderer/components/settings/components/SettingsSectionHeader.tsx +5 -1
  132. package/src/renderer/components/settings/components/SettingsSelect.tsx +5 -3
  133. package/src/renderer/components/settings/components/SettingsToggle.tsx +2 -2
  134. package/src/renderer/components/settings/sections/AdvancedSection.tsx +11 -42
  135. package/src/renderer/components/settings/sections/CliStatusSection.tsx +72 -113
  136. package/src/renderer/components/settings/sections/ConfigEditorDialog.tsx +1 -1
  137. package/src/renderer/components/settings/sections/GeneralSection.tsx +11 -3
  138. package/src/renderer/components/settings/sections/HarnessSection.tsx +18 -14
  139. package/src/renderer/components/settings/sections/PlatformsSection.tsx +3 -3
  140. package/src/renderer/components/settings/sections/TaskBusSection.tsx +33 -40
  141. package/src/renderer/components/settings/sections/index.ts +0 -1
  142. package/src/renderer/components/sidebar/SessionFiltersPopover.tsx +1 -1
  143. package/src/renderer/components/sidebar/SessionItem.tsx +3 -3
  144. package/src/renderer/components/sidebar/SidebarSessions.tsx +184 -6
  145. package/src/renderer/components/sidebar/SidebarTaskItem.tsx +4 -4
  146. package/src/renderer/components/sidebar/WorkspaceBrowser.tsx +40 -5
  147. package/src/renderer/components/splash/splashScene.ts +121 -929
  148. package/src/renderer/components/system-manager/FolderBrowser.tsx +163 -0
  149. package/src/renderer/components/system-manager/SystemManagerView.tsx +351 -0
  150. package/src/renderer/components/tasks/TasksView.tsx +112 -134
  151. package/src/renderer/components/team/CcSessionsSection.tsx +431 -89
  152. package/src/renderer/components/team/ClaudeLogsFilterPopover.tsx +1 -1
  153. package/src/renderer/components/team/ClaudeLogsPanel.tsx +1 -1
  154. package/src/renderer/components/team/CollapsibleTeamSection.tsx +17 -32
  155. package/src/renderer/components/team/ProcessesSection.tsx +2 -2
  156. package/src/renderer/components/team/TaskTooltip.tsx +2 -2
  157. package/src/renderer/components/team/TeamDetailView.tsx +319 -123
  158. package/src/renderer/components/team/TeamListFilterPopover.tsx +1 -1
  159. package/src/renderer/components/team/TeamListView.tsx +109 -124
  160. package/src/renderer/components/team/TeamSessionsSection.tsx +6 -6
  161. package/src/renderer/components/team/UnreadCommentsBadge.tsx +1 -1
  162. package/src/renderer/components/team/activity/ActivityItem.tsx +9 -9
  163. package/src/renderer/components/team/activity/ActivityTimeline.tsx +5 -5
  164. package/src/renderer/components/team/activity/LeadThoughtsGroup.tsx +3 -3
  165. package/src/renderer/components/team/activity/ReplyQuoteBlock.tsx +4 -4
  166. package/src/renderer/components/team/dialogs/CreateTaskDialog.tsx +4 -4
  167. package/src/renderer/components/team/dialogs/CreateTeamDialog.tsx +84 -306
  168. package/src/renderer/components/team/dialogs/EditTeamDialog.tsx +259 -342
  169. package/src/renderer/components/team/dialogs/GlobalTaskDetailDialog.tsx +1 -1
  170. package/src/renderer/components/team/dialogs/LaunchTeamDialog.tsx +18 -16
  171. package/src/renderer/components/team/dialogs/PlatformBindingDialog.tsx +221 -0
  172. package/src/renderer/components/team/dialogs/PlatformManualForm.tsx +8 -1
  173. package/src/renderer/components/team/dialogs/PlatformSetupQR.tsx +5 -5
  174. package/src/renderer/components/team/dialogs/RuntimeConfigDialog.tsx +361 -0
  175. package/src/renderer/components/team/dialogs/SendMessageDialog.tsx +6 -6
  176. package/src/renderer/components/team/dialogs/SkipPermissionsCheckbox.tsx +6 -6
  177. package/src/renderer/components/team/dialogs/StatusHistoryTimeline.tsx +1 -1
  178. package/src/renderer/components/team/dialogs/TaskAttachments.tsx +1 -1
  179. package/src/renderer/components/team/dialogs/TaskCommentInput.tsx +6 -6
  180. package/src/renderer/components/team/dialogs/TaskCommentsSection.tsx +4 -4
  181. package/src/renderer/components/team/dialogs/TaskDetailDialog.tsx +3 -3
  182. package/src/renderer/components/team/dialogs/platformMeta.ts +122 -11
  183. package/src/renderer/components/team/dialogs/useTeamEditForm.ts +17 -5
  184. package/src/renderer/components/team/editor/EditorFileTree.tsx +4 -4
  185. package/src/renderer/components/team/editor/EditorSearchPanel.tsx +1 -1
  186. package/src/renderer/components/team/editor/MarkdownSplitView.tsx +1 -1
  187. package/src/renderer/components/team/editor/NewFileDialog.tsx +1 -1
  188. package/src/renderer/components/team/editor/ProjectEditorOverlay.tsx +1 -1
  189. package/src/renderer/components/team/editor/SearchInFilesPanel.tsx +1 -1
  190. package/src/renderer/components/team/kanban/KanbanBoard.tsx +9 -9
  191. package/src/renderer/components/team/kanban/KanbanFilterPopover.tsx +4 -4
  192. package/src/renderer/components/team/kanban/KanbanSearchInput.tsx +1 -1
  193. package/src/renderer/components/team/kanban/KanbanSortPopover.tsx +5 -5
  194. package/src/renderer/components/team/kanban/KanbanTaskCard.tsx +4 -4
  195. package/src/renderer/components/team/members/MemberCard.tsx +14 -47
  196. package/src/renderer/components/team/members/MemberDetailDialog.tsx +3 -95
  197. package/src/renderer/components/team/members/MemberDetailStats.tsx +50 -65
  198. package/src/renderer/components/team/members/MemberDraftRow.tsx +1 -1
  199. package/src/renderer/components/team/members/MemberStatsTab.tsx +2 -2
  200. package/src/renderer/components/team/members/MemberWorkspaceTab.tsx +1 -1
  201. package/src/renderer/components/team/messages/MessageComposer.tsx +10 -112
  202. package/src/renderer/components/team/messages/MessagesFilterPopover.tsx +1 -1
  203. package/src/renderer/components/team/messages/MessagesPanel.tsx +136 -119
  204. package/src/renderer/components/team/review/ChangeReviewDialog.tsx +1 -1
  205. package/src/renderer/components/team/schedule/ScheduleStatusBadge.tsx +3 -3
  206. package/src/renderer/components/team/sidebar/TeamSidebarRail.tsx +4 -4
  207. package/src/renderer/components/team/tasks/TaskRow.tsx +1 -1
  208. package/src/renderer/components/team/tools/AddMcpInline.tsx +27 -17
  209. package/src/renderer/components/team/tools/McpChip.tsx +6 -3
  210. package/src/renderer/components/team/tools/SkillChip.tsx +3 -3
  211. package/src/renderer/components/team/tools/ToolsSection.tsx +418 -70
  212. package/src/renderer/components/ui/MemberSelect.tsx +2 -2
  213. package/src/renderer/components/ui/MentionSuggestionList.tsx +2 -2
  214. package/src/renderer/components/ui/MentionableTextarea.tsx +3 -3
  215. package/src/renderer/hooks/useExtensionsTabState.ts +3 -114
  216. package/src/renderer/index.css +56 -39
  217. package/src/renderer/index.html +17 -50
  218. package/src/renderer/store/index.ts +2 -1
  219. package/src/renderer/store/slices/scheduleSlice.ts +1 -1
  220. package/src/renderer/store/slices/teamSlice.ts +45 -168
  221. package/src/renderer/utils/claudeCodeOnlyProviders.ts +3 -10
  222. package/src/renderer/utils/memberHelpers.ts +5 -17
  223. package/src/renderer/utils/openCodeRuntimeDeliveryDiagnostics.ts +4 -2
  224. package/src/renderer/utils/providerSlashCommands.ts +0 -5
  225. package/src/renderer/utils/scheduleFormatters.ts +3 -1
  226. package/src/renderer/utils/teamMessageFiltering.ts +14 -1
  227. package/src/renderer/utils/teamModelAvailability.ts +18 -2
  228. package/src/shared/types/api.ts +121 -2
  229. package/src/shared/types/ccConnect.ts +2 -0
  230. package/src/shared/types/index.ts +3 -0
  231. package/src/shared/types/systemManager.ts +49 -0
  232. package/src/shared/types/team.ts +29 -0
  233. package/src/shared/types/terminal.ts +4 -2
  234. package/src/shared/utils/extensionNormalizers.ts +15 -8
  235. package/src/shared/utils/providerExtensionCapabilities.ts +2 -2
  236. package/dist-renderer/assets/ProjectEditorOverlay-lJZi-9Hp.js +0 -52
  237. package/dist-renderer/assets/channel-yIlSKy0e.js +0 -1
  238. package/dist-renderer/assets/classDiagram-2ON5EDUG-24fHez0s.js +0 -1
  239. package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-24fHez0s.js +0 -1
  240. package/dist-renderer/assets/clone-BTNuUva-.js +0 -1
  241. package/dist-renderer/assets/index-Bi6nrZ4z.css +0 -1
  242. package/dist-renderer/assets/splashScene-C8lWNnm4.js +0 -1
  243. package/dist-renderer/assets/stateDiagram-v2-4FDKWEC3-_m6iPPUR.js +0 -1
@@ -10,9 +10,9 @@ import {
10
10
  } from 'react';
11
11
  import { Sheet, type SheetRef } from 'react-modal-sheet';
12
12
 
13
- import { api } from '@renderer/api';
14
13
  import { Badge } from '@renderer/components/ui/badge';
15
14
  import { Button } from '@renderer/components/ui/button';
15
+ import { MemberBadge } from '@renderer/components/team/MemberBadge';
16
16
  import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip';
17
17
  import { useStableTeamMentionMeta } from '@renderer/hooks/useStableTeamMentionMeta';
18
18
  import { useTeamMessagesExpanded } from '@renderer/hooks/useTeamMessagesExpanded';
@@ -20,6 +20,7 @@ import { useTeamMessagesRead } from '@renderer/hooks/useTeamMessagesRead';
20
20
  import { useStore } from '@renderer/store';
21
21
  import { selectTeamMessages } from '@renderer/store/slices/teamSlice';
22
22
  import { filterTeamMessages } from '@renderer/utils/teamMessageFiltering';
23
+ import { cn } from '@renderer/lib/utils';
23
24
  import { toMessageKey } from '@renderer/utils/teamMessageKey';
24
25
  import { shouldExcludeInboxTextFromReplyCandidates } from '@shared/utils/idleNotificationSemantics';
25
26
  import {
@@ -56,7 +57,6 @@ import type { TeamMessagesPanelMode } from '@renderer/types/teamMessagesPanelMod
56
57
  import type {
57
58
  AgentActionMode,
58
59
  CcSession,
59
- CcSessionDetail,
60
60
  InboxMessage,
61
61
  ResolvedTeamMember,
62
62
  TaskRef,
@@ -93,6 +93,8 @@ interface MessagesPanelProps {
93
93
  timeWindow: TimeWindow | null;
94
94
  /** Current lead session ID. */
95
95
  currentLeadSessionId?: string;
96
+ /** cc-connect sessions owned by the parent team detail view. */
97
+ sessions?: CcSession[];
96
98
  /** Pending replies tracker (shared with parent for MemberList). */
97
99
  pendingRepliesByMember: Record<string, number>;
98
100
  /** Update pending replies tracker. */
@@ -186,6 +188,7 @@ export const MessagesPanel = memo(function MessagesPanel({
186
188
  leadContextUpdatedAt,
187
189
  timeWindow,
188
190
  currentLeadSessionId,
191
+ sessions = [],
189
192
  pendingRepliesByMember,
190
193
  onPendingReplyChange,
191
194
  onMemberClick,
@@ -334,10 +337,8 @@ export const MessagesPanel = memo(function MessagesPanel({
334
337
  const [expandedItemKey, setExpandedItemKey] = useState<string | null>(
335
338
  initialSidebarStateRef.current.expandedItemKey
336
339
  );
337
- const [teamSessions, setTeamSessions] = useState<CcSession[]>([]);
338
- const [selectedSessionDetail, setSelectedSessionDetail] = useState<CcSessionDetail | null>(null);
339
- const [selectedSessionDetailLoading, setSelectedSessionDetailLoading] = useState(false);
340
340
  const [selectedSessionKey, setSelectedSessionKey] = useState<string | null>(null);
341
+ const [quickParticipantFilter, setQuickParticipantFilter] = useState<string | null>(null);
341
342
  const [messagesScrollTop, setMessagesScrollTop] = useState(
342
343
  initialSidebarStateRef.current.messagesScrollTop
343
344
  );
@@ -355,70 +356,25 @@ export const MessagesPanel = memo(function MessagesPanel({
355
356
  setMessagesCollapsed(initialSidebarStateRef.current.messagesCollapsed);
356
357
  setMessagesSearchBarVisible(initialSidebarStateRef.current.messagesSearchBarVisible);
357
358
  setExpandedItemKey(initialSidebarStateRef.current.expandedItemKey);
359
+ setSelectedSessionKey(null);
360
+ setQuickParticipantFilter(null);
358
361
  setMessagesScrollTop(initialSidebarStateRef.current.messagesScrollTop);
359
362
  setBottomSheetSnapIndex(initialSidebarStateRef.current.bottomSheetSnapIndex);
360
363
  }, [teamName]);
361
364
 
362
- useEffect(() => {
363
- let cancelled = false;
364
- void api.teams
365
- .getTeamSessions(teamName)
366
- .then((sessions) => {
367
- if (cancelled) return;
368
- const sortedSessions = [...sessions].sort(
369
- (a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
370
- );
371
- setTeamSessions(sortedSessions);
372
- setSelectedSessionKey((current) => {
373
- if (current && sortedSessions.some((session) => session.sessionKey === current))
374
- return current;
375
- return sortedSessions[0]?.sessionKey ?? null;
376
- });
377
- })
378
- .catch(() => {
379
- if (!cancelled) {
380
- setTeamSessions([]);
381
- setSelectedSessionKey(null);
382
- }
383
- });
384
- return () => {
385
- cancelled = true;
386
- };
387
- // Refetch when the lead session id changes (e.g. a new session is spawned)
388
- // so the session list/selector reflects the updated id without a remount.
389
- }, [teamName, currentLeadSessionId]);
390
-
391
- const selectedSession = useMemo(
392
- () => teamSessions.find((session) => session.sessionKey === selectedSessionKey) ?? null,
393
- [selectedSessionKey, teamSessions]
365
+ const teamSessions = useMemo(
366
+ () =>
367
+ [...sessions].sort(
368
+ (a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
369
+ ),
370
+ [sessions]
394
371
  );
395
- const selectedIsHermitLocalSession =
396
- selectedSession?.platform === 'hermit' ||
397
- selectedSession?.sessionKey === `hermit:${teamName}:session`;
398
372
 
399
373
  useEffect(() => {
400
- if (!selectedSession || selectedIsHermitLocalSession) {
401
- setSelectedSessionDetail(null);
402
- setSelectedSessionDetailLoading(false);
403
- return;
404
- }
405
- let cancelled = false;
406
- setSelectedSessionDetailLoading(true);
407
- void api.teams
408
- .getSessionDetail(teamName, selectedSession.id, 200)
409
- .then((detail) => {
410
- if (!cancelled) setSelectedSessionDetail(detail);
411
- })
412
- .catch(() => {
413
- if (!cancelled) setSelectedSessionDetail(null);
414
- })
415
- .finally(() => {
416
- if (!cancelled) setSelectedSessionDetailLoading(false);
417
- });
418
- return () => {
419
- cancelled = true;
420
- };
421
- }, [selectedIsHermitLocalSession, selectedSession, teamName]);
374
+ setSelectedSessionKey((current) =>
375
+ current && teamSessions.some((session) => session.sessionKey === current) ? current : null
376
+ );
377
+ }, [teamSessions]);
422
378
 
423
379
  useEffect(() => {
424
380
  setTeamMessagesSidebarUiState(teamName, {
@@ -541,64 +497,127 @@ export const MessagesPanel = memo(function MessagesPanel({
541
497
  const newestFirst = (items: InboxMessage[]) =>
542
498
  [...items].sort((a, b) => Date.parse(b.timestamp) - Date.parse(a.timestamp));
543
499
  if (!selectedSessionKey) return newestFirst(effectiveMessages);
544
- if (selectedSession && !selectedIsHermitLocalSession) {
545
- if (!selectedSessionDetail) {
546
- return [];
547
- }
548
- return [...selectedSessionDetail.history].reverse().map(
549
- (entry, index): InboxMessage => ({
550
- messageId: `${selectedSessionDetail.id}:${index}:${entry.timestamp}`,
551
- from: entry.role === 'user' ? 'user' : selectedSessionDetail.name || teamName,
552
- to: entry.role === 'user' ? selectedSessionDetail.name || teamName : 'user',
553
- text: entry.content,
554
- timestamp: entry.timestamp,
555
- read: true,
556
- source: entry.role === 'user' ? 'user_sent' : 'inbox',
557
- session: {
558
- id: selectedSessionDetail.id,
559
- key: selectedSessionDetail.sessionKey,
560
- platform: selectedSessionDetail.platform,
561
- title:
562
- selectedSession.title ||
563
- selectedSession.chatName ||
564
- selectedSession.userName ||
565
- selectedSession.sessionKey,
566
- chatName: selectedSession.chatName,
567
- userName: selectedSession.userName,
568
- },
569
- })
570
- );
571
- }
572
500
  return newestFirst(
573
- effectiveMessages.filter((message) => {
574
- return message.session?.key === selectedSessionKey;
575
- })
501
+ effectiveMessages.filter((message) => message.session?.key === selectedSessionKey)
576
502
  );
577
- }, [
578
- effectiveMessages,
579
- selectedIsHermitLocalSession,
580
- selectedSession,
581
- selectedSessionDetail,
582
- selectedSessionKey,
583
- teamName,
584
- ]);
503
+ }, [effectiveMessages, selectedSessionKey]);
504
+
505
+ const participantOptions = useMemo(() => {
506
+ const senderNames = new Set<string>();
507
+ for (const message of sessionScopedMessages) {
508
+ const sender = message.from?.trim();
509
+ if (sender) senderNames.add(sender);
510
+ }
511
+
512
+ const seen = new Set<string>();
513
+ const orderedSenders: string[] = [];
514
+ const addSender = (value: string | null | undefined) => {
515
+ const trimmed = value?.trim();
516
+ if (!trimmed || seen.has(trimmed) || !senderNames.has(trimmed)) return;
517
+ seen.add(trimmed);
518
+ orderedSenders.push(trimmed);
519
+ };
520
+
521
+ addSender('user');
522
+ for (const member of members) addSender(member.name);
523
+ for (const message of sessionScopedMessages) addSender(message.from);
524
+
525
+ return orderedSenders.slice(0, 24);
526
+ }, [members, sessionScopedMessages]);
527
+
528
+ useEffect(() => {
529
+ if (quickParticipantFilter && !participantOptions.includes(quickParticipantFilter)) {
530
+ setQuickParticipantFilter(null);
531
+ }
532
+ }, [participantOptions, quickParticipantFilter]);
533
+
534
+ const matchesParticipant = useCallback((message: InboxMessage, participant: string): boolean => {
535
+ return message.from?.trim() === participant;
536
+ }, []);
585
537
 
586
538
  const filteredMessages = useMemo(() => {
587
- return filterTeamMessages(sessionScopedMessages, {
539
+ const participantFiltered = quickParticipantFilter
540
+ ? sessionScopedMessages.filter((message) =>
541
+ matchesParticipant(message, quickParticipantFilter)
542
+ )
543
+ : sessionScopedMessages;
544
+ return filterTeamMessages(participantFiltered, {
588
545
  timeWindow,
589
546
  filter: messagesFilter,
590
547
  searchQuery: messagesSearchQuery,
591
548
  });
592
- }, [messagesFilter, messagesSearchQuery, sessionScopedMessages, timeWindow]);
549
+ }, [
550
+ matchesParticipant,
551
+ messagesFilter,
552
+ messagesSearchQuery,
553
+ quickParticipantFilter,
554
+ sessionScopedMessages,
555
+ timeWindow,
556
+ ]);
557
+
558
+ const setParticipantFilter = useCallback((name: string | null) => {
559
+ setQuickParticipantFilter(name);
560
+ }, []);
561
+
562
+ const participantFilterBar = (
563
+ <div className="flex items-center gap-1 overflow-x-auto pb-1 text-[11px]">
564
+ <button
565
+ type="button"
566
+ className={cn(
567
+ 'shrink-0 rounded-full border px-2 py-0.5 transition-colors',
568
+ quickParticipantFilter === null
569
+ ? 'border-indigo-500/40 bg-indigo-500/10 text-indigo-500'
570
+ : 'border-[var(--color-border)] text-[var(--color-text-muted)] hover:text-[var(--color-text)]'
571
+ )}
572
+ onClick={() => setParticipantFilter(null)}
573
+ >
574
+ 全部成员
575
+ </button>
576
+ {participantOptions.map((participant) => (
577
+ <button
578
+ key={participant}
579
+ type="button"
580
+ className={cn(
581
+ 'shrink-0 rounded-full border px-2 py-0.5 transition-colors',
582
+ quickParticipantFilter === participant
583
+ ? 'border-indigo-500/40 bg-indigo-500/10 text-indigo-500'
584
+ : 'border-[var(--color-border)] text-[var(--color-text-muted)] hover:text-[var(--color-text)]'
585
+ )}
586
+ onClick={() =>
587
+ setParticipantFilter(quickParticipantFilter === participant ? null : participant)
588
+ }
589
+ >
590
+ <MemberBadge
591
+ name={participant === 'user' ? '用户' : participant}
592
+ size="sm"
593
+ hideAvatar
594
+ disableHoverCard
595
+ />
596
+ </button>
597
+ ))}
598
+ </div>
599
+ );
593
600
 
594
601
  const activityTimelineMessages = useMemo(() => {
595
- return filterTeamMessages(sessionScopedMessages, {
602
+ const participantFiltered = quickParticipantFilter
603
+ ? sessionScopedMessages.filter((message) =>
604
+ matchesParticipant(message, quickParticipantFilter)
605
+ )
606
+ : sessionScopedMessages;
607
+ return filterTeamMessages(participantFiltered, {
596
608
  includePassiveIdlePeerSummariesWhenNoiseHidden: true,
597
609
  timeWindow,
598
610
  filter: messagesFilter,
599
611
  searchQuery: messagesSearchQuery,
600
612
  });
601
- }, [messagesFilter, messagesSearchQuery, sessionScopedMessages, timeWindow]);
613
+ }, [
614
+ matchesParticipant,
615
+ messagesFilter,
616
+ messagesSearchQuery,
617
+ quickParticipantFilter,
618
+ sessionScopedMessages,
619
+ timeWindow,
620
+ ]);
602
621
 
603
622
  const replyCandidateMessages = useMemo(
604
623
  () =>
@@ -773,6 +792,10 @@ export const MessagesPanel = memo(function MessagesPanel({
773
792
  toTeam,
774
793
  text: description,
775
794
  messageId: optimisticMessageId,
795
+ sessionKey:
796
+ selectedSessionKey && selectedSessionKey !== '__unassigned__'
797
+ ? selectedSessionKey
798
+ : undefined,
776
799
  });
777
800
  } catch (error) {
778
801
  const rawMessage = error instanceof Error ? error.message : '跨团队任务派发失败';
@@ -935,13 +958,11 @@ export const MessagesPanel = memo(function MessagesPanel({
935
958
  sendWarning={sendMessageWarning}
936
959
  sendDebugDetails={sendMessageDebugDetails}
937
960
  lastResult={lastSendMessageResult}
938
- sessions={teamSessions}
939
- selectedSessionKey={selectedSessionKey}
940
- onSessionChange={setSelectedSessionKey}
941
961
  textareaRef={composerTextareaRef}
942
962
  onSend={handleSend}
943
963
  onDispatchTask={handleDispatchTaskToTeam}
944
964
  />
965
+ {participantFilterBar}
945
966
  <StatusBlock
946
967
  members={members}
947
968
  tasks={tasks}
@@ -1035,7 +1056,7 @@ export const MessagesPanel = memo(function MessagesPanel({
1035
1056
  <TooltipTrigger asChild>
1036
1057
  <Badge
1037
1058
  variant="secondary"
1038
- className="bg-blue-500/20 px-1.5 py-0.5 text-[10px] font-normal leading-none text-blue-600 dark:text-blue-400"
1059
+ className="bg-indigo-500/20 px-1.5 py-0.5 text-[10px] font-normal leading-none text-indigo-600 dark:text-indigo-400"
1039
1060
  >
1040
1061
  {messagesUnreadCount} 条新消息
1041
1062
  </Badge>
@@ -1048,7 +1069,7 @@ export const MessagesPanel = memo(function MessagesPanel({
1048
1069
  <TooltipTrigger asChild>
1049
1070
  <button
1050
1071
  type="button"
1051
- className="flex items-center gap-1 rounded-md px-1.5 py-1 text-[11px] text-blue-400 transition-colors hover:bg-blue-500/10"
1072
+ className="flex items-center gap-1 rounded-md px-1.5 py-1 text-[11px] text-indigo-400 transition-colors hover:bg-indigo-500/10"
1052
1073
  onClick={handleMarkAllRead}
1053
1074
  >
1054
1075
  <CheckCheck size={12} />
@@ -1132,13 +1153,11 @@ export const MessagesPanel = memo(function MessagesPanel({
1132
1153
  sendWarning={sendMessageWarning}
1133
1154
  sendDebugDetails={sendMessageDebugDetails}
1134
1155
  lastResult={lastSendMessageResult}
1135
- sessions={teamSessions}
1136
- selectedSessionKey={selectedSessionKey}
1137
- onSessionChange={setSelectedSessionKey}
1138
1156
  textareaRef={composerTextareaRef}
1139
1157
  onSend={handleSend}
1140
1158
  onDispatchTask={handleDispatchTaskToTeam}
1141
1159
  />
1160
+ {participantFilterBar}
1142
1161
  <StatusBlock
1143
1162
  members={members}
1144
1163
  tasks={tasks}
@@ -1272,7 +1291,7 @@ export const MessagesPanel = memo(function MessagesPanel({
1272
1291
  <TooltipTrigger asChild>
1273
1292
  <Badge
1274
1293
  variant="secondary"
1275
- className="bg-blue-500/20 px-1 py-0 text-[9px] font-normal leading-none text-blue-600 dark:text-blue-400"
1294
+ className="bg-indigo-500/20 px-1 py-0 text-[9px] font-normal leading-none text-indigo-600 dark:text-indigo-400"
1276
1295
  >
1277
1296
  {messagesUnreadCount} 条新消息
1278
1297
  </Badge>
@@ -1290,7 +1309,7 @@ export const MessagesPanel = memo(function MessagesPanel({
1290
1309
  <Button
1291
1310
  variant="ghost"
1292
1311
  size="sm"
1293
- className="size-[22px] p-0 text-blue-400 hover:bg-blue-500/10 hover:text-blue-300"
1312
+ className="size-[22px] p-0 text-indigo-400 hover:bg-indigo-500/10 hover:text-indigo-300"
1294
1313
  onClick={handleMarkAllRead}
1295
1314
  aria-label="将全部消息标为已读"
1296
1315
  >
@@ -1420,13 +1439,11 @@ export const MessagesPanel = memo(function MessagesPanel({
1420
1439
  sendWarning={sendMessageWarning}
1421
1440
  sendDebugDetails={sendMessageDebugDetails}
1422
1441
  lastResult={lastSendMessageResult}
1423
- sessions={teamSessions}
1424
- selectedSessionKey={selectedSessionKey}
1425
- onSessionChange={setSelectedSessionKey}
1426
1442
  textareaRef={composerTextareaRef}
1427
1443
  onSend={handleSend}
1428
1444
  onDispatchTask={handleDispatchTaskToTeam}
1429
1445
  />
1446
+ {participantFilterBar}
1430
1447
  </div>
1431
1448
  </div>
1432
1449
  <div className="shrink-0 px-3 pt-2">
@@ -1525,7 +1542,7 @@ export const MessagesPanel = memo(function MessagesPanel({
1525
1542
  <TooltipTrigger asChild>
1526
1543
  <button
1527
1544
  type="button"
1528
- className="pointer-events-auto flex items-center gap-1 rounded-md px-1.5 py-1 text-[11px] text-blue-400 transition-colors hover:bg-blue-500/10"
1545
+ className="pointer-events-auto flex items-center gap-1 rounded-md px-1.5 py-1 text-[11px] text-indigo-400 transition-colors hover:bg-indigo-500/10"
1529
1546
  onClick={(e) => {
1530
1547
  e.stopPropagation();
1531
1548
  handleMarkAllRead();
@@ -106,7 +106,7 @@ export const ChangeReviewDialog: React.FC<ChangeReviewDialogProps> = ({
106
106
  ? 'flex items-center gap-2 rounded-md bg-emerald-500/5 px-3 py-2 font-mono text-xs text-emerald-400'
107
107
  : status === 'deleted'
108
108
  ? 'flex items-center gap-2 rounded-md bg-red-500/5 px-3 py-2 font-mono text-xs text-red-400'
109
- : 'flex items-center gap-2 rounded-md bg-blue-500/5 px-3 py-2 font-mono text-xs text-blue-400'
109
+ : 'flex items-center gap-2 rounded-md bg-indigo-500/5 px-3 py-2 font-mono text-xs text-indigo-400'
110
110
  }
111
111
  >
112
112
  <span className="w-12 shrink-0 text-center font-sans text-[10px] uppercase tracking-wide opacity-60">
@@ -20,7 +20,7 @@ interface ScheduleStatusBadgeProps {
20
20
  }
21
21
 
22
22
  export const ScheduleStatusBadge = ({ status }: ScheduleStatusBadgeProps): React.JSX.Element => {
23
- const config = SCHEDULE_STATUS_CONFIG[status];
23
+ const config = SCHEDULE_STATUS_CONFIG[status] ?? { label: status, className: 'bg-zinc-500/15 text-zinc-400 border-zinc-500/20' };
24
24
  return (
25
25
  <span
26
26
  className={`inline-flex items-center rounded-full border px-1.5 py-0.5 text-[10px] font-medium ${config.className}`}
@@ -36,7 +36,7 @@ export const ScheduleStatusBadge = ({ status }: ScheduleStatusBadgeProps): React
36
36
 
37
37
  const RUN_STATUS_CONFIG: Record<ScheduleRunStatus, { label: string; className: string }> = {
38
38
  pending: { label: '等待中', className: 'text-zinc-400' },
39
- warming_up: { label: '预热中', className: 'text-blue-400' },
39
+ warming_up: { label: '预热中', className: 'text-indigo-400' },
40
40
  warm: { label: '已预热', className: 'text-cyan-400' },
41
41
  running: { label: '运行中', className: 'text-emerald-400' },
42
42
  completed: { label: '已完成', className: 'text-emerald-400' },
@@ -50,6 +50,6 @@ interface RunStatusBadgeProps {
50
50
  }
51
51
 
52
52
  export const RunStatusBadge = ({ status }: RunStatusBadgeProps): React.JSX.Element => {
53
- const config = RUN_STATUS_CONFIG[status];
53
+ const config = RUN_STATUS_CONFIG[status] ?? { label: status, className: 'text-zinc-400' };
54
54
  return <span className={`text-[10px] font-medium ${config.className}`}>{config.label}</span>;
55
55
  };
@@ -30,14 +30,14 @@ export const TeamSidebarRail = memo(function TeamSidebarRail({
30
30
  const [logsOpen, setLogsOpen] = useState(false);
31
31
  const logsSeparator = logsOpen ? (
32
32
  <div
33
- className={`group relative h-3 shrink-0 cursor-row-resize ${isLogsResizing ? 'bg-blue-500/10' : ''}`}
33
+ className={`group relative h-3 shrink-0 cursor-row-resize ${isLogsResizing ? 'bg-indigo-500/10' : ''}`}
34
34
  onMouseDown={onLogsResizeMouseDown}
35
35
  >
36
36
  <div
37
37
  className={`absolute inset-x-0 top-1/2 h-0.5 -translate-y-1/2 transition-colors ${
38
38
  isLogsResizing
39
- ? 'bg-blue-500'
40
- : 'bg-[var(--color-text-muted)]/35 group-hover:bg-blue-500/90'
39
+ ? 'bg-indigo-500'
40
+ : 'bg-[var(--color-text-muted)]/35 group-hover:bg-indigo-500/90'
41
41
  }`}
42
42
  />
43
43
  </div>
@@ -60,7 +60,7 @@ export const TeamSidebarRail = memo(function TeamSidebarRail({
60
60
  <MessagesPanel position="sidebar" {...messagesPanelProps} />
61
61
  </div>
62
62
  <div
63
- className={`absolute inset-y-0 right-0 z-20 w-1 cursor-col-resize transition-colors hover:bg-blue-500/30 ${isResizing ? 'bg-blue-500/40' : ''}`}
63
+ className={`absolute inset-y-0 right-0 z-20 w-1 cursor-col-resize transition-colors hover:bg-indigo-500/30 ${isResizing ? 'bg-indigo-500/40' : ''}`}
64
64
  onMouseDown={onResizeMouseDown}
65
65
  />
66
66
  </div>
@@ -53,7 +53,7 @@ export const TaskRow = ({ task }: TaskRowProps): React.JSX.Element => {
53
53
  </td>
54
54
  <td className="px-3 py-2 text-xs">
55
55
  {blocksIds.length > 0 ? (
56
- <span className="text-blue-600 dark:text-blue-400">
56
+ <span className="text-indigo-600 dark:text-indigo-400">
57
57
  {blocksIds.map((id) => `#${deriveTaskDisplayId(id)}`).join(', ')}
58
58
  </span>
59
59
  ) : (
@@ -1,46 +1,56 @@
1
1
  /**
2
- * AddMcpInline — opens CustomMcpServerDialog for adding a custom MCP server.
3
- * Refreshes parent list when dialog closes (install may have occurred).
2
+ * AddMcpInline — creates a reusable global MCP template from a team context.
4
3
  */
5
4
 
6
5
  import { useState } from 'react';
7
6
 
8
7
  import { Button } from '@renderer/components/ui/button';
9
- import { CustomMcpServerDialog } from '@renderer/components/extensions/mcp/CustomMcpServerDialog';
8
+ import { McpLibraryEntryDialog } from '@renderer/components/extensions/mcp/McpLibraryEntryDialog';
9
+
10
+ import type { McpLibraryEntry } from '@shared/types/extensions';
10
11
 
11
12
  interface AddMcpInlineProps {
12
- projectPath: string | null;
13
- harnessType: string;
14
- onAdded: () => void;
13
+ onAdded: (entry: McpLibraryEntry) => void;
15
14
  onCancel: () => void;
16
15
  }
17
16
 
18
- export const AddMcpInline = ({
19
- onAdded,
20
- onCancel,
21
- }: AddMcpInlineProps): React.JSX.Element => {
17
+ export const AddMcpInline = ({ onAdded, onCancel }: AddMcpInlineProps): React.JSX.Element => {
22
18
  const [dialogOpen, setDialogOpen] = useState(true);
23
19
 
24
- const handleClose = () => {
20
+ const handleSaved = (entry: McpLibraryEntry): void => {
21
+ setDialogOpen(false);
22
+ onAdded(entry);
23
+ };
24
+
25
+ const handleClose = (): void => {
25
26
  setDialogOpen(false);
26
- // Always refresh when dialog closes — install may have happened
27
- onAdded();
27
+ onCancel();
28
28
  };
29
29
 
30
30
  return (
31
31
  <>
32
- <div className="flex items-center gap-2">
33
- <Button variant="outline" size="sm" className="h-7 gap-1 text-xs" onClick={() => setDialogOpen(true)}>
34
- 添加自定义 MCP
32
+ <div className="flex items-center gap-2 rounded-md border border-dashed border-[var(--color-border)] px-2 py-2">
33
+ <div className="min-w-0 flex-1 text-xs text-[var(--color-text-muted)]">
34
+ 先保存一个全局模板,随后可为当前项目填写独立实例名和参数。
35
+ </div>
36
+ <Button
37
+ variant="outline"
38
+ size="sm"
39
+ className="h-7 gap-1 text-xs"
40
+ onClick={() => setDialogOpen(true)}
41
+ >
42
+ 添加模板
35
43
  </Button>
36
44
  <Button variant="ghost" size="sm" onClick={onCancel} className="h-7 text-xs">
37
45
  取消
38
46
  </Button>
39
47
  </div>
40
48
 
41
- <CustomMcpServerDialog
49
+ <McpLibraryEntryDialog
42
50
  open={dialogOpen}
51
+ entry={null}
43
52
  onClose={handleClose}
53
+ onSaved={handleSaved}
44
54
  />
45
55
  </>
46
56
  );
@@ -26,14 +26,17 @@ export const McpChip = ({ entry, diagnostic, onRemove }: McpChipProps): React.JS
26
26
 
27
27
  return (
28
28
  <div className="group inline-flex items-center gap-1.5 rounded-full bg-[var(--color-bg-secondary)] px-2.5 py-1 text-xs transition-colors hover:bg-[var(--color-bg-secondary-hover)]">
29
- <span className={`size-2 shrink-0 rounded-full ${statusColor}`} title={diagnostic?.status ?? 'unknown'} />
29
+ <span
30
+ className={`size-2 shrink-0 rounded-full ${statusColor}`}
31
+ title={diagnostic?.status ?? 'unknown'}
32
+ />
30
33
  <span className="max-w-[120px] truncate text-[var(--color-text)]">{entry.name}</span>
31
34
  <button
32
35
  type="button"
33
36
  className="shrink-0 rounded-full p-0.5 opacity-0 transition-opacity hover:bg-red-500/20 group-hover:opacity-100"
34
37
  onClick={() => onRemove(entry)}
35
- aria-label={`删除 ${entry.name}`}
36
- title="点击删除"
38
+ aria-label={`从当前项目移除 MCP 实例 ${entry.name}`}
39
+ title="移除项目实例"
37
40
  >
38
41
  <X size={10} className="text-[var(--color-text-muted)] hover:text-red-400" />
39
42
  </button>
@@ -17,7 +17,7 @@ export const SkillChip = ({ skill, onRemove }: SkillChipProps): React.JSX.Elemen
17
17
  <div className="group inline-flex items-center gap-1.5 rounded-full bg-[var(--color-bg-secondary)] px-2.5 py-1 text-xs transition-colors hover:bg-[var(--color-bg-secondary-hover)]">
18
18
  <span className="max-w-[120px] truncate text-[var(--color-text)]">{skill.name}</span>
19
19
  {skill.scope && (
20
- <span className="rounded bg-blue-500/20 px-1 py-0.5 text-[10px] text-blue-400">
20
+ <span className="rounded bg-indigo-500/20 px-1 py-0.5 text-[10px] text-indigo-400">
21
21
  {skill.scope === 'project' ? '项目' : '用户'}
22
22
  </span>
23
23
  )}
@@ -25,8 +25,8 @@ export const SkillChip = ({ skill, onRemove }: SkillChipProps): React.JSX.Elemen
25
25
  type="button"
26
26
  className="shrink-0 rounded-full p-0.5 opacity-0 transition-opacity hover:bg-red-500/20 group-hover:opacity-100"
27
27
  onClick={() => onRemove(skill)}
28
- aria-label={`删除 ${skill.name}`}
29
- title="点击删除"
28
+ aria-label={`从当前团队禁用 ${skill.name}`}
29
+ title="从当前团队禁用"
30
30
  >
31
31
  <X size={10} className="text-[var(--color-text-muted)] hover:text-red-400" />
32
32
  </button>