@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.
- package/dist-renderer/assets/ProjectEditorOverlay-krO5vQxX.js +58 -0
- package/dist-renderer/assets/{TeamGraphOverlay-DYT3bwFR.js → TeamGraphOverlay-DqhQzcTr.js} +1 -1
- package/dist-renderer/assets/{_basePickBy-Dbt_EU-e.js → _basePickBy-B7kSYPxr.js} +1 -1
- package/dist-renderer/assets/{_baseUniq-DWo68sXI.js → _baseUniq-CnjxqwAk.js} +1 -1
- package/dist-renderer/assets/{arc-DXH1iZQK.js → arc-CLeZuINP.js} +1 -1
- package/dist-renderer/assets/{architectureDiagram-VXUJARFQ-cjffS2Qr.js → architectureDiagram-VXUJARFQ-QKtqaqdY.js} +1 -1
- package/dist-renderer/assets/{blockDiagram-VD42YOAC-BKdZF02Y.js → blockDiagram-VD42YOAC-BqdrzO_f.js} +1 -1
- package/dist-renderer/assets/{c4Diagram-YG6GDRKO-CN27pqaI.js → c4Diagram-YG6GDRKO-gwPlCxDC.js} +1 -1
- package/dist-renderer/assets/channel-DpMHF50r.js +1 -0
- package/dist-renderer/assets/{chunk-4BX2VUAB-CXPCI7g_.js → chunk-4BX2VUAB-C6XLurL4.js} +1 -1
- package/dist-renderer/assets/{chunk-55IACEB6-BGAXQZRC.js → chunk-55IACEB6-Ds6quhEP.js} +1 -1
- package/dist-renderer/assets/{chunk-B4BG7PRW-TPDaA_KQ.js → chunk-B4BG7PRW-5UlA1_e9.js} +1 -1
- package/dist-renderer/assets/{chunk-DI55MBZ5-D1ADe_tq.js → chunk-DI55MBZ5-ywFrqIsY.js} +1 -1
- package/dist-renderer/assets/{chunk-FMBD7UC4-Beimtg3a.js → chunk-FMBD7UC4-C7ifUA17.js} +1 -1
- package/dist-renderer/assets/{chunk-QN33PNHL-OjNBu854.js → chunk-QN33PNHL-BxGCo80U.js} +1 -1
- package/dist-renderer/assets/{chunk-QZHKN3VN-DinqvbH8.js → chunk-QZHKN3VN-B2CuaZs6.js} +1 -1
- package/dist-renderer/assets/{chunk-TZMSLE5B-BfFtlPSZ.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-D9z9Dgt7.js → cose-bilkent-S5V4N54A-Cz1GVtLp.js} +1 -1
- package/dist-renderer/assets/{dagre-6UL2VRFP-n1g-DhEE.js → dagre-6UL2VRFP-BrmR-P4h.js} +1 -1
- package/dist-renderer/assets/{diagram-PSM6KHXK-BvxFq-BE.js → diagram-PSM6KHXK-DbNjC5Rg.js} +1 -1
- package/dist-renderer/assets/{diagram-QEK2KX5R-wVnJuwza.js → diagram-QEK2KX5R-qkRX5_Mq.js} +1 -1
- package/dist-renderer/assets/{diagram-S2PKOQOG-B707WJQw.js → diagram-S2PKOQOG-CyL5rCv2.js} +1 -1
- package/dist-renderer/assets/{erDiagram-Q2GNP2WA-C-_1dGHs.js → erDiagram-Q2GNP2WA-Dox3-bA5.js} +1 -1
- package/dist-renderer/assets/{flowDiagram-NV44I4VS-CMTSi3H6.js → flowDiagram-NV44I4VS-BtkaxlDL.js} +1 -1
- package/dist-renderer/assets/{ganttDiagram-JELNMOA3-DZ0bNrAA.js → ganttDiagram-JELNMOA3-Dhy_d9GK.js} +1 -1
- package/dist-renderer/assets/{gitGraphDiagram-V2S2FVAM-DNVfGooQ.js → gitGraphDiagram-V2S2FVAM-B5XRhIQA.js} +1 -1
- package/dist-renderer/assets/{graph-865j_tM_.js → graph-CsoEwUhS.js} +1 -1
- package/dist-renderer/assets/{index-C_F9N5x-.js → index-BWPWmJNo.js} +1 -1
- package/dist-renderer/assets/{index-LwDIsXJN.js → index-Bu2R-Se7.js} +586 -740
- package/dist-renderer/assets/index-CnWV3BhG.css +32 -0
- package/dist-renderer/assets/{index-DuUaf8at.js → index-D-3KgskL.js} +1 -1
- package/dist-renderer/assets/{index-BTx1nc4T.js → index-DGEBzLNT.js} +1 -1
- package/dist-renderer/assets/{index-2EW-eu3q.js → index-NhHNs2Oo.js} +1 -1
- package/dist-renderer/assets/{index-4dEMStJj.js → index-h17WuEyf.js} +1 -1
- package/dist-renderer/assets/{infoDiagram-HS3SLOUP-CyqtElLq.js → infoDiagram-HS3SLOUP-hMGmNojH.js} +1 -1
- package/dist-renderer/assets/{journeyDiagram-XKPGCS4Q-BvjQ0Hm0.js → journeyDiagram-XKPGCS4Q-DXV2rBDl.js} +1 -1
- package/dist-renderer/assets/{kanban-definition-3W4ZIXB7-CJJ-k0zT.js → kanban-definition-3W4ZIXB7-Bf99WLRy.js} +1 -1
- package/dist-renderer/assets/{layout-CnV6rQAG.js → layout-C3XWrpwo.js} +1 -1
- package/dist-renderer/assets/{linear-Cw3UQgyX.js → linear-OEEcn8KN.js} +1 -1
- package/dist-renderer/assets/{mindmap-definition-VGOIOE7T-C5tDaGSK.js → mindmap-definition-VGOIOE7T-Dpi3S2x4.js} +1 -1
- package/dist-renderer/assets/{pieDiagram-ADFJNKIX-CiIpPsau.js → pieDiagram-ADFJNKIX-xTPPhtNx.js} +1 -1
- package/dist-renderer/assets/{quadrantDiagram-AYHSOK5B-C3gtowNj.js → quadrantDiagram-AYHSOK5B-euniyDlz.js} +1 -1
- package/dist-renderer/assets/{requirementDiagram-UZGBJVZJ-CXBTrAnU.js → requirementDiagram-UZGBJVZJ-D9Uiw4kF.js} +1 -1
- package/dist-renderer/assets/{sankeyDiagram-TZEHDZUN-wziX77xG.js → sankeyDiagram-TZEHDZUN-CySU4nED.js} +1 -1
- package/dist-renderer/assets/{sequenceDiagram-WL72ISMW-sYqopcrj.js → sequenceDiagram-WL72ISMW-JVGpET6V.js} +1 -1
- package/dist-renderer/assets/splashScene-D0YB9uxm.js +17 -0
- package/dist-renderer/assets/{stateDiagram-FKZM4ZOC-Bl1-0_Cp.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-CIRjJUBo.js → timeline-definition-IT6M3QCI-DmycNUUe.js} +1 -1
- package/dist-renderer/assets/{treemap-GDKQZRPO-CVPuNe1n.js → treemap-GDKQZRPO-DPq4gZuB.js} +1 -1
- package/dist-renderer/assets/{xychartDiagram-PRI3JC2R-3nT9yHwp.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 +30 -50
- package/src/main/server.ts +890 -247
- package/src/main/services/extensions/ExtensionFacadeService.ts +4 -56
- package/src/main/services/extensions/catalog/PluginCatalogService.ts +4 -2
- package/src/main/services/extensions/library/McpLibraryService.ts +243 -0
- 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/session-intelligence/UsageTelemetryService.ts +14 -1
- 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 +32 -8
- 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 +174 -38
- 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 +12 -221
- 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 +10 -2
- package/src/renderer/components/extensions/plugins/PluginsPanel.tsx +40 -22
- 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 +325 -114
- 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 +57 -0
- package/src/renderer/components/team/tools/AddSkillInline.tsx +61 -0
- package/src/renderer/components/team/tools/McpChip.tsx +45 -0
- package/src/renderer/components/team/tools/SkillChip.tsx +35 -0
- package/src/renderer/components/team/tools/ToolsSection.tsx +556 -0
- 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/extensions/api.ts +9 -0
- package/src/shared/types/extensions/index.ts +4 -0
- package/src/shared/types/extensions/mcp.ts +41 -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 +29 -0
- package/src/shared/utils/providerExtensionCapabilities.ts +2 -2
- package/dist-renderer/assets/ProjectEditorOverlay-Va_Vz-zz.js +0 -52
- package/dist-renderer/assets/channel-5dJIx68e.js +0 -1
- package/dist-renderer/assets/classDiagram-2ON5EDUG-BMGXWJ2d.js +0 -1
- package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-BMGXWJ2d.js +0 -1
- package/dist-renderer/assets/clone-D7FWfGY9.js +0 -1
- package/dist-renderer/assets/index-B2z_IyRH.css +0 -1
- package/dist-renderer/assets/splashScene-C8lWNnm4.js +0 -1
- package/dist-renderer/assets/stateDiagram-v2-4FDKWEC3-DOYYvDbi.js +0 -1
- package/src/main/services/extensions/catalog/GlamaMcpEnrichmentService.ts +0 -190
- package/src/main/services/extensions/catalog/McpCatalogAggregator.ts +0 -150
- package/src/main/services/extensions/catalog/OfficialMcpRegistryService.ts +0 -381
- package/src/main/services/extensions/install/McpInstallService.ts +0 -407
- package/src/main/services/extensions/state/McpInstallationStateService.ts +0 -42
- package/src/renderer/components/extensions/mcp/McpServerCard.tsx +0 -314
- package/src/renderer/components/extensions/mcp/McpServerDetailDialog.tsx +0 -765
- package/src/renderer/components/extensions/mcp/McpServersPanel.tsx +0 -593
- package/src/renderer/components/extensions/skills/SkillDetailDialog.tsx +0 -372
- package/src/renderer/components/extensions/skills/SkillImportDialog.tsx +0 -343
- package/src/renderer/components/extensions/skills/SkillsPanel.tsx +0 -659
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
AlertCircle,
|
|
18
18
|
ChevronDown,
|
|
19
19
|
ChevronRight,
|
|
20
|
+
Download,
|
|
20
21
|
Loader2,
|
|
21
22
|
MessageSquare,
|
|
22
23
|
Radio,
|
|
@@ -25,7 +26,14 @@ import {
|
|
|
25
26
|
X,
|
|
26
27
|
} from 'lucide-react';
|
|
27
28
|
|
|
28
|
-
import type {
|
|
29
|
+
import type {
|
|
30
|
+
CcSession,
|
|
31
|
+
CcSessionDetail,
|
|
32
|
+
ConversationTelemetryResponse,
|
|
33
|
+
ConversationTelemetryRow,
|
|
34
|
+
TeamChangeEvent,
|
|
35
|
+
TeamSummary,
|
|
36
|
+
} from '@shared/types';
|
|
29
37
|
|
|
30
38
|
const PAGE_SIZE = 8;
|
|
31
39
|
const REFRESH_INTERVAL_MS = 2000;
|
|
@@ -48,6 +56,9 @@ export const SidebarSessions = (): React.JSX.Element => {
|
|
|
48
56
|
const [visibleCount, setVisibleCount] = useState(PAGE_SIZE);
|
|
49
57
|
const [searchQuery, setSearchQuery] = useState('');
|
|
50
58
|
const [cancellingId, setCancellingId] = useState<string | null>(null);
|
|
59
|
+
const [exporting, setExporting] = useState(false);
|
|
60
|
+
const [telemetryRows, setTelemetryRows] = useState<ConversationTelemetryRow[]>([]);
|
|
61
|
+
const [loadingTelemetry, setLoadingTelemetry] = useState(false);
|
|
51
62
|
const [expandedId, setExpandedId] = useState<string | null>(null);
|
|
52
63
|
const refreshInFlightRef = useRef(false);
|
|
53
64
|
const needsRefreshRef = useRef(false);
|
|
@@ -143,6 +154,35 @@ export const SidebarSessions = (): React.JSX.Element => {
|
|
|
143
154
|
void fetchAll();
|
|
144
155
|
}, [fetchAll]);
|
|
145
156
|
|
|
157
|
+
useEffect(() => {
|
|
158
|
+
let cancelled = false;
|
|
159
|
+
setLoadingTelemetry(true);
|
|
160
|
+
const params = new URLSearchParams({
|
|
161
|
+
includeContent: 'summary',
|
|
162
|
+
includeToolResults: 'false',
|
|
163
|
+
includeSystemMessages: 'false',
|
|
164
|
+
limit: '100000',
|
|
165
|
+
});
|
|
166
|
+
void fetch(`/api/telemetry/conversations?${params.toString()}`)
|
|
167
|
+
.then(async (res) => {
|
|
168
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
169
|
+
return (await res.json()) as ConversationTelemetryResponse;
|
|
170
|
+
})
|
|
171
|
+
.then((data) => {
|
|
172
|
+
if (!cancelled) setTelemetryRows(data.rows);
|
|
173
|
+
})
|
|
174
|
+
.catch((err) => {
|
|
175
|
+
console.error('Failed to load conversation telemetry:', err);
|
|
176
|
+
if (!cancelled) setTelemetryRows([]);
|
|
177
|
+
})
|
|
178
|
+
.finally(() => {
|
|
179
|
+
if (!cancelled) setLoadingTelemetry(false);
|
|
180
|
+
});
|
|
181
|
+
return () => {
|
|
182
|
+
cancelled = true;
|
|
183
|
+
};
|
|
184
|
+
}, []);
|
|
185
|
+
|
|
146
186
|
useEffect(() => {
|
|
147
187
|
setVisibleCount(PAGE_SIZE);
|
|
148
188
|
setExpandedId(null);
|
|
@@ -161,6 +201,20 @@ export const SidebarSessions = (): React.JSX.Element => {
|
|
|
161
201
|
if (scopedTeamName && change.teamName !== scopedTeamName) {
|
|
162
202
|
return;
|
|
163
203
|
}
|
|
204
|
+
// Only refresh the session list on events that may change session state.
|
|
205
|
+
// Skip high-frequency events like lead-context, tool-activity, lead-activity
|
|
206
|
+
// that don't affect the session list.
|
|
207
|
+
const sessionRelevantTypes: ReadonlySet<string> = new Set([
|
|
208
|
+
'inbox',
|
|
209
|
+
'lead-message',
|
|
210
|
+
'task',
|
|
211
|
+
'config',
|
|
212
|
+
'process',
|
|
213
|
+
'member-spawn',
|
|
214
|
+
]);
|
|
215
|
+
if (!sessionRelevantTypes.has(change.type)) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
164
218
|
// Incremental refresh for the changed team — lightweight, no blocking
|
|
165
219
|
void refreshTeam(change.teamName);
|
|
166
220
|
});
|
|
@@ -195,14 +249,78 @@ export const SidebarSessions = (): React.JSX.Element => {
|
|
|
195
249
|
setExpandedId((prev) => (prev === sessionId ? null : sessionId));
|
|
196
250
|
}, []);
|
|
197
251
|
|
|
252
|
+
const handleExportAllSessions = useCallback(async () => {
|
|
253
|
+
setExporting(true);
|
|
254
|
+
try {
|
|
255
|
+
const params = new URLSearchParams({
|
|
256
|
+
format: 'csv',
|
|
257
|
+
includeContent: 'summary',
|
|
258
|
+
includeToolResults: 'false',
|
|
259
|
+
includeSystemMessages: 'false',
|
|
260
|
+
});
|
|
261
|
+
if (scopedTeamName) {
|
|
262
|
+
params.set('teamName', scopedTeamName);
|
|
263
|
+
}
|
|
264
|
+
const res = await fetch(`/api/telemetry/conversations/export?${params.toString()}`);
|
|
265
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
266
|
+
const payload = (await res.json()) as { filename: string; mimeType: string; content: string };
|
|
267
|
+
const blob = new Blob([`${payload.content}`], {
|
|
268
|
+
type: payload.mimeType || 'text/csv;charset=utf-8',
|
|
269
|
+
});
|
|
270
|
+
const url = URL.createObjectURL(blob);
|
|
271
|
+
const link = document.createElement('a');
|
|
272
|
+
link.href = url;
|
|
273
|
+
link.download = payload.filename || 'conversation-telemetry.csv';
|
|
274
|
+
document.body.appendChild(link);
|
|
275
|
+
link.click();
|
|
276
|
+
link.remove();
|
|
277
|
+
URL.revokeObjectURL(url);
|
|
278
|
+
} catch (err) {
|
|
279
|
+
console.error('Failed to export conversation telemetry:', err);
|
|
280
|
+
setError(err instanceof Error ? err.message : '导出失败');
|
|
281
|
+
} finally {
|
|
282
|
+
setExporting(false);
|
|
283
|
+
}
|
|
284
|
+
}, [scopedTeamName]);
|
|
285
|
+
|
|
286
|
+
const telemetryBySession = useMemo(() => {
|
|
287
|
+
const map = new Map<string, ConversationTelemetryRow>();
|
|
288
|
+
for (const row of telemetryRows) {
|
|
289
|
+
if (row.session.ccSessionId) map.set(row.session.ccSessionId, row);
|
|
290
|
+
map.set(row.session.sessionKey, row);
|
|
291
|
+
}
|
|
292
|
+
return map;
|
|
293
|
+
}, [telemetryRows]);
|
|
294
|
+
|
|
198
295
|
// Filter + sort
|
|
199
296
|
const filtered = allSessions.filter((s) => {
|
|
200
297
|
if (!searchQuery.trim()) return true;
|
|
201
298
|
const q = searchQuery.toLowerCase();
|
|
299
|
+
const telemetry = telemetryBySession.get(s.id) ?? telemetryBySession.get(s.sessionKey);
|
|
202
300
|
const title = (s.title || '').toLowerCase();
|
|
203
301
|
const team = s.teamDisplayName.toLowerCase();
|
|
204
|
-
const
|
|
205
|
-
|
|
302
|
+
const sessionKey = s.sessionKey.toLowerCase();
|
|
303
|
+
const platform = s.platform.toLowerCase();
|
|
304
|
+
const userName = (s.userName || telemetry?.identity.userName || '').toLowerCase();
|
|
305
|
+
const chatName = (s.chatName || telemetry?.identity.chatName || '').toLowerCase();
|
|
306
|
+
const firstQuestion = (telemetry?.content.firstUserMessage || '').toLowerCase();
|
|
307
|
+
const lastQuestion = (telemetry?.content.lastUserMessage || '').toLowerCase();
|
|
308
|
+
const lastMsg = (
|
|
309
|
+
s.lastMessage?.content ||
|
|
310
|
+
telemetry?.content.lastMessageContent ||
|
|
311
|
+
''
|
|
312
|
+
).toLowerCase();
|
|
313
|
+
return [
|
|
314
|
+
title,
|
|
315
|
+
team,
|
|
316
|
+
sessionKey,
|
|
317
|
+
platform,
|
|
318
|
+
userName,
|
|
319
|
+
chatName,
|
|
320
|
+
firstQuestion,
|
|
321
|
+
lastQuestion,
|
|
322
|
+
lastMsg,
|
|
323
|
+
].some((value) => value.includes(q));
|
|
206
324
|
});
|
|
207
325
|
|
|
208
326
|
const allSorted = [...filtered].sort(
|
|
@@ -261,7 +379,7 @@ export const SidebarSessions = (): React.JSX.Element => {
|
|
|
261
379
|
|
|
262
380
|
return (
|
|
263
381
|
<div className="flex h-full flex-col overflow-hidden">
|
|
264
|
-
{/* Search */}
|
|
382
|
+
{/* Search / export */}
|
|
265
383
|
<div className="flex shrink-0 items-center gap-1.5 border-b px-2 py-1.5">
|
|
266
384
|
<Search size={12} className="shrink-0 text-[var(--color-text-muted)]" />
|
|
267
385
|
<input
|
|
@@ -283,6 +401,16 @@ export const SidebarSessions = (): React.JSX.Element => {
|
|
|
283
401
|
<X size={12} />
|
|
284
402
|
</button>
|
|
285
403
|
)}
|
|
404
|
+
<button
|
|
405
|
+
type="button"
|
|
406
|
+
className="inline-flex shrink-0 items-center gap-1 rounded-md px-1.5 py-0.5 text-[10px] text-[var(--color-text-muted)] transition-colors hover:bg-[var(--color-surface-raised)] hover:text-[var(--color-text)] disabled:cursor-not-allowed disabled:opacity-50"
|
|
407
|
+
onClick={() => void handleExportAllSessions()}
|
|
408
|
+
disabled={exporting}
|
|
409
|
+
title="导出所有会话为 CSV 表格"
|
|
410
|
+
>
|
|
411
|
+
{exporting ? <Loader2 size={12} className="animate-spin" /> : <Download size={12} />}
|
|
412
|
+
导出表格
|
|
413
|
+
</button>
|
|
286
414
|
</div>
|
|
287
415
|
|
|
288
416
|
{/* Session list */}
|
|
@@ -425,6 +553,56 @@ const SessionRow = ({
|
|
|
425
553
|
return () => window.clearInterval(intervalId);
|
|
426
554
|
}, [isExpanded, session.live, session.teamName, session.id, historyLimit]);
|
|
427
555
|
|
|
556
|
+
// SSE-driven immediate refresh: when inbox or lead-message events arrive for
|
|
557
|
+
// this session's team, refresh the detail right away instead of waiting for
|
|
558
|
+
// the next polling cycle. This makes agent replies appear in <100ms.
|
|
559
|
+
useEffect(() => {
|
|
560
|
+
if (!isExpanded) {
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
const unsubscribe = api.teams.onTeamChange?.((_event, change: TeamChangeEvent) => {
|
|
564
|
+
if (change.teamName !== session.teamName) {
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
if (change.type !== 'inbox' && change.type !== 'lead-message') {
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
void (async () => {
|
|
571
|
+
try {
|
|
572
|
+
const d = await api.teams.getSessionDetail(session.teamName, session.id, historyLimit);
|
|
573
|
+
setDetail(d);
|
|
574
|
+
} catch {
|
|
575
|
+
// silent
|
|
576
|
+
}
|
|
577
|
+
})();
|
|
578
|
+
});
|
|
579
|
+
return () => {
|
|
580
|
+
if (typeof unsubscribe === 'function') {
|
|
581
|
+
unsubscribe();
|
|
582
|
+
}
|
|
583
|
+
};
|
|
584
|
+
}, [isExpanded, session.teamName, session.id, historyLimit]);
|
|
585
|
+
|
|
586
|
+
// Final refresh when session transitions from live → non-live.
|
|
587
|
+
// The polling useEffect above stops when live becomes false, which can miss
|
|
588
|
+
// the last few messages. This effect ensures we capture the complete
|
|
589
|
+
// conversation when the agent finishes.
|
|
590
|
+
const prevLiveRef = useRef(session.live);
|
|
591
|
+
useEffect(() => {
|
|
592
|
+
const wasLive = prevLiveRef.current;
|
|
593
|
+
prevLiveRef.current = session.live;
|
|
594
|
+
if (wasLive && !session.live && isExpanded) {
|
|
595
|
+
void (async () => {
|
|
596
|
+
try {
|
|
597
|
+
const d = await api.teams.getSessionDetail(session.teamName, session.id, historyLimit);
|
|
598
|
+
setDetail(d);
|
|
599
|
+
} catch {
|
|
600
|
+
// silent
|
|
601
|
+
}
|
|
602
|
+
})();
|
|
603
|
+
}
|
|
604
|
+
}, [session.live, isExpanded, session.teamName, session.id, historyLimit]);
|
|
605
|
+
|
|
428
606
|
const handleLoadMoreHistory = useCallback(() => {
|
|
429
607
|
if (loadingDetail || loadingMoreHistory || !hasMoreHistory) {
|
|
430
608
|
return;
|
|
@@ -19,7 +19,7 @@ import type { LucideIcon } from 'lucide-react';
|
|
|
19
19
|
|
|
20
20
|
const statusConfig: Record<TeamTaskStatus, { icon: LucideIcon; color: string; label: string }> = {
|
|
21
21
|
pending: { icon: Circle, color: 'text-amber-400', label: 'pending' },
|
|
22
|
-
in_progress: { icon: Loader2, color: 'text-
|
|
22
|
+
in_progress: { icon: Loader2, color: 'text-indigo-400', label: 'in progress' },
|
|
23
23
|
completed: { icon: CheckCircle2, color: 'text-emerald-400', label: 'completed' },
|
|
24
24
|
deleted: { icon: Circle, color: 'text-zinc-500', label: 'deleted' },
|
|
25
25
|
};
|
|
@@ -145,7 +145,7 @@ export const SidebarTaskItem = ({
|
|
|
145
145
|
|
|
146
146
|
const showTeamRow = showTeamName && !hideTeamName;
|
|
147
147
|
const unreadBackgroundClass =
|
|
148
|
-
unreadCount > 0 ? (isLight ? 'bg-
|
|
148
|
+
unreadCount > 0 ? (isLight ? 'bg-indigo-500/[0.03]' : 'bg-indigo-500/[0.05]') : '';
|
|
149
149
|
|
|
150
150
|
return (
|
|
151
151
|
<button
|
|
@@ -205,9 +205,9 @@ export const SidebarTaskItem = ({
|
|
|
205
205
|
<StatusIcon className={`mr-1.5 inline-block size-3 align-[-1px] ${cfg.color}`} />
|
|
206
206
|
{unreadCount > 0 &&
|
|
207
207
|
(unreadCount === 1 ? (
|
|
208
|
-
<span className="mr-1 inline-block size-1.5 rounded-full bg-
|
|
208
|
+
<span className="mr-1 inline-block size-1.5 rounded-full bg-indigo-400 align-middle" />
|
|
209
209
|
) : (
|
|
210
|
-
<span className="mr-1 inline-flex size-3.5 items-center justify-center rounded-full bg-
|
|
210
|
+
<span className="mr-1 inline-flex size-3.5 items-center justify-center rounded-full bg-indigo-500 align-middle text-[8px] font-bold leading-none text-white">
|
|
211
211
|
{unreadCount > 9 ? '9+' : unreadCount}
|
|
212
212
|
</span>
|
|
213
213
|
))}
|
|
@@ -7,6 +7,7 @@ import { Folder, FolderOpen, ChevronRight, ChevronDown, ArrowUp, HardDrive } fro
|
|
|
7
7
|
import { useShallow } from 'zustand/react/shallow';
|
|
8
8
|
|
|
9
9
|
import type { WorkspaceFileEntry, WorkspaceListResponse } from '@shared/types/editor';
|
|
10
|
+
import { SYSTEM_MANAGER_DISPLAY_NAME, SYSTEM_MANAGER_TEAM_NAME } from '@shared/types/team';
|
|
10
11
|
|
|
11
12
|
function getRelativePath(currentDir: string, rootPath: string): string {
|
|
12
13
|
if (!currentDir || currentDir === rootPath) return '';
|
|
@@ -141,8 +142,13 @@ const TeamWorkspace = ({
|
|
|
141
142
|
className={`shrink-0 text-[var(--color-text-muted)] transition-transform ${isExpanded ? '' : '-rotate-90'}`}
|
|
142
143
|
/>
|
|
143
144
|
<HardDrive size={14} className="shrink-0 text-[var(--color-text-muted)]" />
|
|
144
|
-
<span className="min-w-0 flex-1
|
|
145
|
-
|
|
145
|
+
<span className="min-w-0 flex-1">
|
|
146
|
+
<span className="block truncate text-sm font-medium text-[var(--color-text)]">
|
|
147
|
+
{teamDisplayName}
|
|
148
|
+
</span>
|
|
149
|
+
<span className="block truncate font-mono text-[10px] text-[var(--color-text-muted)]" title={projectPath}>
|
|
150
|
+
{projectPath}
|
|
151
|
+
</span>
|
|
146
152
|
</span>
|
|
147
153
|
<span className="shrink-0 rounded bg-blue-500/20 px-1.5 py-0.5 text-[10px] font-medium text-blue-400">
|
|
148
154
|
当前
|
|
@@ -254,6 +260,7 @@ export const WorkspaceBrowser = (): React.JSX.Element => {
|
|
|
254
260
|
}))
|
|
255
261
|
);
|
|
256
262
|
const revealFileInEditor = useStore((s) => s.revealFileInEditor);
|
|
263
|
+
const [systemManagerProjectPath, setSystemManagerProjectPath] = useState<string | null>(null);
|
|
257
264
|
|
|
258
265
|
const scopedTeamName = useMemo(() => {
|
|
259
266
|
if (!activeTabId) {
|
|
@@ -268,10 +275,38 @@ export const WorkspaceBrowser = (): React.JSX.Element => {
|
|
|
268
275
|
return selectedTeamName;
|
|
269
276
|
}, [activeTabId, paneLayout.panes, selectedTeamName]);
|
|
270
277
|
|
|
278
|
+
useEffect(() => {
|
|
279
|
+
if (scopedTeamName !== SYSTEM_MANAGER_TEAM_NAME) {
|
|
280
|
+
setSystemManagerProjectPath(null);
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
let cancelled = false;
|
|
285
|
+
void api.systemManager
|
|
286
|
+
.getConfig()
|
|
287
|
+
.then((config) => {
|
|
288
|
+
if (!cancelled) setSystemManagerProjectPath(config.selectedWorkDir);
|
|
289
|
+
})
|
|
290
|
+
.catch(() => {
|
|
291
|
+
if (!cancelled) setSystemManagerProjectPath(null);
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
return () => {
|
|
295
|
+
cancelled = true;
|
|
296
|
+
};
|
|
297
|
+
}, [scopedTeamName]);
|
|
298
|
+
|
|
271
299
|
const currentTeamWorkspace = useMemo(() => {
|
|
272
300
|
if (!scopedTeamName) {
|
|
273
301
|
return null;
|
|
274
302
|
}
|
|
303
|
+
if (scopedTeamName === SYSTEM_MANAGER_TEAM_NAME) {
|
|
304
|
+
return {
|
|
305
|
+
teamName: SYSTEM_MANAGER_TEAM_NAME,
|
|
306
|
+
teamDisplayName: SYSTEM_MANAGER_DISPLAY_NAME,
|
|
307
|
+
projectPath: systemManagerProjectPath,
|
|
308
|
+
};
|
|
309
|
+
}
|
|
275
310
|
const team = teams.find((candidate) => candidate.teamName === scopedTeamName);
|
|
276
311
|
if (!team) {
|
|
277
312
|
return null;
|
|
@@ -289,7 +324,7 @@ export const WorkspaceBrowser = (): React.JSX.Element => {
|
|
|
289
324
|
teamDisplayName: team.displayName || team.teamName,
|
|
290
325
|
projectPath,
|
|
291
326
|
};
|
|
292
|
-
}, [scopedTeamName, teams]);
|
|
327
|
+
}, [scopedTeamName, systemManagerProjectPath, teams]);
|
|
293
328
|
|
|
294
329
|
const [expanded, setExpanded] = useState(true);
|
|
295
330
|
|
|
@@ -334,7 +369,7 @@ export const WorkspaceBrowser = (): React.JSX.Element => {
|
|
|
334
369
|
<div className="flex h-full flex-col overflow-hidden">
|
|
335
370
|
<div className="flex-1 overflow-y-auto">
|
|
336
371
|
<TeamWorkspace
|
|
337
|
-
key={currentTeamWorkspace.teamName}
|
|
372
|
+
key={`${currentTeamWorkspace.teamName}:${currentTeamWorkspace.projectPath}`}
|
|
338
373
|
teamDisplayName={currentTeamWorkspace.teamDisplayName}
|
|
339
374
|
projectPath={currentTeamWorkspace.projectPath}
|
|
340
375
|
isExpanded={expanded}
|