@yancyyu/openhermit 1.6.38 → 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 (188) hide show
  1. package/dist-renderer/assets/ProjectEditorOverlay-krO5vQxX.js +58 -0
  2. package/dist-renderer/assets/{TeamGraphOverlay-ZEDfZyHb.js → TeamGraphOverlay-DqhQzcTr.js} +1 -1
  3. package/dist-renderer/assets/{_basePickBy-CIhniz70.js → _basePickBy-B7kSYPxr.js} +1 -1
  4. package/dist-renderer/assets/{_baseUniq-cKAW4Q8I.js → _baseUniq-CnjxqwAk.js} +1 -1
  5. package/dist-renderer/assets/{arc-YmNsoDXW.js → arc-CLeZuINP.js} +1 -1
  6. package/dist-renderer/assets/{architectureDiagram-VXUJARFQ-DHEls2sX.js → architectureDiagram-VXUJARFQ-QKtqaqdY.js} +1 -1
  7. package/dist-renderer/assets/{blockDiagram-VD42YOAC-Bpwf1Sbg.js → blockDiagram-VD42YOAC-BqdrzO_f.js} +1 -1
  8. package/dist-renderer/assets/{c4Diagram-YG6GDRKO-B0IaQ4w5.js → c4Diagram-YG6GDRKO-gwPlCxDC.js} +1 -1
  9. package/dist-renderer/assets/channel-DpMHF50r.js +1 -0
  10. package/dist-renderer/assets/{chunk-4BX2VUAB-DLk-hcFc.js → chunk-4BX2VUAB-C6XLurL4.js} +1 -1
  11. package/dist-renderer/assets/{chunk-55IACEB6-1XRmX_Zm.js → chunk-55IACEB6-Ds6quhEP.js} +1 -1
  12. package/dist-renderer/assets/{chunk-B4BG7PRW-1waH1DAD.js → chunk-B4BG7PRW-5UlA1_e9.js} +1 -1
  13. package/dist-renderer/assets/{chunk-DI55MBZ5-BqpZBtrN.js → chunk-DI55MBZ5-ywFrqIsY.js} +1 -1
  14. package/dist-renderer/assets/{chunk-FMBD7UC4-Bly7vVym.js → chunk-FMBD7UC4-C7ifUA17.js} +1 -1
  15. package/dist-renderer/assets/{chunk-QN33PNHL-Ci2QWBAs.js → chunk-QN33PNHL-BxGCo80U.js} +1 -1
  16. package/dist-renderer/assets/{chunk-QZHKN3VN-YCqFW7d-.js → chunk-QZHKN3VN-B2CuaZs6.js} +1 -1
  17. package/dist-renderer/assets/{chunk-TZMSLE5B-B0xGXInl.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-DxcFNQKT.js → cose-bilkent-S5V4N54A-Cz1GVtLp.js} +1 -1
  22. package/dist-renderer/assets/{dagre-6UL2VRFP-DPo_RfZY.js → dagre-6UL2VRFP-BrmR-P4h.js} +1 -1
  23. package/dist-renderer/assets/{diagram-PSM6KHXK-U3hQsFe4.js → diagram-PSM6KHXK-DbNjC5Rg.js} +1 -1
  24. package/dist-renderer/assets/{diagram-QEK2KX5R-OrwrAy0V.js → diagram-QEK2KX5R-qkRX5_Mq.js} +1 -1
  25. package/dist-renderer/assets/{diagram-S2PKOQOG-CXATPWVw.js → diagram-S2PKOQOG-CyL5rCv2.js} +1 -1
  26. package/dist-renderer/assets/{erDiagram-Q2GNP2WA-B0e8AfMF.js → erDiagram-Q2GNP2WA-Dox3-bA5.js} +1 -1
  27. package/dist-renderer/assets/{flowDiagram-NV44I4VS-CXfzA4jJ.js → flowDiagram-NV44I4VS-BtkaxlDL.js} +1 -1
  28. package/dist-renderer/assets/{ganttDiagram-JELNMOA3-CMr08qVl.js → ganttDiagram-JELNMOA3-Dhy_d9GK.js} +1 -1
  29. package/dist-renderer/assets/{gitGraphDiagram-V2S2FVAM-vYFHpPmy.js → gitGraphDiagram-V2S2FVAM-B5XRhIQA.js} +1 -1
  30. package/dist-renderer/assets/{graph-DOe5j8dH.js → graph-CsoEwUhS.js} +1 -1
  31. package/dist-renderer/assets/{index-BySQS7AB.js → index-BWPWmJNo.js} +1 -1
  32. package/dist-renderer/assets/{index-V7dAKPqd.js → index-Bu2R-Se7.js} +587 -705
  33. package/dist-renderer/assets/index-CnWV3BhG.css +32 -0
  34. package/dist-renderer/assets/{index-CzWxVCRL.js → index-D-3KgskL.js} +1 -1
  35. package/dist-renderer/assets/{index-VJ-MM9xa.js → index-DGEBzLNT.js} +1 -1
  36. package/dist-renderer/assets/{index-B2Dy7M2G.js → index-NhHNs2Oo.js} +1 -1
  37. package/dist-renderer/assets/{index-C_okzZXP.js → index-h17WuEyf.js} +1 -1
  38. package/dist-renderer/assets/{infoDiagram-HS3SLOUP-D_WubR0B.js → infoDiagram-HS3SLOUP-hMGmNojH.js} +1 -1
  39. package/dist-renderer/assets/{journeyDiagram-XKPGCS4Q-w9ca-1TI.js → journeyDiagram-XKPGCS4Q-DXV2rBDl.js} +1 -1
  40. package/dist-renderer/assets/{kanban-definition-3W4ZIXB7-Jg9p6_pN.js → kanban-definition-3W4ZIXB7-Bf99WLRy.js} +1 -1
  41. package/dist-renderer/assets/{layout-B-z3y17c.js → layout-C3XWrpwo.js} +1 -1
  42. package/dist-renderer/assets/{linear-D-RTX5UW.js → linear-OEEcn8KN.js} +1 -1
  43. package/dist-renderer/assets/{mindmap-definition-VGOIOE7T-CDQmHOYP.js → mindmap-definition-VGOIOE7T-Dpi3S2x4.js} +1 -1
  44. package/dist-renderer/assets/{pieDiagram-ADFJNKIX-D_odsQL7.js → pieDiagram-ADFJNKIX-xTPPhtNx.js} +1 -1
  45. package/dist-renderer/assets/{quadrantDiagram-AYHSOK5B-BRsmYWSA.js → quadrantDiagram-AYHSOK5B-euniyDlz.js} +1 -1
  46. package/dist-renderer/assets/{requirementDiagram-UZGBJVZJ-ChNE_BOV.js → requirementDiagram-UZGBJVZJ-D9Uiw4kF.js} +1 -1
  47. package/dist-renderer/assets/{sankeyDiagram-TZEHDZUN-C8FtpwKc.js → sankeyDiagram-TZEHDZUN-CySU4nED.js} +1 -1
  48. package/dist-renderer/assets/{sequenceDiagram-WL72ISMW-DmLCzNcc.js → sequenceDiagram-WL72ISMW-JVGpET6V.js} +1 -1
  49. package/dist-renderer/assets/splashScene-D0YB9uxm.js +17 -0
  50. package/dist-renderer/assets/{stateDiagram-FKZM4ZOC-WJBm4bhu.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-BXs_hOJs.js → timeline-definition-IT6M3QCI-DmycNUUe.js} +1 -1
  53. package/dist-renderer/assets/{treemap-GDKQZRPO-o04MA0G9.js → treemap-GDKQZRPO-DPq4gZuB.js} +1 -1
  54. package/dist-renderer/assets/{xychartDiagram-PRI3JC2R-Czj69XRd.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 +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/common/TerminalPane.tsx +213 -0
  88. package/src/renderer/components/dashboard/DashboardView.tsx +9 -36
  89. package/src/renderer/components/extensions/ExtensionStoreView.tsx +6 -125
  90. package/src/renderer/components/extensions/ExtensionsSubTabTrigger.tsx +1 -1
  91. package/src/renderer/components/extensions/mcp/McpLibraryEnableDialog.tsx +305 -0
  92. package/src/renderer/components/extensions/mcp/McpLibraryEntryDialog.tsx +418 -0
  93. package/src/renderer/components/extensions/mcp/McpLibraryPanel.tsx +404 -0
  94. package/src/renderer/components/extensions/plugins/PluginCard.tsx +6 -6
  95. package/src/renderer/components/extensions/plugins/PluginsPanel.tsx +34 -21
  96. package/src/renderer/components/extensions/skills/SkillsLibraryPanel.tsx +335 -0
  97. package/src/renderer/components/layout/PaneContent.tsx +8 -1
  98. package/src/renderer/components/layout/Sidebar.tsx +11 -54
  99. package/src/renderer/components/layout/SortableTab.tsx +20 -31
  100. package/src/renderer/components/layout/TabBar.tsx +1 -1
  101. package/src/renderer/components/layout/TabContextMenu.tsx +1 -1
  102. package/src/renderer/components/runtime/ProviderRuntimeSettingsDialog.tsx +768 -157
  103. package/src/renderer/components/schedules/SchedulesView.tsx +51 -462
  104. package/src/renderer/components/schedules/calendar/CalendarDayView.tsx +173 -0
  105. package/src/renderer/components/schedules/calendar/CalendarEventBlock.tsx +113 -0
  106. package/src/renderer/components/schedules/calendar/CalendarHeader.tsx +148 -0
  107. package/src/renderer/components/schedules/calendar/CalendarMonthView.tsx +142 -0
  108. package/src/renderer/components/schedules/calendar/CalendarWeekView.tsx +219 -0
  109. package/src/renderer/components/schedules/calendar/ScheduleCalendarBoard.tsx +41 -0
  110. package/src/renderer/components/schedules/calendar/TeamGanttView.tsx +405 -0
  111. package/src/renderer/components/schedules/calendar/computeOccurrences.ts +234 -0
  112. package/src/renderer/components/schedules/calendar/index.ts +2 -0
  113. package/src/renderer/components/schedules/calendar/types.ts +44 -0
  114. package/src/renderer/components/settings/SettingsTabs.tsx +50 -55
  115. package/src/renderer/components/settings/SettingsView.tsx +30 -35
  116. package/src/renderer/components/settings/components/SettingsSectionHeader.tsx +5 -1
  117. package/src/renderer/components/settings/components/SettingsSelect.tsx +5 -3
  118. package/src/renderer/components/settings/components/SettingsToggle.tsx +2 -2
  119. package/src/renderer/components/settings/sections/AdvancedSection.tsx +11 -42
  120. package/src/renderer/components/settings/sections/CliStatusSection.tsx +71 -112
  121. package/src/renderer/components/settings/sections/ConfigEditorDialog.tsx +1 -1
  122. package/src/renderer/components/settings/sections/GeneralSection.tsx +11 -3
  123. package/src/renderer/components/settings/sections/HarnessSection.tsx +18 -14
  124. package/src/renderer/components/settings/sections/PlatformsSection.tsx +3 -3
  125. package/src/renderer/components/settings/sections/TaskBusSection.tsx +33 -40
  126. package/src/renderer/components/settings/sections/index.ts +0 -1
  127. package/src/renderer/components/sidebar/SidebarSessions.tsx +182 -4
  128. package/src/renderer/components/sidebar/SidebarTaskItem.tsx +4 -4
  129. package/src/renderer/components/sidebar/WorkspaceBrowser.tsx +39 -4
  130. package/src/renderer/components/splash/splashScene.ts +121 -929
  131. package/src/renderer/components/system-manager/FolderBrowser.tsx +163 -0
  132. package/src/renderer/components/system-manager/SystemManagerView.tsx +351 -0
  133. package/src/renderer/components/tasks/TasksView.tsx +112 -134
  134. package/src/renderer/components/team/CcSessionsSection.tsx +431 -89
  135. package/src/renderer/components/team/CollapsibleTeamSection.tsx +17 -32
  136. package/src/renderer/components/team/TeamDetailView.tsx +319 -123
  137. package/src/renderer/components/team/TeamListView.tsx +108 -123
  138. package/src/renderer/components/team/dialogs/CreateTaskDialog.tsx +2 -2
  139. package/src/renderer/components/team/dialogs/CreateTeamDialog.tsx +84 -306
  140. package/src/renderer/components/team/dialogs/EditTeamDialog.tsx +259 -342
  141. package/src/renderer/components/team/dialogs/GlobalTaskDetailDialog.tsx +1 -1
  142. package/src/renderer/components/team/dialogs/LaunchTeamDialog.tsx +17 -15
  143. package/src/renderer/components/team/dialogs/PlatformBindingDialog.tsx +221 -0
  144. package/src/renderer/components/team/dialogs/PlatformManualForm.tsx +7 -0
  145. package/src/renderer/components/team/dialogs/PlatformSetupQR.tsx +1 -1
  146. package/src/renderer/components/team/dialogs/RuntimeConfigDialog.tsx +361 -0
  147. package/src/renderer/components/team/dialogs/platformMeta.ts +122 -11
  148. package/src/renderer/components/team/dialogs/useTeamEditForm.ts +17 -5
  149. package/src/renderer/components/team/kanban/KanbanBoard.tsx +9 -9
  150. package/src/renderer/components/team/members/MemberCard.tsx +14 -47
  151. package/src/renderer/components/team/members/MemberDetailDialog.tsx +3 -95
  152. package/src/renderer/components/team/members/MemberDetailStats.tsx +50 -65
  153. package/src/renderer/components/team/messages/MessageComposer.tsx +8 -110
  154. package/src/renderer/components/team/messages/MessagesPanel.tsx +131 -114
  155. package/src/renderer/components/team/schedule/ScheduleStatusBadge.tsx +2 -2
  156. package/src/renderer/components/team/tools/AddMcpInline.tsx +27 -17
  157. package/src/renderer/components/team/tools/McpChip.tsx +6 -3
  158. package/src/renderer/components/team/tools/SkillChip.tsx +2 -2
  159. package/src/renderer/components/team/tools/ToolsSection.tsx +418 -70
  160. package/src/renderer/hooks/useExtensionsTabState.ts +3 -114
  161. package/src/renderer/index.css +39 -22
  162. package/src/renderer/index.html +17 -50
  163. package/src/renderer/store/index.ts +2 -1
  164. package/src/renderer/store/slices/scheduleSlice.ts +1 -1
  165. package/src/renderer/store/slices/teamSlice.ts +45 -168
  166. package/src/renderer/utils/claudeCodeOnlyProviders.ts +3 -10
  167. package/src/renderer/utils/memberHelpers.ts +5 -17
  168. package/src/renderer/utils/openCodeRuntimeDeliveryDiagnostics.ts +4 -2
  169. package/src/renderer/utils/providerSlashCommands.ts +0 -5
  170. package/src/renderer/utils/scheduleFormatters.ts +3 -1
  171. package/src/renderer/utils/teamMessageFiltering.ts +14 -1
  172. package/src/renderer/utils/teamModelAvailability.ts +18 -2
  173. package/src/shared/types/api.ts +121 -2
  174. package/src/shared/types/ccConnect.ts +2 -0
  175. package/src/shared/types/index.ts +3 -0
  176. package/src/shared/types/systemManager.ts +49 -0
  177. package/src/shared/types/team.ts +29 -0
  178. package/src/shared/types/terminal.ts +4 -2
  179. package/src/shared/utils/extensionNormalizers.ts +15 -8
  180. package/src/shared/utils/providerExtensionCapabilities.ts +2 -2
  181. package/dist-renderer/assets/ProjectEditorOverlay-lJZi-9Hp.js +0 -52
  182. package/dist-renderer/assets/channel-yIlSKy0e.js +0 -1
  183. package/dist-renderer/assets/classDiagram-2ON5EDUG-24fHez0s.js +0 -1
  184. package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-24fHez0s.js +0 -1
  185. package/dist-renderer/assets/clone-BTNuUva-.js +0 -1
  186. package/dist-renderer/assets/index-Bi6nrZ4z.css +0 -1
  187. package/dist-renderer/assets/splashScene-C8lWNnm4.js +0 -1
  188. package/dist-renderer/assets/stateDiagram-v2-4FDKWEC3-_m6iPPUR.js +0 -1
@@ -46,15 +46,9 @@ function hashStringToIndex(str: string): number {
46
46
  export function agentAvatarUrl(name: string, size = 64): string {
47
47
  void size;
48
48
  const normalized = name.trim().toLowerCase();
49
- if (isLeadMemberName(normalized)) {
50
- return LEAD_PARTICIPANT_AVATAR_URL;
51
- }
52
49
 
53
- // Temporarily disabled external avatar API.
54
- // return `https://robohash.org/${encodeURIComponent(name)}?size=${size}x${size}`;
55
- return getParticipantAvatarUrlByIndex(
56
- hashStringToIndex(normalized) % PARTICIPANT_AVATAR_URLS.length
57
- );
50
+ // DiceBear adventurer avatars deterministic per name, no API key needed
51
+ return `https://api.dicebear.com/9.x/adventurer/svg?seed=${encodeURIComponent(normalized)}&backgroundColor=c0aede,d1d4f9,ffd5dc,ffdfbf,b6e3f4,c1f0c1`;
58
52
  }
59
53
 
60
54
  export const STATUS_DOT_COLORS: Record<MemberStatus, string> = {
@@ -804,22 +798,16 @@ export function buildMemberAvatarMap(members: readonly MemberAvatarInput[]): Map
804
798
  const teammateMembers = activeMembers.filter((member) => !isLeadMember(member));
805
799
 
806
800
  for (const [index, member] of leadMembers.entries()) {
807
- map.set(member.name, index === 0 ? LEAD_PARTICIPANT_AVATAR_URL : agentAvatarUrl(member.name));
801
+ map.set(member.name, agentAvatarUrl(member.name));
808
802
  }
809
803
 
810
804
  for (const [index, member] of teammateMembers.entries()) {
811
- map.set(
812
- member.name,
813
- getParticipantAvatarUrlByIndex(1 + (index % (PARTICIPANT_AVATAR_URLS.length - 1)))
814
- );
805
+ map.set(member.name, agentAvatarUrl(member.name));
815
806
  }
816
807
 
817
808
  for (const member of members) {
818
809
  if (!map.has(member.name)) {
819
- map.set(
820
- member.name,
821
- isLeadMember(member) ? LEAD_PARTICIPANT_AVATAR_URL : agentAvatarUrl(member.name)
822
- );
810
+ map.set(member.name, agentAvatarUrl(member.name));
823
811
  }
824
812
  }
825
813
 
@@ -17,6 +17,8 @@ interface OpenCodeRuntimeDeliveryDiagnostics {
17
17
  debugDetails: OpenCodeRuntimeDeliveryDebugDetails | null;
18
18
  }
19
19
 
20
+ const FAILED_WARNING =
21
+ 'OpenCode runtime delivery failed. Message was saved to inbox, but live delivery did not complete.';
20
22
  const PENDING_WARNING =
21
23
  'OpenCode runtime delivery is still being checked. Message was saved and will be retried if needed.';
22
24
 
@@ -33,7 +35,7 @@ export function buildOpenCodeRuntimeDeliveryDiagnostics(
33
35
  const isFailed = runtimeDelivery.delivered === false;
34
36
  if (isFailed) {
35
37
  return {
36
- warning: null,
38
+ warning: FAILED_WARNING,
37
39
  debugDetails: {
38
40
  messageId: result.messageId,
39
41
  providerId: runtimeDelivery.providerId,
@@ -64,7 +66,7 @@ export function buildOpenCodeRuntimeDeliveryDiagnostics(
64
66
  debugDetails: {
65
67
  messageId: result.messageId,
66
68
  providerId: runtimeDelivery.providerId,
67
- delivered: null,
69
+ delivered: typeof runtimeDelivery.delivered === 'boolean' ? runtimeDelivery.delivered : null,
68
70
  responsePending: true,
69
71
  responseState: runtimeDelivery.responseState ?? null,
70
72
  ledgerStatus: runtimeDelivery.ledgerStatus ?? null,
@@ -39,11 +39,6 @@ const CODEX_SLASH_COMMAND_SUGGESTIONS: readonly KnownSlashCommandDefinition[] =
39
39
  command: '/status',
40
40
  description: 'Show session configuration and token usage.',
41
41
  },
42
- {
43
- name: 'mcp',
44
- command: '/mcp',
45
- description: 'List configured MCP tools for this session.',
46
- },
47
42
  {
48
43
  name: 'mention',
49
44
  command: '/mention',
@@ -8,8 +8,10 @@ export function formatNextRun(isoString?: string): string {
8
8
  if (!isoString) return '暂无';
9
9
  try {
10
10
  const date = new Date(isoString);
11
+ const ts = date.getTime();
12
+ if (!Number.isFinite(ts)) return isoString;
11
13
  const now = Date.now();
12
- const diffMs = date.getTime() - now;
14
+ const diffMs = ts - now;
13
15
 
14
16
  if (diffMs < 0) return '已逾期';
15
17
 
@@ -70,7 +70,20 @@ export function filterTeamMessages(
70
70
  const summary = getSanitizedInboxMessageSummary(m).toLowerCase();
71
71
  const from = (m.from ?? '').toLowerCase();
72
72
  const to = (m.to ?? '').toLowerCase();
73
- return text.includes(q) || summary.includes(q) || from.includes(q) || to.includes(q);
73
+ const sessionTitle = (m.session?.title ?? '').toLowerCase();
74
+ const sessionUserName = (m.session?.userName ?? '').toLowerCase();
75
+ const sessionChatName = (m.session?.chatName ?? '').toLowerCase();
76
+ const sessionKey = (m.session?.key ?? '').toLowerCase();
77
+ return (
78
+ text.includes(q) ||
79
+ summary.includes(q) ||
80
+ from.includes(q) ||
81
+ to.includes(q) ||
82
+ sessionTitle.includes(q) ||
83
+ sessionUserName.includes(q) ||
84
+ sessionChatName.includes(q) ||
85
+ sessionKey.includes(q)
86
+ );
74
87
  });
75
88
  }
76
89
 
@@ -402,7 +402,19 @@ export function isTeamModelAvailableForUi(
402
402
  return getRuntimeModelAvailability(providerId, trimmed, providerStatus) === 'available';
403
403
  }
404
404
 
405
- return true;
405
+ if (!providerStatus) {
406
+ return true;
407
+ }
408
+
409
+ const hasRuntimeModelTruth =
410
+ providerStatus.models.length > 0 ||
411
+ (providerStatus.modelCatalog?.models.length ?? 0) > 0 ||
412
+ (providerStatus.modelAvailability?.length ?? 0) > 0;
413
+ if (!hasRuntimeModelTruth) {
414
+ return true;
415
+ }
416
+
417
+ return getRuntimeModelAvailability(providerId, trimmed, providerStatus) === 'available';
406
418
  }
407
419
 
408
420
  export function normalizeExplicitTeamModelForUi(
@@ -437,7 +449,11 @@ export function normalizeTeamModelForUi(
437
449
  return isTeamModelAvailableForUi(providerId, trimmed, providerStatus) ? normalized : '';
438
450
  }
439
451
 
440
- return normalized;
452
+ if (providerId === 'codex' && trimmed === 'gpt-5.4-mini') {
453
+ return '';
454
+ }
455
+
456
+ return isTeamModelAvailableForUi(providerId, trimmed, providerStatus) ? normalized : '';
441
457
  }
442
458
 
443
459
  export function getTeamModelSelectionError(
@@ -81,6 +81,7 @@ import type {
81
81
  TeamProvisioningModelVerificationMode,
82
82
  TeamProvisioningPrepareResult,
83
83
  TeamProvisioningProgress,
84
+ SystemManagerSummary,
84
85
  TeamSummary,
85
86
  TeamTask,
86
87
  TeamTaskStatus,
@@ -93,6 +94,7 @@ import type {
93
94
  ToolApprovalSettings,
94
95
  UpdateKanbanPatch,
95
96
  } from './team';
97
+ import type { SystemManagerAPI } from './systemManager';
96
98
  import type { TerminalAPI } from './terminal';
97
99
  import type { WaterfallData } from './visualization';
98
100
  import type { RecentProjectsElectronApi } from '@features/recent-projects/contracts';
@@ -491,8 +493,8 @@ export interface CcSession {
491
493
  projectId: string;
492
494
  sessionKey: string;
493
495
  platform: string;
494
- userName: string;
495
- chatName: string;
496
+ userName: string | null;
497
+ chatName: string | null;
496
498
  active: boolean;
497
499
  live: boolean;
498
500
  historyCount: number;
@@ -522,8 +524,122 @@ export interface CcSessionDetail {
522
524
  history: CcSessionMessage[];
523
525
  }
524
526
 
527
+ export type ConversationTelemetryExportFormat = 'csv' | 'json' | 'markdown' | 'plaintext';
528
+
529
+ export type ConversationTelemetryIncludeContent = 'none' | 'summary' | 'full';
530
+
531
+ export interface ConversationTelemetryQuery {
532
+ teamName?: string;
533
+ platform?: string;
534
+ from?: string;
535
+ to?: string;
536
+ identityType?: 'person' | 'group' | 'unknown';
537
+ identityId?: string;
538
+ includeContent?: ConversationTelemetryIncludeContent;
539
+ includeToolResults?: boolean;
540
+ includeSystemMessages?: boolean;
541
+ limit?: number;
542
+ offset?: number;
543
+ }
544
+
545
+ export interface ConversationTelemetryMessage {
546
+ role: 'user' | 'assistant' | 'system' | 'tool' | 'unknown';
547
+ timestamp?: string;
548
+ content: string;
549
+ uuid?: string;
550
+ parentUuid?: string | null;
551
+ model?: string;
552
+ requestId?: string;
553
+ usage?: {
554
+ inputTokens: number;
555
+ outputTokens: number;
556
+ cacheReadTokens: number;
557
+ cacheCreationTokens: number;
558
+ totalTokens: number;
559
+ };
560
+ isMeta?: boolean;
561
+ }
562
+
563
+ export interface ConversationTelemetryRow {
564
+ teamName: string;
565
+ teamDisplayName: string;
566
+ projectName: string;
567
+ session: {
568
+ ccSessionId?: string;
569
+ sessionKey: string;
570
+ agentSessionId?: string;
571
+ claudeSessionId?: string;
572
+ projectPath?: string;
573
+ jsonlRelPath?: string;
574
+ createdAt?: string;
575
+ updatedAt?: string;
576
+ startTime?: string;
577
+ endTime?: string;
578
+ active?: boolean;
579
+ live?: boolean;
580
+ matchStatus: 'matched' | 'missing-agent-session-id' | 'jsonl-not-found' | 'ambiguous' | 'local-only';
581
+ };
582
+ identity: {
583
+ platform: string;
584
+ type: 'person' | 'group' | 'unknown';
585
+ id?: string;
586
+ userId?: string;
587
+ chatId?: string;
588
+ displayName: string;
589
+ userName?: string;
590
+ chatName?: string;
591
+ confidence: 'exact-id' | 'name-only' | 'allowlist-fallback' | 'session-key-only' | 'missing-id';
592
+ };
593
+ content: {
594
+ messageCount: number;
595
+ userMessageCount: number;
596
+ assistantMessageCount: number;
597
+ toolResultCount: number;
598
+ firstUserMessage?: string;
599
+ firstUserMessageAt?: string;
600
+ lastUserMessage?: string;
601
+ lastUserMessageAt?: string;
602
+ lastMessageRole?: ConversationTelemetryMessage['role'];
603
+ lastMessageContent?: string;
604
+ lastMessageAt?: string;
605
+ text?: string;
606
+ messages?: ConversationTelemetryMessage[];
607
+ };
608
+ usage: {
609
+ inputTokens: number;
610
+ outputTokens: number;
611
+ cacheReadTokens: number;
612
+ cacheCreationTokens: number;
613
+ totalTokens: number;
614
+ assistantTurnsWithUsage: number;
615
+ models: Record<string, number>;
616
+ toolCalls: Record<string, number>;
617
+ usageSource: 'claude-jsonl' | 'missing';
618
+ };
619
+ }
620
+
621
+ export interface ConversationTelemetryResponse {
622
+ rows: ConversationTelemetryRow[];
623
+ nextOffset?: number;
624
+ computedAt: string;
625
+ summary: {
626
+ conversations: number;
627
+ runningConversations: number;
628
+ missingIdentityIds: number;
629
+ unmatchedSessions: number;
630
+ totalTokens: number;
631
+ };
632
+ }
633
+
634
+ export interface ConversationTelemetryExportResponse {
635
+ filename: string;
636
+ mimeType: string;
637
+ content: string;
638
+ }
639
+
525
640
  export interface TeamsAPI {
526
641
  list: () => Promise<TeamSummary[]>;
642
+ ensureSystemManager: () => Promise<SystemManagerSummary>;
527
643
  getData: (teamName: string) => Promise<TeamViewSnapshot>;
528
644
  getTaskChangePresence: (teamName: string) => Promise<Record<string, TaskChangePresenceState>>;
529
645
  setChangePresenceTracking: (teamName: string, enabled: boolean) => Promise<void>;
@@ -1096,6 +1212,9 @@ export interface ElectronAPI extends RecentProjectsElectronApi {
1096
1212
  // CLI Installer API
1097
1213
  cliInstaller: CliInstallerAPI;
1098
1214
 
1215
+ // System Manager / Control Console API
1216
+ systemManager: SystemManagerAPI;
1217
+
1099
1218
  // Embedded Terminal API (xterm.js + node-pty)
1100
1219
  terminal: TerminalAPI;
1101
1220
 
@@ -93,6 +93,8 @@ export interface CcProjectSettingsUpdate {
93
93
  reply_footer?: boolean;
94
94
  inject_sender?: boolean;
95
95
  platform_allow_from?: Record<string, string>;
96
+ /** 群聊允许的 chat ID,* 表示所有群聊 */
97
+ platform_allow_chat?: Record<string, string>;
96
98
  }
97
99
 
98
100
  export interface CcAddPlatformRequest {
@@ -41,6 +41,9 @@ export type * from './providers';
41
41
  // Re-export Terminal types
42
42
  export type * from './terminal';
43
43
 
44
+ // Re-export System Manager types
45
+ export type * from './systemManager';
46
+
44
47
  // Re-export Editor types
45
48
  export type * from './editor';
46
49
 
@@ -0,0 +1,49 @@
1
+ export interface SystemManagerStatus {
2
+ displayName: '控制台';
3
+ defaultWorkDir: string;
4
+ selectedWorkDir: string;
5
+ workflowFolder?: string;
6
+ claudeCommand: 'claude';
7
+ localStatus: 'ready' | 'missing-claude' | 'error';
8
+ error?: string;
9
+ }
10
+
11
+ export interface SystemManagerConfig {
12
+ schemaVersion: 1;
13
+ selectedWorkDir: string;
14
+ workflowFolder?: string;
15
+ updatedAt: string;
16
+ }
17
+
18
+ export interface SystemManagerConfigPatch {
19
+ selectedWorkDir?: string;
20
+ workflowFolder?: string | null;
21
+ }
22
+
23
+ export interface WorkflowPromptSummary {
24
+ id: string;
25
+ label: string;
26
+ filename: string;
27
+ path: string;
28
+ sizeBytes: number;
29
+ updatedAt: string;
30
+ }
31
+
32
+ export interface WorkflowPromptListResponse {
33
+ folder: string;
34
+ prompts: WorkflowPromptSummary[];
35
+ warnings: string[];
36
+ }
37
+
38
+ export interface WorkflowPromptContentResponse {
39
+ prompt: WorkflowPromptSummary;
40
+ content: string;
41
+ }
42
+
43
+ export interface SystemManagerAPI {
44
+ getStatus: () => Promise<SystemManagerStatus>;
45
+ getConfig: () => Promise<SystemManagerConfig>;
46
+ updateConfig: (patch: SystemManagerConfigPatch) => Promise<SystemManagerConfig>;
47
+ listWorkflowPrompts: (folder: string) => Promise<WorkflowPromptListResponse>;
48
+ readWorkflowPrompt: (folder: string, id: string) => Promise<WorkflowPromptContentResponse>;
49
+ }
@@ -1,6 +1,22 @@
1
1
  import type { ExecutionTarget } from './api';
2
2
  import type { EnhancedChunk } from '@main/types';
3
3
 
4
+ export const SYSTEM_MANAGER_TEAM_NAME = 'system-manager';
5
+ export const SYSTEM_MANAGER_DISPLAY_NAME = '控制台';
6
+ export const SYSTEM_MANAGER_BIND_PROJECT = 'my-project';
7
+
8
+ export interface SystemManagerSummary {
9
+ teamName: typeof SYSTEM_MANAGER_TEAM_NAME;
10
+ displayName: typeof SYSTEM_MANAGER_DISPLAY_NAME;
11
+ bindProject: typeof SYSTEM_MANAGER_BIND_PROJECT;
12
+ workDir: string;
13
+ projectPath?: string;
14
+ description: string;
15
+ localStatus: 'ready';
16
+ ccConnectProjectStatus: 'bound' | 'missing';
17
+ feishuStatus: 'unbound' | 'connected' | 'error' | 'unknown';
18
+ }
19
+
4
20
  export interface TeamMember {
5
21
  name: string;
6
22
  agentId?: string;
@@ -36,6 +52,8 @@ export interface TeamConfig {
36
52
  managedSources?: string;
37
53
  disabledCommands?: string[];
38
54
  platformAllowFrom?: Record<string, string>;
55
+ /** 群聊允许的 chat ID(按平台),* 表示所有群聊 */
56
+ platformAllowChat?: Record<string, string>;
39
57
  members?: TeamMember[];
40
58
  projectPath?: string;
41
59
  projectPathHistory?: string[];
@@ -61,6 +79,8 @@ export interface TeamUpdateConfigRequest {
61
79
  managedSources?: string;
62
80
  disabledCommands?: string[];
63
81
  platformAllowFrom?: Record<string, string>;
82
+ /** 群聊允许的 chat ID(按平台),* 表示所有群聊 */
83
+ platformAllowChat?: Record<string, string>;
64
84
  executionTarget?: ExecutionTarget;
65
85
  leadProviderId?: TeamProviderId;
66
86
  leadModel?: string;
@@ -122,6 +142,13 @@ export interface TeamSummary {
122
142
  runtimeCandidatePendingCount?: number;
123
143
  noRuntimePendingCount?: number;
124
144
  permissionPendingCount?: number;
145
+ /** Aggregated session stats from local JSONL files */
146
+ stats?: {
147
+ sessions: number;
148
+ messages: number;
149
+ tokens: number;
150
+ durationMs: number;
151
+ };
125
152
  }
126
153
 
127
154
  export type TeamTaskStatus = 'pending' | 'in_progress' | 'completed' | 'deleted';
@@ -1092,6 +1119,8 @@ export interface TeamViewSnapshot {
1092
1119
  processes: TeamProcess[];
1093
1120
  warnings?: string[];
1094
1121
  isAlive?: boolean;
1122
+ /** Bound external platforms (feishu, telegram, etc.) from cc-connect */
1123
+ platforms?: import('./ccConnect').CcProjectPlatform[];
1095
1124
  /** cc-connect project name this team is bound to */
1096
1125
  bindProject?: string;
1097
1126
  /** 团队协作开关:false = 独立作战,true = 可跨团队调度 */
@@ -40,8 +40,10 @@ export interface TerminalAPI {
40
40
  write: (ptyId: string, data: string) => void;
41
41
  /** Resize PTY terminal (fire-and-forget). */
42
42
  resize: (ptyId: string, cols: number, rows: number) => void;
43
- /** Kill PTY process (fire-and-forget). */
44
- kill: (ptyId: string) => void;
43
+ /** Kill PTY process. */
44
+ kill: (ptyId: string) => Promise<void>;
45
+ /** Open command in system Terminal.app (macOS). */
46
+ openExternal: (options: { command: string; args?: string[]; cwd?: string }) => Promise<void>;
45
47
  /** Subscribe to PTY data output. Returns cleanup function. */
46
48
  onData: (cb: (event: unknown, ptyId: string, data: string) => void) => () => void;
47
49
  /** Subscribe to PTY exit events. Returns cleanup function. */
@@ -109,15 +109,14 @@ export function buildPluginId(pluginName: string, marketplaceName: string): stri
109
109
  /**
110
110
  * Substrings that mark a plugin as "essential" (必装) — recommended/required for
111
111
  * the workbench. Matched against both the pluginId and homepage so it works
112
- * regardless of the marketplace name a plugin is published under. Note the codex
113
- * plugin ships as `codex@openai-codex` (repo: openai/codex-plugin-cc), so the
114
- * pluginId alone does not contain "codex-plugin-cc" — the homepage does.
112
+ * regardless of the marketplace name a plugin is published under.
115
113
  */
116
- export const ESSENTIAL_PLUGIN_PATTERNS = [
117
- 'oh-my-claudecode',
118
- 'codex@openai-codex',
119
- 'codex-plugin-cc',
120
- ] as const;
114
+ export const ESSENTIAL_PLUGIN_PATTERNS = ['oh-my-claudecode'] as const;
115
+
116
+ /**
117
+ * Marketplace plugins that should not be shown in Hermit's plugin store.
118
+ */
119
+ export const HIDDEN_PLUGIN_PATTERNS = ['codex@openai-codex', 'codex-plugin-cc'] as const;
121
120
 
122
121
  /**
123
122
  * Whether a plugin is one of the essential plugins surfaced with a 必装 badge and
@@ -128,6 +127,14 @@ export function isEssentialPlugin(plugin: { pluginId: string; homepage?: string
128
127
  return ESSENTIAL_PLUGIN_PATTERNS.some((pattern) => haystack.includes(pattern));
129
128
  }
130
129
 
130
+ /**
131
+ * Whether a plugin should be hidden from the plugin store catalog.
132
+ */
133
+ export function isHiddenPluginFromStore(plugin: { pluginId: string; homepage?: string }): boolean {
134
+ const haystack = `${plugin.pluginId} ${plugin.homepage ?? ''}`.toLowerCase();
135
+ return HIDDEN_PLUGIN_PATTERNS.some((pattern) => haystack.includes(pattern));
136
+ }
137
+
131
138
  /**
132
139
  * Namespaced operation-state key for plugin install/uninstall UI state.
133
140
  */
@@ -58,12 +58,12 @@ export function createLegacyRuntimeFallbackCliExtensionCapabilities(
58
58
  export function getCliProviderExtensionCapabilities(
59
59
  provider: Pick<CliProviderStatus, 'capabilities'> | null | undefined
60
60
  ): CliExtensionCapabilities {
61
- const fallback = createDefaultCliExtensionCapabilities();
62
61
  const extensions = provider?.capabilities?.extensions;
63
62
  if (!extensions) {
64
- return fallback;
63
+ return createLegacyRuntimeFallbackCliExtensionCapabilities();
65
64
  }
66
65
 
66
+ const fallback = createDefaultCliExtensionCapabilities();
67
67
  return {
68
68
  plugins: extensions.plugins ?? fallback.plugins,
69
69
  mcp: extensions.mcp ?? fallback.mcp,