@yancyyu/openhermit 1.6.41 → 1.6.43
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/README.md +98 -89
- package/bin/hermit.mjs +96 -0
- package/dist-renderer/assets/{ProjectEditorOverlay-Br0X83Jf.js → ProjectEditorOverlay-C98qSs7-.js} +1 -1
- package/dist-renderer/assets/{TeamGraphOverlay-DHMTbZPZ.js → TeamGraphOverlay-CsBbZwcL.js} +1 -1
- package/dist-renderer/assets/{_basePickBy-DzIiX7yH.js → _basePickBy-ZOyLWjMK.js} +1 -1
- package/dist-renderer/assets/{_baseUniq-6hZuzTLU.js → _baseUniq-DBb726rt.js} +1 -1
- package/dist-renderer/assets/{arc-CXgO6fx_.js → arc-CdiTaR_R.js} +1 -1
- package/dist-renderer/assets/{architectureDiagram-VXUJARFQ-DKWgtDHr.js → architectureDiagram-VXUJARFQ-Cz3sc5TH.js} +1 -1
- package/dist-renderer/assets/{blockDiagram-VD42YOAC-DOMUcC40.js → blockDiagram-VD42YOAC-DE4c-KJ3.js} +1 -1
- package/dist-renderer/assets/{c4Diagram-YG6GDRKO-B_k2L7qX.js → c4Diagram-YG6GDRKO-CmTMDTrV.js} +1 -1
- package/dist-renderer/assets/channel-KTpqi9eT.js +1 -0
- package/dist-renderer/assets/{chunk-4BX2VUAB-BeD_ccFy.js → chunk-4BX2VUAB-rhHy3tFl.js} +1 -1
- package/dist-renderer/assets/{chunk-55IACEB6-ClZfkA5w.js → chunk-55IACEB6-fLZBzuo_.js} +1 -1
- package/dist-renderer/assets/{chunk-B4BG7PRW-5XluxXsn.js → chunk-B4BG7PRW-DOzxQhim.js} +1 -1
- package/dist-renderer/assets/{chunk-DI55MBZ5-BzIjjNVm.js → chunk-DI55MBZ5-COQCcXC5.js} +1 -1
- package/dist-renderer/assets/{chunk-FMBD7UC4-HgH3MK_H.js → chunk-FMBD7UC4-IKU9U_Y4.js} +1 -1
- package/dist-renderer/assets/{chunk-QN33PNHL-WeC5T3Ba.js → chunk-QN33PNHL-D6WV154X.js} +1 -1
- package/dist-renderer/assets/{chunk-QZHKN3VN-Cu1ApHfW.js → chunk-QZHKN3VN-D90_2DQp.js} +1 -1
- package/dist-renderer/assets/{chunk-TZMSLE5B-BOhlynJM.js → chunk-TZMSLE5B-BQEil57G.js} +1 -1
- package/dist-renderer/assets/classDiagram-2ON5EDUG-lpzulY5X.js +1 -0
- package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-lpzulY5X.js +1 -0
- package/dist-renderer/assets/clone-CriGymY9.js +1 -0
- package/dist-renderer/assets/{cose-bilkent-S5V4N54A-DGZSihDQ.js → cose-bilkent-S5V4N54A-6WiK6U2P.js} +1 -1
- package/dist-renderer/assets/{dagre-6UL2VRFP-CnxwCbku.js → dagre-6UL2VRFP-DF4MMuTn.js} +1 -1
- package/dist-renderer/assets/{diagram-PSM6KHXK-DsIhoxdI.js → diagram-PSM6KHXK-CcF1eZ7E.js} +1 -1
- package/dist-renderer/assets/{diagram-QEK2KX5R-Cmh9KUF5.js → diagram-QEK2KX5R-DYlOVPQB.js} +1 -1
- package/dist-renderer/assets/{diagram-S2PKOQOG-CKxV456A.js → diagram-S2PKOQOG-BHXWsZOP.js} +1 -1
- package/dist-renderer/assets/{erDiagram-Q2GNP2WA-EnvYjOjc.js → erDiagram-Q2GNP2WA-GjmuBx8d.js} +1 -1
- package/dist-renderer/assets/{flowDiagram-NV44I4VS-BmNeWY_A.js → flowDiagram-NV44I4VS-BuS7YVHk.js} +1 -1
- package/dist-renderer/assets/{ganttDiagram-JELNMOA3-D30fyK-u.js → ganttDiagram-JELNMOA3-3Teu5tAa.js} +1 -1
- package/dist-renderer/assets/{gitGraphDiagram-V2S2FVAM-CrUNiYg1.js → gitGraphDiagram-V2S2FVAM-BiLdCYu5.js} +1 -1
- package/dist-renderer/assets/{graph-CY1gTfTb.js → graph-CDP_R8ct.js} +1 -1
- package/dist-renderer/assets/{index-CaEbzwAU.js → index-BSZdT-g-.js} +1 -1
- package/dist-renderer/assets/{index-D5K-SjBG.js → index-BhWvMqsz.js} +1 -1
- package/dist-renderer/assets/{index-9_hO4N1e.js → index-C2_AupSj.js} +1 -1
- package/dist-renderer/assets/{index-59r209c1.js → index-C5ujiwAR.js} +580 -588
- package/dist-renderer/assets/index-CIS2CTK9.css +1 -0
- package/dist-renderer/assets/{index-DMR9B1UP.js → index-CVNjLwkq.js} +1 -1
- package/dist-renderer/assets/{index-BC2hXmg_.js → index-CwG3se0q.js} +1 -1
- package/dist-renderer/assets/{infoDiagram-HS3SLOUP-By_XUlcD.js → infoDiagram-HS3SLOUP-DLHUFo72.js} +1 -1
- package/dist-renderer/assets/{journeyDiagram-XKPGCS4Q-BM1LJE9m.js → journeyDiagram-XKPGCS4Q-BE07RpJD.js} +1 -1
- package/dist-renderer/assets/{kanban-definition-3W4ZIXB7-DHIW3aTA.js → kanban-definition-3W4ZIXB7-DDHZy4NB.js} +1 -1
- package/dist-renderer/assets/{layout-DAKiL_Mo.js → layout-5nA5wUxO.js} +1 -1
- package/dist-renderer/assets/{linear-DwOaRYea.js → linear-BtF1i2qN.js} +1 -1
- package/dist-renderer/assets/{mindmap-definition-VGOIOE7T-b7bJ2cha.js → mindmap-definition-VGOIOE7T-Z1Ui9Sqy.js} +1 -1
- package/dist-renderer/assets/{pieDiagram-ADFJNKIX-DxyL9Zr2.js → pieDiagram-ADFJNKIX-LCjxckWv.js} +1 -1
- package/dist-renderer/assets/{quadrantDiagram-AYHSOK5B-CR33pHlF.js → quadrantDiagram-AYHSOK5B-BOwKjSco.js} +1 -1
- package/dist-renderer/assets/{requirementDiagram-UZGBJVZJ-BAiSRSlh.js → requirementDiagram-UZGBJVZJ-pChP8Znd.js} +1 -1
- package/dist-renderer/assets/{sankeyDiagram-TZEHDZUN-C8JmDjoa.js → sankeyDiagram-TZEHDZUN-DifZ2qpo.js} +1 -1
- package/dist-renderer/assets/{sequenceDiagram-WL72ISMW-c1d0Wi1m.js → sequenceDiagram-WL72ISMW-CJg-WYyY.js} +1 -1
- package/dist-renderer/assets/{splashScene-D0YB9uxm.js → splashScene-94xWCzLA.js} +1 -1
- package/dist-renderer/assets/{stateDiagram-FKZM4ZOC-nT8BiH2O.js → stateDiagram-FKZM4ZOC-DWHOoFdv.js} +1 -1
- package/dist-renderer/assets/stateDiagram-v2-4FDKWEC3-CGYZOoMb.js +1 -0
- package/dist-renderer/assets/{timeline-definition-IT6M3QCI-DpoRepUA.js → timeline-definition-IT6M3QCI-CPgokIo8.js} +1 -1
- package/dist-renderer/assets/{treemap-GDKQZRPO-C41UJeIH.js → treemap-GDKQZRPO-DAVqSR9L.js} +1 -1
- package/dist-renderer/assets/{xychartDiagram-PRI3JC2R-KMjGARKN.js → xychartDiagram-PRI3JC2R-CCOcGbrD.js} +1 -1
- package/dist-renderer/chat-community-qr.jpg +0 -0
- package/dist-renderer/fonts/Agave-Bold.ttf +0 -0
- package/dist-renderer/fonts/Agave-Regular.ttf +0 -0
- package/dist-renderer/icon.png +0 -0
- package/dist-renderer/icon.rar +0 -0
- package/dist-renderer/index.html +3 -3
- package/package.json +21 -26
- package/src/features/worker-society/core/application/WorkerSocietyService.test.ts +802 -0
- package/src/features/worker-society/core/application/WorkerSocietyService.ts +428 -0
- package/src/features/worker-society/core/application/fakes.ts +101 -0
- package/src/features/worker-society/core/application/ports.ts +70 -0
- package/src/features/worker-society/core/domain/models/society.ts +141 -0
- package/src/features/worker-society/core/domain/policies/societyPolicies.test.ts +739 -0
- package/src/features/worker-society/core/domain/policies/societyPolicies.ts +496 -0
- package/src/features/worker-society/main/adapters/input/societyMcp.test.ts +317 -0
- package/src/features/worker-society/main/adapters/input/societyMcp.ts +257 -0
- package/src/features/worker-society/main/adapters/input/societyRoutes.test.ts +695 -0
- package/src/features/worker-society/main/adapters/input/societyRoutes.ts +194 -0
- package/src/features/worker-society/main/composition/societyComposition.test.ts +74 -0
- package/src/features/worker-society/main/composition/societyComposition.ts +70 -0
- package/src/features/worker-society/main/composition/workerSocietyPlugin.test.ts +69 -0
- package/src/features/worker-society/main/composition/workerSocietyPlugin.ts +67 -0
- package/src/features/worker-society/main/infrastructure/crossTeamMessageGateway.test.ts +132 -0
- package/src/features/worker-society/main/infrastructure/crossTeamMessageGateway.ts +84 -0
- package/src/features/worker-society/main/infrastructure/fsStores.test.ts +216 -0
- package/src/features/worker-society/main/infrastructure/fsStores.ts +113 -0
- package/src/features/worker-society/main/infrastructure/mergingProfileStore.test.ts +195 -0
- package/src/features/worker-society/main/infrastructure/mergingProfileStore.ts +96 -0
- package/src/features/worker-society/renderer/SocietyGraph.tsx +166 -0
- package/src/features/worker-society/renderer/SocietyNodeLabels.tsx +139 -0
- package/src/features/worker-society/renderer/SocietyNodeOverlay.tsx +339 -0
- package/src/features/worker-society/renderer/SocietyView.tsx +437 -0
- package/src/features/worker-society/renderer/index.ts +11 -0
- package/src/features/worker-society/renderer/societyApi.test.ts +259 -0
- package/src/features/worker-society/renderer/societyApi.ts +144 -0
- package/src/features/worker-society/renderer/societyGraphAdapter.test.ts +321 -0
- package/src/features/worker-society/renderer/societyGraphAdapter.ts +240 -0
- package/src/features/worker-society/renderer/societyOverlayActions.test.ts +57 -0
- package/src/features/worker-society/renderer/societyOverlayActions.ts +49 -0
- package/src/features/worker-society/renderer/societyStore.test.ts +218 -0
- package/src/features/worker-society/renderer/societyStore.ts +146 -0
- package/src/features/worker-society/renderer/societyViewUtils.test.ts +81 -0
- package/src/features/worker-society/renderer/societyViewUtils.ts +68 -0
- package/src/main/ipc/extensions.ts +27 -0
- package/src/main/server.ts +1731 -539
- package/src/main/services/ccConnect/CcConnectBridge.ts +26 -11
- package/src/main/services/ccConnect/CcConnectClient.ts +9 -2
- package/src/main/services/ccConnect/workDirReconcile.test.ts +57 -0
- package/src/main/services/ccConnect/workDirReconcile.ts +36 -0
- package/src/main/services/direct-cli/DirectCliSessionManager.test.ts +397 -0
- package/src/main/services/direct-cli/DirectCliSessionManager.ts +508 -0
- package/src/main/services/direct-cli/DirectCliSessionStore.test.ts +79 -0
- package/src/main/services/direct-cli/DirectCliSessionStore.ts +97 -0
- package/src/main/services/direct-cli/__tests__/directCliMessageId.test.ts +40 -0
- package/src/main/services/direct-cli/directCliMessageId.ts +21 -0
- package/src/main/services/direct-cli/index.ts +17 -0
- package/src/main/services/extensions/capability-packs/CapabilityPackLoaderService.ts +637 -0
- package/src/main/services/extensions/catalog/PluginCatalogService.ts +2 -2
- package/src/main/services/loop-assets/LoopAssetsScannerService.ts +657 -0
- package/src/main/services/runtime/providerAwareCliEnv.ts +33 -5
- package/src/main/services/session-intelligence/LocalSessionScanner.ts +156 -71
- package/src/main/services/session-intelligence/SessionUsageParser.ts +103 -8
- package/src/main/services/session-intelligence/UsageTelemetryService.ts +11 -0
- package/src/main/services/session-intelligence/__tests__/teamSessionListMapper.test.ts +104 -0
- package/src/main/services/session-intelligence/teamSessionListMapper.ts +78 -0
- package/src/main/services/system-manager/AdminLoopInitializer.ts +95 -0
- package/src/main/services/system-manager/BuiltinWorkflowSeeder.ts +744 -0
- package/src/main/services/system-manager/SystemManagerConfigService.ts +19 -1
- package/src/main/services/system-manager/WorkflowPromptService.ts +58 -5
- package/src/main/services/system-manager/__tests__/AdminLoopInitializer.test.ts +129 -0
- package/src/main/services/system-manager/__tests__/SystemManagerConfigService.test.ts +60 -0
- package/src/main/services/teams-mvp/CollaborationBoardService.ts +2 -0
- package/src/main/services/teams-mvp/OpsRunbookContext.ts +60 -0
- package/src/main/services/teams-mvp/TaskDispatchService.test.ts +305 -0
- package/src/main/services/teams-mvp/TaskDispatchService.ts +250 -131
- package/src/main/services/teams-mvp/TeamProvisioningService.ts +12 -2
- package/src/main/services/teams-mvp/TeamWorkspaceService.test.ts +207 -0
- package/src/main/services/teams-mvp/TeamWorkspaceService.ts +104 -51
- package/src/main/services/teams-mvp/index.ts +6 -0
- package/src/main/utils/externalPlatformSessionRouting.ts +92 -0
- package/src/main/utils/toolApprovalRules.ts +151 -0
- package/src/renderer/App.tsx +24 -89
- package/src/renderer/api/httpClient.ts +132 -52
- package/src/renderer/api/providers.ts +5 -16
- package/src/renderer/components/chat/CommunityChatView.tsx +81 -0
- package/src/renderer/components/dashboard/DashboardView.tsx +130 -84
- package/src/renderer/components/extensions/ExtensionStoreView.tsx +39 -5
- package/src/renderer/components/extensions/ExtensionsSubTabTrigger.tsx +2 -1
- package/src/renderer/components/extensions/capability-packs/CapabilityPacksPanel.tsx +170 -0
- package/src/renderer/components/layout/PaneContent.tsx +10 -2
- package/src/renderer/components/layout/SortableTab.tsx +4 -0
- package/src/renderer/components/layout/TabBarActions.tsx +13 -16
- package/src/renderer/components/runtime/ProviderRuntimeSettingsDialog.tsx +4 -135
- package/src/renderer/components/schedules/SchedulesView.tsx +22 -14
- package/src/renderer/components/schedules/calendar/CalendarEventBlock.tsx +7 -6
- package/src/renderer/components/settings/SettingsTabs.tsx +24 -21
- package/src/renderer/components/settings/SettingsView.tsx +22 -13
- package/src/renderer/components/settings/components/SettingRow.tsx +13 -5
- package/src/renderer/components/settings/components/SettingsSectionCard.tsx +53 -0
- package/src/renderer/components/settings/components/SettingsSectionHeader.tsx +10 -6
- package/src/renderer/components/settings/components/SettingsSelect.tsx +12 -9
- package/src/renderer/components/settings/components/SettingsToggle.tsx +6 -5
- package/src/renderer/components/settings/components/index.ts +1 -0
- package/src/renderer/components/settings/sections/AdvancedSection.tsx +78 -59
- package/src/renderer/components/settings/sections/CliStatusSection.tsx +32 -44
- package/src/renderer/components/settings/sections/ConfigEditorDialog.tsx +1 -1
- package/src/renderer/components/settings/sections/GeneralSection.tsx +216 -186
- package/src/renderer/components/settings/sections/PlatformsSection.tsx +25 -17
- package/src/renderer/components/settings/sections/TaskBusSection.tsx +63 -22
- package/src/renderer/components/sidebar/SidebarSessions.tsx +120 -80
- package/src/renderer/components/sidebar/SidebarTaskItem.tsx +1 -1
- package/src/renderer/components/splash/splashScene.ts +6 -2
- package/src/renderer/components/system-manager/SystemManagerView.tsx +169 -255
- package/src/renderer/components/tasks/TasksView.tsx +63 -37
- package/src/renderer/components/team/CcSessionsSection.tsx +124 -89
- package/src/renderer/components/team/HarnessBrandLogos.tsx +318 -0
- package/src/renderer/components/team/HarnessSelect.tsx +25 -26
- package/src/renderer/components/team/TeamDetailView.tsx +137 -153
- package/src/renderer/components/team/TeamEmptyState.tsx +9 -37
- package/src/renderer/components/team/TeamListView.tsx +144 -30
- package/src/renderer/components/team/__tests__/CcSessionsSection.hasLocalFile.test.tsx +128 -0
- package/src/renderer/components/team/activity/ActivityItem.tsx +21 -9
- package/src/renderer/components/team/activity/ActivityTimeline.tsx +2 -2
- package/src/renderer/components/team/dialogs/AdvancedCliSection.tsx +1 -1
- package/src/renderer/components/team/dialogs/CreateTaskDialog.tsx +13 -10
- package/src/renderer/components/team/dialogs/CreateTeamDialog.tsx +189 -57
- package/src/renderer/components/team/dialogs/EditTeamDialog.tsx +9 -157
- package/src/renderer/components/team/dialogs/LaunchTeamDialog.tsx +19 -15
- package/src/renderer/components/team/dialogs/PlatformBindingDialog.tsx +48 -10
- package/src/renderer/components/team/dialogs/PlatformManualForm.tsx +11 -12
- package/src/renderer/components/team/dialogs/PlatformSetupQR.tsx +39 -37
- package/src/renderer/components/team/dialogs/RuntimeConfigDialog.tsx +434 -64
- package/src/renderer/components/team/dialogs/SendMessageDialog.tsx +12 -10
- package/src/renderer/components/team/dialogs/TaskDetailDialog.tsx +2 -2
- package/src/renderer/components/team/dialogs/__tests__/CreateTeamDialog.bindProject.test.tsx +399 -0
- package/src/renderer/components/team/dialogs/__tests__/CreateTeamDialog.chineseRepro.test.tsx +253 -0
- package/src/renderer/components/team/dialogs/platformAllowUtils.ts +91 -0
- package/src/renderer/components/team/dialogs/teammateRuntimeCompatibility.tsx +1 -1
- package/src/renderer/components/team/kanban/KanbanTaskCard.test.tsx +41 -0
- package/src/renderer/components/team/kanban/KanbanTaskCard.tsx +41 -86
- package/src/renderer/components/team/loop-console/LoopCommandComposer.tsx +310 -0
- package/src/renderer/components/team/loop-console/LoopConsolePanel.tsx +372 -0
- package/src/renderer/components/team/loop-console/loopSendIntent.test.ts +85 -0
- package/src/renderer/components/team/loop-console/loopSendIntent.ts +221 -0
- package/src/renderer/components/team/loop-console/useLeadSessionToolActivity.ts +74 -0
- package/src/renderer/components/team/loop-console/useLoopCommandSuggestions.ts +165 -0
- package/src/renderer/components/team/loop-console/useLoopConsoleController.ts +266 -0
- package/src/renderer/components/team/members/LeadModelRow.test.tsx +1 -1
- package/src/renderer/components/team/members/LeadModelRow.tsx +5 -3
- package/src/renderer/components/team/members/MemberDetailDialog.tsx +11 -0
- package/src/renderer/components/team/members/MemberDetailStats.tsx +13 -3
- package/src/renderer/components/team/members/MemberDraftRow.test.tsx +1 -1
- package/src/renderer/components/team/members/MemberDraftRow.tsx +1 -1
- package/src/renderer/components/team/members/MemberMessagesTab.tsx +2 -2
- package/src/renderer/components/team/members/MemberStatsTab.tsx +1 -1
- package/src/renderer/components/team/messages/MessageComposer.tsx +150 -44
- package/src/renderer/components/team/messages/MessagesFilterPopover.tsx +2 -2
- package/src/renderer/components/team/messages/MessagesPanel.tsx +34 -28
- package/src/renderer/components/team/schedule/CcCronScheduleDialog.tsx +6 -6
- package/src/renderer/components/team/taskLogs/ExactTaskLogCard.tsx +2 -2
- package/src/renderer/components/team/taskLogs/TaskLogStreamSection.tsx +1 -1
- package/src/renderer/components/terminal/TerminalPanel.tsx +2 -3
- package/src/renderer/components/ui/MentionableTextarea.tsx +5 -1
- package/src/renderer/constants/teamColors.ts +5 -5
- package/src/renderer/hooks/useExtensionsTabState.ts +1 -1
- package/src/renderer/hooks/useMentionDetection.ts +5 -1
- package/src/renderer/hooks/useProjectWorkflowCommands.ts +57 -0
- package/src/renderer/hooks/useTeamSuggestions.ts +2 -0
- package/src/renderer/index.css +19 -2
- package/src/renderer/main.tsx +7 -1
- package/src/renderer/store/index.ts +18 -1
- package/src/renderer/store/slices/extensionsSlice.ts +83 -0
- package/src/renderer/store/slices/tabSlice.ts +61 -0
- package/src/renderer/store/slices/teamSlice.ts +138 -9
- package/src/renderer/types/mention.ts +8 -0
- package/src/renderer/types/tabs.ts +3 -1
- package/src/renderer/utils/__tests__/bindProjectSlug.test.ts +69 -0
- package/src/renderer/utils/__tests__/groupTransformer.test.ts +148 -0
- package/src/renderer/utils/__tests__/initialRoute.test.ts +101 -0
- package/src/renderer/utils/__tests__/leadToolActivity.test.ts +124 -0
- package/src/renderer/utils/__tests__/mergeTeamMessages.test.ts +81 -0
- package/src/renderer/utils/__tests__/teamMessageFiltering.test.ts +213 -0
- package/src/renderer/utils/__tests__/teamMessageKey.test.ts +75 -0
- package/src/renderer/utils/__tests__/workflowCommandExecution.test.ts +173 -0
- package/src/renderer/utils/__tests__/workflowCommandSuggestions.test.ts +59 -0
- package/src/renderer/utils/bindProjectSlug.ts +57 -0
- package/src/renderer/utils/capabilityCommandExecution.ts +113 -0
- package/src/renderer/utils/initialRoute.ts +89 -0
- package/src/renderer/utils/leadToolActivity.ts +117 -0
- package/src/renderer/utils/loopShortcutSuggestions.ts +106 -0
- package/src/renderer/utils/mentionSuggestions.ts +1 -1
- package/src/renderer/utils/slashCommandRegistry.ts +231 -0
- package/src/renderer/utils/teamMentionDirective.ts +31 -0
- package/src/renderer/utils/workflowCommandExecution.ts +96 -0
- package/src/renderer/utils/workflowCommandSuggestions.ts +49 -0
- package/src/shared/types/api.ts +79 -4
- package/src/shared/types/ccConnect.ts +1 -0
- package/src/shared/types/extensions/api.ts +19 -0
- package/src/shared/types/extensions/capabilityPack.ts +118 -0
- package/src/shared/types/extensions/index.ts +29 -1
- package/src/shared/types/index.ts +6 -0
- package/src/shared/types/loopAssets.ts +54 -0
- package/src/shared/types/providers.ts +0 -16
- package/src/shared/types/systemManager.ts +26 -1
- package/src/shared/types/team.ts +43 -3
- package/src/shared/types/terminal.ts +2 -36
- package/src/shared/types/worker.test.ts +28 -0
- package/src/shared/types/worker.ts +3 -0
- package/src/shared/utils/__tests__/effortLevels.test.ts +88 -0
- package/src/shared/utils/__tests__/providerBackend.test.ts +88 -0
- package/src/shared/utils/__tests__/providerLaunchArgs.test.ts +220 -0
- package/src/shared/utils/claudeStreamJson.test.ts +187 -0
- package/src/shared/utils/claudeStreamJson.ts +153 -0
- package/src/shared/utils/providerLaunchArgs.ts +217 -0
- package/src/shared/utils/slashCommands.ts +10 -0
- package/src/types/node-pty.d.ts +8 -0
- package/dist-renderer/assets/channel-D0XS_akr.js +0 -1
- package/dist-renderer/assets/classDiagram-2ON5EDUG-D13Ffs0U.js +0 -1
- package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-D13Ffs0U.js +0 -1
- package/dist-renderer/assets/clone-B1ZrxI1D.js +0 -1
- package/dist-renderer/assets/index-iyjkpSus.css +0 -32
- package/dist-renderer/assets/stateDiagram-v2-4FDKWEC3-Dmibmlso.js +0 -1
- package/src/main/services/system-manager/SystemManagerPtyService.ts +0 -233
- package/src/renderer/components/common/TerminalPane.tsx +0 -213
- package/src/renderer/components/team/dialogs/useTeamEditForm.ts +0 -292
|
@@ -59,12 +59,14 @@ import { isLeadAgentType, isLeadMember } from '@shared/utils/leadDetection';
|
|
|
59
59
|
import { deriveTaskDisplayId, formatTaskDisplayLabel } from '@shared/utils/taskIdentity';
|
|
60
60
|
import {
|
|
61
61
|
AlertTriangle,
|
|
62
|
+
Bot,
|
|
62
63
|
Columns3,
|
|
63
64
|
Download,
|
|
64
65
|
FolderOpen,
|
|
65
66
|
GitBranch,
|
|
66
67
|
History,
|
|
67
68
|
Link,
|
|
69
|
+
Network,
|
|
68
70
|
Pencil,
|
|
69
71
|
Play,
|
|
70
72
|
Plus,
|
|
@@ -92,18 +94,23 @@ import { KanbanSearchInput } from './kanban/KanbanSearchInput';
|
|
|
92
94
|
import { TrashDialog } from './kanban/TrashDialog';
|
|
93
95
|
import { MemberDetailDialog } from './members/MemberDetailDialog';
|
|
94
96
|
|
|
95
|
-
|
|
96
97
|
import type { TeamMessagesPanelMode } from '@renderer/types/teamMessagesPanelMode';
|
|
97
98
|
import type { ComponentProps } from 'react';
|
|
98
99
|
|
|
99
|
-
import { TerminalPane, type TerminalPaneRef } from '@renderer/components/common/TerminalPane';
|
|
100
|
-
|
|
101
100
|
const ProjectEditorOverlay = lazy(() =>
|
|
102
101
|
import('./editor/ProjectEditorOverlay').then((m) => ({ default: m.ProjectEditorOverlay }))
|
|
103
102
|
);
|
|
103
|
+
import { LoopConsolePanel } from './loop-console/LoopConsolePanel';
|
|
104
104
|
import { MemberList } from './members/MemberList';
|
|
105
105
|
import { MessagesPanel } from './messages/MessagesPanel';
|
|
106
|
-
import {
|
|
106
|
+
import {
|
|
107
|
+
CcSessionsSection,
|
|
108
|
+
buildAllSessionsCsv,
|
|
109
|
+
buildAllSessionsCsvFilename,
|
|
110
|
+
downloadTextFile,
|
|
111
|
+
hasDataRows,
|
|
112
|
+
isExportPayload,
|
|
113
|
+
} from './CcSessionsSection';
|
|
107
114
|
import { ChangeReviewDialog } from './review/ChangeReviewDialog';
|
|
108
115
|
import {
|
|
109
116
|
getTeamPendingRepliesState,
|
|
@@ -239,7 +246,7 @@ const TeamOfflineStatusBanner = memo(function TeamOfflineStatusBanner({
|
|
|
239
246
|
teamName: string;
|
|
240
247
|
onLaunch: () => void;
|
|
241
248
|
}): React.JSX.Element {
|
|
242
|
-
const message = '
|
|
249
|
+
const message = 'Agent 未运行:当前没有本地 Claude/Agent 进程在运行,已有状态和任务仍会保留。';
|
|
243
250
|
|
|
244
251
|
return (
|
|
245
252
|
<div
|
|
@@ -261,7 +268,7 @@ const TeamOfflineStatusBanner = memo(function TeamOfflineStatusBanner({
|
|
|
261
268
|
onClick={onLaunch}
|
|
262
269
|
>
|
|
263
270
|
<Play size={12} />
|
|
264
|
-
|
|
271
|
+
启动 Agent
|
|
265
272
|
</Button>
|
|
266
273
|
</div>
|
|
267
274
|
);
|
|
@@ -691,7 +698,7 @@ const LeadContextBridge = memo(function LeadContextBridge({
|
|
|
691
698
|
</div>
|
|
692
699
|
<div className="flex flex-1 items-center justify-center p-4">
|
|
693
700
|
<p className="text-xs text-[var(--color-text-muted)]">
|
|
694
|
-
{leadSessionLoading ? '正在加载上下文…' : '
|
|
701
|
+
{leadSessionLoading ? '正在加载上下文…' : '打开 Lead 会话后可查看上下文。'}
|
|
695
702
|
</p>
|
|
696
703
|
</div>
|
|
697
704
|
</div>
|
|
@@ -898,11 +905,6 @@ function getCommandForHarness(harness?: string): string {
|
|
|
898
905
|
}
|
|
899
906
|
}
|
|
900
907
|
|
|
901
|
-
/** All CcAgentType values run as local CLI agents */
|
|
902
|
-
function isLocalHarness(harness?: string): boolean {
|
|
903
|
-
return !!harness;
|
|
904
|
-
}
|
|
905
|
-
|
|
906
908
|
export const TeamDetailView = ({
|
|
907
909
|
teamName,
|
|
908
910
|
isPaneFocused = false,
|
|
@@ -934,11 +936,8 @@ export const TeamDetailView = ({
|
|
|
934
936
|
mode: 'launch',
|
|
935
937
|
});
|
|
936
938
|
const [editorOpen, setEditorOpen] = useState(false);
|
|
937
|
-
const [terminalHeight, setTerminalHeight] = useState(400);
|
|
938
939
|
const contentRef = useRef<HTMLDivElement>(null);
|
|
939
940
|
const provisioningBannerRef = useRef<HTMLDivElement>(null);
|
|
940
|
-
const terminalPaneRef = useRef<TerminalPaneRef>(null);
|
|
941
|
-
const terminalSpawnedForTeamRef = useRef<string | null>(null);
|
|
942
941
|
const wasProvisioningRef = useRef(false);
|
|
943
942
|
|
|
944
943
|
// Set inert on background content when editor overlay is open (a11y focus trap)
|
|
@@ -969,10 +968,7 @@ export const TeamDetailView = ({
|
|
|
969
968
|
setSendDialogOpen(true);
|
|
970
969
|
};
|
|
971
970
|
const onOpenProfile = (e: Event) => {
|
|
972
|
-
const {
|
|
973
|
-
teamName: tn,
|
|
974
|
-
memberName,
|
|
975
|
-
} = (e as CustomEvent).detail ?? {};
|
|
971
|
+
const { teamName: tn, memberName } = (e as CustomEvent).detail ?? {};
|
|
976
972
|
if (tn !== teamName || !data) return;
|
|
977
973
|
const member = members.find((m: { name: string }) => m.name === memberName);
|
|
978
974
|
if (member) {
|
|
@@ -998,9 +994,9 @@ export const TeamDetailView = ({
|
|
|
998
994
|
const onStartTask = taskAction((taskId) => {
|
|
999
995
|
void (async () => {
|
|
1000
996
|
try {
|
|
997
|
+
const task = data?.tasks.find((t: { id: string }) => t.id === taskId);
|
|
1001
998
|
const result = await startTaskByUser(teamName, taskId);
|
|
1002
|
-
if (data?.isAlive) {
|
|
1003
|
-
const task = data.tasks.find((t: { id: string }) => t.id === taskId);
|
|
999
|
+
if (data?.isAlive && !task?.dispatchMeta) {
|
|
1004
1000
|
try {
|
|
1005
1001
|
if (result.notifiedOwner && task?.owner) {
|
|
1006
1002
|
await api.teams.processSend(
|
|
@@ -1018,6 +1014,8 @@ export const TeamDetailView = ({
|
|
|
1018
1014
|
})();
|
|
1019
1015
|
});
|
|
1020
1016
|
const onCompleteTask = taskAction((taskId) => {
|
|
1017
|
+
const task = data?.tasks.find((t: { id: string }) => t.id === taskId);
|
|
1018
|
+
if (task?.status === 'in_progress') return;
|
|
1021
1019
|
void (async () => {
|
|
1022
1020
|
try {
|
|
1023
1021
|
await updateTaskStatus(teamName, taskId, 'completed');
|
|
@@ -1036,6 +1034,8 @@ export const TeamDetailView = ({
|
|
|
1036
1034
|
})();
|
|
1037
1035
|
});
|
|
1038
1036
|
const onRequestReviewTask = taskAction((taskId) => {
|
|
1037
|
+
const task = data?.tasks.find((t: { id: string }) => t.id === taskId);
|
|
1038
|
+
if (task?.status === 'in_progress') return;
|
|
1039
1039
|
void (async () => {
|
|
1040
1040
|
try {
|
|
1041
1041
|
await requestReview(teamName, taskId);
|
|
@@ -1048,6 +1048,8 @@ export const TeamDetailView = ({
|
|
|
1048
1048
|
setRequestChangesTaskId(taskId);
|
|
1049
1049
|
});
|
|
1050
1050
|
const onCancelTask = taskAction((taskId) => {
|
|
1051
|
+
const task = data?.tasks.find((t: { id: string }) => t.id === taskId);
|
|
1052
|
+
if (task?.status === 'in_progress') return;
|
|
1051
1053
|
void (async () => {
|
|
1052
1054
|
try {
|
|
1053
1055
|
await updateTaskStatus(teamName, taskId, 'pending');
|
|
@@ -1066,7 +1068,11 @@ export const TeamDetailView = ({
|
|
|
1066
1068
|
}
|
|
1067
1069
|
})();
|
|
1068
1070
|
});
|
|
1069
|
-
const onDeleteTaskGraph = taskAction((taskId) =>
|
|
1071
|
+
const onDeleteTaskGraph = taskAction((taskId) => {
|
|
1072
|
+
const task = data?.tasks.find((t: { id: string }) => t.id === taskId);
|
|
1073
|
+
if (task?.status === 'in_progress') return;
|
|
1074
|
+
handleDeleteTask(taskId);
|
|
1075
|
+
});
|
|
1070
1076
|
|
|
1071
1077
|
window.addEventListener('graph:start-task', onStartTask);
|
|
1072
1078
|
window.addEventListener('graph:complete-task', onCompleteTask);
|
|
@@ -1187,6 +1193,8 @@ export const TeamDetailView = ({
|
|
|
1187
1193
|
error,
|
|
1188
1194
|
projects,
|
|
1189
1195
|
repositoryGroups,
|
|
1196
|
+
fetchSkillsCatalog,
|
|
1197
|
+
mcpFetchInstalled,
|
|
1190
1198
|
initTabUIState,
|
|
1191
1199
|
selectTeam,
|
|
1192
1200
|
updateKanban,
|
|
@@ -1229,11 +1237,16 @@ export const TeamDetailView = ({
|
|
|
1229
1237
|
pendingReviewRequest,
|
|
1230
1238
|
setPendingReviewRequest,
|
|
1231
1239
|
teams,
|
|
1240
|
+
teamSummaryDisplayName,
|
|
1232
1241
|
fetchTeams,
|
|
1242
|
+
leadActivity,
|
|
1243
|
+
leadContextUpdatedAt,
|
|
1233
1244
|
} = useStore(
|
|
1234
1245
|
useShallow((s) => ({
|
|
1235
1246
|
projects: s.projects,
|
|
1236
1247
|
repositoryGroups: s.repositoryGroups,
|
|
1248
|
+
fetchSkillsCatalog: s.fetchSkillsCatalog,
|
|
1249
|
+
mcpFetchInstalled: s.mcpFetchInstalled,
|
|
1237
1250
|
initTabUIState: s.initTabUIState,
|
|
1238
1251
|
selectTeam: s.selectTeam,
|
|
1239
1252
|
updateKanban: s.updateKanban,
|
|
@@ -1280,7 +1293,10 @@ export const TeamDetailView = ({
|
|
|
1280
1293
|
pendingReviewRequest: s.pendingReviewRequest,
|
|
1281
1294
|
setPendingReviewRequest: s.setPendingReviewRequest,
|
|
1282
1295
|
teams: s.teams,
|
|
1296
|
+
teamSummaryDisplayName: teamName ? s.teamByName[teamName]?.displayName : undefined,
|
|
1283
1297
|
fetchTeams: s.fetchTeams,
|
|
1298
|
+
leadActivity: teamName ? s.leadActivityByTeam[teamName] : undefined,
|
|
1299
|
+
leadContextUpdatedAt: teamName ? s.leadContextByTeam[teamName]?.updatedAt : undefined,
|
|
1284
1300
|
}))
|
|
1285
1301
|
);
|
|
1286
1302
|
|
|
@@ -1305,6 +1321,14 @@ export const TeamDetailView = ({
|
|
|
1305
1321
|
setTeamPendingRepliesState(teamName, pendingRepliesByMember);
|
|
1306
1322
|
}, [pendingRepliesByMember, teamName]);
|
|
1307
1323
|
|
|
1324
|
+
useEffect(() => {
|
|
1325
|
+
const projectPath = data?.config.projectPath;
|
|
1326
|
+
void fetchSkillsCatalog(projectPath ?? undefined);
|
|
1327
|
+
if (projectPath) {
|
|
1328
|
+
void mcpFetchInstalled(projectPath);
|
|
1329
|
+
}
|
|
1330
|
+
}, [data?.config.projectPath, fetchSkillsCatalog, mcpFetchInstalled]);
|
|
1331
|
+
|
|
1308
1332
|
useEffect(() => {
|
|
1309
1333
|
const wasProvisioning = wasProvisioningRef.current;
|
|
1310
1334
|
wasProvisioningRef.current = isTeamProvisioning;
|
|
@@ -1331,24 +1355,6 @@ export const TeamDetailView = ({
|
|
|
1331
1355
|
void fetchDeletedTasks(teamName);
|
|
1332
1356
|
}, [teamName, selectTeam, fetchDeletedTasks]);
|
|
1333
1357
|
|
|
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
|
-
|
|
1352
1358
|
// Recovery: after HMR, all mounted TeamDetailView effects re-run simultaneously.
|
|
1353
1359
|
// With CSS display-toggle (all tabs stay mounted), the last selectTeam() call wins
|
|
1354
1360
|
// and other tabs get stuck with mismatched data (permanent skeleton).
|
|
@@ -1716,21 +1722,8 @@ export const TeamDetailView = ({
|
|
|
1716
1722
|
}, []);
|
|
1717
1723
|
|
|
1718
1724
|
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
|
-
}
|
|
1732
1725
|
openLaunchDialog('relaunch');
|
|
1733
|
-
}, [
|
|
1726
|
+
}, [openLaunchDialog]);
|
|
1734
1727
|
|
|
1735
1728
|
const handleStartCcConnectTeam = useCallback(() => {
|
|
1736
1729
|
void (async () => {
|
|
@@ -1924,6 +1917,8 @@ export const TeamDetailView = ({
|
|
|
1924
1917
|
|
|
1925
1918
|
const handleDeleteTask = useCallback(
|
|
1926
1919
|
(taskId: string) => {
|
|
1920
|
+
const task = taskMapRef.current.get(taskId);
|
|
1921
|
+
if (task?.status === 'in_progress') return;
|
|
1927
1922
|
void (async () => {
|
|
1928
1923
|
const confirmed = await confirm({
|
|
1929
1924
|
title: '删除任务',
|
|
@@ -2054,6 +2049,7 @@ export const TeamDetailView = ({
|
|
|
2054
2049
|
pendingRepliesByMember,
|
|
2055
2050
|
onPendingReplyChange: setPendingRepliesByMember,
|
|
2056
2051
|
onMemberClick: handleSelectMember,
|
|
2052
|
+
onTaskIdClick: handleTaskIdClick,
|
|
2057
2053
|
onReplyToMessage: handleReplyToMessage,
|
|
2058
2054
|
onRestartTeam: handleRestartTeam,
|
|
2059
2055
|
inlineScrollContainerRef: contentRef,
|
|
@@ -2068,6 +2064,7 @@ export const TeamDetailView = ({
|
|
|
2068
2064
|
handleReplyToMessage,
|
|
2069
2065
|
handleRestartTeam,
|
|
2070
2066
|
handleSelectMember,
|
|
2067
|
+
handleTaskIdClick,
|
|
2071
2068
|
pendingRepliesByMember,
|
|
2072
2069
|
teamName,
|
|
2073
2070
|
timeWindow,
|
|
@@ -2133,35 +2130,38 @@ export const TeamDetailView = ({
|
|
|
2133
2130
|
const draftTeamSummary = useStore.getState().teamByName[teamName];
|
|
2134
2131
|
const draftDisplayName = draftTeamSummary?.displayName || teamName;
|
|
2135
2132
|
const draftCwd = draftTeamSummary?.projectPath || draftTeamSummary?.workDir || '';
|
|
2133
|
+
const draftCommand = getCommandForHarness(draftTeamSummary?.harness);
|
|
2136
2134
|
|
|
2137
2135
|
return (
|
|
2138
|
-
|
|
2139
|
-
<div
|
|
2140
|
-
<
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
<div className="flex items-center gap-3
|
|
2136
|
+
<div className="size-full overflow-auto p-6">
|
|
2137
|
+
<div ref={provisioningBannerRef}>
|
|
2138
|
+
<TeamProvisioningBanner teamName={teamName} />
|
|
2139
|
+
</div>
|
|
2140
|
+
<div className="mt-4 rounded-2xl border border-[var(--color-border)] bg-[var(--color-surface-raised)] p-5">
|
|
2141
|
+
<div className="flex flex-wrap items-center gap-3">
|
|
2144
2142
|
<p className="text-sm font-medium text-text">{draftDisplayName}</p>
|
|
2145
2143
|
<span className="rounded-full bg-indigo-500/20 px-2 py-0.5 text-[10px] font-medium text-indigo-400">
|
|
2146
|
-
{
|
|
2144
|
+
{draftCommand}
|
|
2147
2145
|
</span>
|
|
2148
2146
|
</div>
|
|
2149
|
-
<
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2147
|
+
<p className="mt-3 max-w-2xl text-sm leading-6 text-[var(--color-text-secondary)]">
|
|
2148
|
+
终端不再嵌入页面。需要接管这个工作区时,请在系统终端中打开默认 CLI。
|
|
2149
|
+
</p>
|
|
2150
|
+
<Button
|
|
2151
|
+
size="sm"
|
|
2152
|
+
variant="outline"
|
|
2153
|
+
className="mt-4"
|
|
2154
|
+
disabled={!draftCwd}
|
|
2155
|
+
onClick={() => {
|
|
2156
|
+
if (!draftCwd) return;
|
|
2157
|
+
void api.terminal.openExternal({ command: draftCommand, cwd: draftCwd });
|
|
2158
|
+
}}
|
|
2159
|
+
>
|
|
2160
|
+
<Play size={13} />
|
|
2161
|
+
在系统终端打开
|
|
2162
|
+
</Button>
|
|
2163
2163
|
</div>
|
|
2164
|
-
|
|
2164
|
+
</div>
|
|
2165
2165
|
);
|
|
2166
2166
|
}
|
|
2167
2167
|
|
|
@@ -2198,6 +2198,11 @@ export const TeamDetailView = ({
|
|
|
2198
2198
|
);
|
|
2199
2199
|
}
|
|
2200
2200
|
|
|
2201
|
+
// Prefer the store summary's displayName over data.config.name: for a draft or
|
|
2202
|
+
// partially-provisioned team (no team.json on disk) the server-side getData falls
|
|
2203
|
+
// back to the slug for config.name, but the user-facing name survives in teamByName.
|
|
2204
|
+
const displayTeamName = teamSummaryDisplayName || data.config.name || teamName;
|
|
2205
|
+
|
|
2201
2206
|
const headerColorSet = data.config.color
|
|
2202
2207
|
? getTeamColorSet(data.config.color)
|
|
2203
2208
|
: nameColorSet(data.config.name);
|
|
@@ -2235,17 +2240,19 @@ export const TeamDetailView = ({
|
|
|
2235
2240
|
<div className="min-w-0 flex-1">
|
|
2236
2241
|
<div className="flex items-center gap-2">
|
|
2237
2242
|
<h2 className="text-base font-semibold text-[var(--color-text)]">
|
|
2238
|
-
{
|
|
2243
|
+
{displayTeamName}
|
|
2239
2244
|
</h2>
|
|
2240
|
-
{data.platforms
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2245
|
+
{data.platforms
|
|
2246
|
+
?.filter((pl) => pl.type !== 'bridge')
|
|
2247
|
+
.map((pl) => (
|
|
2248
|
+
<span
|
|
2249
|
+
key={pl.type}
|
|
2250
|
+
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"
|
|
2251
|
+
>
|
|
2252
|
+
<span className="size-1.5 rounded-full bg-emerald-400" />
|
|
2253
|
+
{pl.type}
|
|
2254
|
+
</span>
|
|
2255
|
+
))}
|
|
2249
2256
|
{isTeamProvisioning && (
|
|
2250
2257
|
<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">
|
|
2251
2258
|
<span className="size-1.5 animate-pulse rounded-full bg-yellow-400" />
|
|
@@ -2324,22 +2331,18 @@ export const TeamDetailView = ({
|
|
|
2324
2331
|
)}
|
|
2325
2332
|
>
|
|
2326
2333
|
<div className="flex min-w-0 flex-1 flex-wrap items-center gap-x-3 gap-y-0.5">
|
|
2327
|
-
{data.
|
|
2334
|
+
{data.teamName && (
|
|
2328
2335
|
<span className="flex items-center gap-1 text-[11px] text-[var(--color-text-secondary)]">
|
|
2329
2336
|
<FolderOpen size={11} className="shrink-0 text-[var(--color-text-muted)]" />
|
|
2330
2337
|
<Tooltip>
|
|
2331
2338
|
<TooltipTrigger asChild>
|
|
2332
|
-
<span className="max-w-60 truncate font-mono">
|
|
2333
|
-
{data.config.projectPath
|
|
2334
|
-
.replace(/\\/g, '/')
|
|
2335
|
-
.split('/')
|
|
2336
|
-
.filter(Boolean)
|
|
2337
|
-
.pop() ?? data.config.projectPath}
|
|
2338
|
-
</span>
|
|
2339
|
+
<span className="max-w-60 truncate font-mono">@{data.teamName}</span>
|
|
2339
2340
|
</TooltipTrigger>
|
|
2340
2341
|
<TooltipContent side="bottom">
|
|
2341
2342
|
<span className="font-mono text-xs">
|
|
2342
|
-
{
|
|
2343
|
+
{data.config.projectPath
|
|
2344
|
+
? formatProjectPath(data.config.projectPath)
|
|
2345
|
+
: data.teamName}
|
|
2343
2346
|
</span>
|
|
2344
2347
|
</TooltipContent>
|
|
2345
2348
|
</Tooltip>
|
|
@@ -2417,7 +2420,7 @@ export const TeamDetailView = ({
|
|
|
2417
2420
|
title="会话"
|
|
2418
2421
|
icon={<MessageSquare size={14} />}
|
|
2419
2422
|
badge={ccSessions.length}
|
|
2420
|
-
defaultOpen={
|
|
2423
|
+
defaultOpen={false}
|
|
2421
2424
|
action={
|
|
2422
2425
|
ccSessions.length > 0 ? (
|
|
2423
2426
|
<button
|
|
@@ -2496,6 +2499,8 @@ export const TeamDetailView = ({
|
|
|
2496
2499
|
/>
|
|
2497
2500
|
}
|
|
2498
2501
|
onRequestReview={(taskId) => {
|
|
2502
|
+
const task = taskMapRef.current.get(taskId);
|
|
2503
|
+
if (task?.status === 'in_progress') return;
|
|
2499
2504
|
void (async () => {
|
|
2500
2505
|
try {
|
|
2501
2506
|
await requestReview(teamName, taskId);
|
|
@@ -2532,9 +2537,9 @@ export const TeamDetailView = ({
|
|
|
2532
2537
|
onStartTask={(taskId) => {
|
|
2533
2538
|
void (async () => {
|
|
2534
2539
|
try {
|
|
2540
|
+
const task = data?.tasks.find((t) => t.id === taskId);
|
|
2535
2541
|
const result = await startTaskByUser(teamName, taskId);
|
|
2536
|
-
if (data?.isAlive) {
|
|
2537
|
-
const task = data.tasks.find((t) => t.id === taskId);
|
|
2542
|
+
if (data?.isAlive && !task?.dispatchMeta) {
|
|
2538
2543
|
try {
|
|
2539
2544
|
if (result.notifiedOwner && task?.owner) {
|
|
2540
2545
|
await api.teams.processSend(
|
|
@@ -2560,6 +2565,8 @@ export const TeamDetailView = ({
|
|
|
2560
2565
|
})();
|
|
2561
2566
|
}}
|
|
2562
2567
|
onCompleteTask={(taskId) => {
|
|
2568
|
+
const task = taskMapRef.current.get(taskId);
|
|
2569
|
+
if (task?.status === 'in_progress') return;
|
|
2563
2570
|
void (async () => {
|
|
2564
2571
|
try {
|
|
2565
2572
|
await updateTaskStatus(teamName, taskId, 'completed');
|
|
@@ -2572,6 +2579,7 @@ export const TeamDetailView = ({
|
|
|
2572
2579
|
void (async () => {
|
|
2573
2580
|
try {
|
|
2574
2581
|
const task = data?.tasks.find((t) => t.id === taskId);
|
|
2582
|
+
if (task?.status === 'in_progress') return;
|
|
2575
2583
|
await updateTaskStatus(teamName, taskId, 'pending');
|
|
2576
2584
|
|
|
2577
2585
|
if (task?.owner) {
|
|
@@ -2668,6 +2676,34 @@ export const TeamDetailView = ({
|
|
|
2668
2676
|
</CollapsibleTeamSection>
|
|
2669
2677
|
)}
|
|
2670
2678
|
|
|
2679
|
+
<CollapsibleTeamSection
|
|
2680
|
+
sectionId="loop-console"
|
|
2681
|
+
title="指令台"
|
|
2682
|
+
icon={<MessageSquare size={14} />}
|
|
2683
|
+
badge={data.isAlive ? 'online' : 'offline'}
|
|
2684
|
+
defaultOpen
|
|
2685
|
+
>
|
|
2686
|
+
<LoopConsolePanel
|
|
2687
|
+
teamName={teamName}
|
|
2688
|
+
members={activeMembers}
|
|
2689
|
+
tasks={data.tasks}
|
|
2690
|
+
isTeamAlive={data.isAlive}
|
|
2691
|
+
isProvisioning={isTeamProvisioning}
|
|
2692
|
+
leadActivity={leadActivity}
|
|
2693
|
+
leadContextUpdatedAt={leadContextUpdatedAt}
|
|
2694
|
+
currentLeadSessionId={data.config.leadSessionId}
|
|
2695
|
+
leadProjectPath={data.config.projectPath}
|
|
2696
|
+
sessions={ccSessions}
|
|
2697
|
+
pendingRepliesByMember={pendingRepliesByMember}
|
|
2698
|
+
onPendingReplyChange={setPendingRepliesByMember}
|
|
2699
|
+
onMemberClick={handleSelectMember}
|
|
2700
|
+
onTaskClick={handleOpenTask}
|
|
2701
|
+
onReplyToMessage={handleReplyToMessage}
|
|
2702
|
+
onRestartTeam={handleRestartTeam}
|
|
2703
|
+
onTaskIdClick={handleTaskIdClick}
|
|
2704
|
+
/>
|
|
2705
|
+
</CollapsibleTeamSection>
|
|
2706
|
+
|
|
2671
2707
|
<ReviewDialog
|
|
2672
2708
|
open={requestChangesTaskId !== null}
|
|
2673
2709
|
teamName={teamName}
|
|
@@ -2755,7 +2791,7 @@ export const TeamDetailView = ({
|
|
|
2755
2791
|
<DialogHeader>
|
|
2756
2792
|
<DialogTitle>移除成员</DialogTitle>
|
|
2757
2793
|
<DialogDescription>
|
|
2758
|
-
确认将 “{removeMemberConfirm}”
|
|
2794
|
+
确认将 “{removeMemberConfirm}” 从团队中移除?任务与 动态会保留,
|
|
2759
2795
|
但该名称将无法再次使用。
|
|
2760
2796
|
</DialogDescription>
|
|
2761
2797
|
</DialogHeader>
|
|
@@ -2789,7 +2825,7 @@ export const TeamDetailView = ({
|
|
|
2789
2825
|
<DialogHeader>
|
|
2790
2826
|
<DialogTitle>删除团队</DialogTitle>
|
|
2791
2827
|
<DialogDescription>
|
|
2792
|
-
确认删除团队 “{
|
|
2828
|
+
确认删除团队 “{displayTeamName}
|
|
2793
2829
|
”?此操作不可恢复,所有团队数据与任务都将被删除。
|
|
2794
2830
|
</DialogDescription>
|
|
2795
2831
|
</DialogHeader>
|
|
@@ -2924,59 +2960,7 @@ export const TeamDetailView = ({
|
|
|
2924
2960
|
{teamAgentRuntimeWatcher}
|
|
2925
2961
|
{leadContextWatcher}
|
|
2926
2962
|
<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
|
-
)}
|
|
2963
|
+
<div className="min-h-0 flex-1 overflow-hidden">{renderBody()}</div>
|
|
2980
2964
|
</div>
|
|
2981
2965
|
{data && teamName !== SYSTEM_MANAGER_TEAM_NAME ? (
|
|
2982
2966
|
<RuntimeConfigDialog
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { Button } from '@renderer/components/ui/button';
|
|
2
|
+
|
|
3
|
+
import { AGENT_TYPE_LABELS, ALL_AGENT_TYPES } from './HarnessCards';
|
|
4
|
+
import { HarnessIcon } from './HarnessSelect';
|
|
5
|
+
|
|
2
6
|
import type { CcAgentType } from '@shared/types/ccConnect';
|
|
3
|
-
import { ALL_AGENT_TYPES, AGENT_TYPE_LABELS } from './HarnessCards';
|
|
4
7
|
|
|
5
8
|
interface TeamEmptyStateProps {
|
|
6
9
|
canCreate: boolean;
|
|
@@ -31,9 +34,9 @@ export const TeamEmptyState = ({
|
|
|
31
34
|
return (
|
|
32
35
|
<div className="flex size-full flex-col items-center justify-center gap-6 px-6">
|
|
33
36
|
<div className="text-center">
|
|
34
|
-
<p className="text-lg font-medium text-[var(--color-text)]"
|
|
37
|
+
<p className="text-lg font-medium text-[var(--color-text)]">还没有 Agent runtime</p>
|
|
35
38
|
<p className="mt-2 text-sm text-[var(--color-text-muted)]">
|
|
36
|
-
选择一种 Agent
|
|
39
|
+
选择一种 Agent 类型启动循环,或创建自定义 runtime。
|
|
37
40
|
</p>
|
|
38
41
|
</div>
|
|
39
42
|
|
|
@@ -51,7 +54,7 @@ export const TeamEmptyState = ({
|
|
|
51
54
|
className="flex flex-col items-center gap-1.5 rounded-lg border border-[var(--color-border)] bg-[var(--color-surface)] p-3 text-center transition-colors hover:border-[var(--color-border-emphasis)] hover:bg-[var(--color-surface-raised)]"
|
|
52
55
|
onClick={() => onSelectHarness(type)}
|
|
53
56
|
>
|
|
54
|
-
<
|
|
57
|
+
<HarnessIcon type={type} className="size-6" />
|
|
55
58
|
<span className="text-xs font-medium text-[var(--color-text)]">
|
|
56
59
|
{AGENT_TYPE_LABELS[type]}
|
|
57
60
|
</span>
|
|
@@ -71,43 +74,12 @@ export const TeamEmptyState = ({
|
|
|
71
74
|
</div>
|
|
72
75
|
|
|
73
76
|
<Button size="sm" disabled={!canCreate} onClick={onCreateTeam}>
|
|
74
|
-
|
|
77
|
+
创建自定义 runtime
|
|
75
78
|
</Button>
|
|
76
79
|
|
|
77
80
|
{!canCreate && (
|
|
78
|
-
<p className="text-xs text-[var(--color-text-muted)]"
|
|
81
|
+
<p className="text-xs text-[var(--color-text-muted)]">只有本地桌面模式支持创建 runtime。</p>
|
|
79
82
|
)}
|
|
80
83
|
</div>
|
|
81
84
|
);
|
|
82
85
|
};
|
|
83
|
-
|
|
84
|
-
function getHarnessIcon(type: CcAgentType): string {
|
|
85
|
-
switch (type) {
|
|
86
|
-
case 'claudecode':
|
|
87
|
-
return '🤖';
|
|
88
|
-
case 'codex':
|
|
89
|
-
return '🔬';
|
|
90
|
-
case 'cursor':
|
|
91
|
-
return '💻';
|
|
92
|
-
case 'gemini':
|
|
93
|
-
return '💎';
|
|
94
|
-
case 'iflow':
|
|
95
|
-
return '🌊';
|
|
96
|
-
case 'kimi':
|
|
97
|
-
return '🌙';
|
|
98
|
-
case 'devin':
|
|
99
|
-
return '🧑💻';
|
|
100
|
-
case 'opencode':
|
|
101
|
-
return '🔓';
|
|
102
|
-
case 'qoder':
|
|
103
|
-
return '⚡';
|
|
104
|
-
case 'pi':
|
|
105
|
-
return '🥧';
|
|
106
|
-
case 'acp':
|
|
107
|
-
return '🔗';
|
|
108
|
-
case 'tmux':
|
|
109
|
-
return '🖥️';
|
|
110
|
-
default:
|
|
111
|
-
return '📦';
|
|
112
|
-
}
|
|
113
|
-
}
|