@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.
- package/dist-renderer/assets/ProjectEditorOverlay-krO5vQxX.js +58 -0
- package/dist-renderer/assets/{TeamGraphOverlay-ZEDfZyHb.js → TeamGraphOverlay-DqhQzcTr.js} +1 -1
- package/dist-renderer/assets/{_basePickBy-CIhniz70.js → _basePickBy-B7kSYPxr.js} +1 -1
- package/dist-renderer/assets/{_baseUniq-cKAW4Q8I.js → _baseUniq-CnjxqwAk.js} +1 -1
- package/dist-renderer/assets/{arc-YmNsoDXW.js → arc-CLeZuINP.js} +1 -1
- package/dist-renderer/assets/{architectureDiagram-VXUJARFQ-DHEls2sX.js → architectureDiagram-VXUJARFQ-QKtqaqdY.js} +1 -1
- package/dist-renderer/assets/{blockDiagram-VD42YOAC-Bpwf1Sbg.js → blockDiagram-VD42YOAC-BqdrzO_f.js} +1 -1
- package/dist-renderer/assets/{c4Diagram-YG6GDRKO-B0IaQ4w5.js → c4Diagram-YG6GDRKO-gwPlCxDC.js} +1 -1
- package/dist-renderer/assets/channel-DpMHF50r.js +1 -0
- package/dist-renderer/assets/{chunk-4BX2VUAB-DLk-hcFc.js → chunk-4BX2VUAB-C6XLurL4.js} +1 -1
- package/dist-renderer/assets/{chunk-55IACEB6-1XRmX_Zm.js → chunk-55IACEB6-Ds6quhEP.js} +1 -1
- package/dist-renderer/assets/{chunk-B4BG7PRW-1waH1DAD.js → chunk-B4BG7PRW-5UlA1_e9.js} +1 -1
- package/dist-renderer/assets/{chunk-DI55MBZ5-BqpZBtrN.js → chunk-DI55MBZ5-ywFrqIsY.js} +1 -1
- package/dist-renderer/assets/{chunk-FMBD7UC4-Bly7vVym.js → chunk-FMBD7UC4-C7ifUA17.js} +1 -1
- package/dist-renderer/assets/{chunk-QN33PNHL-Ci2QWBAs.js → chunk-QN33PNHL-BxGCo80U.js} +1 -1
- package/dist-renderer/assets/{chunk-QZHKN3VN-YCqFW7d-.js → chunk-QZHKN3VN-B2CuaZs6.js} +1 -1
- package/dist-renderer/assets/{chunk-TZMSLE5B-B0xGXInl.js → chunk-TZMSLE5B-Ds1hInvp.js} +1 -1
- package/dist-renderer/assets/classDiagram-2ON5EDUG-CBYCBVRl.js +1 -0
- package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-CBYCBVRl.js +1 -0
- package/dist-renderer/assets/clone-DcMF6Psb.js +1 -0
- package/dist-renderer/assets/{cose-bilkent-S5V4N54A-DxcFNQKT.js → cose-bilkent-S5V4N54A-Cz1GVtLp.js} +1 -1
- package/dist-renderer/assets/{dagre-6UL2VRFP-DPo_RfZY.js → dagre-6UL2VRFP-BrmR-P4h.js} +1 -1
- package/dist-renderer/assets/{diagram-PSM6KHXK-U3hQsFe4.js → diagram-PSM6KHXK-DbNjC5Rg.js} +1 -1
- package/dist-renderer/assets/{diagram-QEK2KX5R-OrwrAy0V.js → diagram-QEK2KX5R-qkRX5_Mq.js} +1 -1
- package/dist-renderer/assets/{diagram-S2PKOQOG-CXATPWVw.js → diagram-S2PKOQOG-CyL5rCv2.js} +1 -1
- package/dist-renderer/assets/{erDiagram-Q2GNP2WA-B0e8AfMF.js → erDiagram-Q2GNP2WA-Dox3-bA5.js} +1 -1
- package/dist-renderer/assets/{flowDiagram-NV44I4VS-CXfzA4jJ.js → flowDiagram-NV44I4VS-BtkaxlDL.js} +1 -1
- package/dist-renderer/assets/{ganttDiagram-JELNMOA3-CMr08qVl.js → ganttDiagram-JELNMOA3-Dhy_d9GK.js} +1 -1
- package/dist-renderer/assets/{gitGraphDiagram-V2S2FVAM-vYFHpPmy.js → gitGraphDiagram-V2S2FVAM-B5XRhIQA.js} +1 -1
- package/dist-renderer/assets/{graph-DOe5j8dH.js → graph-CsoEwUhS.js} +1 -1
- package/dist-renderer/assets/{index-BySQS7AB.js → index-BWPWmJNo.js} +1 -1
- package/dist-renderer/assets/{index-V7dAKPqd.js → index-Bu2R-Se7.js} +587 -705
- package/dist-renderer/assets/index-CnWV3BhG.css +32 -0
- package/dist-renderer/assets/{index-CzWxVCRL.js → index-D-3KgskL.js} +1 -1
- package/dist-renderer/assets/{index-VJ-MM9xa.js → index-DGEBzLNT.js} +1 -1
- package/dist-renderer/assets/{index-B2Dy7M2G.js → index-NhHNs2Oo.js} +1 -1
- package/dist-renderer/assets/{index-C_okzZXP.js → index-h17WuEyf.js} +1 -1
- package/dist-renderer/assets/{infoDiagram-HS3SLOUP-D_WubR0B.js → infoDiagram-HS3SLOUP-hMGmNojH.js} +1 -1
- package/dist-renderer/assets/{journeyDiagram-XKPGCS4Q-w9ca-1TI.js → journeyDiagram-XKPGCS4Q-DXV2rBDl.js} +1 -1
- package/dist-renderer/assets/{kanban-definition-3W4ZIXB7-Jg9p6_pN.js → kanban-definition-3W4ZIXB7-Bf99WLRy.js} +1 -1
- package/dist-renderer/assets/{layout-B-z3y17c.js → layout-C3XWrpwo.js} +1 -1
- package/dist-renderer/assets/{linear-D-RTX5UW.js → linear-OEEcn8KN.js} +1 -1
- package/dist-renderer/assets/{mindmap-definition-VGOIOE7T-CDQmHOYP.js → mindmap-definition-VGOIOE7T-Dpi3S2x4.js} +1 -1
- package/dist-renderer/assets/{pieDiagram-ADFJNKIX-D_odsQL7.js → pieDiagram-ADFJNKIX-xTPPhtNx.js} +1 -1
- package/dist-renderer/assets/{quadrantDiagram-AYHSOK5B-BRsmYWSA.js → quadrantDiagram-AYHSOK5B-euniyDlz.js} +1 -1
- package/dist-renderer/assets/{requirementDiagram-UZGBJVZJ-ChNE_BOV.js → requirementDiagram-UZGBJVZJ-D9Uiw4kF.js} +1 -1
- package/dist-renderer/assets/{sankeyDiagram-TZEHDZUN-C8FtpwKc.js → sankeyDiagram-TZEHDZUN-CySU4nED.js} +1 -1
- package/dist-renderer/assets/{sequenceDiagram-WL72ISMW-DmLCzNcc.js → sequenceDiagram-WL72ISMW-JVGpET6V.js} +1 -1
- package/dist-renderer/assets/splashScene-D0YB9uxm.js +17 -0
- package/dist-renderer/assets/{stateDiagram-FKZM4ZOC-WJBm4bhu.js → stateDiagram-FKZM4ZOC-B2FY5qqi.js} +1 -1
- package/dist-renderer/assets/stateDiagram-v2-4FDKWEC3-DcoMiR8H.js +1 -0
- package/dist-renderer/assets/{timeline-definition-IT6M3QCI-BXs_hOJs.js → timeline-definition-IT6M3QCI-DmycNUUe.js} +1 -1
- package/dist-renderer/assets/{treemap-GDKQZRPO-o04MA0G9.js → treemap-GDKQZRPO-DPq4gZuB.js} +1 -1
- package/dist-renderer/assets/{xychartDiagram-PRI3JC2R-Czj69XRd.js → xychartDiagram-PRI3JC2R-J6VVJzRq.js} +1 -1
- package/dist-renderer/index.html +20 -53
- package/package.json +25 -18
- package/src/main/ipc/extensions.ts +2 -1
- package/src/main/server.ts +873 -221
- package/src/main/services/extensions/ExtensionFacadeService.ts +2 -5
- package/src/main/services/extensions/catalog/PluginCatalogService.ts +4 -2
- package/src/main/services/session-intelligence/ConversationTelemetryService.ts +1101 -0
- package/src/main/services/session-intelligence/LocalSessionScanner.ts +512 -0
- package/src/main/services/session-intelligence/SessionUsageParser.ts +4 -4
- package/src/main/services/system-manager/SystemManagerConfigService.ts +122 -0
- package/src/main/services/system-manager/SystemManagerPtyService.ts +233 -0
- package/src/main/services/system-manager/WorkflowPromptService.ts +75 -0
- package/src/main/services/teams-mvp/TaskDispatchService.ts +5 -6
- package/src/main/services/teams-mvp/TeamProvisioningService.ts +39 -2
- package/src/main/services/teams-mvp/TeamWorkspaceService.ts +22 -4
- package/src/main/utils/teamProjectResolution.ts +15 -0
- package/src/renderer/App.tsx +8 -4
- package/src/renderer/api/httpClient.ts +68 -18
- package/src/renderer/api/providers.ts +23 -2
- package/src/renderer/assets/participant-avatars/01.svg +3 -0
- package/src/renderer/assets/participant-avatars/02.svg +3 -0
- package/src/renderer/assets/participant-avatars/03.svg +3 -0
- package/src/renderer/assets/participant-avatars/04.svg +3 -0
- package/src/renderer/assets/participant-avatars/05.svg +3 -0
- package/src/renderer/assets/participant-avatars/06.svg +3 -0
- package/src/renderer/assets/participant-avatars/07.svg +3 -0
- package/src/renderer/assets/participant-avatars/08.svg +3 -0
- package/src/renderer/assets/participant-avatars/09.svg +3 -0
- package/src/renderer/assets/participant-avatars/10.svg +3 -0
- package/src/renderer/assets/participant-avatars/11.svg +3 -0
- package/src/renderer/assets/participant-avatars/12.svg +3 -0
- package/src/renderer/assets/participant-avatars/13.svg +3 -0
- package/src/renderer/components/common/TerminalPane.tsx +213 -0
- package/src/renderer/components/dashboard/DashboardView.tsx +9 -36
- package/src/renderer/components/extensions/ExtensionStoreView.tsx +6 -125
- package/src/renderer/components/extensions/ExtensionsSubTabTrigger.tsx +1 -1
- package/src/renderer/components/extensions/mcp/McpLibraryEnableDialog.tsx +305 -0
- package/src/renderer/components/extensions/mcp/McpLibraryEntryDialog.tsx +418 -0
- package/src/renderer/components/extensions/mcp/McpLibraryPanel.tsx +404 -0
- package/src/renderer/components/extensions/plugins/PluginCard.tsx +6 -6
- package/src/renderer/components/extensions/plugins/PluginsPanel.tsx +34 -21
- package/src/renderer/components/extensions/skills/SkillsLibraryPanel.tsx +335 -0
- package/src/renderer/components/layout/PaneContent.tsx +8 -1
- package/src/renderer/components/layout/Sidebar.tsx +11 -54
- package/src/renderer/components/layout/SortableTab.tsx +20 -31
- package/src/renderer/components/layout/TabBar.tsx +1 -1
- package/src/renderer/components/layout/TabContextMenu.tsx +1 -1
- package/src/renderer/components/runtime/ProviderRuntimeSettingsDialog.tsx +768 -157
- package/src/renderer/components/schedules/SchedulesView.tsx +51 -462
- package/src/renderer/components/schedules/calendar/CalendarDayView.tsx +173 -0
- package/src/renderer/components/schedules/calendar/CalendarEventBlock.tsx +113 -0
- package/src/renderer/components/schedules/calendar/CalendarHeader.tsx +148 -0
- package/src/renderer/components/schedules/calendar/CalendarMonthView.tsx +142 -0
- package/src/renderer/components/schedules/calendar/CalendarWeekView.tsx +219 -0
- package/src/renderer/components/schedules/calendar/ScheduleCalendarBoard.tsx +41 -0
- package/src/renderer/components/schedules/calendar/TeamGanttView.tsx +405 -0
- package/src/renderer/components/schedules/calendar/computeOccurrences.ts +234 -0
- package/src/renderer/components/schedules/calendar/index.ts +2 -0
- package/src/renderer/components/schedules/calendar/types.ts +44 -0
- package/src/renderer/components/settings/SettingsTabs.tsx +50 -55
- package/src/renderer/components/settings/SettingsView.tsx +30 -35
- package/src/renderer/components/settings/components/SettingsSectionHeader.tsx +5 -1
- package/src/renderer/components/settings/components/SettingsSelect.tsx +5 -3
- package/src/renderer/components/settings/components/SettingsToggle.tsx +2 -2
- package/src/renderer/components/settings/sections/AdvancedSection.tsx +11 -42
- package/src/renderer/components/settings/sections/CliStatusSection.tsx +71 -112
- package/src/renderer/components/settings/sections/ConfigEditorDialog.tsx +1 -1
- package/src/renderer/components/settings/sections/GeneralSection.tsx +11 -3
- package/src/renderer/components/settings/sections/HarnessSection.tsx +18 -14
- package/src/renderer/components/settings/sections/PlatformsSection.tsx +3 -3
- package/src/renderer/components/settings/sections/TaskBusSection.tsx +33 -40
- package/src/renderer/components/settings/sections/index.ts +0 -1
- package/src/renderer/components/sidebar/SidebarSessions.tsx +182 -4
- package/src/renderer/components/sidebar/SidebarTaskItem.tsx +4 -4
- package/src/renderer/components/sidebar/WorkspaceBrowser.tsx +39 -4
- package/src/renderer/components/splash/splashScene.ts +121 -929
- package/src/renderer/components/system-manager/FolderBrowser.tsx +163 -0
- package/src/renderer/components/system-manager/SystemManagerView.tsx +351 -0
- package/src/renderer/components/tasks/TasksView.tsx +112 -134
- package/src/renderer/components/team/CcSessionsSection.tsx +431 -89
- package/src/renderer/components/team/CollapsibleTeamSection.tsx +17 -32
- package/src/renderer/components/team/TeamDetailView.tsx +319 -123
- package/src/renderer/components/team/TeamListView.tsx +108 -123
- package/src/renderer/components/team/dialogs/CreateTaskDialog.tsx +2 -2
- package/src/renderer/components/team/dialogs/CreateTeamDialog.tsx +84 -306
- package/src/renderer/components/team/dialogs/EditTeamDialog.tsx +259 -342
- package/src/renderer/components/team/dialogs/GlobalTaskDetailDialog.tsx +1 -1
- package/src/renderer/components/team/dialogs/LaunchTeamDialog.tsx +17 -15
- package/src/renderer/components/team/dialogs/PlatformBindingDialog.tsx +221 -0
- package/src/renderer/components/team/dialogs/PlatformManualForm.tsx +7 -0
- package/src/renderer/components/team/dialogs/PlatformSetupQR.tsx +1 -1
- package/src/renderer/components/team/dialogs/RuntimeConfigDialog.tsx +361 -0
- package/src/renderer/components/team/dialogs/platformMeta.ts +122 -11
- package/src/renderer/components/team/dialogs/useTeamEditForm.ts +17 -5
- package/src/renderer/components/team/kanban/KanbanBoard.tsx +9 -9
- package/src/renderer/components/team/members/MemberCard.tsx +14 -47
- package/src/renderer/components/team/members/MemberDetailDialog.tsx +3 -95
- package/src/renderer/components/team/members/MemberDetailStats.tsx +50 -65
- package/src/renderer/components/team/messages/MessageComposer.tsx +8 -110
- package/src/renderer/components/team/messages/MessagesPanel.tsx +131 -114
- package/src/renderer/components/team/schedule/ScheduleStatusBadge.tsx +2 -2
- package/src/renderer/components/team/tools/AddMcpInline.tsx +27 -17
- package/src/renderer/components/team/tools/McpChip.tsx +6 -3
- package/src/renderer/components/team/tools/SkillChip.tsx +2 -2
- package/src/renderer/components/team/tools/ToolsSection.tsx +418 -70
- package/src/renderer/hooks/useExtensionsTabState.ts +3 -114
- package/src/renderer/index.css +39 -22
- package/src/renderer/index.html +17 -50
- package/src/renderer/store/index.ts +2 -1
- package/src/renderer/store/slices/scheduleSlice.ts +1 -1
- package/src/renderer/store/slices/teamSlice.ts +45 -168
- package/src/renderer/utils/claudeCodeOnlyProviders.ts +3 -10
- package/src/renderer/utils/memberHelpers.ts +5 -17
- package/src/renderer/utils/openCodeRuntimeDeliveryDiagnostics.ts +4 -2
- package/src/renderer/utils/providerSlashCommands.ts +0 -5
- package/src/renderer/utils/scheduleFormatters.ts +3 -1
- package/src/renderer/utils/teamMessageFiltering.ts +14 -1
- package/src/renderer/utils/teamModelAvailability.ts +18 -2
- package/src/shared/types/api.ts +121 -2
- package/src/shared/types/ccConnect.ts +2 -0
- package/src/shared/types/index.ts +3 -0
- package/src/shared/types/systemManager.ts +49 -0
- package/src/shared/types/team.ts +29 -0
- package/src/shared/types/terminal.ts +4 -2
- package/src/shared/utils/extensionNormalizers.ts +15 -8
- package/src/shared/utils/providerExtensionCapabilities.ts +2 -2
- package/dist-renderer/assets/ProjectEditorOverlay-lJZi-9Hp.js +0 -52
- package/dist-renderer/assets/channel-yIlSKy0e.js +0 -1
- package/dist-renderer/assets/classDiagram-2ON5EDUG-24fHez0s.js +0 -1
- package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-24fHez0s.js +0 -1
- package/dist-renderer/assets/clone-BTNuUva-.js +0 -1
- package/dist-renderer/assets/index-Bi6nrZ4z.css +0 -1
- package/dist-renderer/assets/splashScene-C8lWNnm4.js +0 -1
- package/dist-renderer/assets/stateDiagram-v2-4FDKWEC3-_m6iPPUR.js +0 -1
|
@@ -10,9 +10,9 @@ import {
|
|
|
10
10
|
} from 'react';
|
|
11
11
|
import { Sheet, type SheetRef } from 'react-modal-sheet';
|
|
12
12
|
|
|
13
|
-
import { api } from '@renderer/api';
|
|
14
13
|
import { Badge } from '@renderer/components/ui/badge';
|
|
15
14
|
import { Button } from '@renderer/components/ui/button';
|
|
15
|
+
import { MemberBadge } from '@renderer/components/team/MemberBadge';
|
|
16
16
|
import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip';
|
|
17
17
|
import { useStableTeamMentionMeta } from '@renderer/hooks/useStableTeamMentionMeta';
|
|
18
18
|
import { useTeamMessagesExpanded } from '@renderer/hooks/useTeamMessagesExpanded';
|
|
@@ -20,6 +20,7 @@ import { useTeamMessagesRead } from '@renderer/hooks/useTeamMessagesRead';
|
|
|
20
20
|
import { useStore } from '@renderer/store';
|
|
21
21
|
import { selectTeamMessages } from '@renderer/store/slices/teamSlice';
|
|
22
22
|
import { filterTeamMessages } from '@renderer/utils/teamMessageFiltering';
|
|
23
|
+
import { cn } from '@renderer/lib/utils';
|
|
23
24
|
import { toMessageKey } from '@renderer/utils/teamMessageKey';
|
|
24
25
|
import { shouldExcludeInboxTextFromReplyCandidates } from '@shared/utils/idleNotificationSemantics';
|
|
25
26
|
import {
|
|
@@ -56,7 +57,6 @@ import type { TeamMessagesPanelMode } from '@renderer/types/teamMessagesPanelMod
|
|
|
56
57
|
import type {
|
|
57
58
|
AgentActionMode,
|
|
58
59
|
CcSession,
|
|
59
|
-
CcSessionDetail,
|
|
60
60
|
InboxMessage,
|
|
61
61
|
ResolvedTeamMember,
|
|
62
62
|
TaskRef,
|
|
@@ -93,6 +93,8 @@ interface MessagesPanelProps {
|
|
|
93
93
|
timeWindow: TimeWindow | null;
|
|
94
94
|
/** Current lead session ID. */
|
|
95
95
|
currentLeadSessionId?: string;
|
|
96
|
+
/** cc-connect sessions owned by the parent team detail view. */
|
|
97
|
+
sessions?: CcSession[];
|
|
96
98
|
/** Pending replies tracker (shared with parent for MemberList). */
|
|
97
99
|
pendingRepliesByMember: Record<string, number>;
|
|
98
100
|
/** Update pending replies tracker. */
|
|
@@ -186,6 +188,7 @@ export const MessagesPanel = memo(function MessagesPanel({
|
|
|
186
188
|
leadContextUpdatedAt,
|
|
187
189
|
timeWindow,
|
|
188
190
|
currentLeadSessionId,
|
|
191
|
+
sessions = [],
|
|
189
192
|
pendingRepliesByMember,
|
|
190
193
|
onPendingReplyChange,
|
|
191
194
|
onMemberClick,
|
|
@@ -334,10 +337,8 @@ export const MessagesPanel = memo(function MessagesPanel({
|
|
|
334
337
|
const [expandedItemKey, setExpandedItemKey] = useState<string | null>(
|
|
335
338
|
initialSidebarStateRef.current.expandedItemKey
|
|
336
339
|
);
|
|
337
|
-
const [teamSessions, setTeamSessions] = useState<CcSession[]>([]);
|
|
338
|
-
const [selectedSessionDetail, setSelectedSessionDetail] = useState<CcSessionDetail | null>(null);
|
|
339
|
-
const [selectedSessionDetailLoading, setSelectedSessionDetailLoading] = useState(false);
|
|
340
340
|
const [selectedSessionKey, setSelectedSessionKey] = useState<string | null>(null);
|
|
341
|
+
const [quickParticipantFilter, setQuickParticipantFilter] = useState<string | null>(null);
|
|
341
342
|
const [messagesScrollTop, setMessagesScrollTop] = useState(
|
|
342
343
|
initialSidebarStateRef.current.messagesScrollTop
|
|
343
344
|
);
|
|
@@ -355,70 +356,25 @@ export const MessagesPanel = memo(function MessagesPanel({
|
|
|
355
356
|
setMessagesCollapsed(initialSidebarStateRef.current.messagesCollapsed);
|
|
356
357
|
setMessagesSearchBarVisible(initialSidebarStateRef.current.messagesSearchBarVisible);
|
|
357
358
|
setExpandedItemKey(initialSidebarStateRef.current.expandedItemKey);
|
|
359
|
+
setSelectedSessionKey(null);
|
|
360
|
+
setQuickParticipantFilter(null);
|
|
358
361
|
setMessagesScrollTop(initialSidebarStateRef.current.messagesScrollTop);
|
|
359
362
|
setBottomSheetSnapIndex(initialSidebarStateRef.current.bottomSheetSnapIndex);
|
|
360
363
|
}, [teamName]);
|
|
361
364
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
const sortedSessions = [...sessions].sort(
|
|
369
|
-
(a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
|
|
370
|
-
);
|
|
371
|
-
setTeamSessions(sortedSessions);
|
|
372
|
-
setSelectedSessionKey((current) => {
|
|
373
|
-
if (current && sortedSessions.some((session) => session.sessionKey === current))
|
|
374
|
-
return current;
|
|
375
|
-
return sortedSessions[0]?.sessionKey ?? null;
|
|
376
|
-
});
|
|
377
|
-
})
|
|
378
|
-
.catch(() => {
|
|
379
|
-
if (!cancelled) {
|
|
380
|
-
setTeamSessions([]);
|
|
381
|
-
setSelectedSessionKey(null);
|
|
382
|
-
}
|
|
383
|
-
});
|
|
384
|
-
return () => {
|
|
385
|
-
cancelled = true;
|
|
386
|
-
};
|
|
387
|
-
// Refetch when the lead session id changes (e.g. a new session is spawned)
|
|
388
|
-
// so the session list/selector reflects the updated id without a remount.
|
|
389
|
-
}, [teamName, currentLeadSessionId]);
|
|
390
|
-
|
|
391
|
-
const selectedSession = useMemo(
|
|
392
|
-
() => teamSessions.find((session) => session.sessionKey === selectedSessionKey) ?? null,
|
|
393
|
-
[selectedSessionKey, teamSessions]
|
|
365
|
+
const teamSessions = useMemo(
|
|
366
|
+
() =>
|
|
367
|
+
[...sessions].sort(
|
|
368
|
+
(a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
|
|
369
|
+
),
|
|
370
|
+
[sessions]
|
|
394
371
|
);
|
|
395
|
-
const selectedIsHermitLocalSession =
|
|
396
|
-
selectedSession?.platform === 'hermit' ||
|
|
397
|
-
selectedSession?.sessionKey === `hermit:${teamName}:session`;
|
|
398
372
|
|
|
399
373
|
useEffect(() => {
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
}
|
|
405
|
-
let cancelled = false;
|
|
406
|
-
setSelectedSessionDetailLoading(true);
|
|
407
|
-
void api.teams
|
|
408
|
-
.getSessionDetail(teamName, selectedSession.id, 200)
|
|
409
|
-
.then((detail) => {
|
|
410
|
-
if (!cancelled) setSelectedSessionDetail(detail);
|
|
411
|
-
})
|
|
412
|
-
.catch(() => {
|
|
413
|
-
if (!cancelled) setSelectedSessionDetail(null);
|
|
414
|
-
})
|
|
415
|
-
.finally(() => {
|
|
416
|
-
if (!cancelled) setSelectedSessionDetailLoading(false);
|
|
417
|
-
});
|
|
418
|
-
return () => {
|
|
419
|
-
cancelled = true;
|
|
420
|
-
};
|
|
421
|
-
}, [selectedIsHermitLocalSession, selectedSession, teamName]);
|
|
374
|
+
setSelectedSessionKey((current) =>
|
|
375
|
+
current && teamSessions.some((session) => session.sessionKey === current) ? current : null
|
|
376
|
+
);
|
|
377
|
+
}, [teamSessions]);
|
|
422
378
|
|
|
423
379
|
useEffect(() => {
|
|
424
380
|
setTeamMessagesSidebarUiState(teamName, {
|
|
@@ -541,64 +497,127 @@ export const MessagesPanel = memo(function MessagesPanel({
|
|
|
541
497
|
const newestFirst = (items: InboxMessage[]) =>
|
|
542
498
|
[...items].sort((a, b) => Date.parse(b.timestamp) - Date.parse(a.timestamp));
|
|
543
499
|
if (!selectedSessionKey) return newestFirst(effectiveMessages);
|
|
544
|
-
if (selectedSession && !selectedIsHermitLocalSession) {
|
|
545
|
-
if (!selectedSessionDetail) {
|
|
546
|
-
return [];
|
|
547
|
-
}
|
|
548
|
-
return [...selectedSessionDetail.history].reverse().map(
|
|
549
|
-
(entry, index): InboxMessage => ({
|
|
550
|
-
messageId: `${selectedSessionDetail.id}:${index}:${entry.timestamp}`,
|
|
551
|
-
from: entry.role === 'user' ? 'user' : selectedSessionDetail.name || teamName,
|
|
552
|
-
to: entry.role === 'user' ? selectedSessionDetail.name || teamName : 'user',
|
|
553
|
-
text: entry.content,
|
|
554
|
-
timestamp: entry.timestamp,
|
|
555
|
-
read: true,
|
|
556
|
-
source: entry.role === 'user' ? 'user_sent' : 'inbox',
|
|
557
|
-
session: {
|
|
558
|
-
id: selectedSessionDetail.id,
|
|
559
|
-
key: selectedSessionDetail.sessionKey,
|
|
560
|
-
platform: selectedSessionDetail.platform,
|
|
561
|
-
title:
|
|
562
|
-
selectedSession.title ||
|
|
563
|
-
selectedSession.chatName ||
|
|
564
|
-
selectedSession.userName ||
|
|
565
|
-
selectedSession.sessionKey,
|
|
566
|
-
chatName: selectedSession.chatName,
|
|
567
|
-
userName: selectedSession.userName,
|
|
568
|
-
},
|
|
569
|
-
})
|
|
570
|
-
);
|
|
571
|
-
}
|
|
572
500
|
return newestFirst(
|
|
573
|
-
effectiveMessages.filter((message) =>
|
|
574
|
-
return message.session?.key === selectedSessionKey;
|
|
575
|
-
})
|
|
501
|
+
effectiveMessages.filter((message) => message.session?.key === selectedSessionKey)
|
|
576
502
|
);
|
|
577
|
-
}, [
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
503
|
+
}, [effectiveMessages, selectedSessionKey]);
|
|
504
|
+
|
|
505
|
+
const participantOptions = useMemo(() => {
|
|
506
|
+
const senderNames = new Set<string>();
|
|
507
|
+
for (const message of sessionScopedMessages) {
|
|
508
|
+
const sender = message.from?.trim();
|
|
509
|
+
if (sender) senderNames.add(sender);
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
const seen = new Set<string>();
|
|
513
|
+
const orderedSenders: string[] = [];
|
|
514
|
+
const addSender = (value: string | null | undefined) => {
|
|
515
|
+
const trimmed = value?.trim();
|
|
516
|
+
if (!trimmed || seen.has(trimmed) || !senderNames.has(trimmed)) return;
|
|
517
|
+
seen.add(trimmed);
|
|
518
|
+
orderedSenders.push(trimmed);
|
|
519
|
+
};
|
|
520
|
+
|
|
521
|
+
addSender('user');
|
|
522
|
+
for (const member of members) addSender(member.name);
|
|
523
|
+
for (const message of sessionScopedMessages) addSender(message.from);
|
|
524
|
+
|
|
525
|
+
return orderedSenders.slice(0, 24);
|
|
526
|
+
}, [members, sessionScopedMessages]);
|
|
527
|
+
|
|
528
|
+
useEffect(() => {
|
|
529
|
+
if (quickParticipantFilter && !participantOptions.includes(quickParticipantFilter)) {
|
|
530
|
+
setQuickParticipantFilter(null);
|
|
531
|
+
}
|
|
532
|
+
}, [participantOptions, quickParticipantFilter]);
|
|
533
|
+
|
|
534
|
+
const matchesParticipant = useCallback((message: InboxMessage, participant: string): boolean => {
|
|
535
|
+
return message.from?.trim() === participant;
|
|
536
|
+
}, []);
|
|
585
537
|
|
|
586
538
|
const filteredMessages = useMemo(() => {
|
|
587
|
-
|
|
539
|
+
const participantFiltered = quickParticipantFilter
|
|
540
|
+
? sessionScopedMessages.filter((message) =>
|
|
541
|
+
matchesParticipant(message, quickParticipantFilter)
|
|
542
|
+
)
|
|
543
|
+
: sessionScopedMessages;
|
|
544
|
+
return filterTeamMessages(participantFiltered, {
|
|
588
545
|
timeWindow,
|
|
589
546
|
filter: messagesFilter,
|
|
590
547
|
searchQuery: messagesSearchQuery,
|
|
591
548
|
});
|
|
592
|
-
}, [
|
|
549
|
+
}, [
|
|
550
|
+
matchesParticipant,
|
|
551
|
+
messagesFilter,
|
|
552
|
+
messagesSearchQuery,
|
|
553
|
+
quickParticipantFilter,
|
|
554
|
+
sessionScopedMessages,
|
|
555
|
+
timeWindow,
|
|
556
|
+
]);
|
|
557
|
+
|
|
558
|
+
const setParticipantFilter = useCallback((name: string | null) => {
|
|
559
|
+
setQuickParticipantFilter(name);
|
|
560
|
+
}, []);
|
|
561
|
+
|
|
562
|
+
const participantFilterBar = (
|
|
563
|
+
<div className="flex items-center gap-1 overflow-x-auto pb-1 text-[11px]">
|
|
564
|
+
<button
|
|
565
|
+
type="button"
|
|
566
|
+
className={cn(
|
|
567
|
+
'shrink-0 rounded-full border px-2 py-0.5 transition-colors',
|
|
568
|
+
quickParticipantFilter === null
|
|
569
|
+
? 'border-blue-500/40 bg-blue-500/10 text-blue-500'
|
|
570
|
+
: 'border-[var(--color-border)] text-[var(--color-text-muted)] hover:text-[var(--color-text)]'
|
|
571
|
+
)}
|
|
572
|
+
onClick={() => setParticipantFilter(null)}
|
|
573
|
+
>
|
|
574
|
+
全部成员
|
|
575
|
+
</button>
|
|
576
|
+
{participantOptions.map((participant) => (
|
|
577
|
+
<button
|
|
578
|
+
key={participant}
|
|
579
|
+
type="button"
|
|
580
|
+
className={cn(
|
|
581
|
+
'shrink-0 rounded-full border px-2 py-0.5 transition-colors',
|
|
582
|
+
quickParticipantFilter === participant
|
|
583
|
+
? 'border-blue-500/40 bg-blue-500/10 text-blue-500'
|
|
584
|
+
: 'border-[var(--color-border)] text-[var(--color-text-muted)] hover:text-[var(--color-text)]'
|
|
585
|
+
)}
|
|
586
|
+
onClick={() =>
|
|
587
|
+
setParticipantFilter(quickParticipantFilter === participant ? null : participant)
|
|
588
|
+
}
|
|
589
|
+
>
|
|
590
|
+
<MemberBadge
|
|
591
|
+
name={participant === 'user' ? '用户' : participant}
|
|
592
|
+
size="sm"
|
|
593
|
+
hideAvatar
|
|
594
|
+
disableHoverCard
|
|
595
|
+
/>
|
|
596
|
+
</button>
|
|
597
|
+
))}
|
|
598
|
+
</div>
|
|
599
|
+
);
|
|
593
600
|
|
|
594
601
|
const activityTimelineMessages = useMemo(() => {
|
|
595
|
-
|
|
602
|
+
const participantFiltered = quickParticipantFilter
|
|
603
|
+
? sessionScopedMessages.filter((message) =>
|
|
604
|
+
matchesParticipant(message, quickParticipantFilter)
|
|
605
|
+
)
|
|
606
|
+
: sessionScopedMessages;
|
|
607
|
+
return filterTeamMessages(participantFiltered, {
|
|
596
608
|
includePassiveIdlePeerSummariesWhenNoiseHidden: true,
|
|
597
609
|
timeWindow,
|
|
598
610
|
filter: messagesFilter,
|
|
599
611
|
searchQuery: messagesSearchQuery,
|
|
600
612
|
});
|
|
601
|
-
}, [
|
|
613
|
+
}, [
|
|
614
|
+
matchesParticipant,
|
|
615
|
+
messagesFilter,
|
|
616
|
+
messagesSearchQuery,
|
|
617
|
+
quickParticipantFilter,
|
|
618
|
+
sessionScopedMessages,
|
|
619
|
+
timeWindow,
|
|
620
|
+
]);
|
|
602
621
|
|
|
603
622
|
const replyCandidateMessages = useMemo(
|
|
604
623
|
() =>
|
|
@@ -773,6 +792,10 @@ export const MessagesPanel = memo(function MessagesPanel({
|
|
|
773
792
|
toTeam,
|
|
774
793
|
text: description,
|
|
775
794
|
messageId: optimisticMessageId,
|
|
795
|
+
sessionKey:
|
|
796
|
+
selectedSessionKey && selectedSessionKey !== '__unassigned__'
|
|
797
|
+
? selectedSessionKey
|
|
798
|
+
: undefined,
|
|
776
799
|
});
|
|
777
800
|
} catch (error) {
|
|
778
801
|
const rawMessage = error instanceof Error ? error.message : '跨团队任务派发失败';
|
|
@@ -935,13 +958,11 @@ export const MessagesPanel = memo(function MessagesPanel({
|
|
|
935
958
|
sendWarning={sendMessageWarning}
|
|
936
959
|
sendDebugDetails={sendMessageDebugDetails}
|
|
937
960
|
lastResult={lastSendMessageResult}
|
|
938
|
-
sessions={teamSessions}
|
|
939
|
-
selectedSessionKey={selectedSessionKey}
|
|
940
|
-
onSessionChange={setSelectedSessionKey}
|
|
941
961
|
textareaRef={composerTextareaRef}
|
|
942
962
|
onSend={handleSend}
|
|
943
963
|
onDispatchTask={handleDispatchTaskToTeam}
|
|
944
964
|
/>
|
|
965
|
+
{participantFilterBar}
|
|
945
966
|
<StatusBlock
|
|
946
967
|
members={members}
|
|
947
968
|
tasks={tasks}
|
|
@@ -1132,13 +1153,11 @@ export const MessagesPanel = memo(function MessagesPanel({
|
|
|
1132
1153
|
sendWarning={sendMessageWarning}
|
|
1133
1154
|
sendDebugDetails={sendMessageDebugDetails}
|
|
1134
1155
|
lastResult={lastSendMessageResult}
|
|
1135
|
-
sessions={teamSessions}
|
|
1136
|
-
selectedSessionKey={selectedSessionKey}
|
|
1137
|
-
onSessionChange={setSelectedSessionKey}
|
|
1138
1156
|
textareaRef={composerTextareaRef}
|
|
1139
1157
|
onSend={handleSend}
|
|
1140
1158
|
onDispatchTask={handleDispatchTaskToTeam}
|
|
1141
1159
|
/>
|
|
1160
|
+
{participantFilterBar}
|
|
1142
1161
|
<StatusBlock
|
|
1143
1162
|
members={members}
|
|
1144
1163
|
tasks={tasks}
|
|
@@ -1420,13 +1439,11 @@ export const MessagesPanel = memo(function MessagesPanel({
|
|
|
1420
1439
|
sendWarning={sendMessageWarning}
|
|
1421
1440
|
sendDebugDetails={sendMessageDebugDetails}
|
|
1422
1441
|
lastResult={lastSendMessageResult}
|
|
1423
|
-
sessions={teamSessions}
|
|
1424
|
-
selectedSessionKey={selectedSessionKey}
|
|
1425
|
-
onSessionChange={setSelectedSessionKey}
|
|
1426
1442
|
textareaRef={composerTextareaRef}
|
|
1427
1443
|
onSend={handleSend}
|
|
1428
1444
|
onDispatchTask={handleDispatchTaskToTeam}
|
|
1429
1445
|
/>
|
|
1446
|
+
{participantFilterBar}
|
|
1430
1447
|
</div>
|
|
1431
1448
|
</div>
|
|
1432
1449
|
<div className="shrink-0 px-3 pt-2">
|
|
@@ -20,7 +20,7 @@ interface ScheduleStatusBadgeProps {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export const ScheduleStatusBadge = ({ status }: ScheduleStatusBadgeProps): React.JSX.Element => {
|
|
23
|
-
const config = SCHEDULE_STATUS_CONFIG[status];
|
|
23
|
+
const config = SCHEDULE_STATUS_CONFIG[status] ?? { label: status, className: 'bg-zinc-500/15 text-zinc-400 border-zinc-500/20' };
|
|
24
24
|
return (
|
|
25
25
|
<span
|
|
26
26
|
className={`inline-flex items-center rounded-full border px-1.5 py-0.5 text-[10px] font-medium ${config.className}`}
|
|
@@ -50,6 +50,6 @@ interface RunStatusBadgeProps {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
export const RunStatusBadge = ({ status }: RunStatusBadgeProps): React.JSX.Element => {
|
|
53
|
-
const config = RUN_STATUS_CONFIG[status];
|
|
53
|
+
const config = RUN_STATUS_CONFIG[status] ?? { label: status, className: 'text-zinc-400' };
|
|
54
54
|
return <span className={`text-[10px] font-medium ${config.className}`}>{config.label}</span>;
|
|
55
55
|
};
|
|
@@ -1,46 +1,56 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* AddMcpInline —
|
|
3
|
-
* Refreshes parent list when dialog closes (install may have occurred).
|
|
2
|
+
* AddMcpInline — creates a reusable global MCP template from a team context.
|
|
4
3
|
*/
|
|
5
4
|
|
|
6
5
|
import { useState } from 'react';
|
|
7
6
|
|
|
8
7
|
import { Button } from '@renderer/components/ui/button';
|
|
9
|
-
import {
|
|
8
|
+
import { McpLibraryEntryDialog } from '@renderer/components/extensions/mcp/McpLibraryEntryDialog';
|
|
9
|
+
|
|
10
|
+
import type { McpLibraryEntry } from '@shared/types/extensions';
|
|
10
11
|
|
|
11
12
|
interface AddMcpInlineProps {
|
|
12
|
-
|
|
13
|
-
harnessType: string;
|
|
14
|
-
onAdded: () => void;
|
|
13
|
+
onAdded: (entry: McpLibraryEntry) => void;
|
|
15
14
|
onCancel: () => void;
|
|
16
15
|
}
|
|
17
16
|
|
|
18
|
-
export const AddMcpInline = ({
|
|
19
|
-
onAdded,
|
|
20
|
-
onCancel,
|
|
21
|
-
}: AddMcpInlineProps): React.JSX.Element => {
|
|
17
|
+
export const AddMcpInline = ({ onAdded, onCancel }: AddMcpInlineProps): React.JSX.Element => {
|
|
22
18
|
const [dialogOpen, setDialogOpen] = useState(true);
|
|
23
19
|
|
|
24
|
-
const
|
|
20
|
+
const handleSaved = (entry: McpLibraryEntry): void => {
|
|
21
|
+
setDialogOpen(false);
|
|
22
|
+
onAdded(entry);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const handleClose = (): void => {
|
|
25
26
|
setDialogOpen(false);
|
|
26
|
-
|
|
27
|
-
onAdded();
|
|
27
|
+
onCancel();
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
return (
|
|
31
31
|
<>
|
|
32
|
-
<div className="flex items-center gap-2">
|
|
33
|
-
<
|
|
34
|
-
|
|
32
|
+
<div className="flex items-center gap-2 rounded-md border border-dashed border-[var(--color-border)] px-2 py-2">
|
|
33
|
+
<div className="min-w-0 flex-1 text-xs text-[var(--color-text-muted)]">
|
|
34
|
+
先保存一个全局模板,随后可为当前项目填写独立实例名和参数。
|
|
35
|
+
</div>
|
|
36
|
+
<Button
|
|
37
|
+
variant="outline"
|
|
38
|
+
size="sm"
|
|
39
|
+
className="h-7 gap-1 text-xs"
|
|
40
|
+
onClick={() => setDialogOpen(true)}
|
|
41
|
+
>
|
|
42
|
+
添加模板
|
|
35
43
|
</Button>
|
|
36
44
|
<Button variant="ghost" size="sm" onClick={onCancel} className="h-7 text-xs">
|
|
37
45
|
取消
|
|
38
46
|
</Button>
|
|
39
47
|
</div>
|
|
40
48
|
|
|
41
|
-
<
|
|
49
|
+
<McpLibraryEntryDialog
|
|
42
50
|
open={dialogOpen}
|
|
51
|
+
entry={null}
|
|
43
52
|
onClose={handleClose}
|
|
53
|
+
onSaved={handleSaved}
|
|
44
54
|
/>
|
|
45
55
|
</>
|
|
46
56
|
);
|
|
@@ -26,14 +26,17 @@ export const McpChip = ({ entry, diagnostic, onRemove }: McpChipProps): React.JS
|
|
|
26
26
|
|
|
27
27
|
return (
|
|
28
28
|
<div className="group inline-flex items-center gap-1.5 rounded-full bg-[var(--color-bg-secondary)] px-2.5 py-1 text-xs transition-colors hover:bg-[var(--color-bg-secondary-hover)]">
|
|
29
|
-
<span
|
|
29
|
+
<span
|
|
30
|
+
className={`size-2 shrink-0 rounded-full ${statusColor}`}
|
|
31
|
+
title={diagnostic?.status ?? 'unknown'}
|
|
32
|
+
/>
|
|
30
33
|
<span className="max-w-[120px] truncate text-[var(--color-text)]">{entry.name}</span>
|
|
31
34
|
<button
|
|
32
35
|
type="button"
|
|
33
36
|
className="shrink-0 rounded-full p-0.5 opacity-0 transition-opacity hover:bg-red-500/20 group-hover:opacity-100"
|
|
34
37
|
onClick={() => onRemove(entry)}
|
|
35
|
-
aria-label={
|
|
36
|
-
title="
|
|
38
|
+
aria-label={`从当前项目移除 MCP 实例 ${entry.name}`}
|
|
39
|
+
title="移除项目实例"
|
|
37
40
|
>
|
|
38
41
|
<X size={10} className="text-[var(--color-text-muted)] hover:text-red-400" />
|
|
39
42
|
</button>
|
|
@@ -25,8 +25,8 @@ export const SkillChip = ({ skill, onRemove }: SkillChipProps): React.JSX.Elemen
|
|
|
25
25
|
type="button"
|
|
26
26
|
className="shrink-0 rounded-full p-0.5 opacity-0 transition-opacity hover:bg-red-500/20 group-hover:opacity-100"
|
|
27
27
|
onClick={() => onRemove(skill)}
|
|
28
|
-
aria-label={
|
|
29
|
-
title="
|
|
28
|
+
aria-label={`从当前团队禁用 ${skill.name}`}
|
|
29
|
+
title="从当前团队禁用"
|
|
30
30
|
>
|
|
31
31
|
<X size={10} className="text-[var(--color-text-muted)] hover:text-red-400" />
|
|
32
32
|
</button>
|