@yancyyu/openhermit 1.6.37 → 1.6.39

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 (205) hide show
  1. package/dist-renderer/assets/ProjectEditorOverlay-krO5vQxX.js +58 -0
  2. package/dist-renderer/assets/{TeamGraphOverlay-DYT3bwFR.js → TeamGraphOverlay-DqhQzcTr.js} +1 -1
  3. package/dist-renderer/assets/{_basePickBy-Dbt_EU-e.js → _basePickBy-B7kSYPxr.js} +1 -1
  4. package/dist-renderer/assets/{_baseUniq-DWo68sXI.js → _baseUniq-CnjxqwAk.js} +1 -1
  5. package/dist-renderer/assets/{arc-DXH1iZQK.js → arc-CLeZuINP.js} +1 -1
  6. package/dist-renderer/assets/{architectureDiagram-VXUJARFQ-cjffS2Qr.js → architectureDiagram-VXUJARFQ-QKtqaqdY.js} +1 -1
  7. package/dist-renderer/assets/{blockDiagram-VD42YOAC-BKdZF02Y.js → blockDiagram-VD42YOAC-BqdrzO_f.js} +1 -1
  8. package/dist-renderer/assets/{c4Diagram-YG6GDRKO-CN27pqaI.js → c4Diagram-YG6GDRKO-gwPlCxDC.js} +1 -1
  9. package/dist-renderer/assets/channel-DpMHF50r.js +1 -0
  10. package/dist-renderer/assets/{chunk-4BX2VUAB-CXPCI7g_.js → chunk-4BX2VUAB-C6XLurL4.js} +1 -1
  11. package/dist-renderer/assets/{chunk-55IACEB6-BGAXQZRC.js → chunk-55IACEB6-Ds6quhEP.js} +1 -1
  12. package/dist-renderer/assets/{chunk-B4BG7PRW-TPDaA_KQ.js → chunk-B4BG7PRW-5UlA1_e9.js} +1 -1
  13. package/dist-renderer/assets/{chunk-DI55MBZ5-D1ADe_tq.js → chunk-DI55MBZ5-ywFrqIsY.js} +1 -1
  14. package/dist-renderer/assets/{chunk-FMBD7UC4-Beimtg3a.js → chunk-FMBD7UC4-C7ifUA17.js} +1 -1
  15. package/dist-renderer/assets/{chunk-QN33PNHL-OjNBu854.js → chunk-QN33PNHL-BxGCo80U.js} +1 -1
  16. package/dist-renderer/assets/{chunk-QZHKN3VN-DinqvbH8.js → chunk-QZHKN3VN-B2CuaZs6.js} +1 -1
  17. package/dist-renderer/assets/{chunk-TZMSLE5B-BfFtlPSZ.js → chunk-TZMSLE5B-Ds1hInvp.js} +1 -1
  18. package/dist-renderer/assets/classDiagram-2ON5EDUG-CBYCBVRl.js +1 -0
  19. package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-CBYCBVRl.js +1 -0
  20. package/dist-renderer/assets/clone-DcMF6Psb.js +1 -0
  21. package/dist-renderer/assets/{cose-bilkent-S5V4N54A-D9z9Dgt7.js → cose-bilkent-S5V4N54A-Cz1GVtLp.js} +1 -1
  22. package/dist-renderer/assets/{dagre-6UL2VRFP-n1g-DhEE.js → dagre-6UL2VRFP-BrmR-P4h.js} +1 -1
  23. package/dist-renderer/assets/{diagram-PSM6KHXK-BvxFq-BE.js → diagram-PSM6KHXK-DbNjC5Rg.js} +1 -1
  24. package/dist-renderer/assets/{diagram-QEK2KX5R-wVnJuwza.js → diagram-QEK2KX5R-qkRX5_Mq.js} +1 -1
  25. package/dist-renderer/assets/{diagram-S2PKOQOG-B707WJQw.js → diagram-S2PKOQOG-CyL5rCv2.js} +1 -1
  26. package/dist-renderer/assets/{erDiagram-Q2GNP2WA-C-_1dGHs.js → erDiagram-Q2GNP2WA-Dox3-bA5.js} +1 -1
  27. package/dist-renderer/assets/{flowDiagram-NV44I4VS-CMTSi3H6.js → flowDiagram-NV44I4VS-BtkaxlDL.js} +1 -1
  28. package/dist-renderer/assets/{ganttDiagram-JELNMOA3-DZ0bNrAA.js → ganttDiagram-JELNMOA3-Dhy_d9GK.js} +1 -1
  29. package/dist-renderer/assets/{gitGraphDiagram-V2S2FVAM-DNVfGooQ.js → gitGraphDiagram-V2S2FVAM-B5XRhIQA.js} +1 -1
  30. package/dist-renderer/assets/{graph-865j_tM_.js → graph-CsoEwUhS.js} +1 -1
  31. package/dist-renderer/assets/{index-C_F9N5x-.js → index-BWPWmJNo.js} +1 -1
  32. package/dist-renderer/assets/{index-LwDIsXJN.js → index-Bu2R-Se7.js} +586 -740
  33. package/dist-renderer/assets/index-CnWV3BhG.css +32 -0
  34. package/dist-renderer/assets/{index-DuUaf8at.js → index-D-3KgskL.js} +1 -1
  35. package/dist-renderer/assets/{index-BTx1nc4T.js → index-DGEBzLNT.js} +1 -1
  36. package/dist-renderer/assets/{index-2EW-eu3q.js → index-NhHNs2Oo.js} +1 -1
  37. package/dist-renderer/assets/{index-4dEMStJj.js → index-h17WuEyf.js} +1 -1
  38. package/dist-renderer/assets/{infoDiagram-HS3SLOUP-CyqtElLq.js → infoDiagram-HS3SLOUP-hMGmNojH.js} +1 -1
  39. package/dist-renderer/assets/{journeyDiagram-XKPGCS4Q-BvjQ0Hm0.js → journeyDiagram-XKPGCS4Q-DXV2rBDl.js} +1 -1
  40. package/dist-renderer/assets/{kanban-definition-3W4ZIXB7-CJJ-k0zT.js → kanban-definition-3W4ZIXB7-Bf99WLRy.js} +1 -1
  41. package/dist-renderer/assets/{layout-CnV6rQAG.js → layout-C3XWrpwo.js} +1 -1
  42. package/dist-renderer/assets/{linear-Cw3UQgyX.js → linear-OEEcn8KN.js} +1 -1
  43. package/dist-renderer/assets/{mindmap-definition-VGOIOE7T-C5tDaGSK.js → mindmap-definition-VGOIOE7T-Dpi3S2x4.js} +1 -1
  44. package/dist-renderer/assets/{pieDiagram-ADFJNKIX-CiIpPsau.js → pieDiagram-ADFJNKIX-xTPPhtNx.js} +1 -1
  45. package/dist-renderer/assets/{quadrantDiagram-AYHSOK5B-C3gtowNj.js → quadrantDiagram-AYHSOK5B-euniyDlz.js} +1 -1
  46. package/dist-renderer/assets/{requirementDiagram-UZGBJVZJ-CXBTrAnU.js → requirementDiagram-UZGBJVZJ-D9Uiw4kF.js} +1 -1
  47. package/dist-renderer/assets/{sankeyDiagram-TZEHDZUN-wziX77xG.js → sankeyDiagram-TZEHDZUN-CySU4nED.js} +1 -1
  48. package/dist-renderer/assets/{sequenceDiagram-WL72ISMW-sYqopcrj.js → sequenceDiagram-WL72ISMW-JVGpET6V.js} +1 -1
  49. package/dist-renderer/assets/splashScene-D0YB9uxm.js +17 -0
  50. package/dist-renderer/assets/{stateDiagram-FKZM4ZOC-Bl1-0_Cp.js → stateDiagram-FKZM4ZOC-B2FY5qqi.js} +1 -1
  51. package/dist-renderer/assets/stateDiagram-v2-4FDKWEC3-DcoMiR8H.js +1 -0
  52. package/dist-renderer/assets/{timeline-definition-IT6M3QCI-CIRjJUBo.js → timeline-definition-IT6M3QCI-DmycNUUe.js} +1 -1
  53. package/dist-renderer/assets/{treemap-GDKQZRPO-CVPuNe1n.js → treemap-GDKQZRPO-DPq4gZuB.js} +1 -1
  54. package/dist-renderer/assets/{xychartDiagram-PRI3JC2R-3nT9yHwp.js → xychartDiagram-PRI3JC2R-J6VVJzRq.js} +1 -1
  55. package/dist-renderer/index.html +20 -53
  56. package/package.json +25 -18
  57. package/src/main/ipc/extensions.ts +30 -50
  58. package/src/main/server.ts +890 -247
  59. package/src/main/services/extensions/ExtensionFacadeService.ts +4 -56
  60. package/src/main/services/extensions/catalog/PluginCatalogService.ts +4 -2
  61. package/src/main/services/extensions/library/McpLibraryService.ts +243 -0
  62. package/src/main/services/session-intelligence/ConversationTelemetryService.ts +1101 -0
  63. package/src/main/services/session-intelligence/LocalSessionScanner.ts +512 -0
  64. package/src/main/services/session-intelligence/SessionUsageParser.ts +4 -4
  65. package/src/main/services/session-intelligence/UsageTelemetryService.ts +14 -1
  66. package/src/main/services/system-manager/SystemManagerConfigService.ts +122 -0
  67. package/src/main/services/system-manager/SystemManagerPtyService.ts +233 -0
  68. package/src/main/services/system-manager/WorkflowPromptService.ts +75 -0
  69. package/src/main/services/teams-mvp/TaskDispatchService.ts +32 -8
  70. package/src/main/services/teams-mvp/TeamProvisioningService.ts +39 -2
  71. package/src/main/services/teams-mvp/TeamWorkspaceService.ts +22 -4
  72. package/src/main/utils/teamProjectResolution.ts +15 -0
  73. package/src/renderer/App.tsx +8 -4
  74. package/src/renderer/api/httpClient.ts +174 -38
  75. package/src/renderer/api/providers.ts +23 -2
  76. package/src/renderer/assets/participant-avatars/01.svg +3 -0
  77. package/src/renderer/assets/participant-avatars/02.svg +3 -0
  78. package/src/renderer/assets/participant-avatars/03.svg +3 -0
  79. package/src/renderer/assets/participant-avatars/04.svg +3 -0
  80. package/src/renderer/assets/participant-avatars/05.svg +3 -0
  81. package/src/renderer/assets/participant-avatars/06.svg +3 -0
  82. package/src/renderer/assets/participant-avatars/07.svg +3 -0
  83. package/src/renderer/assets/participant-avatars/08.svg +3 -0
  84. package/src/renderer/assets/participant-avatars/09.svg +3 -0
  85. package/src/renderer/assets/participant-avatars/10.svg +3 -0
  86. package/src/renderer/assets/participant-avatars/11.svg +3 -0
  87. package/src/renderer/assets/participant-avatars/12.svg +3 -0
  88. package/src/renderer/assets/participant-avatars/13.svg +3 -0
  89. package/src/renderer/components/common/TerminalPane.tsx +213 -0
  90. package/src/renderer/components/dashboard/DashboardView.tsx +9 -36
  91. package/src/renderer/components/extensions/ExtensionStoreView.tsx +12 -221
  92. package/src/renderer/components/extensions/ExtensionsSubTabTrigger.tsx +1 -1
  93. package/src/renderer/components/extensions/mcp/McpLibraryEnableDialog.tsx +305 -0
  94. package/src/renderer/components/extensions/mcp/McpLibraryEntryDialog.tsx +418 -0
  95. package/src/renderer/components/extensions/mcp/McpLibraryPanel.tsx +404 -0
  96. package/src/renderer/components/extensions/plugins/PluginCard.tsx +10 -2
  97. package/src/renderer/components/extensions/plugins/PluginsPanel.tsx +40 -22
  98. package/src/renderer/components/extensions/skills/SkillsLibraryPanel.tsx +335 -0
  99. package/src/renderer/components/layout/PaneContent.tsx +8 -1
  100. package/src/renderer/components/layout/Sidebar.tsx +11 -54
  101. package/src/renderer/components/layout/SortableTab.tsx +20 -31
  102. package/src/renderer/components/layout/TabBar.tsx +1 -1
  103. package/src/renderer/components/layout/TabContextMenu.tsx +1 -1
  104. package/src/renderer/components/runtime/ProviderRuntimeSettingsDialog.tsx +768 -157
  105. package/src/renderer/components/schedules/SchedulesView.tsx +51 -462
  106. package/src/renderer/components/schedules/calendar/CalendarDayView.tsx +173 -0
  107. package/src/renderer/components/schedules/calendar/CalendarEventBlock.tsx +113 -0
  108. package/src/renderer/components/schedules/calendar/CalendarHeader.tsx +148 -0
  109. package/src/renderer/components/schedules/calendar/CalendarMonthView.tsx +142 -0
  110. package/src/renderer/components/schedules/calendar/CalendarWeekView.tsx +219 -0
  111. package/src/renderer/components/schedules/calendar/ScheduleCalendarBoard.tsx +41 -0
  112. package/src/renderer/components/schedules/calendar/TeamGanttView.tsx +405 -0
  113. package/src/renderer/components/schedules/calendar/computeOccurrences.ts +234 -0
  114. package/src/renderer/components/schedules/calendar/index.ts +2 -0
  115. package/src/renderer/components/schedules/calendar/types.ts +44 -0
  116. package/src/renderer/components/settings/SettingsTabs.tsx +50 -55
  117. package/src/renderer/components/settings/SettingsView.tsx +30 -35
  118. package/src/renderer/components/settings/components/SettingsSectionHeader.tsx +5 -1
  119. package/src/renderer/components/settings/components/SettingsSelect.tsx +5 -3
  120. package/src/renderer/components/settings/components/SettingsToggle.tsx +2 -2
  121. package/src/renderer/components/settings/sections/AdvancedSection.tsx +11 -42
  122. package/src/renderer/components/settings/sections/CliStatusSection.tsx +71 -112
  123. package/src/renderer/components/settings/sections/ConfigEditorDialog.tsx +1 -1
  124. package/src/renderer/components/settings/sections/GeneralSection.tsx +11 -3
  125. package/src/renderer/components/settings/sections/HarnessSection.tsx +18 -14
  126. package/src/renderer/components/settings/sections/PlatformsSection.tsx +3 -3
  127. package/src/renderer/components/settings/sections/TaskBusSection.tsx +33 -40
  128. package/src/renderer/components/settings/sections/index.ts +0 -1
  129. package/src/renderer/components/sidebar/SidebarSessions.tsx +182 -4
  130. package/src/renderer/components/sidebar/SidebarTaskItem.tsx +4 -4
  131. package/src/renderer/components/sidebar/WorkspaceBrowser.tsx +39 -4
  132. package/src/renderer/components/splash/splashScene.ts +121 -929
  133. package/src/renderer/components/system-manager/FolderBrowser.tsx +163 -0
  134. package/src/renderer/components/system-manager/SystemManagerView.tsx +351 -0
  135. package/src/renderer/components/tasks/TasksView.tsx +112 -134
  136. package/src/renderer/components/team/CcSessionsSection.tsx +431 -89
  137. package/src/renderer/components/team/CollapsibleTeamSection.tsx +17 -32
  138. package/src/renderer/components/team/TeamDetailView.tsx +325 -114
  139. package/src/renderer/components/team/TeamListView.tsx +108 -123
  140. package/src/renderer/components/team/dialogs/CreateTaskDialog.tsx +2 -2
  141. package/src/renderer/components/team/dialogs/CreateTeamDialog.tsx +84 -306
  142. package/src/renderer/components/team/dialogs/EditTeamDialog.tsx +259 -342
  143. package/src/renderer/components/team/dialogs/GlobalTaskDetailDialog.tsx +1 -1
  144. package/src/renderer/components/team/dialogs/LaunchTeamDialog.tsx +17 -15
  145. package/src/renderer/components/team/dialogs/PlatformBindingDialog.tsx +221 -0
  146. package/src/renderer/components/team/dialogs/PlatformManualForm.tsx +7 -0
  147. package/src/renderer/components/team/dialogs/PlatformSetupQR.tsx +1 -1
  148. package/src/renderer/components/team/dialogs/RuntimeConfigDialog.tsx +361 -0
  149. package/src/renderer/components/team/dialogs/platformMeta.ts +122 -11
  150. package/src/renderer/components/team/dialogs/useTeamEditForm.ts +17 -5
  151. package/src/renderer/components/team/kanban/KanbanBoard.tsx +9 -9
  152. package/src/renderer/components/team/members/MemberCard.tsx +14 -47
  153. package/src/renderer/components/team/members/MemberDetailDialog.tsx +3 -95
  154. package/src/renderer/components/team/members/MemberDetailStats.tsx +50 -65
  155. package/src/renderer/components/team/messages/MessageComposer.tsx +8 -110
  156. package/src/renderer/components/team/messages/MessagesPanel.tsx +131 -114
  157. package/src/renderer/components/team/schedule/ScheduleStatusBadge.tsx +2 -2
  158. package/src/renderer/components/team/tools/AddMcpInline.tsx +57 -0
  159. package/src/renderer/components/team/tools/AddSkillInline.tsx +61 -0
  160. package/src/renderer/components/team/tools/McpChip.tsx +45 -0
  161. package/src/renderer/components/team/tools/SkillChip.tsx +35 -0
  162. package/src/renderer/components/team/tools/ToolsSection.tsx +556 -0
  163. package/src/renderer/hooks/useExtensionsTabState.ts +3 -114
  164. package/src/renderer/index.css +39 -22
  165. package/src/renderer/index.html +17 -50
  166. package/src/renderer/store/index.ts +2 -1
  167. package/src/renderer/store/slices/scheduleSlice.ts +1 -1
  168. package/src/renderer/store/slices/teamSlice.ts +45 -168
  169. package/src/renderer/utils/claudeCodeOnlyProviders.ts +3 -10
  170. package/src/renderer/utils/memberHelpers.ts +5 -17
  171. package/src/renderer/utils/openCodeRuntimeDeliveryDiagnostics.ts +4 -2
  172. package/src/renderer/utils/providerSlashCommands.ts +0 -5
  173. package/src/renderer/utils/scheduleFormatters.ts +3 -1
  174. package/src/renderer/utils/teamMessageFiltering.ts +14 -1
  175. package/src/renderer/utils/teamModelAvailability.ts +18 -2
  176. package/src/shared/types/api.ts +121 -2
  177. package/src/shared/types/ccConnect.ts +2 -0
  178. package/src/shared/types/extensions/api.ts +9 -0
  179. package/src/shared/types/extensions/index.ts +4 -0
  180. package/src/shared/types/extensions/mcp.ts +41 -0
  181. package/src/shared/types/index.ts +3 -0
  182. package/src/shared/types/systemManager.ts +49 -0
  183. package/src/shared/types/team.ts +29 -0
  184. package/src/shared/types/terminal.ts +4 -2
  185. package/src/shared/utils/extensionNormalizers.ts +29 -0
  186. package/src/shared/utils/providerExtensionCapabilities.ts +2 -2
  187. package/dist-renderer/assets/ProjectEditorOverlay-Va_Vz-zz.js +0 -52
  188. package/dist-renderer/assets/channel-5dJIx68e.js +0 -1
  189. package/dist-renderer/assets/classDiagram-2ON5EDUG-BMGXWJ2d.js +0 -1
  190. package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-BMGXWJ2d.js +0 -1
  191. package/dist-renderer/assets/clone-D7FWfGY9.js +0 -1
  192. package/dist-renderer/assets/index-B2z_IyRH.css +0 -1
  193. package/dist-renderer/assets/splashScene-C8lWNnm4.js +0 -1
  194. package/dist-renderer/assets/stateDiagram-v2-4FDKWEC3-DOYYvDbi.js +0 -1
  195. package/src/main/services/extensions/catalog/GlamaMcpEnrichmentService.ts +0 -190
  196. package/src/main/services/extensions/catalog/McpCatalogAggregator.ts +0 -150
  197. package/src/main/services/extensions/catalog/OfficialMcpRegistryService.ts +0 -381
  198. package/src/main/services/extensions/install/McpInstallService.ts +0 -407
  199. package/src/main/services/extensions/state/McpInstallationStateService.ts +0 -42
  200. package/src/renderer/components/extensions/mcp/McpServerCard.tsx +0 -314
  201. package/src/renderer/components/extensions/mcp/McpServerDetailDialog.tsx +0 -765
  202. package/src/renderer/components/extensions/mcp/McpServersPanel.tsx +0 -593
  203. package/src/renderer/components/extensions/skills/SkillDetailDialog.tsx +0 -372
  204. package/src/renderer/components/extensions/skills/SkillImportDialog.tsx +0 -343
  205. package/src/renderer/components/extensions/skills/SkillsPanel.tsx +0 -659
@@ -36,6 +36,7 @@ import { buildTaskCountsByTeam, normalizePath } from '@renderer/utils/pathNormal
36
36
  import { emitOpenHermitEvent, OPEN_HERMIT_EVENTS } from '@renderer/utils/openHermitEvents';
37
37
  import { getBaseName } from '@renderer/utils/pathUtils';
38
38
  import { nameColorSet } from '@renderer/utils/projectColor';
39
+ import { formatRelativeTime, formatTokensCompact } from '@renderer/utils/formatters';
39
40
  import {
40
41
  CheckCircle,
41
42
  Clock,
@@ -48,9 +49,12 @@ import {
48
49
  RotateCcw,
49
50
  Search,
50
51
  Trash2,
52
+ Users,
51
53
  } from 'lucide-react';
52
54
  import { useShallow } from 'zustand/react/shallow';
53
55
 
56
+ import { SYSTEM_MANAGER_TEAM_NAME } from '@shared/types/team';
57
+
54
58
  import { CreateTeamDialog } from './dialogs/CreateTeamDialog';
55
59
  import { LaunchTeamDialog } from './dialogs/LaunchTeamDialog';
56
60
  import { TeamEmptyState } from './TeamEmptyState';
@@ -61,8 +65,6 @@ import {
61
65
  teamMatchesProjectSelection,
62
66
  } from './teamProjectSelection';
63
67
 
64
- import type { ActiveTeamRef, TeamCopyData } from './dialogs/CreateTeamDialog';
65
- import type { TeamListFilterState } from './TeamListFilterPopover';
66
68
  import type {
67
69
  ResolvedTeamMember,
68
70
  TeamCreateRequest,
@@ -73,6 +75,8 @@ import type {
73
75
  TeamTemplateSource,
74
76
  TeamTemplateSummary,
75
77
  } from '@shared/types';
78
+ import type { ActiveTeamRef, TeamCopyData } from './dialogs/CreateTeamDialog';
79
+ import type { TeamListFilterState } from './TeamListFilterPopover';
76
80
 
77
81
  function generateUniqueName(sourceName: string, existingNames: string[]): string {
78
82
  const base = sourceName.replace(/-\d+$/, '');
@@ -226,6 +230,17 @@ function resolveTeamStatus(
226
230
  return null;
227
231
  }
228
232
 
233
+ function formatDurationShort(ms: number): string {
234
+ if (ms < 60_000) return `${Math.round(ms / 1000)}s`;
235
+ const minutes = Math.floor(ms / 60_000);
236
+ if (minutes < 60) return `${minutes}m`;
237
+ const hours = Math.floor(minutes / 60);
238
+ const remainMin = minutes % 60;
239
+ if (hours < 24) return `${hours}h ${remainMin}m`;
240
+ const days = Math.floor(hours / 24);
241
+ return `${days}d ${hours % 24}h`;
242
+ }
243
+
229
244
  const StatusBadge = ({ status }: { status: TeamStatus | null }): React.JSX.Element | null => {
230
245
  if (!status) return null;
231
246
  switch (status) {
@@ -279,6 +294,7 @@ export const TeamListView = (): React.JSX.Element => {
279
294
  teamsError,
280
295
  fetchTeams,
281
296
  openTeamTab,
297
+ openSystemManager,
282
298
  deleteTeam,
283
299
  restoreTeam,
284
300
  permanentlyDeleteTeam,
@@ -298,6 +314,7 @@ export const TeamListView = (): React.JSX.Element => {
298
314
  teamsError: s.teamsError,
299
315
  fetchTeams: s.fetchTeams,
300
316
  openTeamTab: s.openTeamTab,
317
+ openSystemManager: s.openSystemManager,
301
318
  deleteTeam: s.deleteTeam,
302
319
  restoreTeam: s.restoreTeam,
303
320
  permanentlyDeleteTeam: s.permanentlyDeleteTeam,
@@ -442,6 +459,11 @@ export const TeamListView = (): React.JSX.Element => {
442
459
  : null;
443
460
 
444
461
  result = [...result].sort((a, b) => {
462
+ // 0. Project-level system manager is a namespace node, not a regular worker team.
463
+ const managerA = a.teamName === SYSTEM_MANAGER_TEAM_NAME ? 0 : 1;
464
+ const managerB = b.teamName === SYSTEM_MANAGER_TEAM_NAME ? 0 : 1;
465
+ if (managerA !== managerB) return managerA - managerB;
466
+
445
467
  // 1. Alive (running) teams first
446
468
  const aliveA = aliveSet.has(a.teamName) ? 0 : 1;
447
469
  const aliveB = aliveSet.has(b.teamName) ? 0 : 1;
@@ -528,8 +550,8 @@ export const TeamListView = (): React.JSX.Element => {
528
550
  }
529
551
  const confirmed = await confirm({
530
552
  title: '删除数字员工',
531
- message: `确定删除数字员工”${teamDisplayName}”吗?此操作会同步删除 cc-connect 项目并移除本地数据。`,
532
- confirmLabel: '删除并重启',
553
+ message: `确定删除数字员工”${teamDisplayName}”吗?此操作会移除本地配置数据。`,
554
+ confirmLabel: '删除',
533
555
  cancelLabel: '取消',
534
556
  variant: 'danger',
535
557
  });
@@ -988,8 +1010,13 @@ export const TeamListView = (): React.JSX.Element => {
988
1010
  <div className="flex items-center justify-between">
989
1011
  <h2 className="text-base font-semibold text-[var(--color-text)]">选择数字员工</h2>
990
1012
  <div className="flex items-center gap-2">
991
- <Button variant="outline" size="sm" disabled={!canCreate} onClick={openTemplateDialog}>
992
- 从模板创建
1013
+ <Button
1014
+ variant="outline"
1015
+ size="sm"
1016
+ className="border-cyan-500/30 text-cyan-300 hover:bg-cyan-500/10"
1017
+ onClick={() => void openSystemManager()}
1018
+ >
1019
+ 控制台
993
1020
  </Button>
994
1021
  <Button
995
1022
  variant="outline"
@@ -1100,13 +1127,13 @@ export const TeamListView = (): React.JSX.Element => {
1100
1127
  ? teamMatchesProjectSelection(team, currentProjectPath)
1101
1128
  : false;
1102
1129
  const isDeleting = deletingTeamName === team.teamName;
1130
+ const isSystemManager = team.teamName === SYSTEM_MANAGER_TEAM_NAME;
1103
1131
  return (
1104
1132
  <div
1105
1133
  key={team.teamName}
1106
1134
  role="button"
1107
1135
  tabIndex={0}
1108
- className="group relative flex cursor-pointer flex-col overflow-hidden rounded-lg border border-l-[3px] border-[var(--color-border)] bg-[var(--color-surface)] p-4 hover:bg-[var(--color-surface-raised)]"
1109
- style={teamColorSet ? { borderLeftColor: teamColorSet.border } : undefined}
1136
+ className="group relative flex cursor-pointer flex-col overflow-hidden rounded-lg border border-[var(--color-border)] bg-[var(--color-surface)] p-4 transition-colors hover:border-[var(--color-border-emphasis)] hover:bg-[var(--color-surface-raised)]"
1110
1137
  onClick={
1111
1138
  isDeleting ? undefined : () => openTeamTab(team.teamName, team.projectPath)
1112
1139
  }
@@ -1124,149 +1151,107 @@ export const TeamListView = (): React.JSX.Element => {
1124
1151
  </div>
1125
1152
  )}
1126
1153
  <div className="flex flex-1 flex-col">
1127
- <div className="flex items-start justify-between gap-2">
1128
- <div className="flex min-w-0 flex-1 items-center gap-2.5">
1129
- <img
1130
- src={agentAvatarUrl(team.teamName)}
1131
- alt={team.displayName}
1132
- className="size-9 shrink-0 rounded-lg border bg-[var(--color-surface-raised)] object-cover"
1133
- style={teamColorSet ? { borderColor: teamColorSet.border } : undefined}
1134
- draggable={false}
1135
- />
1136
- <div className="flex min-w-0 flex-1 flex-col gap-0.5">
1137
- <div className="flex min-w-0 items-center gap-1.5">
1138
- <h3 className="min-w-0 flex-1 truncate text-sm font-semibold text-[var(--color-text)]">
1139
- {team.displayName}
1140
- </h3>
1141
- <StatusBadge status={status} />
1142
- {team.pendingDelete || team.restartRequired ? (
1143
- <PendingDeleteBadge />
1144
- ) : null}
1145
- </div>
1146
- <span className="truncate font-mono text-[10px] text-[var(--color-text-muted)]">
1147
- 工号 {team.teamName}
1154
+ {/* Row 1: Avatar + Name + Status + Actions */}
1155
+ <div className="flex items-center gap-2.5">
1156
+ <img
1157
+ src={agentAvatarUrl(team.teamName)}
1158
+ alt={team.displayName}
1159
+ className="size-8 shrink-0 rounded-md border border-transparent"
1160
+ style={teamColorSet ? { borderColor: teamColorSet.border + '60' } : undefined}
1161
+ draggable={false}
1162
+ />
1163
+ <div className="flex min-w-0 flex-1 items-center gap-2">
1164
+ <h3 className="min-w-0 truncate text-[13px] font-medium text-[var(--color-text)]">
1165
+ {team.displayName}
1166
+ </h3>
1167
+ {isSystemManager ? (
1168
+ <span className="shrink-0 rounded bg-cyan-500/15 px-1.5 py-px text-[9px] font-medium text-cyan-400">
1169
+ SYS
1148
1170
  </span>
1149
- </div>
1171
+ ) : null}
1172
+ <StatusBadge status={status} />
1173
+ {team.pendingDelete || team.restartRequired ? (
1174
+ <PendingDeleteBadge />
1175
+ ) : null}
1150
1176
  {team.projectPath &&
1151
1177
  (() => {
1152
1178
  const branch = branchByPath[normalizePath(team.projectPath)];
1153
1179
  if (!branch) return null;
1154
1180
  return (
1155
1181
  <span
1156
- className="flex shrink-0 items-center gap-1 rounded bg-[var(--color-surface-raised)] px-1.5 py-0.5 text-[10px] text-[var(--color-text-muted)]"
1182
+ className="flex shrink-0 items-center gap-1 text-[10px] text-[var(--color-text-muted)] opacity-60"
1157
1183
  title={branch}
1158
1184
  >
1159
- <GitBranch size={10} />
1160
- <span className="max-w-24 truncate">{branch}</span>
1185
+ <GitBranch size={9} />
1186
+ <span className="max-w-20 truncate">{branch}</span>
1161
1187
  </span>
1162
1188
  );
1163
1189
  })()}
1164
1190
  </div>
1165
- <div className="flex shrink-0 gap-1">
1166
- {!team.pendingCreate && (
1191
+ <div className="flex shrink-0 gap-0.5">
1192
+ {!team.pendingCreate && !isSystemManager && (
1167
1193
  <Tooltip>
1168
1194
  <TooltipTrigger asChild>
1169
1195
  <button
1170
1196
  type="button"
1171
- className="shrink-0 rounded p-1 text-[var(--color-text-muted)] opacity-0 transition-opacity hover:bg-blue-500/10 hover:text-blue-300 group-hover:opacity-100"
1197
+ className="rounded p-1 text-[var(--color-text-muted)] opacity-0 transition-opacity hover:bg-[var(--color-surface-raised)] group-hover:opacity-60 hover:!opacity-100"
1172
1198
  onClick={(e) => handleCopyTeam(team.teamName, e)}
1173
1199
  >
1174
- <Copy size={14} />
1200
+ <Copy size={13} />
1175
1201
  </button>
1176
1202
  </TooltipTrigger>
1177
1203
  <TooltipContent side="bottom">复制数字员工</TooltipContent>
1178
1204
  </Tooltip>
1179
1205
  )}
1180
- {team.teamName !== 'default' && team.teamName !== 'my-project' && (
1181
- <Tooltip>
1182
- <TooltipTrigger asChild>
1183
- <button
1184
- type="button"
1185
- className="shrink-0 rounded p-1 text-[var(--color-text-muted)] opacity-0 transition-opacity hover:bg-red-500/10 hover:text-red-300 group-hover:opacity-100"
1186
- onClick={(e) =>
1187
- handleDeleteTeam(team.teamName, !!team.pendingCreate, e)
1188
- }
1189
- >
1190
- <Trash2 size={14} />
1191
- </button>
1192
- </TooltipTrigger>
1193
- <TooltipContent side="bottom">删除数字员工</TooltipContent>
1194
- </Tooltip>
1195
- )}
1206
+ {team.teamName !== 'default' &&
1207
+ team.teamName !== 'my-project' &&
1208
+ !isSystemManager && (
1209
+ <Tooltip>
1210
+ <TooltipTrigger asChild>
1211
+ <button
1212
+ type="button"
1213
+ className="rounded p-1 text-[var(--color-text-muted)] opacity-0 transition-opacity hover:bg-red-500/10 hover:text-red-400 group-hover:opacity-60 hover:!opacity-100"
1214
+ onClick={(e) =>
1215
+ handleDeleteTeam(team.teamName, !!team.pendingCreate, e)
1216
+ }
1217
+ >
1218
+ <Trash2 size={13} />
1219
+ </button>
1220
+ </TooltipTrigger>
1221
+ <TooltipContent side="bottom">删除数字员工</TooltipContent>
1222
+ </Tooltip>
1223
+ )}
1196
1224
  </div>
1197
1225
  </div>
1198
- <div className="mt-2 flex min-h-10 items-start gap-2">
1199
- <p className="line-clamp-2 min-w-0 flex-1 text-xs text-[var(--color-text-muted)]">
1200
- {team.description || '暂无描述'}
1201
- </p>
1202
- </div>
1203
- <div className="mt-3 flex flex-wrap items-center gap-1.5">
1204
- {team.members && team.members.length > 0 ? (
1205
- renderMemberChips(team.members, isLight)
1206
- ) : team.memberCount === 0 ? (
1207
- <Badge variant="secondary" className="text-[10px] font-normal">
1208
- 单人
1209
- </Badge>
1226
+
1227
+ {/* Row 2: Description */}
1228
+ <p className="mt-1.5 line-clamp-1 min-w-0 pl-[42px] text-[11px] leading-snug text-[var(--color-text-muted)]">
1229
+ {team.description || '暂无描述'}
1230
+ </p>
1231
+
1232
+ {/* Row 3: Stats bar */}
1233
+ <div className="mt-2 flex items-center gap-1.5 pl-[42px] text-[10px] tabular-nums">
1234
+ {team.stats && team.stats.sessions > 0 ? (
1235
+ <>
1236
+ <span className="text-blue-400">{team.stats.sessions} sessions</span>
1237
+ <span className="text-[var(--color-text-muted)] opacity-30">·</span>
1238
+ <span className="text-emerald-400">{formatTokensCompact(team.stats.tokens)}</span>
1239
+ {team.stats.durationMs > 0 && (
1240
+ <>
1241
+ <span className="text-[var(--color-text-muted)] opacity-30">·</span>
1242
+ <span className="text-amber-400">{formatDurationShort(team.stats.durationMs)}</span>
1243
+ </>
1244
+ )}
1245
+ </>
1210
1246
  ) : (
1211
- <Badge variant="secondary" className="text-[10px] font-normal">
1212
- 成员:{team.memberCount}
1213
- </Badge>
1247
+ <span className="text-[var(--color-text-muted)] opacity-50">no activity</span>
1248
+ )}
1249
+ {team.lastActivity && (
1250
+ <>
1251
+ <span className="text-[var(--color-text-muted)] opacity-30">·</span>
1252
+ <span className="text-[var(--color-text-muted)]">{formatRelativeTime(team.lastActivity)}</span>
1253
+ </>
1214
1254
  )}
1215
- </div>
1216
- <div className="mt-auto">
1217
- {(() => {
1218
- const tc = taskCountsByTeam.get(team.teamName);
1219
- const pending = tc?.pending ?? 0;
1220
- const inProgress = tc?.inProgress ?? 0;
1221
- const completed = tc?.completed ?? 0;
1222
- const totalTasks = pending + inProgress + completed;
1223
- const completedRatio = totalTasks > 0 ? completed / totalTasks : 0;
1224
- return (
1225
- <div className="mt-2 w-full space-y-1.5">
1226
- <div className="flex items-center gap-2">
1227
- <div
1228
- className="h-1.5 flex-1 overflow-hidden rounded-full bg-[var(--color-surface-raised)]"
1229
- role="progressbar"
1230
- aria-valuenow={completed}
1231
- aria-valuemin={0}
1232
- aria-valuemax={totalTasks}
1233
- aria-label={`任务 ${completed}/${totalTasks} 已完成`}
1234
- >
1235
- <div
1236
- className="h-full rounded-full bg-emerald-500 transition-all duration-200"
1237
- style={{ width: `${Math.round(completedRatio * 100)}%` }}
1238
- />
1239
- </div>
1240
- <span className="shrink-0 text-[10px] font-medium tracking-tight text-[var(--color-text-muted)]">
1241
- {completed}/{totalTasks}
1242
- </span>
1243
- </div>
1244
- {totalTasks > 0 && (
1245
- <div className="flex flex-wrap items-center gap-x-3 gap-y-0.5 text-[10px] text-[var(--color-text-muted)]">
1246
- {inProgress > 0 && (
1247
- <span className="inline-flex items-center gap-1">
1248
- <Play size={10} className="shrink-0 text-blue-400" />
1249
- {inProgress} 进行中
1250
- </span>
1251
- )}
1252
- {pending > 0 && (
1253
- <span className="inline-flex items-center gap-1">
1254
- <Clock size={10} className="shrink-0 text-amber-400" />
1255
- {pending} 待办
1256
- </span>
1257
- )}
1258
- {completed > 0 && (
1259
- <span className="inline-flex items-center gap-1">
1260
- <CheckCircle size={10} className="shrink-0 text-emerald-400" />
1261
- {completed} 已完成
1262
- </span>
1263
- )}
1264
- </div>
1265
- )}
1266
- </div>
1267
- );
1268
- })()}
1269
- {renderTeamRecentPaths(team, status, matchesCurrentProject, isLight)}
1270
1255
  </div>
1271
1256
  </div>
1272
1257
  </div>
@@ -233,7 +233,7 @@ export const CreateTaskDialog = ({
233
233
  >
234
234
  <AlertTriangle size={14} className="mt-0.5 shrink-0" />
235
235
  <p className="text-xs leading-relaxed">
236
- 团队当前离线。任务会加入 <strong>待处理</strong>,启动团队后即可开始执行。
236
+ 数字员工当前未运行:没有本地 Claude/Agent 进程在运行。任务会加入 <strong>待处理</strong>,启动数字员工后即可开始执行。
237
237
  </p>
238
238
  </div>
239
239
  ) : null}
@@ -468,7 +468,7 @@ export const CreateTaskDialog = ({
468
468
  </div>
469
469
  {!isTeamAlive ? (
470
470
  <p className="text-[10px] text-[var(--color-text-muted)]">
471
- 团队当前离线。请先启动团队,才能立即开始任务。
471
+ 数字员工当前未运行。请先启动数字员工,才能立即开始任务。
472
472
  </p>
473
473
  ) : null}
474
474
  </div>