@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
@@ -0,0 +1,335 @@
1
+ /**
2
+ * SkillsLibraryPanel — global user skills library management.
3
+ */
4
+
5
+ import { useCallback, useEffect, useMemo, useState } from 'react';
6
+
7
+ import { api } from '@renderer/api';
8
+ import { confirm } from '@renderer/components/common/ConfirmDialog';
9
+ import { Badge } from '@renderer/components/ui/badge';
10
+ import { Button } from '@renderer/components/ui/button';
11
+ import { useStore } from '@renderer/store';
12
+ import { formatSkillRootKind, getSkillAudienceLabel } from '@shared/utils/skillRoots';
13
+ import { AlertCircle, Edit, FileText, Plus, RefreshCw, Trash2 } from 'lucide-react';
14
+
15
+ import { SearchInput } from '../common/SearchInput';
16
+
17
+ import { SkillEditorDialog } from './SkillEditorDialog';
18
+
19
+ import type { SkillCatalogItem, SkillDetail } from '@shared/types/extensions';
20
+
21
+ interface SkillsLibraryPanelProps {
22
+ projectPath: string | null;
23
+ projectLabel: string | null;
24
+ }
25
+
26
+ type EditorState =
27
+ | { mode: 'create'; detail: null }
28
+ | { mode: 'edit'; detail: SkillDetail | null; skillId: string };
29
+
30
+ function formatScope(scope: SkillCatalogItem['scope']): string {
31
+ return scope === 'project' ? '项目' : '个人';
32
+ }
33
+
34
+ function formatInvocationMode(mode: SkillCatalogItem['invocationMode']): string {
35
+ return mode === 'manual-only' ? '手动调用' : '自动触发';
36
+ }
37
+
38
+ function matchesSearch(skill: SkillCatalogItem, query: string): boolean {
39
+ const normalizedQuery = query.trim().toLowerCase();
40
+ if (!normalizedQuery) return true;
41
+
42
+ return [skill.name, skill.description, skill.folderName, skill.rootKind, skill.scope]
43
+ .filter(Boolean)
44
+ .some((value) => value.toLowerCase().includes(normalizedQuery));
45
+ }
46
+
47
+ interface SkillLibraryCardProps {
48
+ skill: SkillCatalogItem;
49
+ isLoadingDetail: boolean;
50
+ isDeleting: boolean;
51
+ onEdit: (skill: SkillCatalogItem) => void;
52
+ onDelete: (skill: SkillCatalogItem) => void;
53
+ }
54
+
55
+ const SkillLibraryCard = ({
56
+ skill,
57
+ isLoadingDetail,
58
+ isDeleting,
59
+ onEdit,
60
+ onDelete,
61
+ }: SkillLibraryCardProps): React.JSX.Element => {
62
+ const statusBadge = skill.isValid ? (
63
+ <Badge className="border-emerald-500/30 bg-emerald-500/10 text-emerald-400" variant="outline">
64
+ 可用
65
+ </Badge>
66
+ ) : (
67
+ <Badge className="border-amber-500/30 bg-amber-500/10 text-amber-300" variant="outline">
68
+ 需检查
69
+ </Badge>
70
+ );
71
+
72
+ return (
73
+ <div className="flex flex-col gap-3 rounded-xl border border-border bg-white/[0.025] p-4 transition-colors hover:border-border-emphasis hover:bg-white/[0.045]">
74
+ <div className="flex items-start justify-between gap-3">
75
+ <div className="min-w-0 space-y-1">
76
+ <div className="flex min-w-0 items-center gap-2">
77
+ <FileText className="size-4 shrink-0 text-text-muted" />
78
+ <h3 className="truncate text-sm font-semibold text-text">{skill.name}</h3>
79
+ </div>
80
+ <div className="flex flex-wrap items-center gap-1.5">
81
+ <Badge variant="secondary" className="text-[11px]">
82
+ {formatSkillRootKind(skill.rootKind)}
83
+ </Badge>
84
+ <Badge
85
+ variant="outline"
86
+ className="bg-surface-raised/60 border-border text-[11px] text-text-secondary"
87
+ >
88
+ {formatScope(skill.scope)}
89
+ </Badge>
90
+ <Badge
91
+ variant="outline"
92
+ className="bg-surface-raised/60 border-border text-[11px] text-text-secondary"
93
+ >
94
+ {getSkillAudienceLabel(skill.rootKind)}
95
+ </Badge>
96
+ <Badge
97
+ variant="outline"
98
+ className="bg-surface-raised/60 border-border text-[11px] text-text-secondary"
99
+ >
100
+ {formatInvocationMode(skill.invocationMode)}
101
+ </Badge>
102
+ {statusBadge}
103
+ </div>
104
+ </div>
105
+ <div className="flex shrink-0 items-center gap-1">
106
+ <Button
107
+ variant="ghost"
108
+ size="icon"
109
+ className="size-8"
110
+ onClick={() => onEdit(skill)}
111
+ disabled={isLoadingDetail || isDeleting}
112
+ title="编辑 Skill"
113
+ >
114
+ <Edit className="size-3.5" />
115
+ </Button>
116
+ <Button
117
+ variant="ghost"
118
+ size="icon"
119
+ className="size-8 text-red-300 hover:text-red-200"
120
+ onClick={() => onDelete(skill)}
121
+ disabled={isDeleting || isLoadingDetail}
122
+ title="删除 Skill"
123
+ >
124
+ <Trash2 className="size-3.5" />
125
+ </Button>
126
+ </div>
127
+ </div>
128
+
129
+ <p className="line-clamp-3 min-h-[3.75rem] text-xs leading-5 text-text-secondary">
130
+ {skill.description || '没有描述。'}
131
+ </p>
132
+
133
+ <div className="flex flex-wrap items-center gap-2 text-[11px] text-text-muted">
134
+ <span className="truncate">{skill.folderName}</span>
135
+ {skill.flags.hasScripts ? <Badge variant="outline">脚本</Badge> : null}
136
+ {skill.flags.hasReferences ? <Badge variant="outline">参考资料</Badge> : null}
137
+ {skill.flags.hasAssets ? <Badge variant="outline">资源</Badge> : null}
138
+ {skill.issues.length > 0 ? (
139
+ <span className="inline-flex items-center gap-1 text-amber-300">
140
+ <AlertCircle className="size-3" />
141
+ {skill.issues.length} 个提示
142
+ </span>
143
+ ) : null}
144
+ </div>
145
+ </div>
146
+ );
147
+ };
148
+
149
+ export const SkillsLibraryPanel = ({
150
+ projectPath,
151
+ projectLabel,
152
+ }: SkillsLibraryPanelProps): React.JSX.Element => {
153
+ const fetchSkillDetail = useStore((s) => s.fetchSkillDetail);
154
+ const deleteSkill = useStore((s) => s.deleteSkill);
155
+ const skillDetailsById = useStore((s) => s.skillsDetailsById);
156
+ const skillDetailLoadingById = useStore((s) => s.skillsDetailLoadingById);
157
+
158
+ const [skills, setSkills] = useState<SkillCatalogItem[]>([]);
159
+ const [search, setSearch] = useState('');
160
+ const [loading, setLoading] = useState(false);
161
+ const [error, setError] = useState<string | null>(null);
162
+ const [editorState, setEditorState] = useState<EditorState | null>(null);
163
+ const [openingSkillId, setOpeningSkillId] = useState<string | null>(null);
164
+ const [deletingSkillId, setDeletingSkillId] = useState<string | null>(null);
165
+
166
+ const loadSkills = useCallback(async (): Promise<void> => {
167
+ setLoading(true);
168
+ setError(null);
169
+ try {
170
+ const nextSkills = (await api.skills?.list()) ?? [];
171
+ setSkills(nextSkills);
172
+ } catch (err) {
173
+ setError(err instanceof Error ? err.message : '加载全局 Skill 失败');
174
+ } finally {
175
+ setLoading(false);
176
+ }
177
+ }, []);
178
+
179
+ useEffect(() => {
180
+ void loadSkills();
181
+ }, [loadSkills]);
182
+
183
+ const filteredSkills = useMemo(
184
+ () => skills.filter((skill) => matchesSearch(skill, search)),
185
+ [skills, search]
186
+ );
187
+
188
+ const openCreateDialog = useCallback(() => {
189
+ setEditorState({ mode: 'create', detail: null });
190
+ }, []);
191
+
192
+ const openEditDialog = useCallback(
193
+ (skill: SkillCatalogItem) => {
194
+ const cachedDetail = skillDetailsById[skill.id];
195
+ if (cachedDetail) {
196
+ setEditorState({ mode: 'edit', skillId: skill.id, detail: cachedDetail });
197
+ return;
198
+ }
199
+
200
+ setOpeningSkillId(skill.id);
201
+ setError(null);
202
+ void fetchSkillDetail(skill.id)
203
+ .then(() => {
204
+ setEditorState({ mode: 'edit', skillId: skill.id, detail: null });
205
+ })
206
+ .catch((err) => {
207
+ setError(err instanceof Error ? err.message : '加载 Skill 详情失败');
208
+ })
209
+ .finally(() => {
210
+ setOpeningSkillId((current) => (current === skill.id ? null : current));
211
+ });
212
+ },
213
+ [fetchSkillDetail, skillDetailsById]
214
+ );
215
+
216
+ const handleDelete = useCallback(
217
+ (skill: SkillCatalogItem) => {
218
+ void (async () => {
219
+ const confirmed = await confirm({
220
+ title: '删除 Skill',
221
+ message: `确认删除全局 Skill「${skill.name}」?此操作会删除对应的 Skill 文件。`,
222
+ confirmLabel: '删除',
223
+ cancelLabel: '取消',
224
+ variant: 'danger',
225
+ });
226
+ if (!confirmed) return;
227
+
228
+ setDeletingSkillId(skill.id);
229
+ setError(null);
230
+ try {
231
+ await deleteSkill({ skillId: skill.id });
232
+ await loadSkills();
233
+ } catch (err) {
234
+ setError(err instanceof Error ? err.message : '删除 Skill 失败');
235
+ } finally {
236
+ setDeletingSkillId(null);
237
+ }
238
+ })();
239
+ },
240
+ [deleteSkill, loadSkills]
241
+ );
242
+
243
+ const handleSaved = useCallback(
244
+ (_skillId: string | null) => {
245
+ setEditorState(null);
246
+ void loadSkills();
247
+ },
248
+ [loadSkills]
249
+ );
250
+
251
+ const editorDetail = useMemo(() => {
252
+ if (!editorState) return null;
253
+ if (editorState.mode === 'create') return null;
254
+ return skillDetailsById[editorState.skillId] ?? editorState.detail;
255
+ }, [editorState, skillDetailsById]);
256
+
257
+ return (
258
+ <div className="flex flex-col gap-4">
259
+ <div className="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
260
+ <div>
261
+ <h2 className="text-sm font-semibold text-text">全局 Skill 库</h2>
262
+ <p className="text-xs text-text-muted">
263
+ 管理个人范围 Skill。创建和编辑会保存到全局用户范围,不会写入当前项目。
264
+ </p>
265
+ </div>
266
+ <div className="flex flex-wrap items-center gap-2">
267
+ <Badge variant="secondary" className="font-normal">
268
+ {skills.length} 个 Skill
269
+ </Badge>
270
+ {projectPath ? (
271
+ <Badge variant="outline" className="font-normal text-text-muted">
272
+ 当前项目:{projectLabel ?? projectPath}
273
+ </Badge>
274
+ ) : null}
275
+ <Button variant="outline" size="sm" onClick={() => void loadSkills()} disabled={loading}>
276
+ <RefreshCw className={loading ? 'mr-2 size-3.5 animate-spin' : 'mr-2 size-3.5'} />
277
+ 刷新
278
+ </Button>
279
+ <Button size="sm" onClick={openCreateDialog}>
280
+ <Plus className="mr-2 size-3.5" />
281
+ 新建 Skill
282
+ </Button>
283
+ </div>
284
+ </div>
285
+
286
+ <SearchInput
287
+ value={search}
288
+ onChange={setSearch}
289
+ placeholder="搜索 Skill..."
290
+ debounceMs={120}
291
+ />
292
+
293
+ {error ? (
294
+ <div className="rounded-md border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-sm text-amber-300">
295
+ {error}
296
+ </div>
297
+ ) : null}
298
+
299
+ {loading && skills.length === 0 ? (
300
+ <div className="rounded-xl border border-border bg-white/[0.025] px-4 py-8 text-center text-sm text-text-muted">
301
+ 正在加载全局 Skill...
302
+ </div>
303
+ ) : filteredSkills.length > 0 ? (
304
+ <div className="grid gap-3 md:grid-cols-2 xl:grid-cols-3">
305
+ {filteredSkills.map((skill) => (
306
+ <SkillLibraryCard
307
+ key={skill.id}
308
+ skill={skill}
309
+ isLoadingDetail={
310
+ openingSkillId === skill.id || Boolean(skillDetailLoadingById[skill.id])
311
+ }
312
+ isDeleting={deletingSkillId === skill.id}
313
+ onEdit={openEditDialog}
314
+ onDelete={handleDelete}
315
+ />
316
+ ))}
317
+ </div>
318
+ ) : (
319
+ <div className="rounded-xl border border-border bg-white/[0.025] px-4 py-8 text-center text-sm text-text-muted">
320
+ {search ? '没有匹配的 Skill。' : '全局 Skill 库为空,点击“新建 Skill”创建第一个 Skill。'}
321
+ </div>
322
+ )}
323
+
324
+ <SkillEditorDialog
325
+ open={Boolean(editorState)}
326
+ mode={editorState?.mode ?? 'create'}
327
+ projectPath={null}
328
+ projectLabel={projectLabel}
329
+ detail={editorDetail}
330
+ onClose={() => setEditorState(null)}
331
+ onSaved={handleSaved}
332
+ />
333
+ </div>
334
+ );
335
+ };
@@ -5,6 +5,7 @@
5
5
 
6
6
  import { TeamGraphTab } from '@features/agent-graph/renderer';
7
7
  import { TabUIProvider } from '@renderer/contexts/TabUIContext';
8
+ import { SYSTEM_MANAGER_TEAM_NAME } from '@shared/types/team';
8
9
 
9
10
  import { DashboardView } from '../dashboard/DashboardView';
10
11
  import { ExtensionStoreView } from '../extensions/ExtensionStoreView';
@@ -13,6 +14,7 @@ import { SessionReportTab } from '../report/SessionReportTab';
13
14
  import { SchedulesView } from '../schedules/SchedulesView';
14
15
  import { SettingsView } from '../settings/SettingsView';
15
16
  import { TasksView } from '../tasks/TasksView';
17
+ import { SystemManagerView } from '../system-manager/SystemManagerView';
16
18
  import { TeamDetailView } from '../team/TeamDetailView';
17
19
  import { TeamListView } from '../team/TeamListView';
18
20
 
@@ -51,7 +53,12 @@ export const PaneContent = ({ pane, isPaneFocused }: PaneContentProps): React.JS
51
53
  {tab.type === 'notifications' && <NotificationsView />}
52
54
  {tab.type === 'settings' && <SettingsView />}
53
55
  {tab.type === 'teams' && <TeamListView />}
54
- {tab.type === 'team' && (
56
+ {tab.type === 'team' && tab.teamName === SYSTEM_MANAGER_TEAM_NAME && (
57
+ <TabUIProvider tabId={tab.id}>
58
+ <SystemManagerView isPaneFocused={isPaneFocused} />
59
+ </TabUIProvider>
60
+ )}
61
+ {tab.type === 'team' && tab.teamName !== SYSTEM_MANAGER_TEAM_NAME && (
55
62
  <TabUIProvider tabId={tab.id}>
56
63
  <TeamDetailView teamName={tab.teamName ?? ''} isPaneFocused={isPaneFocused} />
57
64
  </TabUIProvider>
@@ -73,8 +73,8 @@ export const PaneResizeHandle = ({ leftPaneId }: PaneResizeHandleProps): React.J
73
73
  return (
74
74
  // eslint-disable-next-line jsx-a11y/no-static-element-interactions -- resize handle requires mouse interaction
75
75
  <div
76
- className={`flex w-1 shrink-0 cursor-col-resize items-center justify-center transition-colors hover:bg-blue-500/50 ${
77
- isResizing ? 'bg-blue-500/50' : ''
76
+ className={`flex w-1 shrink-0 cursor-col-resize items-center justify-center transition-colors hover:bg-indigo-500/50 ${
77
+ isResizing ? 'bg-indigo-500/50' : ''
78
78
  }`}
79
79
  style={{
80
80
  backgroundColor: isResizing ? undefined : 'var(--color-border)',
@@ -2,8 +2,8 @@
2
2
  * Sidebar - Navigation with task list and session list.
3
3
  *
4
4
  * Structure:
5
- * - Tab bar: Collapse button + Tasks | Sessions
6
- * - Scrollable Body: Task list or date-grouped session list
5
+ * - Tab bar: Collapse button + Workspace
6
+ * - Scrollable Body: workspace browser
7
7
  * - Resizable: Drag right edge to resize
8
8
  * - Collapsible: Cmd+B to toggle (Notion-style)
9
9
  */
@@ -15,11 +15,9 @@ import { formatShortcut } from '@renderer/utils/stringUtils';
15
15
  import { PanelLeft } from 'lucide-react';
16
16
  import { useShallow } from 'zustand/react/shallow';
17
17
 
18
- import { DateGroupedSessions } from '../sidebar/DateGroupedSessions';
19
- import { SidebarSessions } from '../sidebar/SidebarSessions';
20
18
  import { WorkspaceBrowser } from '../sidebar/WorkspaceBrowser';
21
19
 
22
- type SidebarTab = 'workspace' | 'sessions';
20
+ type SidebarTab = 'workspace';
23
21
 
24
22
  const MIN_WIDTH = 200;
25
23
  const MAX_WIDTH = 500;
@@ -34,7 +32,7 @@ export const Sidebar = (): React.JSX.Element => {
34
32
  );
35
33
  const [width, setWidth] = useState(DEFAULT_WIDTH);
36
34
  const [isResizing, setIsResizing] = useState(false);
37
- const [sidebarTab, setSidebarTab] = useState<SidebarTab>('workspace');
35
+ const [sidebarTab] = useState<SidebarTab>('workspace');
38
36
  const [isCollapseHovered, setIsCollapseHovered] = useState(false);
39
37
  const sidebarRef = useRef<HTMLDivElement>(null);
40
38
 
@@ -123,54 +121,22 @@ export const Sidebar = (): React.JSX.Element => {
123
121
  <button
124
122
  type="button"
125
123
  role="tab"
126
- aria-selected={sidebarTab === 'workspace'}
124
+ aria-selected
127
125
  aria-controls="sidebar-workspace-panel"
128
126
  id="sidebar-tab-workspace"
129
- className={`relative px-3 py-1.5 text-[11px] font-medium transition-colors ${
130
- sidebarTab === 'workspace'
131
- ? 'text-text'
132
- : 'text-text-muted hover:text-text-secondary'
133
- }`}
134
- style={
135
- sidebarTab === 'workspace'
136
- ? {
137
- borderBottom: '2px solid var(--color-text)',
138
- marginBottom: '-1px',
139
- }
140
- : undefined
141
- }
142
- onClick={() => setSidebarTab('workspace')}
127
+ className="relative px-3 py-1.5 text-[11px] font-medium text-text transition-colors"
128
+ style={{
129
+ borderBottom: '2px solid var(--color-text)',
130
+ marginBottom: '-1px',
131
+ }}
143
132
  >
144
133
  工作空间
145
134
  </button>
146
- <button
147
- type="button"
148
- role="tab"
149
- aria-selected={sidebarTab === 'sessions'}
150
- aria-controls="sidebar-sessions-panel"
151
- id="sidebar-tab-sessions"
152
- className={`relative px-3 py-1.5 text-[11px] font-medium transition-colors ${
153
- sidebarTab === 'sessions'
154
- ? 'text-text'
155
- : 'text-text-muted hover:text-text-secondary'
156
- }`}
157
- style={
158
- sidebarTab === 'sessions'
159
- ? {
160
- borderBottom: '2px solid var(--color-text)',
161
- marginBottom: '-1px',
162
- }
163
- : undefined
164
- }
165
- onClick={() => setSidebarTab('sessions')}
166
- >
167
- 会话
168
- </button>
169
135
  </div>
170
136
  <div className="flex-1" />
171
137
  </div>
172
138
 
173
- {/* Content: Workspace or Sessions list */}
139
+ {/* Content: Workspace browser */}
174
140
  <div
175
141
  id="sidebar-workspace-panel"
176
142
  role="tabpanel"
@@ -180,15 +146,6 @@ export const Sidebar = (): React.JSX.Element => {
180
146
  >
181
147
  <WorkspaceBrowser />
182
148
  </div>
183
- <div
184
- id="sidebar-sessions-panel"
185
- role="tabpanel"
186
- aria-labelledby="sidebar-tab-sessions"
187
- hidden={sidebarTab !== 'sessions'}
188
- className="min-w-0 flex-1 overflow-hidden"
189
- >
190
- <SidebarSessions />
191
- </div>
192
149
  </div>
193
150
 
194
151
  {/* Resize handle - only interactive when expanded */}
@@ -196,8 +153,8 @@ export const Sidebar = (): React.JSX.Element => {
196
153
  <button
197
154
  type="button"
198
155
  aria-label="调整侧栏宽度"
199
- className={`absolute left-0 top-0 z-20 h-full w-1 cursor-col-resize border-0 bg-transparent p-0 transition-colors hover:bg-blue-500/50 ${
200
- isResizing ? 'bg-blue-500/50' : ''
156
+ className={`absolute left-0 top-0 z-20 h-full w-1 cursor-col-resize border-0 bg-transparent p-0 transition-colors hover:bg-indigo-500/50 ${
157
+ isResizing ? 'bg-indigo-500/50' : ''
201
158
  }`}
202
159
  onMouseDown={handleResizeStart}
203
160
  />
@@ -8,12 +8,7 @@ import { useCallback, useState } from 'react';
8
8
  import { useSortable } from '@dnd-kit/sortable';
9
9
  import { CSS } from '@dnd-kit/utilities';
10
10
  import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip';
11
- import {
12
- getTeamColorSet,
13
- getThemedBadge,
14
- getThemedBorder,
15
- getThemedText,
16
- } from '@renderer/constants/teamColors';
11
+ import { getTeamColorSet } from '@renderer/constants/teamColors';
17
12
  import { useTheme } from '@renderer/hooks/useTheme';
18
13
  import { useStore } from '@renderer/store';
19
14
  import { nameColorSet } from '@renderer/utils/projectColor';
@@ -91,15 +86,11 @@ export const SortableTab = ({
91
86
  team?.color ??
92
87
  (s.selectedTeamName === tab.teamName ? s.selectedTeamData?.config.color : undefined);
93
88
  if (explicitColor) return getTeamColorSet(explicitColor);
94
- // Fallback: deterministic color derived from display name
95
89
  const displayName = team?.displayName ?? tab.label;
96
90
  return nameColorSet(displayName, isLight);
97
91
  })
98
92
  );
99
- const activeBorderColor = teamColorSet
100
- ? getThemedBorder(teamColorSet, isLight)
101
- : 'var(--color-accent, #6366f1)';
102
- const inactiveTeamTextColor = teamColorSet ? getThemedText(teamColorSet, isLight) : null;
93
+ const accentColor = teamColorSet?.text ?? null;
103
94
 
104
95
  const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
105
96
  id: tab.id,
@@ -116,33 +107,25 @@ export const SortableTab = ({
116
107
  transition: isDragging ? 'none' : transition,
117
108
  opacity: isDragging ? 0.3 : 1,
118
109
  backgroundColor: isActive
119
- ? teamColorSet
120
- ? getThemedBadge(teamColorSet, isLight)
121
- : 'var(--color-surface-raised)'
110
+ ? 'var(--color-surface-raised)'
122
111
  : isHovered
123
- ? teamColorSet
124
- ? getThemedBadge(teamColorSet, isLight)
125
- : 'var(--color-surface-overlay)'
126
- : teamColorSet
127
- ? getThemedBadge(teamColorSet, isLight)
128
- : 'transparent',
112
+ ? 'var(--color-surface-overlay)'
113
+ : 'transparent',
129
114
  color: isActive
130
115
  ? 'var(--color-text)'
131
- : inactiveTeamTextColor
132
- ? inactiveTeamTextColor
133
- : isHovered
134
- ? 'var(--color-text)'
135
- : 'var(--color-text-muted)',
116
+ : isHovered
117
+ ? 'var(--color-text)'
118
+ : 'var(--color-text-muted)',
136
119
  outline: isSelected ? '1px solid var(--color-border-emphasis)' : 'none',
137
120
  outlineOffset: '-1px',
138
- borderTop: isActive ? `1px solid ${activeBorderColor}` : '1px solid transparent',
139
- borderLeft: '1px solid transparent',
140
- borderRight: '1px solid transparent',
121
+ borderTop: isActive ? '1px solid var(--color-border)' : '1px solid transparent',
122
+ borderLeft: '1px solid var(--color-border-subtle)',
123
+ borderRight: isActive ? '1px solid var(--color-border)' : '1px solid transparent',
141
124
  borderBottom: isActive ? '1px solid var(--color-surface-raised)' : '1px solid transparent',
142
- borderTopLeftRadius: '8px',
143
- borderTopRightRadius: '8px',
144
- borderBottomLeftRadius: isActive ? 0 : '8px',
145
- borderBottomRightRadius: isActive ? 0 : '8px',
125
+ borderTopLeftRadius: '0',
126
+ borderTopRightRadius: '0',
127
+ borderBottomLeftRadius: '0',
128
+ borderBottomRightRadius: '0',
146
129
  marginBottom: isActive ? '-1px' : 0,
147
130
  position: 'relative' as const,
148
131
  zIndex: isActive ? 1 : 0,
@@ -184,6 +167,12 @@ export const SortableTab = ({
184
167
  }
185
168
  }}
186
169
  >
170
+ {isActive && accentColor && (
171
+ <div
172
+ className="absolute bottom-0 left-2 right-2 h-[2px] rounded-full"
173
+ style={{ backgroundColor: accentColor, opacity: 0.6 }}
174
+ />
175
+ )}
187
176
  <Icon className="size-4 shrink-0" />
188
177
  {tab.fromSearch && (
189
178
  <span title="从搜索打开">
@@ -192,7 +181,7 @@ export const SortableTab = ({
192
181
  )}
193
182
  {isPinned && (
194
183
  <span title="已固定会话">
195
- <Pin className="size-3 shrink-0 text-blue-400" />
184
+ <Pin className="size-3 shrink-0 text-indigo-400" />
196
185
  </span>
197
186
  )}
198
187
  <span
@@ -264,7 +264,7 @@ export const TabBar = ({ paneId }: TabBarProps): React.JSX.Element => {
264
264
  scrollContainerRef.current = el;
265
265
  setDroppableRef(el);
266
266
  }}
267
- className="scrollbar-none flex min-w-0 flex-1 items-center gap-1"
267
+ className="scrollbar-none flex min-w-0 flex-1 items-center"
268
268
  style={{
269
269
  outline: isDroppableOver ? '1px dashed var(--color-accent, #6366f1)' : 'none',
270
270
  outlineOffset: '-1px',
@@ -87,7 +87,7 @@ export const TabContextMenu = ({
87
87
  return (
88
88
  <div
89
89
  ref={menuRef}
90
- className="fixed z-50 min-w-[220px] overflow-hidden rounded-md border py-1 shadow-lg"
90
+ className="fixed z-50 min-w-[220px] overflow-hidden border py-1 shadow-lg"
91
91
  style={{
92
92
  left: clampedX,
93
93
  top: clampedY,
@@ -97,7 +97,7 @@ export const CostSection = ({
97
97
  <div className="mb-1.5 flex h-3 w-full overflow-hidden rounded-full">
98
98
  <div
99
99
  className="h-full"
100
- style={{ width: `${parentPct}%`, backgroundColor: '#60a5fa' }}
100
+ style={{ width: `${parentPct}%`, backgroundColor: '#818cf8' }}
101
101
  />
102
102
  <div
103
103
  className="h-full"
@@ -108,7 +108,7 @@ export const CostSection = ({
108
108
  <div className="flex items-center gap-1.5">
109
109
  <span
110
110
  className="inline-block size-2 rounded-full"
111
- style={{ backgroundColor: '#60a5fa' }}
111
+ style={{ backgroundColor: '#818cf8' }}
112
112
  />
113
113
  <span className="text-text-secondary">主会话:{fmt(data.parentCostUsd)}</span>
114
114
  </div>
@@ -153,7 +153,7 @@ export const InsightsSection = ({
153
153
  <div className="mb-2 text-xs font-medium text-text-muted">
154
154
  Agent Tree ({agentTree.agentCount} agent{agentTree.agentCount !== 1 ? 's' : ''})
155
155
  {agentTree.hasTeamMode && (
156
- <span className="ml-2 rounded px-1.5 py-0.5 text-xs" style={{ color: '#60a5fa' }}>
156
+ <span className="ml-2 rounded px-1.5 py-0.5 text-xs" style={{ color: '#818cf8' }}>
157
157
  Team Mode
158
158
  </span>
159
159
  )}
@@ -191,7 +191,7 @@ export const ProviderRuntimeBackendSelector = ({
191
191
  className="shrink-0 rounded-full px-1.5 py-0.5 text-[10px]"
192
192
  style={{
193
193
  color: '#93c5fd',
194
- backgroundColor: 'rgba(59, 130, 246, 0.14)',
194
+ backgroundColor: 'rgba(99, 102, 241, 0.14)',
195
195
  }}
196
196
  >
197
197
  {getProviderRuntimeBackendAudienceLabel(option)}
@@ -259,7 +259,7 @@ export const ProviderRuntimeBackendSelector = ({
259
259
  className="rounded-full px-1.5 py-0.5 text-[10px]"
260
260
  style={{
261
261
  color: '#93c5fd',
262
- backgroundColor: 'rgba(59, 130, 246, 0.14)',
262
+ backgroundColor: 'rgba(99, 102, 241, 0.14)',
263
263
  }}
264
264
  >
265
265
  {selectedAudienceLabel}