@yancyyu/openhermit 1.6.38 → 1.6.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-renderer/assets/ProjectEditorOverlay-CemDOX-3.js +58 -0
- package/dist-renderer/assets/{TeamGraphOverlay-ZEDfZyHb.js → TeamGraphOverlay-hPY770Db.js} +1 -1
- package/dist-renderer/assets/{_basePickBy-CIhniz70.js → _basePickBy-BHHrJT1i.js} +1 -1
- package/dist-renderer/assets/{_baseUniq-cKAW4Q8I.js → _baseUniq-CWErBtke.js} +1 -1
- package/dist-renderer/assets/{arc-YmNsoDXW.js → arc-C_o2_Uv8.js} +1 -1
- package/dist-renderer/assets/{architectureDiagram-VXUJARFQ-DHEls2sX.js → architectureDiagram-VXUJARFQ-DUW0LI3t.js} +1 -1
- package/dist-renderer/assets/{blockDiagram-VD42YOAC-Bpwf1Sbg.js → blockDiagram-VD42YOAC-CWbCE9hQ.js} +1 -1
- package/dist-renderer/assets/{c4Diagram-YG6GDRKO-B0IaQ4w5.js → c4Diagram-YG6GDRKO-BjLadrfV.js} +1 -1
- package/dist-renderer/assets/channel-DyP9YlCF.js +1 -0
- package/dist-renderer/assets/{chunk-4BX2VUAB-DLk-hcFc.js → chunk-4BX2VUAB-CPnvjZl9.js} +1 -1
- package/dist-renderer/assets/{chunk-55IACEB6-1XRmX_Zm.js → chunk-55IACEB6-OlL47yXQ.js} +1 -1
- package/dist-renderer/assets/{chunk-B4BG7PRW-1waH1DAD.js → chunk-B4BG7PRW-DTasjbm8.js} +1 -1
- package/dist-renderer/assets/{chunk-DI55MBZ5-BqpZBtrN.js → chunk-DI55MBZ5-C5_Xaqkk.js} +1 -1
- package/dist-renderer/assets/{chunk-FMBD7UC4-Bly7vVym.js → chunk-FMBD7UC4-NdoM4DMR.js} +1 -1
- package/dist-renderer/assets/{chunk-QN33PNHL-Ci2QWBAs.js → chunk-QN33PNHL-C8Fybejy.js} +1 -1
- package/dist-renderer/assets/{chunk-QZHKN3VN-YCqFW7d-.js → chunk-QZHKN3VN-E98TYFXJ.js} +1 -1
- package/dist-renderer/assets/{chunk-TZMSLE5B-B0xGXInl.js → chunk-TZMSLE5B-h4lFgkIq.js} +1 -1
- package/dist-renderer/assets/classDiagram-2ON5EDUG-BqffFTae.js +1 -0
- package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-BqffFTae.js +1 -0
- package/dist-renderer/assets/clone-MPcKWs2O.js +1 -0
- package/dist-renderer/assets/{cose-bilkent-S5V4N54A-DxcFNQKT.js → cose-bilkent-S5V4N54A-DtQ7fkrs.js} +1 -1
- package/dist-renderer/assets/{dagre-6UL2VRFP-DPo_RfZY.js → dagre-6UL2VRFP-CN-nL_z4.js} +1 -1
- package/dist-renderer/assets/{diagram-PSM6KHXK-U3hQsFe4.js → diagram-PSM6KHXK-DVJtqmm-.js} +1 -1
- package/dist-renderer/assets/{diagram-QEK2KX5R-OrwrAy0V.js → diagram-QEK2KX5R-DlxHxyXh.js} +1 -1
- package/dist-renderer/assets/{diagram-S2PKOQOG-CXATPWVw.js → diagram-S2PKOQOG-7dpzO6x6.js} +1 -1
- package/dist-renderer/assets/{erDiagram-Q2GNP2WA-B0e8AfMF.js → erDiagram-Q2GNP2WA-GP1TqsHi.js} +1 -1
- package/dist-renderer/assets/{flowDiagram-NV44I4VS-CXfzA4jJ.js → flowDiagram-NV44I4VS-C7ZLETuH.js} +1 -1
- package/dist-renderer/assets/{ganttDiagram-JELNMOA3-CMr08qVl.js → ganttDiagram-JELNMOA3-CvPB68dH.js} +1 -1
- package/dist-renderer/assets/{gitGraphDiagram-V2S2FVAM-vYFHpPmy.js → gitGraphDiagram-V2S2FVAM-B5yOm3w7.js} +1 -1
- package/dist-renderer/assets/{graph-DOe5j8dH.js → graph-smeyY1YZ.js} +1 -1
- package/dist-renderer/assets/{index-BySQS7AB.js → index-BJx8XvG1.js} +1 -1
- package/dist-renderer/assets/{index-C_okzZXP.js → index-CQaXUAua.js} +1 -1
- package/dist-renderer/assets/{index-VJ-MM9xa.js → index-CajRpxO2.js} +1 -1
- package/dist-renderer/assets/{index-V7dAKPqd.js → index-ChG4rE-E.js} +587 -705
- package/dist-renderer/assets/index-DUd0uw9C.css +32 -0
- package/dist-renderer/assets/{index-CzWxVCRL.js → index-IhmXZWqf.js} +1 -1
- package/dist-renderer/assets/{index-B2Dy7M2G.js → index-x_JkoDRH.js} +1 -1
- package/dist-renderer/assets/{infoDiagram-HS3SLOUP-D_WubR0B.js → infoDiagram-HS3SLOUP-D-hWRQGY.js} +1 -1
- package/dist-renderer/assets/{journeyDiagram-XKPGCS4Q-w9ca-1TI.js → journeyDiagram-XKPGCS4Q-Bb6W8rUG.js} +1 -1
- package/dist-renderer/assets/{kanban-definition-3W4ZIXB7-Jg9p6_pN.js → kanban-definition-3W4ZIXB7-CnHdUX0q.js} +1 -1
- package/dist-renderer/assets/{layout-B-z3y17c.js → layout-pqss_zkI.js} +1 -1
- package/dist-renderer/assets/{linear-D-RTX5UW.js → linear-B1mFITNh.js} +1 -1
- package/dist-renderer/assets/{mindmap-definition-VGOIOE7T-CDQmHOYP.js → mindmap-definition-VGOIOE7T-DTD9q7-D.js} +1 -1
- package/dist-renderer/assets/{pieDiagram-ADFJNKIX-D_odsQL7.js → pieDiagram-ADFJNKIX-Df3mhrn7.js} +1 -1
- package/dist-renderer/assets/{quadrantDiagram-AYHSOK5B-BRsmYWSA.js → quadrantDiagram-AYHSOK5B-B1FZ09vH.js} +1 -1
- package/dist-renderer/assets/{requirementDiagram-UZGBJVZJ-ChNE_BOV.js → requirementDiagram-UZGBJVZJ-aEO78thZ.js} +1 -1
- package/dist-renderer/assets/{sankeyDiagram-TZEHDZUN-C8FtpwKc.js → sankeyDiagram-TZEHDZUN-6Ui--jp-.js} +1 -1
- package/dist-renderer/assets/{sequenceDiagram-WL72ISMW-DmLCzNcc.js → sequenceDiagram-WL72ISMW-DF4Q1cAM.js} +1 -1
- package/dist-renderer/assets/splashScene-D0YB9uxm.js +17 -0
- package/dist-renderer/assets/{stateDiagram-FKZM4ZOC-WJBm4bhu.js → stateDiagram-FKZM4ZOC-BqA2BI8C.js} +1 -1
- package/dist-renderer/assets/stateDiagram-v2-4FDKWEC3-Cs2ZtUD2.js +1 -0
- package/dist-renderer/assets/{timeline-definition-IT6M3QCI-BXs_hOJs.js → timeline-definition-IT6M3QCI-DoOkw_A8.js} +1 -1
- package/dist-renderer/assets/{treemap-GDKQZRPO-o04MA0G9.js → treemap-GDKQZRPO-DUe26QdD.js} +1 -1
- package/dist-renderer/assets/{xychartDiagram-PRI3JC2R-Czj69XRd.js → xychartDiagram-PRI3JC2R-BKCnj5Xn.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/chat/ChatHistoryItem.tsx +1 -1
- package/src/renderer/components/chat/items/SubagentItem.tsx +2 -2
- package/src/renderer/components/chat/viewers/MermaidDiagram.tsx +2 -2
- package/src/renderer/components/common/ErrorBoundary.tsx +1 -1
- package/src/renderer/components/common/TerminalPane.tsx +213 -0
- package/src/renderer/components/dashboard/CliStatusBanner.tsx +7 -7
- package/src/renderer/components/dashboard/DashboardView.tsx +9 -36
- package/src/renderer/components/extensions/ExtensionStoreView.tsx +7 -126
- package/src/renderer/components/extensions/ExtensionsSubTabTrigger.tsx +1 -1
- package/src/renderer/components/extensions/common/ExtensionToast.tsx +3 -3
- package/src/renderer/components/extensions/common/SourceBadge.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/CategoryChips.tsx +1 -1
- package/src/renderer/components/extensions/plugins/PluginCard.tsx +6 -6
- package/src/renderer/components/extensions/plugins/PluginDetailDialog.tsx +2 -2
- package/src/renderer/components/extensions/plugins/PluginsPanel.tsx +34 -21
- package/src/renderer/components/extensions/skills/SkillEditorDialog.tsx +1 -1
- package/src/renderer/components/extensions/skills/SkillsLibraryPanel.tsx +335 -0
- package/src/renderer/components/layout/PaneContent.tsx +8 -1
- package/src/renderer/components/layout/PaneResizeHandle.tsx +2 -2
- package/src/renderer/components/layout/Sidebar.tsx +13 -56
- package/src/renderer/components/layout/SortableTab.tsx +22 -33
- package/src/renderer/components/layout/TabBar.tsx +1 -1
- package/src/renderer/components/layout/TabContextMenu.tsx +1 -1
- package/src/renderer/components/report/sections/CostSection.tsx +2 -2
- package/src/renderer/components/report/sections/InsightsSection.tsx +1 -1
- package/src/renderer/components/runtime/ProviderRuntimeBackendSelector.tsx +2 -2
- 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/search/CommandPalette.tsx +4 -4
- 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 +72 -113
- 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/SessionFiltersPopover.tsx +1 -1
- package/src/renderer/components/sidebar/SessionItem.tsx +3 -3
- package/src/renderer/components/sidebar/SidebarSessions.tsx +184 -6
- package/src/renderer/components/sidebar/SidebarTaskItem.tsx +4 -4
- package/src/renderer/components/sidebar/WorkspaceBrowser.tsx +40 -5
- 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/ClaudeLogsFilterPopover.tsx +1 -1
- package/src/renderer/components/team/ClaudeLogsPanel.tsx +1 -1
- package/src/renderer/components/team/CollapsibleTeamSection.tsx +17 -32
- package/src/renderer/components/team/ProcessesSection.tsx +2 -2
- package/src/renderer/components/team/TaskTooltip.tsx +2 -2
- package/src/renderer/components/team/TeamDetailView.tsx +319 -123
- package/src/renderer/components/team/TeamListFilterPopover.tsx +1 -1
- package/src/renderer/components/team/TeamListView.tsx +109 -124
- package/src/renderer/components/team/TeamSessionsSection.tsx +6 -6
- package/src/renderer/components/team/UnreadCommentsBadge.tsx +1 -1
- package/src/renderer/components/team/activity/ActivityItem.tsx +9 -9
- package/src/renderer/components/team/activity/ActivityTimeline.tsx +5 -5
- package/src/renderer/components/team/activity/LeadThoughtsGroup.tsx +3 -3
- package/src/renderer/components/team/activity/ReplyQuoteBlock.tsx +4 -4
- package/src/renderer/components/team/dialogs/CreateTaskDialog.tsx +4 -4
- 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 +18 -16
- package/src/renderer/components/team/dialogs/PlatformBindingDialog.tsx +221 -0
- package/src/renderer/components/team/dialogs/PlatformManualForm.tsx +8 -1
- package/src/renderer/components/team/dialogs/PlatformSetupQR.tsx +5 -5
- package/src/renderer/components/team/dialogs/RuntimeConfigDialog.tsx +361 -0
- package/src/renderer/components/team/dialogs/SendMessageDialog.tsx +6 -6
- package/src/renderer/components/team/dialogs/SkipPermissionsCheckbox.tsx +6 -6
- package/src/renderer/components/team/dialogs/StatusHistoryTimeline.tsx +1 -1
- package/src/renderer/components/team/dialogs/TaskAttachments.tsx +1 -1
- package/src/renderer/components/team/dialogs/TaskCommentInput.tsx +6 -6
- package/src/renderer/components/team/dialogs/TaskCommentsSection.tsx +4 -4
- package/src/renderer/components/team/dialogs/TaskDetailDialog.tsx +3 -3
- 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/editor/EditorFileTree.tsx +4 -4
- package/src/renderer/components/team/editor/EditorSearchPanel.tsx +1 -1
- package/src/renderer/components/team/editor/MarkdownSplitView.tsx +1 -1
- package/src/renderer/components/team/editor/NewFileDialog.tsx +1 -1
- package/src/renderer/components/team/editor/ProjectEditorOverlay.tsx +1 -1
- package/src/renderer/components/team/editor/SearchInFilesPanel.tsx +1 -1
- package/src/renderer/components/team/kanban/KanbanBoard.tsx +9 -9
- package/src/renderer/components/team/kanban/KanbanFilterPopover.tsx +4 -4
- package/src/renderer/components/team/kanban/KanbanSearchInput.tsx +1 -1
- package/src/renderer/components/team/kanban/KanbanSortPopover.tsx +5 -5
- package/src/renderer/components/team/kanban/KanbanTaskCard.tsx +4 -4
- 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/members/MemberDraftRow.tsx +1 -1
- package/src/renderer/components/team/members/MemberStatsTab.tsx +2 -2
- package/src/renderer/components/team/members/MemberWorkspaceTab.tsx +1 -1
- package/src/renderer/components/team/messages/MessageComposer.tsx +10 -112
- package/src/renderer/components/team/messages/MessagesFilterPopover.tsx +1 -1
- package/src/renderer/components/team/messages/MessagesPanel.tsx +136 -119
- package/src/renderer/components/team/review/ChangeReviewDialog.tsx +1 -1
- package/src/renderer/components/team/schedule/ScheduleStatusBadge.tsx +3 -3
- package/src/renderer/components/team/sidebar/TeamSidebarRail.tsx +4 -4
- package/src/renderer/components/team/tasks/TaskRow.tsx +1 -1
- 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 +3 -3
- package/src/renderer/components/team/tools/ToolsSection.tsx +418 -70
- package/src/renderer/components/ui/MemberSelect.tsx +2 -2
- package/src/renderer/components/ui/MentionSuggestionList.tsx +2 -2
- package/src/renderer/components/ui/MentionableTextarea.tsx +3 -3
- package/src/renderer/hooks/useExtensionsTabState.ts +3 -114
- package/src/renderer/index.css +56 -39
- 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
|
@@ -60,9 +60,11 @@ import { deriveTaskDisplayId, formatTaskDisplayLabel } from '@shared/utils/taskI
|
|
|
60
60
|
import {
|
|
61
61
|
AlertTriangle,
|
|
62
62
|
Columns3,
|
|
63
|
+
Download,
|
|
63
64
|
FolderOpen,
|
|
64
65
|
GitBranch,
|
|
65
66
|
History,
|
|
67
|
+
Link,
|
|
66
68
|
Pencil,
|
|
67
69
|
Play,
|
|
68
70
|
Plus,
|
|
@@ -71,16 +73,16 @@ import {
|
|
|
71
73
|
Loader2,
|
|
72
74
|
MessageSquare,
|
|
73
75
|
MoreHorizontal,
|
|
74
|
-
Shield,
|
|
75
76
|
Users,
|
|
76
|
-
Wrench,
|
|
77
77
|
} from 'lucide-react';
|
|
78
78
|
import { useShallow } from 'zustand/react/shallow';
|
|
79
79
|
|
|
80
80
|
import { CreateTaskDialog } from './dialogs/CreateTaskDialog';
|
|
81
81
|
import { EditTeamDialog } from './dialogs/EditTeamDialog';
|
|
82
82
|
import { LaunchTeamDialog, type TeamLaunchDialogMode } from './dialogs/LaunchTeamDialog';
|
|
83
|
+
import { PlatformBindingDialog } from './dialogs/PlatformBindingDialog';
|
|
83
84
|
import { ReviewDialog } from './dialogs/ReviewDialog';
|
|
85
|
+
import { RuntimeConfigDialog } from './dialogs/RuntimeConfigDialog';
|
|
84
86
|
import { SendMessageDialog } from './dialogs/SendMessageDialog';
|
|
85
87
|
import { TaskDetailDialog } from './dialogs/TaskDetailDialog';
|
|
86
88
|
import { executeTeamRelaunch } from './dialogs/teamRelaunchFlow';
|
|
@@ -89,25 +91,26 @@ import { UNASSIGNED_OWNER } from './kanban/KanbanFilterPopover';
|
|
|
89
91
|
import { KanbanSearchInput } from './kanban/KanbanSearchInput';
|
|
90
92
|
import { TrashDialog } from './kanban/TrashDialog';
|
|
91
93
|
import { MemberDetailDialog } from './members/MemberDetailDialog';
|
|
92
|
-
|
|
94
|
+
|
|
93
95
|
|
|
94
96
|
import type { TeamMessagesPanelMode } from '@renderer/types/teamMessagesPanelMode';
|
|
95
97
|
import type { ComponentProps } from 'react';
|
|
96
98
|
|
|
99
|
+
import { TerminalPane, type TerminalPaneRef } from '@renderer/components/common/TerminalPane';
|
|
100
|
+
|
|
97
101
|
const ProjectEditorOverlay = lazy(() =>
|
|
98
102
|
import('./editor/ProjectEditorOverlay').then((m) => ({ default: m.ProjectEditorOverlay }))
|
|
99
103
|
);
|
|
100
104
|
import { MemberList } from './members/MemberList';
|
|
101
105
|
import { MessagesPanel } from './messages/MessagesPanel';
|
|
106
|
+
import { CcSessionsSection, buildAllSessionsCsv, buildAllSessionsCsvFilename, downloadTextFile, hasDataRows, isExportPayload } from './CcSessionsSection';
|
|
102
107
|
import { ChangeReviewDialog } from './review/ChangeReviewDialog';
|
|
103
|
-
import { ProjectEnvPanel } from '../extensions/env/ProjectEnvPanel';
|
|
104
108
|
import {
|
|
105
109
|
getTeamPendingRepliesState,
|
|
106
110
|
setTeamPendingRepliesState,
|
|
107
111
|
} from './sidebar/teamSidebarUiState';
|
|
108
112
|
import { CollapsibleTeamSection } from './CollapsibleTeamSection';
|
|
109
113
|
import { ProcessesSection } from './ProcessesSection';
|
|
110
|
-
import { ToolsSection } from './tools/ToolsSection';
|
|
111
114
|
import { getLaunchJoinMilestonesFromMembers, getLaunchJoinState } from './provisioningSteps';
|
|
112
115
|
import { TeamProvisioningBanner } from './TeamProvisioningBanner';
|
|
113
116
|
import {
|
|
@@ -121,6 +124,7 @@ import type { ContextInjection } from '@renderer/types/contextInjection';
|
|
|
121
124
|
import type { Session } from '@renderer/types/data';
|
|
122
125
|
import type { InlineChip } from '@renderer/types/inlineChip';
|
|
123
126
|
import type {
|
|
127
|
+
CcSession,
|
|
124
128
|
EffortLevel,
|
|
125
129
|
GlobalProvider,
|
|
126
130
|
MemberSpawnStatusEntry,
|
|
@@ -134,6 +138,7 @@ import type {
|
|
|
134
138
|
TeamTaskWithKanban,
|
|
135
139
|
TeamViewSnapshot,
|
|
136
140
|
} from '@shared/types';
|
|
141
|
+
import { SYSTEM_MANAGER_TEAM_NAME } from '@shared/types/team';
|
|
137
142
|
import type { EditorSelectionAction } from '@shared/types/editor';
|
|
138
143
|
import type { ContextUsageLike } from '@shared/utils/contextMetrics';
|
|
139
144
|
|
|
@@ -234,7 +239,7 @@ const TeamOfflineStatusBanner = memo(function TeamOfflineStatusBanner({
|
|
|
234
239
|
teamName: string;
|
|
235
240
|
onLaunch: () => void;
|
|
236
241
|
}): React.JSX.Element {
|
|
237
|
-
const message = '
|
|
242
|
+
const message = '数字员工未运行:当前没有本地 Claude/Agent 进程在运行,已有数据和任务仍会保留。';
|
|
238
243
|
|
|
239
244
|
return (
|
|
240
245
|
<div
|
|
@@ -256,7 +261,7 @@ const TeamOfflineStatusBanner = memo(function TeamOfflineStatusBanner({
|
|
|
256
261
|
onClick={onLaunch}
|
|
257
262
|
>
|
|
258
263
|
<Play size={12} />
|
|
259
|
-
|
|
264
|
+
启动数字员工
|
|
260
265
|
</Button>
|
|
261
266
|
</div>
|
|
262
267
|
);
|
|
@@ -861,6 +866,43 @@ const TeamMemberDetailDialogBridge = memo(function TeamMemberDetailDialogBridge(
|
|
|
861
866
|
);
|
|
862
867
|
});
|
|
863
868
|
|
|
869
|
+
/** Map agent harness type to CLI command name */
|
|
870
|
+
function getCommandForHarness(harness?: string): string {
|
|
871
|
+
switch (harness) {
|
|
872
|
+
case 'claudecode':
|
|
873
|
+
return 'claude';
|
|
874
|
+
case 'codex':
|
|
875
|
+
return 'codex';
|
|
876
|
+
case 'opencode':
|
|
877
|
+
return 'opencode';
|
|
878
|
+
case 'cursor':
|
|
879
|
+
return 'cursor';
|
|
880
|
+
case 'gemini':
|
|
881
|
+
return 'gemini';
|
|
882
|
+
case 'iflow':
|
|
883
|
+
return 'iflow';
|
|
884
|
+
case 'kimi':
|
|
885
|
+
return 'kimi';
|
|
886
|
+
case 'qoder':
|
|
887
|
+
return 'qoder';
|
|
888
|
+
case 'pi':
|
|
889
|
+
return 'pi';
|
|
890
|
+
case 'acp':
|
|
891
|
+
return 'acp';
|
|
892
|
+
case 'tmux':
|
|
893
|
+
return 'tmux';
|
|
894
|
+
case 'devin':
|
|
895
|
+
return 'devin';
|
|
896
|
+
default:
|
|
897
|
+
return 'claude';
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
/** All CcAgentType values run as local CLI agents */
|
|
902
|
+
function isLocalHarness(harness?: string): boolean {
|
|
903
|
+
return !!harness;
|
|
904
|
+
}
|
|
905
|
+
|
|
864
906
|
export const TeamDetailView = ({
|
|
865
907
|
teamName,
|
|
866
908
|
isPaneFocused = false,
|
|
@@ -869,10 +911,6 @@ export const TeamDetailView = ({
|
|
|
869
911
|
const [requestChangesTaskId, setRequestChangesTaskId] = useState<string | null>(null);
|
|
870
912
|
const [selectedTask, setSelectedTask] = useState<TeamTaskWithKanban | null>(null);
|
|
871
913
|
const [selectedMember, setSelectedMember] = useState<ResolvedTeamMember | null>(null);
|
|
872
|
-
const [selectedMemberView, setSelectedMemberView] = useState<{
|
|
873
|
-
initialTab?: MemberDetailTab;
|
|
874
|
-
initialActivityFilter?: MemberActivityFilter;
|
|
875
|
-
} | null>(null);
|
|
876
914
|
const [pendingRepliesByMember, setPendingRepliesByMember] = useState<Record<string, number>>(() =>
|
|
877
915
|
getTeamPendingRepliesState(teamName)
|
|
878
916
|
);
|
|
@@ -886,7 +924,7 @@ export const TeamDetailView = ({
|
|
|
886
924
|
const [removeMemberConfirm, setRemoveMemberConfirm] = useState<string | null>(null);
|
|
887
925
|
const [updatingRoleLoading, setUpdatingRoleLoading] = useState(false);
|
|
888
926
|
const [editDialogOpen, setEditDialogOpen] = useState(false);
|
|
889
|
-
const [
|
|
927
|
+
const [bindingDialogOpen, setBindingDialogOpen] = useState(false);
|
|
890
928
|
const [headerMenuOpen, setHeaderMenuOpen] = useState(false);
|
|
891
929
|
const [launchDialogState, setLaunchDialogState] = useState<{
|
|
892
930
|
open: boolean;
|
|
@@ -896,8 +934,11 @@ export const TeamDetailView = ({
|
|
|
896
934
|
mode: 'launch',
|
|
897
935
|
});
|
|
898
936
|
const [editorOpen, setEditorOpen] = useState(false);
|
|
937
|
+
const [terminalHeight, setTerminalHeight] = useState(400);
|
|
899
938
|
const contentRef = useRef<HTMLDivElement>(null);
|
|
900
939
|
const provisioningBannerRef = useRef<HTMLDivElement>(null);
|
|
940
|
+
const terminalPaneRef = useRef<TerminalPaneRef>(null);
|
|
941
|
+
const terminalSpawnedForTeamRef = useRef<string | null>(null);
|
|
901
942
|
const wasProvisioningRef = useRef(false);
|
|
902
943
|
|
|
903
944
|
// Set inert on background content when editor overlay is open (a11y focus trap)
|
|
@@ -931,17 +972,11 @@ export const TeamDetailView = ({
|
|
|
931
972
|
const {
|
|
932
973
|
teamName: tn,
|
|
933
974
|
memberName,
|
|
934
|
-
initialTab,
|
|
935
|
-
initialActivityFilter,
|
|
936
975
|
} = (e as CustomEvent).detail ?? {};
|
|
937
976
|
if (tn !== teamName || !data) return;
|
|
938
977
|
const member = members.find((m: { name: string }) => m.name === memberName);
|
|
939
978
|
if (member) {
|
|
940
979
|
setSelectedMember(member);
|
|
941
|
-
setSelectedMemberView({
|
|
942
|
-
initialTab,
|
|
943
|
-
initialActivityFilter,
|
|
944
|
-
});
|
|
945
980
|
}
|
|
946
981
|
};
|
|
947
982
|
const onCreateTask = (e: Event) => {
|
|
@@ -1088,6 +1123,56 @@ export const TeamDetailView = ({
|
|
|
1088
1123
|
const [sessions, setSessions] = useState<Session[]>([]);
|
|
1089
1124
|
const [sessionsLoading, setSessionsLoading] = useState(false);
|
|
1090
1125
|
const [sessionsError, setSessionsError] = useState<string | null>(null);
|
|
1126
|
+
const [ccSessions, setCcSessions] = useState<CcSession[]>([]);
|
|
1127
|
+
const [ccSessionsLoading, setCcSessionsLoading] = useState(false);
|
|
1128
|
+
const [ccSessionsError, setCcSessionsError] = useState<string | null>(null);
|
|
1129
|
+
const [ccExporting, setCcExporting] = useState(false);
|
|
1130
|
+
|
|
1131
|
+
const handleExportAllCcSessions = useCallback(async () => {
|
|
1132
|
+
if (ccExporting) return;
|
|
1133
|
+
setCcExporting(true);
|
|
1134
|
+
try {
|
|
1135
|
+
const params = new URLSearchParams({
|
|
1136
|
+
teamName,
|
|
1137
|
+
format: 'csv',
|
|
1138
|
+
includeContent: 'full',
|
|
1139
|
+
includeToolResults: 'false',
|
|
1140
|
+
includeSystemMessages: 'false',
|
|
1141
|
+
});
|
|
1142
|
+
const res = await fetch(`/api/telemetry/conversations/export?${params.toString()}`);
|
|
1143
|
+
if (res.ok) {
|
|
1144
|
+
const payload = (await res.json()) as unknown;
|
|
1145
|
+
if (isExportPayload(payload) && hasDataRows(payload.content)) {
|
|
1146
|
+
downloadTextFile(payload.content, payload.filename, payload.mimeType);
|
|
1147
|
+
return;
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
const details = await Promise.all(
|
|
1152
|
+
ccSessions.map(async (session) => {
|
|
1153
|
+
try {
|
|
1154
|
+
const detail = await api.teams.getSessionDetail(
|
|
1155
|
+
teamName,
|
|
1156
|
+
session.id,
|
|
1157
|
+
Math.max(session.historyCount, 1)
|
|
1158
|
+
);
|
|
1159
|
+
return { session, detail };
|
|
1160
|
+
} catch {
|
|
1161
|
+
return { session, detail: null };
|
|
1162
|
+
}
|
|
1163
|
+
})
|
|
1164
|
+
);
|
|
1165
|
+
downloadTextFile(
|
|
1166
|
+
buildAllSessionsCsv(details),
|
|
1167
|
+
buildAllSessionsCsvFilename(teamName),
|
|
1168
|
+
'text/csv;charset=utf-8'
|
|
1169
|
+
);
|
|
1170
|
+
} catch (err) {
|
|
1171
|
+
console.error('Failed to export all conversation telemetry:', err);
|
|
1172
|
+
} finally {
|
|
1173
|
+
setCcExporting(false);
|
|
1174
|
+
}
|
|
1175
|
+
}, [ccExporting, ccSessions, teamName]);
|
|
1091
1176
|
const [kanbanFilter, setKanbanFilter] = useState<KanbanFilterState>({
|
|
1092
1177
|
sessionId: null,
|
|
1093
1178
|
selectedOwners: new Set(),
|
|
@@ -1246,6 +1331,24 @@ export const TeamDetailView = ({
|
|
|
1246
1331
|
void fetchDeletedTasks(teamName);
|
|
1247
1332
|
}, [teamName, selectTeam, fetchDeletedTasks]);
|
|
1248
1333
|
|
|
1334
|
+
// Spawn terminal PTY once per team — imperative, no autoSpawn.
|
|
1335
|
+
// TerminalPane lives outside renderBody() so it never unmounts on data refresh.
|
|
1336
|
+
// terminalSpawnedForTeamRef guards against re-spawning on data changes.
|
|
1337
|
+
useEffect(() => {
|
|
1338
|
+
if (!data || !teamName || teamName === SYSTEM_MANAGER_TEAM_NAME) return;
|
|
1339
|
+
const cwd = data.config.projectPath || data.config.executionTarget?.cwd || data.workDir || '';
|
|
1340
|
+
if (!cwd) return;
|
|
1341
|
+
const harness = data.config.agentType || data.harness;
|
|
1342
|
+
const spawnKey = `${teamName}:${harness ?? ''}`;
|
|
1343
|
+
if (terminalSpawnedForTeamRef.current === spawnKey) return;
|
|
1344
|
+
terminalSpawnedForTeamRef.current = spawnKey;
|
|
1345
|
+
void terminalPaneRef.current?.spawn({
|
|
1346
|
+
command: getCommandForHarness(harness),
|
|
1347
|
+
args: [],
|
|
1348
|
+
cwd,
|
|
1349
|
+
});
|
|
1350
|
+
}, [data, teamName]);
|
|
1351
|
+
|
|
1249
1352
|
// Recovery: after HMR, all mounted TeamDetailView effects re-run simultaneously.
|
|
1250
1353
|
// With CSS display-toggle (all tabs stay mounted), the last selectTeam() call wins
|
|
1251
1354
|
// and other tabs get stuck with mismatched data (permanent skeleton).
|
|
@@ -1354,6 +1457,38 @@ export const TeamDetailView = ({
|
|
|
1354
1457
|
teamName,
|
|
1355
1458
|
]);
|
|
1356
1459
|
|
|
1460
|
+
useEffect(() => {
|
|
1461
|
+
if (!teamName) return;
|
|
1462
|
+
let cancelled = false;
|
|
1463
|
+
setCcSessions([]);
|
|
1464
|
+
|
|
1465
|
+
const loadCcSessions = async (showLoading: boolean): Promise<void> => {
|
|
1466
|
+
if (showLoading) setCcSessionsLoading(true);
|
|
1467
|
+
setCcSessionsError(null);
|
|
1468
|
+
try {
|
|
1469
|
+
const result = await api.teams.getTeamSessions(teamName);
|
|
1470
|
+
if (!cancelled) setCcSessions(result);
|
|
1471
|
+
} catch (e) {
|
|
1472
|
+
if (!cancelled) {
|
|
1473
|
+
setCcSessions([]);
|
|
1474
|
+
setCcSessionsError(e instanceof Error ? e.message : '加载运行会话失败');
|
|
1475
|
+
}
|
|
1476
|
+
} finally {
|
|
1477
|
+
if (!cancelled && showLoading) setCcSessionsLoading(false);
|
|
1478
|
+
}
|
|
1479
|
+
};
|
|
1480
|
+
|
|
1481
|
+
void loadCcSessions(true);
|
|
1482
|
+
const interval = window.setInterval(() => {
|
|
1483
|
+
void loadCcSessions(false);
|
|
1484
|
+
}, 3_000);
|
|
1485
|
+
|
|
1486
|
+
return () => {
|
|
1487
|
+
cancelled = true;
|
|
1488
|
+
window.clearInterval(interval);
|
|
1489
|
+
};
|
|
1490
|
+
}, [teamName, data?.isAlive]);
|
|
1491
|
+
|
|
1357
1492
|
useEffect(() => {
|
|
1358
1493
|
if (!projectId) return;
|
|
1359
1494
|
|
|
@@ -1581,8 +1716,21 @@ export const TeamDetailView = ({
|
|
|
1581
1716
|
}, []);
|
|
1582
1717
|
|
|
1583
1718
|
const handleRestartTeam = useCallback(() => {
|
|
1719
|
+
const cfg = data?.config;
|
|
1720
|
+
const harness = cfg?.agentType || data?.harness;
|
|
1721
|
+
if (isLocalHarness(harness)) {
|
|
1722
|
+
const cwd = cfg?.projectPath || cfg?.executionTarget?.cwd || data?.workDir || '';
|
|
1723
|
+
if (cwd) {
|
|
1724
|
+
terminalPaneRef.current?.spawn({
|
|
1725
|
+
command: getCommandForHarness(harness),
|
|
1726
|
+
args: [],
|
|
1727
|
+
cwd,
|
|
1728
|
+
});
|
|
1729
|
+
return;
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1584
1732
|
openLaunchDialog('relaunch');
|
|
1585
|
-
}, [openLaunchDialog]);
|
|
1733
|
+
}, [data, openLaunchDialog]);
|
|
1586
1734
|
|
|
1587
1735
|
const handleStartCcConnectTeam = useCallback(() => {
|
|
1588
1736
|
void (async () => {
|
|
@@ -1590,7 +1738,6 @@ export const TeamDetailView = ({
|
|
|
1590
1738
|
openLaunchDialog('launch');
|
|
1591
1739
|
return;
|
|
1592
1740
|
}
|
|
1593
|
-
await api.ccSettings.restart();
|
|
1594
1741
|
await api.teams.launchTeam({
|
|
1595
1742
|
teamName,
|
|
1596
1743
|
cwd: data.config.projectPath,
|
|
@@ -1631,7 +1778,6 @@ export const TeamDetailView = ({
|
|
|
1631
1778
|
);
|
|
1632
1779
|
|
|
1633
1780
|
const handleRestartTeamFromEdit = useCallback(async (): Promise<void> => {
|
|
1634
|
-
await api.ccSettings.restart();
|
|
1635
1781
|
await Promise.all([fetchTeams(), selectTeam(teamName)]);
|
|
1636
1782
|
}, [fetchTeams, selectTeam, teamName]);
|
|
1637
1783
|
|
|
@@ -1677,12 +1823,12 @@ export const TeamDetailView = ({
|
|
|
1677
1823
|
|
|
1678
1824
|
const handleSelectMember = useCallback((member: ResolvedTeamMember) => {
|
|
1679
1825
|
setSelectedMember(member);
|
|
1680
|
-
|
|
1826
|
+
setSelectedMember(null);
|
|
1681
1827
|
}, []);
|
|
1682
1828
|
|
|
1683
1829
|
const closeSelectedMemberDialog = useCallback(() => {
|
|
1684
1830
|
setSelectedMember(null);
|
|
1685
|
-
|
|
1831
|
+
setSelectedMember(null);
|
|
1686
1832
|
}, []);
|
|
1687
1833
|
|
|
1688
1834
|
const handleSendMessageToMember = useCallback((member: ResolvedTeamMember) => {
|
|
@@ -1771,7 +1917,7 @@ export const TeamDetailView = ({
|
|
|
1771
1917
|
const member = membersWithLiveBranches.find((m) => m.name === pendingMemberProfile);
|
|
1772
1918
|
if (member) {
|
|
1773
1919
|
setSelectedMember(member);
|
|
1774
|
-
|
|
1920
|
+
setSelectedMember(null);
|
|
1775
1921
|
}
|
|
1776
1922
|
useStore.getState().closeMemberProfile();
|
|
1777
1923
|
}, [pendingMemberProfile, membersWithLiveBranches]);
|
|
@@ -1837,9 +1983,6 @@ export const TeamDetailView = ({
|
|
|
1837
1983
|
void (async () => {
|
|
1838
1984
|
try {
|
|
1839
1985
|
const result = await deleteTeam(teamName);
|
|
1840
|
-
if (result.restartRequired) {
|
|
1841
|
-
await api.ccSettings.restart();
|
|
1842
|
-
}
|
|
1843
1986
|
await fetchTeams();
|
|
1844
1987
|
setDeleteConfirmOpen(false);
|
|
1845
1988
|
if (tabId) closeTab(tabId);
|
|
@@ -1906,7 +2049,7 @@ export const TeamDetailView = ({
|
|
|
1906
2049
|
tasks: data?.tasks ?? [],
|
|
1907
2050
|
isTeamAlive: data?.isAlive,
|
|
1908
2051
|
timeWindow,
|
|
1909
|
-
|
|
2052
|
+
sessions: ccSessions,
|
|
1910
2053
|
currentLeadSessionId: data?.config.leadSessionId,
|
|
1911
2054
|
pendingRepliesByMember,
|
|
1912
2055
|
onPendingReplyChange: setPendingRepliesByMember,
|
|
@@ -1921,12 +2064,12 @@ export const TeamDetailView = ({
|
|
|
1921
2064
|
data?.config.leadSessionId,
|
|
1922
2065
|
data?.isAlive,
|
|
1923
2066
|
data?.tasks,
|
|
2067
|
+
ccSessions,
|
|
1924
2068
|
handleReplyToMessage,
|
|
1925
2069
|
handleRestartTeam,
|
|
1926
2070
|
handleSelectMember,
|
|
1927
2071
|
pendingRepliesByMember,
|
|
1928
2072
|
teamName,
|
|
1929
|
-
teamSessionIds,
|
|
1930
2073
|
timeWindow,
|
|
1931
2074
|
keepMessagesInline,
|
|
1932
2075
|
]
|
|
@@ -1989,6 +2132,7 @@ export const TeamDetailView = ({
|
|
|
1989
2132
|
if (error === 'TEAM_DRAFT') {
|
|
1990
2133
|
const draftTeamSummary = useStore.getState().teamByName[teamName];
|
|
1991
2134
|
const draftDisplayName = draftTeamSummary?.displayName || teamName;
|
|
2135
|
+
const draftCwd = draftTeamSummary?.projectPath || draftTeamSummary?.workDir || '';
|
|
1992
2136
|
|
|
1993
2137
|
return (
|
|
1994
2138
|
<>
|
|
@@ -1996,44 +2140,27 @@ export const TeamDetailView = ({
|
|
|
1996
2140
|
<div ref={provisioningBannerRef}>
|
|
1997
2141
|
<TeamProvisioningBanner teamName={teamName} />
|
|
1998
2142
|
</div>
|
|
1999
|
-
<div className="flex
|
|
2000
|
-
<
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
>
|
|
2019
|
-
删除
|
|
2020
|
-
</button>
|
|
2021
|
-
</div>
|
|
2022
|
-
</div>
|
|
2143
|
+
<div className="flex items-center gap-3 py-2">
|
|
2144
|
+
<p className="text-sm font-medium text-text">{draftDisplayName}</p>
|
|
2145
|
+
<span className="rounded-full bg-indigo-500/20 px-2 py-0.5 text-[10px] font-medium text-indigo-400">
|
|
2146
|
+
{getCommandForHarness()}
|
|
2147
|
+
</span>
|
|
2148
|
+
</div>
|
|
2149
|
+
<div className="h-[calc(100vh-16rem)] overflow-hidden rounded-lg border border-[var(--color-border-subtle)]">
|
|
2150
|
+
<TerminalPane
|
|
2151
|
+
ref={terminalPaneRef}
|
|
2152
|
+
autoSpawn={
|
|
2153
|
+
draftCwd
|
|
2154
|
+
? {
|
|
2155
|
+
command: getCommandForHarness(),
|
|
2156
|
+
args: [],
|
|
2157
|
+
cwd: draftCwd,
|
|
2158
|
+
}
|
|
2159
|
+
: undefined
|
|
2160
|
+
}
|
|
2161
|
+
/>
|
|
2023
2162
|
</div>
|
|
2024
2163
|
</div>
|
|
2025
|
-
<LaunchTeamDialog
|
|
2026
|
-
mode={launchDialogState.mode}
|
|
2027
|
-
open={launchDialogOpen}
|
|
2028
|
-
teamName={teamName}
|
|
2029
|
-
members={[]}
|
|
2030
|
-
defaultProjectPath={draftTeamSummary?.projectPath}
|
|
2031
|
-
provisioningError={provisioningError}
|
|
2032
|
-
clearProvisioningError={clearProvisioningError}
|
|
2033
|
-
onClose={closeLaunchDialog}
|
|
2034
|
-
onLaunch={handleLaunchDialogSubmit}
|
|
2035
|
-
onRelaunch={handleRelaunchDialogSubmit}
|
|
2036
|
-
/>
|
|
2037
2164
|
</>
|
|
2038
2165
|
);
|
|
2039
2166
|
}
|
|
@@ -2110,13 +2237,16 @@ export const TeamDetailView = ({
|
|
|
2110
2237
|
<h2 className="text-base font-semibold text-[var(--color-text)]">
|
|
2111
2238
|
{data.config.name}
|
|
2112
2239
|
</h2>
|
|
2113
|
-
{data.
|
|
2114
|
-
<span
|
|
2240
|
+
{data.platforms?.filter((pl) => pl.type !== 'bridge').map((pl) => (
|
|
2241
|
+
<span
|
|
2242
|
+
key={pl.type}
|
|
2243
|
+
className="inline-flex items-center gap-1 rounded-full bg-emerald-500/15 px-1.5 py-0.5 text-[10px] font-medium text-emerald-400"
|
|
2244
|
+
>
|
|
2115
2245
|
<span className="size-1.5 rounded-full bg-emerald-400" />
|
|
2116
|
-
|
|
2246
|
+
{pl.type}
|
|
2117
2247
|
</span>
|
|
2118
|
-
)}
|
|
2119
|
-
{
|
|
2248
|
+
))}
|
|
2249
|
+
{isTeamProvisioning && (
|
|
2120
2250
|
<span className="inline-flex items-center gap-1 rounded-full bg-yellow-500/15 px-1.5 py-0.5 text-[10px] font-medium text-yellow-400">
|
|
2121
2251
|
<span className="size-1.5 animate-pulse rounded-full bg-yellow-400" />
|
|
2122
2252
|
启动中...
|
|
@@ -2125,6 +2255,18 @@ export const TeamDetailView = ({
|
|
|
2125
2255
|
</div>
|
|
2126
2256
|
</div>
|
|
2127
2257
|
<div className="flex shrink-0 items-center gap-1.5">
|
|
2258
|
+
{teamName !== SYSTEM_MANAGER_TEAM_NAME ? (
|
|
2259
|
+
<Button
|
|
2260
|
+
variant="outline"
|
|
2261
|
+
size="sm"
|
|
2262
|
+
className="h-7 gap-1.5 px-2.5 text-xs text-[var(--color-text-secondary)]"
|
|
2263
|
+
disabled={isTeamProvisioning}
|
|
2264
|
+
onClick={() => setBindingDialogOpen(true)}
|
|
2265
|
+
>
|
|
2266
|
+
<Link size={12} />
|
|
2267
|
+
运行时
|
|
2268
|
+
</Button>
|
|
2269
|
+
) : null}
|
|
2128
2270
|
<Button
|
|
2129
2271
|
variant="outline"
|
|
2130
2272
|
size="sm"
|
|
@@ -2146,32 +2288,21 @@ export const TeamDetailView = ({
|
|
|
2146
2288
|
</Button>
|
|
2147
2289
|
</PopoverTrigger>
|
|
2148
2290
|
<PopoverContent align="end" className="w-44 p-1">
|
|
2149
|
-
{
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
type="button"
|
|
2165
|
-
className="flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-xs text-red-400 hover:bg-red-500/10"
|
|
2166
|
-
onClick={() => {
|
|
2167
|
-
setHeaderMenuOpen(false);
|
|
2168
|
-
handleDeleteTeam();
|
|
2169
|
-
}}
|
|
2170
|
-
>
|
|
2171
|
-
<Trash2 size={13} />
|
|
2172
|
-
删除团队
|
|
2173
|
-
</button>
|
|
2174
|
-
)}
|
|
2291
|
+
{teamName !== 'default' &&
|
|
2292
|
+
teamName !== 'my-project' &&
|
|
2293
|
+
teamName !== SYSTEM_MANAGER_TEAM_NAME && (
|
|
2294
|
+
<button
|
|
2295
|
+
type="button"
|
|
2296
|
+
className="flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-xs text-red-400 hover:bg-red-500/10"
|
|
2297
|
+
onClick={() => {
|
|
2298
|
+
setHeaderMenuOpen(false);
|
|
2299
|
+
handleDeleteTeam();
|
|
2300
|
+
}}
|
|
2301
|
+
>
|
|
2302
|
+
<Trash2 size={13} />
|
|
2303
|
+
删除团队
|
|
2304
|
+
</button>
|
|
2305
|
+
)}
|
|
2175
2306
|
</PopoverContent>
|
|
2176
2307
|
</Popover>
|
|
2177
2308
|
</div>
|
|
@@ -2282,15 +2413,38 @@ export const TeamDetailView = ({
|
|
|
2282
2413
|
</CollapsibleTeamSection>
|
|
2283
2414
|
|
|
2284
2415
|
<CollapsibleTeamSection
|
|
2285
|
-
sectionId="
|
|
2286
|
-
title="
|
|
2287
|
-
icon={<
|
|
2288
|
-
|
|
2416
|
+
sectionId="team-sessions"
|
|
2417
|
+
title="会话"
|
|
2418
|
+
icon={<MessageSquare size={14} />}
|
|
2419
|
+
badge={ccSessions.length}
|
|
2420
|
+
defaultOpen={ccSessions.length > 0}
|
|
2421
|
+
action={
|
|
2422
|
+
ccSessions.length > 0 ? (
|
|
2423
|
+
<button
|
|
2424
|
+
type="button"
|
|
2425
|
+
className="inline-flex items-center gap-1 rounded-md px-2 py-0.5 text-[11px] 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"
|
|
2426
|
+
onClick={(e) => {
|
|
2427
|
+
e.stopPropagation();
|
|
2428
|
+
void handleExportAllCcSessions();
|
|
2429
|
+
}}
|
|
2430
|
+
disabled={ccExporting}
|
|
2431
|
+
title="导出所有会话为 CSV 表格"
|
|
2432
|
+
>
|
|
2433
|
+
{ccExporting ? (
|
|
2434
|
+
<Loader2 size={12} className="animate-spin" />
|
|
2435
|
+
) : (
|
|
2436
|
+
<Download size={12} />
|
|
2437
|
+
)}
|
|
2438
|
+
导出
|
|
2439
|
+
</button>
|
|
2440
|
+
) : undefined
|
|
2441
|
+
}
|
|
2289
2442
|
>
|
|
2290
|
-
<
|
|
2443
|
+
<CcSessionsSection
|
|
2291
2444
|
teamName={teamName}
|
|
2292
|
-
|
|
2293
|
-
|
|
2445
|
+
sessions={ccSessions}
|
|
2446
|
+
loading={ccSessionsLoading}
|
|
2447
|
+
error={ccSessionsError}
|
|
2294
2448
|
/>
|
|
2295
2449
|
</CollapsibleTeamSection>
|
|
2296
2450
|
|
|
@@ -2487,8 +2641,6 @@ export const TeamDetailView = ({
|
|
|
2487
2641
|
</div>
|
|
2488
2642
|
</CollapsibleTeamSection>
|
|
2489
2643
|
|
|
2490
|
-
<TeamMessagesPanelBridge position="inline" {...sharedMessagesPanelProps} />
|
|
2491
|
-
|
|
2492
2644
|
{(data.processes?.length ?? 0) > 0 && (
|
|
2493
2645
|
<CollapsibleTeamSection
|
|
2494
2646
|
sectionId="processes"
|
|
@@ -2547,8 +2699,6 @@ export const TeamDetailView = ({
|
|
|
2547
2699
|
teamName={teamName}
|
|
2548
2700
|
members={membersWithLiveBranches}
|
|
2549
2701
|
tasks={data.tasks}
|
|
2550
|
-
initialTab={selectedMemberView?.initialTab}
|
|
2551
|
-
initialActivityFilter={selectedMemberView?.initialActivityFilter}
|
|
2552
2702
|
isTeamAlive={data.isAlive}
|
|
2553
2703
|
isTeamProvisioning={isTeamProvisioning}
|
|
2554
2704
|
launchParams={launchParams}
|
|
@@ -2595,18 +2745,6 @@ export const TeamDetailView = ({
|
|
|
2595
2745
|
}}
|
|
2596
2746
|
/>
|
|
2597
2747
|
|
|
2598
|
-
<Dialog open={envDialogOpen} onOpenChange={setEnvDialogOpen}>
|
|
2599
|
-
<DialogContent className="max-h-[80vh] max-w-lg overflow-y-auto">
|
|
2600
|
-
<DialogHeader>
|
|
2601
|
-
<DialogTitle>项目环境变量</DialogTitle>
|
|
2602
|
-
<DialogDescription>
|
|
2603
|
-
管理当前项目所需的环境变量,供 MCP 和 Skills 使用。
|
|
2604
|
-
</DialogDescription>
|
|
2605
|
-
</DialogHeader>
|
|
2606
|
-
<ProjectEnvPanel projectPath={data.config.projectPath ?? null} />
|
|
2607
|
-
</DialogContent>
|
|
2608
|
-
</Dialog>
|
|
2609
|
-
|
|
2610
2748
|
<Dialog
|
|
2611
2749
|
open={removeMemberConfirm !== null}
|
|
2612
2750
|
onOpenChange={(open) => {
|
|
@@ -2785,14 +2923,72 @@ export const TeamDetailView = ({
|
|
|
2785
2923
|
{spawnStatusWatcher}
|
|
2786
2924
|
{teamAgentRuntimeWatcher}
|
|
2787
2925
|
{leadContextWatcher}
|
|
2788
|
-
|
|
2926
|
+
<div className="flex size-full flex-col overflow-hidden">
|
|
2927
|
+
<div className="min-h-0 flex-1 overflow-hidden">
|
|
2928
|
+
{renderBody()}
|
|
2929
|
+
</div>
|
|
2930
|
+
{/* Persistent terminal — survives data refreshes because it's outside renderBody() */}
|
|
2931
|
+
{teamName && teamName !== SYSTEM_MANAGER_TEAM_NAME && (
|
|
2932
|
+
<div className="shrink-0" style={{ height: terminalHeight }}>
|
|
2933
|
+
{/* Drag handle */}
|
|
2934
|
+
<div
|
|
2935
|
+
className="flex cursor-row-resize items-center justify-center border-t border-[var(--color-border)] py-0.5 transition-colors hover:bg-[var(--color-surface-raised)]"
|
|
2936
|
+
onMouseDown={(e) => {
|
|
2937
|
+
e.preventDefault();
|
|
2938
|
+
const startY = e.clientY;
|
|
2939
|
+
const startH = terminalHeight;
|
|
2940
|
+
const onMove = (ev: MouseEvent) => {
|
|
2941
|
+
const delta = startY - ev.clientY; // drag up = grow
|
|
2942
|
+
const next = Math.max(120, Math.min(800, startH + delta));
|
|
2943
|
+
setTerminalHeight(next);
|
|
2944
|
+
};
|
|
2945
|
+
const onUp = () => {
|
|
2946
|
+
window.removeEventListener('mousemove', onMove);
|
|
2947
|
+
window.removeEventListener('mouseup', onUp);
|
|
2948
|
+
};
|
|
2949
|
+
window.addEventListener('mousemove', onMove);
|
|
2950
|
+
window.addEventListener('mouseup', onUp);
|
|
2951
|
+
}}
|
|
2952
|
+
>
|
|
2953
|
+
<div className="h-1 w-8 rounded-full bg-[var(--color-border)]" />
|
|
2954
|
+
</div>
|
|
2955
|
+
<div className="h-[calc(100%-14px)] overflow-hidden">
|
|
2956
|
+
<div className="flex items-center justify-between px-1 pb-1">
|
|
2957
|
+
<div className="flex items-center gap-1.5 text-xs font-medium text-[var(--color-text-secondary)]">
|
|
2958
|
+
<Terminal size={14} />
|
|
2959
|
+
终端
|
|
2960
|
+
</div>
|
|
2961
|
+
<button
|
|
2962
|
+
type="button"
|
|
2963
|
+
className="flex items-center gap-1 rounded px-1 py-0.5 text-[10px] text-[var(--color-text-muted)] transition-colors hover:bg-[var(--color-surface-raised)] hover:text-[var(--color-text-secondary)]"
|
|
2964
|
+
onClick={() => {
|
|
2965
|
+
const cwd = data?.config.projectPath || data?.config.executionTarget?.cwd || data?.workDir || '';
|
|
2966
|
+
const harness = data?.config.agentType || data?.harness;
|
|
2967
|
+
void api.terminal.openExternal({ command: getCommandForHarness(harness), cwd });
|
|
2968
|
+
}}
|
|
2969
|
+
>
|
|
2970
|
+
<Play size={10} />
|
|
2971
|
+
外部终端
|
|
2972
|
+
</button>
|
|
2973
|
+
</div>
|
|
2974
|
+
<div className="h-[calc(100%-22px)] overflow-hidden rounded-lg border border-[var(--color-border-subtle)]">
|
|
2975
|
+
<TerminalPane ref={terminalPaneRef} />
|
|
2976
|
+
</div>
|
|
2977
|
+
</div>
|
|
2978
|
+
</div>
|
|
2979
|
+
)}
|
|
2980
|
+
</div>
|
|
2981
|
+
{data && teamName !== SYSTEM_MANAGER_TEAM_NAME ? (
|
|
2982
|
+
<RuntimeConfigDialog
|
|
2983
|
+
open={bindingDialogOpen}
|
|
2984
|
+
teamName={teamName}
|
|
2985
|
+
onClose={() => setBindingDialogOpen(false)}
|
|
2986
|
+
/>
|
|
2987
|
+
) : null}
|
|
2789
2988
|
<EditTeamDialog
|
|
2790
2989
|
open={editDialogOpen}
|
|
2791
2990
|
teamName={teamName}
|
|
2792
2991
|
onClose={() => setEditDialogOpen(false)}
|
|
2793
|
-
onDeleteTeam={
|
|
2794
|
-
teamName !== 'default' && teamName !== 'my-project' ? handleDeleteTeam : undefined
|
|
2795
|
-
}
|
|
2796
2992
|
/>
|
|
2797
2993
|
</>
|
|
2798
2994
|
);
|