@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
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import type { ToolApprovalSettings } from '@shared/types/team';
|
|
2
|
+
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Safe bash command prefixes — commands that never need manual approval
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
|
|
7
|
+
const SAFE_PREFIXES: readonly string[] = [
|
|
8
|
+
// Version control
|
|
9
|
+
'git ',
|
|
10
|
+
'git\t',
|
|
11
|
+
// Package managers
|
|
12
|
+
'pnpm ',
|
|
13
|
+
'npm ',
|
|
14
|
+
'npx ',
|
|
15
|
+
'yarn ',
|
|
16
|
+
// File inspection (read-only)
|
|
17
|
+
'ls',
|
|
18
|
+
'cat ',
|
|
19
|
+
'head ',
|
|
20
|
+
'tail ',
|
|
21
|
+
'wc ',
|
|
22
|
+
'less ',
|
|
23
|
+
'more ',
|
|
24
|
+
// Output
|
|
25
|
+
'echo ',
|
|
26
|
+
'printf ',
|
|
27
|
+
// System info
|
|
28
|
+
'pwd',
|
|
29
|
+
'whoami',
|
|
30
|
+
'hostname',
|
|
31
|
+
'date',
|
|
32
|
+
'uname',
|
|
33
|
+
// Search & find (read-only)
|
|
34
|
+
'find ',
|
|
35
|
+
'grep ',
|
|
36
|
+
'rg ',
|
|
37
|
+
'fd ',
|
|
38
|
+
'ag ',
|
|
39
|
+
// Directory & file info
|
|
40
|
+
'tree ',
|
|
41
|
+
'which ',
|
|
42
|
+
'type ',
|
|
43
|
+
'file ',
|
|
44
|
+
// Text processing (read-only)
|
|
45
|
+
'diff ',
|
|
46
|
+
'sort ',
|
|
47
|
+
'uniq ',
|
|
48
|
+
'tr ',
|
|
49
|
+
'cut ',
|
|
50
|
+
// Path utilities
|
|
51
|
+
'basename ',
|
|
52
|
+
'dirname ',
|
|
53
|
+
'realpath ',
|
|
54
|
+
'readlink ',
|
|
55
|
+
// Environment
|
|
56
|
+
'env',
|
|
57
|
+
'printenv',
|
|
58
|
+
// Scripting one-liners (read-only)
|
|
59
|
+
'node -e',
|
|
60
|
+
'node --eval',
|
|
61
|
+
'python -c',
|
|
62
|
+
'python3 -c',
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
// Dangerous patterns — these OVERRIDE safe prefixes and always need approval
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
|
|
69
|
+
const DANGEROUS_PATTERNS: readonly RegExp[] = [
|
|
70
|
+
/\brm\s/, // rm (with space to avoid false positives like "rmdir" intent)
|
|
71
|
+
/\brm$/, // bare "rm" at end
|
|
72
|
+
/\bsudo\b/,
|
|
73
|
+
/\bchmod\b/,
|
|
74
|
+
/\bchown\b/,
|
|
75
|
+
/\bcurl\b.*\|\s*(ba)?sh/,
|
|
76
|
+
/\bwget\b.*\|\s*(ba)?sh/,
|
|
77
|
+
/\bmkfs\b/,
|
|
78
|
+
/\bdd\b/,
|
|
79
|
+
/\bkill\b/,
|
|
80
|
+
/\bkillall\b/,
|
|
81
|
+
/\bpkill\b/,
|
|
82
|
+
/>\s*\//, // redirect to absolute path root
|
|
83
|
+
/\beval\b/,
|
|
84
|
+
/\bexec\b/,
|
|
85
|
+
/\bformat\b/,
|
|
86
|
+
/\bshutdown\b/,
|
|
87
|
+
/\breboot\b/,
|
|
88
|
+
];
|
|
89
|
+
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
// File edit tools that can be auto-allowed
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
|
|
94
|
+
const FILE_EDIT_TOOLS = new Set(['Edit', 'Write', 'NotebookEdit']);
|
|
95
|
+
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
// Public API
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
|
|
100
|
+
export interface AutoAllowResult {
|
|
101
|
+
autoAllow: boolean;
|
|
102
|
+
reason?: string;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Determines whether a tool call should be auto-allowed based on user settings.
|
|
107
|
+
*
|
|
108
|
+
* Logic:
|
|
109
|
+
* 1. File edit tools — auto-allow if `autoAllowFileEdits` is enabled
|
|
110
|
+
* 2. Bash commands — check dangerous patterns FIRST (always block),
|
|
111
|
+
* then check safe prefixes (auto-allow if `autoAllowSafeBash` is enabled)
|
|
112
|
+
* 3. Everything else — requires manual approval
|
|
113
|
+
*/
|
|
114
|
+
export function shouldAutoAllow(
|
|
115
|
+
settings: ToolApprovalSettings,
|
|
116
|
+
toolName: string,
|
|
117
|
+
toolInput: Record<string, unknown>
|
|
118
|
+
): AutoAllowResult {
|
|
119
|
+
// Auto-allow ALL tools (overrides everything)
|
|
120
|
+
if (settings.autoAllowAll) {
|
|
121
|
+
return { autoAllow: true, reason: 'auto_allow_all' };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// File edit auto-allow
|
|
125
|
+
if (settings.autoAllowFileEdits && FILE_EDIT_TOOLS.has(toolName)) {
|
|
126
|
+
return { autoAllow: true, reason: 'auto_allow_category' };
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Safe bash auto-allow
|
|
130
|
+
if (settings.autoAllowSafeBash && toolName === 'Bash') {
|
|
131
|
+
const command = typeof toolInput.command === 'string' ? toolInput.command.trim() : '';
|
|
132
|
+
if (!command) return { autoAllow: false };
|
|
133
|
+
|
|
134
|
+
// Dangerous patterns override safe prefixes — check FIRST
|
|
135
|
+
for (const pattern of DANGEROUS_PATTERNS) {
|
|
136
|
+
if (pattern.test(command)) {
|
|
137
|
+
return { autoAllow: false };
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Check safe prefixes
|
|
142
|
+
for (const prefix of SAFE_PREFIXES) {
|
|
143
|
+
const trimmedPrefix = prefix.trimEnd();
|
|
144
|
+
if (command === trimmedPrefix || command.startsWith(prefix)) {
|
|
145
|
+
return { autoAllow: true, reason: 'auto_allow_category' };
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return { autoAllow: false };
|
|
151
|
+
}
|
package/src/renderer/App.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useEffect, useMemo
|
|
1
|
+
import React, { useEffect, useMemo } from 'react';
|
|
2
2
|
|
|
3
3
|
import { TooltipProvider } from '@renderer/components/ui/tooltip';
|
|
4
4
|
|
|
@@ -18,14 +18,6 @@ import type { Tab } from './types/tabs';
|
|
|
18
18
|
const PERSIST_KEY = 'hermit:lastTeam';
|
|
19
19
|
const DEFAULT_APP_PATH = '/teams';
|
|
20
20
|
|
|
21
|
-
function safeDecodeURIComponent(value: string): string {
|
|
22
|
-
try {
|
|
23
|
-
return decodeURIComponent(value);
|
|
24
|
-
} catch {
|
|
25
|
-
return value;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
21
|
function getActiveTabFromLayout(activeTabId: string | null, paneLayout: PaneLayout): Tab | null {
|
|
30
22
|
if (!activeTabId) return null;
|
|
31
23
|
for (const pane of paneLayout.panes) {
|
|
@@ -57,6 +49,8 @@ function buildPathForTab(activeTab: Tab | null): string {
|
|
|
57
49
|
return '/tasks';
|
|
58
50
|
case 'dashboard':
|
|
59
51
|
return '/dashboard';
|
|
52
|
+
case 'society':
|
|
53
|
+
return '/society';
|
|
60
54
|
case 'session': {
|
|
61
55
|
if (!activeTab.projectId || !activeTab.sessionId) return DEFAULT_APP_PATH;
|
|
62
56
|
return `/session/${encodeURIComponent(activeTab.projectId)}/${encodeURIComponent(activeTab.sessionId)}`;
|
|
@@ -115,93 +109,20 @@ function useTabPathPersistence() {
|
|
|
115
109
|
activeTabId: s.activeTabId,
|
|
116
110
|
paneLayout: s.paneLayout,
|
|
117
111
|
}));
|
|
118
|
-
const [routeReady, setRouteReady] = useState(false);
|
|
119
|
-
const didInitialRouteRestoreRef = useRef(false);
|
|
120
|
-
|
|
121
|
-
useEffect(() => {
|
|
122
|
-
if (didInitialRouteRestoreRef.current) return;
|
|
123
|
-
didInitialRouteRestoreRef.current = true;
|
|
124
|
-
|
|
125
|
-
const pathname = window.location.pathname;
|
|
126
|
-
const segments = pathname
|
|
127
|
-
.split('/')
|
|
128
|
-
.map((segment) => segment.trim())
|
|
129
|
-
.filter((segment) => segment.length > 0)
|
|
130
|
-
.map(safeDecodeURIComponent);
|
|
131
|
-
const state = useStore.getState();
|
|
132
|
-
|
|
133
|
-
if (segments.length === 0) {
|
|
134
|
-
setRouteReady(true);
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const [route, arg1, arg2] = segments;
|
|
139
|
-
switch (route) {
|
|
140
|
-
case 'team':
|
|
141
|
-
if (arg1) state.openTeamTab(arg1);
|
|
142
|
-
break;
|
|
143
|
-
case 'teams':
|
|
144
|
-
state.openTeamsTab();
|
|
145
|
-
break;
|
|
146
|
-
case 'system-manager':
|
|
147
|
-
void state.openSystemManager();
|
|
148
|
-
break;
|
|
149
|
-
case 'settings':
|
|
150
|
-
state.openSettingsTab();
|
|
151
|
-
break;
|
|
152
|
-
case 'extensions':
|
|
153
|
-
state.openExtensionsTab();
|
|
154
|
-
break;
|
|
155
|
-
case 'schedules':
|
|
156
|
-
state.openSchedulesTab();
|
|
157
|
-
break;
|
|
158
|
-
case 'tasks':
|
|
159
|
-
state.openTasksTab();
|
|
160
|
-
break;
|
|
161
|
-
case 'dashboard':
|
|
162
|
-
state.openDashboard();
|
|
163
|
-
break;
|
|
164
|
-
case 'session':
|
|
165
|
-
if (arg1 && arg2) {
|
|
166
|
-
state.navigateToSession(arg1, arg2);
|
|
167
|
-
}
|
|
168
|
-
break;
|
|
169
|
-
case 'notifications':
|
|
170
|
-
state.openTab({ type: 'notifications', label: '通知' });
|
|
171
|
-
break;
|
|
172
|
-
case 'graph':
|
|
173
|
-
if (arg1) {
|
|
174
|
-
state.openTab({ type: 'graph', label: arg1, teamName: arg1 });
|
|
175
|
-
}
|
|
176
|
-
break;
|
|
177
|
-
case 'report':
|
|
178
|
-
if (arg1 && arg2) {
|
|
179
|
-
state.openTab({
|
|
180
|
-
type: 'report',
|
|
181
|
-
label: 'Session Report',
|
|
182
|
-
projectId: arg1,
|
|
183
|
-
sessionId: arg2,
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
break;
|
|
187
|
-
default:
|
|
188
|
-
break;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
setRouteReady(true);
|
|
192
|
-
}, []);
|
|
193
112
|
|
|
194
113
|
const activeTab = useMemo(
|
|
195
114
|
() => getActiveTabFromLayout(activeTabId, paneLayout),
|
|
196
115
|
[activeTabId, paneLayout]
|
|
197
116
|
);
|
|
198
117
|
|
|
118
|
+
// The initial route is restored before first render (main.tsx →
|
|
119
|
+
// restoreInitialRoute), so this hook only keeps the URL in sync as the active
|
|
120
|
+
// tab changes. No post-mount restore, no routeReady gate.
|
|
199
121
|
useEffect(() => {
|
|
200
|
-
if (!routeReady) return;
|
|
201
122
|
const nextPath = buildPathForTab(activeTab);
|
|
202
123
|
if (window.location.pathname === nextPath) return;
|
|
203
124
|
window.history.replaceState(null, '', nextPath);
|
|
204
|
-
}, [activeTab
|
|
125
|
+
}, [activeTab]);
|
|
205
126
|
}
|
|
206
127
|
|
|
207
128
|
declare global {
|
|
@@ -215,6 +136,7 @@ declare global {
|
|
|
215
136
|
const SPLASH_MIN_DURATION_MS = 2800;
|
|
216
137
|
const SPLASH_ENHANCED_HOLD_MS = 800;
|
|
217
138
|
const SPLASH_FADE_MS = 480;
|
|
139
|
+
const SPLASH_ROUTE_RESTORE_FADE_MS = 120;
|
|
218
140
|
const SPLASH_REDUCED_MIN_DURATION_MS = 600;
|
|
219
141
|
const SPLASH_REDUCED_HOLD_MS = 200;
|
|
220
142
|
const SPLASH_REDUCED_FADE_MS = 180;
|
|
@@ -240,9 +162,22 @@ export const App = (): React.JSX.Element => {
|
|
|
240
162
|
const enhancedStartedAt = window.__claudeTeamsSplashEnhancedStartedAt ?? performance.now();
|
|
241
163
|
const elapsed = performance.now() - startedAt;
|
|
242
164
|
const enhancedElapsed = performance.now() - enhancedStartedAt;
|
|
243
|
-
const
|
|
244
|
-
const
|
|
245
|
-
|
|
165
|
+
const routeRestored = window.location.pathname !== '/' && window.location.pathname !== '';
|
|
166
|
+
const minDuration = routeRestored
|
|
167
|
+
? 0
|
|
168
|
+
: reducedMotion
|
|
169
|
+
? SPLASH_REDUCED_MIN_DURATION_MS
|
|
170
|
+
: SPLASH_MIN_DURATION_MS;
|
|
171
|
+
const enhancedHold = routeRestored
|
|
172
|
+
? 0
|
|
173
|
+
: reducedMotion
|
|
174
|
+
? SPLASH_REDUCED_HOLD_MS
|
|
175
|
+
: SPLASH_ENHANCED_HOLD_MS;
|
|
176
|
+
const fadeDuration = routeRestored
|
|
177
|
+
? SPLASH_ROUTE_RESTORE_FADE_MS
|
|
178
|
+
: reducedMotion
|
|
179
|
+
? SPLASH_REDUCED_FADE_MS
|
|
180
|
+
: SPLASH_FADE_MS;
|
|
246
181
|
const avatarReadyMaxWait = reducedMotion
|
|
247
182
|
? SPLASH_REDUCED_AVATAR_READY_MAX_WAIT_MS
|
|
248
183
|
: SPLASH_AVATAR_READY_MAX_WAIT_MS;
|
|
@@ -21,6 +21,8 @@ import type {
|
|
|
21
21
|
BoardTaskLogStreamSummary,
|
|
22
22
|
CcSession,
|
|
23
23
|
CcSessionDetail,
|
|
24
|
+
LoopSessionRequest,
|
|
25
|
+
LoopSessionResponse,
|
|
24
26
|
ClaudeMdFileInfo,
|
|
25
27
|
ClaudeRootFolderSelection,
|
|
26
28
|
ClaudeRootInfo,
|
|
@@ -34,12 +36,14 @@ import type {
|
|
|
34
36
|
CrossTeamAPI,
|
|
35
37
|
CrossTeamMessage,
|
|
36
38
|
CrossTeamSendResult,
|
|
39
|
+
DiscoverableWorker,
|
|
37
40
|
ElectronAPI,
|
|
38
41
|
FileChangeEvent,
|
|
39
42
|
GlobalTask,
|
|
40
43
|
HttpServerAPI,
|
|
41
44
|
HttpServerStatus,
|
|
42
45
|
KanbanColumnId,
|
|
46
|
+
LoopAssetsSnapshot,
|
|
43
47
|
MachineProfile,
|
|
44
48
|
MachineRuntimeProcess,
|
|
45
49
|
MemberFullStats,
|
|
@@ -108,6 +112,12 @@ import type { AgentConfig } from '@shared/types/api';
|
|
|
108
112
|
import type { CliProviderStatus } from '@shared/types/cliInstaller';
|
|
109
113
|
import type { EditorAPI, ProjectAPI, WorkspaceListResponse } from '@shared/types/editor';
|
|
110
114
|
import type {
|
|
115
|
+
CapabilityCommandPromptRequest,
|
|
116
|
+
CapabilityCommandPromptResult,
|
|
117
|
+
CapabilityPackExportRequest,
|
|
118
|
+
CapabilityPackImportRequest,
|
|
119
|
+
CapabilityPackListResult,
|
|
120
|
+
CapabilityPackMutationResult,
|
|
111
121
|
EnrichedPlugin,
|
|
112
122
|
InstalledMcpEntry,
|
|
113
123
|
McpCatalogItem,
|
|
@@ -240,8 +250,8 @@ export class HttpAPIClient implements ElectronAPI {
|
|
|
240
250
|
return JSON.parse(text, (key, value) => HttpAPIClient.reviveDates(key, value)) as T;
|
|
241
251
|
}
|
|
242
252
|
|
|
243
|
-
private async get<T>(path: string): Promise<T> {
|
|
244
|
-
const { controller, timeout } = this.createTimeoutController(
|
|
253
|
+
private async get<T>(path: string, timeoutMs = 10_000): Promise<T> {
|
|
254
|
+
const { controller, timeout } = this.createTimeoutController(timeoutMs);
|
|
245
255
|
try {
|
|
246
256
|
const res = await fetch(`${this.baseUrl}${path}`, { signal: controller.signal });
|
|
247
257
|
return this.parseJson<T>(res);
|
|
@@ -250,8 +260,8 @@ export class HttpAPIClient implements ElectronAPI {
|
|
|
250
260
|
}
|
|
251
261
|
}
|
|
252
262
|
|
|
253
|
-
private async post<T>(path: string, body?: unknown): Promise<T> {
|
|
254
|
-
const { controller, timeout } = this.createTimeoutController(
|
|
263
|
+
private async post<T>(path: string, body?: unknown, timeoutMs = 10_000): Promise<T> {
|
|
264
|
+
const { controller, timeout } = this.createTimeoutController(timeoutMs);
|
|
255
265
|
try {
|
|
256
266
|
const res = await fetch(`${this.baseUrl}${path}`, {
|
|
257
267
|
method: 'POST',
|
|
@@ -280,8 +290,8 @@ export class HttpAPIClient implements ElectronAPI {
|
|
|
280
290
|
}
|
|
281
291
|
}
|
|
282
292
|
|
|
283
|
-
private async del<T>(path: string, body?: unknown): Promise<T> {
|
|
284
|
-
const { controller, timeout } = this.createTimeoutController(
|
|
293
|
+
private async del<T>(path: string, body?: unknown, timeoutMs = 10_000): Promise<T> {
|
|
294
|
+
const { controller, timeout } = this.createTimeoutController(timeoutMs);
|
|
285
295
|
try {
|
|
286
296
|
const res = await fetch(`${this.baseUrl}${path}`, {
|
|
287
297
|
method: 'DELETE',
|
|
@@ -295,8 +305,8 @@ export class HttpAPIClient implements ElectronAPI {
|
|
|
295
305
|
}
|
|
296
306
|
}
|
|
297
307
|
|
|
298
|
-
private async put<T>(path: string, body?: unknown): Promise<T> {
|
|
299
|
-
const { controller, timeout } = this.createTimeoutController(
|
|
308
|
+
private async put<T>(path: string, body?: unknown, timeoutMs = 10_000): Promise<T> {
|
|
309
|
+
const { controller, timeout } = this.createTimeoutController(timeoutMs);
|
|
300
310
|
try {
|
|
301
311
|
const res = await fetch(`${this.baseUrl}${path}`, {
|
|
302
312
|
method: 'PUT',
|
|
@@ -310,8 +320,8 @@ export class HttpAPIClient implements ElectronAPI {
|
|
|
310
320
|
}
|
|
311
321
|
}
|
|
312
322
|
|
|
313
|
-
private async patch<T>(path: string, body?: unknown): Promise<T> {
|
|
314
|
-
const { controller, timeout } = this.createTimeoutController(
|
|
323
|
+
private async patch<T>(path: string, body?: unknown, timeoutMs = 10_000): Promise<T> {
|
|
324
|
+
const { controller, timeout } = this.createTimeoutController(timeoutMs);
|
|
315
325
|
try {
|
|
316
326
|
const res = await fetch(`${this.baseUrl}${path}`, {
|
|
317
327
|
method: 'PATCH',
|
|
@@ -325,8 +335,8 @@ export class HttpAPIClient implements ElectronAPI {
|
|
|
325
335
|
}
|
|
326
336
|
}
|
|
327
337
|
|
|
328
|
-
private async delete<T>(path: string): Promise<T> {
|
|
329
|
-
const { controller, timeout } = this.createTimeoutController(
|
|
338
|
+
private async delete<T>(path: string, timeoutMs = 10_000): Promise<T> {
|
|
339
|
+
const { controller, timeout } = this.createTimeoutController(timeoutMs);
|
|
330
340
|
try {
|
|
331
341
|
const res = await fetch(`${this.baseUrl}${path}`, {
|
|
332
342
|
method: 'DELETE',
|
|
@@ -535,11 +545,11 @@ export class HttpAPIClient implements ElectronAPI {
|
|
|
535
545
|
work_dir?: string;
|
|
536
546
|
agent_type?: string;
|
|
537
547
|
}
|
|
538
|
-
): Promise<{ message: string; restart_required: boolean }> => {
|
|
539
|
-
const res = await this.
|
|
548
|
+
): Promise<{ message: string; restart_required: boolean; restart_handled?: boolean }> => {
|
|
549
|
+
const res = await this.postLong<{
|
|
540
550
|
ok: boolean;
|
|
541
|
-
data: { message: string; restart_required: boolean };
|
|
542
|
-
}>(`/api/projects/${encodeURIComponent(projectName)}/add-platform`, body);
|
|
551
|
+
data: { message: string; restart_required: boolean; restart_handled?: boolean };
|
|
552
|
+
}>(`/api/projects/${encodeURIComponent(projectName)}/add-platform`, body, 120_000);
|
|
543
553
|
return res.data;
|
|
544
554
|
},
|
|
545
555
|
};
|
|
@@ -1093,11 +1103,25 @@ export class HttpAPIClient implements ElectronAPI {
|
|
|
1093
1103
|
};
|
|
1094
1104
|
|
|
1095
1105
|
teams: TeamsAPI = {
|
|
1096
|
-
list: async (): Promise<TeamSummary[]> => this.get<TeamSummary[]>('/api/teams'),
|
|
1106
|
+
list: async (): Promise<TeamSummary[]> => this.get<TeamSummary[]>('/api/teams', 30_000),
|
|
1097
1107
|
ensureSystemManager: async (): Promise<SystemManagerSummary> =>
|
|
1098
1108
|
this.post<SystemManagerSummary>('/api/system-manager/ensure'),
|
|
1099
1109
|
getData: async (teamName: string): Promise<TeamViewSnapshot> =>
|
|
1100
|
-
this.get<TeamViewSnapshot>(`/api/teams/${encodeURIComponent(teamName)}/data
|
|
1110
|
+
this.get<TeamViewSnapshot>(`/api/teams/${encodeURIComponent(teamName)}/data`, 30_000),
|
|
1111
|
+
getLoopAssets: async (teamName: string): Promise<LoopAssetsSnapshot> =>
|
|
1112
|
+
this.get<LoopAssetsSnapshot>(
|
|
1113
|
+
`/api/teams/${encodeURIComponent(teamName)}/loop-assets`,
|
|
1114
|
+
30_000
|
|
1115
|
+
),
|
|
1116
|
+
createLoopSession: async (
|
|
1117
|
+
teamName: string,
|
|
1118
|
+
request: LoopSessionRequest
|
|
1119
|
+
): Promise<LoopSessionResponse> =>
|
|
1120
|
+
this.postLong<LoopSessionResponse>(
|
|
1121
|
+
`/api/teams/${encodeURIComponent(teamName)}/loop-session`,
|
|
1122
|
+
request,
|
|
1123
|
+
30_000
|
|
1124
|
+
),
|
|
1101
1125
|
getTaskChangePresence: async (): Promise<
|
|
1102
1126
|
Record<string, 'has_changes' | 'no_changes' | 'unknown'>
|
|
1103
1127
|
> => {
|
|
@@ -1395,7 +1419,15 @@ export class HttpAPIClient implements ElectronAPI {
|
|
|
1395
1419
|
teamName: string,
|
|
1396
1420
|
config: TeamUpdateConfigRequest
|
|
1397
1421
|
): Promise<TeamConfig> => {
|
|
1398
|
-
|
|
1422
|
+
const result = await this.put<TeamConfig>(
|
|
1423
|
+
`/api/teams/${encodeURIComponent(teamName)}/config`,
|
|
1424
|
+
config,
|
|
1425
|
+
120_000
|
|
1426
|
+
);
|
|
1427
|
+
if (result.ccSyncError) {
|
|
1428
|
+
throw new Error(`配置已保存到本地,但同步到运行时失败:${result.ccSyncError}`);
|
|
1429
|
+
}
|
|
1430
|
+
return result;
|
|
1399
1431
|
},
|
|
1400
1432
|
addTaskComment: async (
|
|
1401
1433
|
teamName: string,
|
|
@@ -1477,7 +1509,9 @@ export class HttpAPIClient implements ElectronAPI {
|
|
|
1477
1509
|
},
|
|
1478
1510
|
restartMember: async (teamName: string, memberName: string): Promise<void> => {
|
|
1479
1511
|
await this.post(
|
|
1480
|
-
`/api/teams/${encodeURIComponent(teamName)}/members/${encodeURIComponent(memberName)}/restart
|
|
1512
|
+
`/api/teams/${encodeURIComponent(teamName)}/members/${encodeURIComponent(memberName)}/restart`,
|
|
1513
|
+
undefined,
|
|
1514
|
+
30_000
|
|
1481
1515
|
);
|
|
1482
1516
|
},
|
|
1483
1517
|
skipMemberForLaunch: async (teamName: string, memberName: string): Promise<void> => {
|
|
@@ -1654,6 +1688,28 @@ export class HttpAPIClient implements ElectronAPI {
|
|
|
1654
1688
|
this.get<CrossTeamMessage[]>(`/api/cross-team/outbox/${encodeURIComponent(teamName)}`),
|
|
1655
1689
|
};
|
|
1656
1690
|
|
|
1691
|
+
workers = {
|
|
1692
|
+
list: () => this.get<{ workers: DiscoverableWorker[] }>('/api/workers'),
|
|
1693
|
+
invoke: (
|
|
1694
|
+
workerId: string,
|
|
1695
|
+
request: {
|
|
1696
|
+
fromTeam?: string;
|
|
1697
|
+
text: string;
|
|
1698
|
+
summary?: string;
|
|
1699
|
+
sessionName?: string;
|
|
1700
|
+
reuse?: boolean;
|
|
1701
|
+
sessionKey?: string;
|
|
1702
|
+
}
|
|
1703
|
+
) =>
|
|
1704
|
+
this.postLong<{
|
|
1705
|
+
ok: boolean;
|
|
1706
|
+
worker: DiscoverableWorker;
|
|
1707
|
+
session: CcSession;
|
|
1708
|
+
reused: boolean;
|
|
1709
|
+
messageSent: boolean;
|
|
1710
|
+
}>(`/api/workers/${encodeURIComponent(workerId)}/invoke`, request, 30_000),
|
|
1711
|
+
};
|
|
1712
|
+
|
|
1657
1713
|
// Collaboration board API
|
|
1658
1714
|
collab = {
|
|
1659
1715
|
getBoard: () => this.get<{ tasks: CollabTask[] }>('/api/collab/board'),
|
|
@@ -2015,14 +2071,19 @@ export class HttpAPIClient implements ElectronAPI {
|
|
|
2015
2071
|
if (forceRefresh) params.set('forceRefresh', 'true');
|
|
2016
2072
|
const qs = params.toString();
|
|
2017
2073
|
const result = await this.get<{ success: boolean; data?: EnrichedPlugin[]; error?: string }>(
|
|
2018
|
-
`/api/extensions/plugins${qs ? `?${qs}` : ''}
|
|
2074
|
+
`/api/extensions/plugins${qs ? `?${qs}` : ''}`,
|
|
2075
|
+
// Catalog assembly scans local installs + remote registries (GitHub),
|
|
2076
|
+
// which routinely exceeds the default 10s — match the team-endpoint
|
|
2077
|
+
// 30s budget so the Extensions store doesn't time out on first open.
|
|
2078
|
+
30_000
|
|
2019
2079
|
);
|
|
2020
2080
|
if (!result.success) throw new Error(result.error ?? 'Failed to get plugins');
|
|
2021
2081
|
return result.data ?? [];
|
|
2022
2082
|
},
|
|
2023
2083
|
getReadme: async (pluginId: string) => {
|
|
2024
2084
|
const result = await this.get<{ success: boolean; data?: string | null; error?: string }>(
|
|
2025
|
-
`/api/extensions/plugins/${encodeURIComponent(pluginId)}/readme
|
|
2085
|
+
`/api/extensions/plugins/${encodeURIComponent(pluginId)}/readme`,
|
|
2086
|
+
30_000
|
|
2026
2087
|
);
|
|
2027
2088
|
if (!result.success) throw new Error(result.error ?? 'Failed to get readme');
|
|
2028
2089
|
return result.data ?? null;
|
|
@@ -2178,6 +2239,47 @@ export class HttpAPIClient implements ElectronAPI {
|
|
|
2178
2239
|
},
|
|
2179
2240
|
};
|
|
2180
2241
|
|
|
2242
|
+
capabilityPacks = {
|
|
2243
|
+
list: async () => {
|
|
2244
|
+
const result = await this.get<{
|
|
2245
|
+
success: boolean;
|
|
2246
|
+
data?: CapabilityPackListResult;
|
|
2247
|
+
error?: string;
|
|
2248
|
+
}>('/api/extensions/capability-packs');
|
|
2249
|
+
if (!result.success)
|
|
2250
|
+
return { packs: [], warnings: result.error ? [result.error] : [], rootDir: '' };
|
|
2251
|
+
return result.data ?? { packs: [], warnings: [], rootDir: '' };
|
|
2252
|
+
},
|
|
2253
|
+
importPack: async (request: CapabilityPackImportRequest) => {
|
|
2254
|
+
const result = await this.post<{
|
|
2255
|
+
success: boolean;
|
|
2256
|
+
data?: CapabilityPackMutationResult;
|
|
2257
|
+
error?: string;
|
|
2258
|
+
}>('/api/extensions/capability-packs/import', request);
|
|
2259
|
+
if (!result.success) throw new Error(result.error ?? 'Import capability pack failed');
|
|
2260
|
+
return result.data ?? { pack: null, warnings: [] };
|
|
2261
|
+
},
|
|
2262
|
+
exportPack: async (request: CapabilityPackExportRequest) => {
|
|
2263
|
+
const result = await this.post<{
|
|
2264
|
+
success: boolean;
|
|
2265
|
+
data?: CapabilityPackMutationResult;
|
|
2266
|
+
error?: string;
|
|
2267
|
+
}>('/api/extensions/capability-packs/export', request);
|
|
2268
|
+
if (!result.success) throw new Error(result.error ?? 'Export capability pack failed');
|
|
2269
|
+
return result.data ?? { pack: null, warnings: [] };
|
|
2270
|
+
},
|
|
2271
|
+
getCommandPrompt: async (request: CapabilityCommandPromptRequest) => {
|
|
2272
|
+
const result = await this.post<{
|
|
2273
|
+
success: boolean;
|
|
2274
|
+
data?: CapabilityCommandPromptResult;
|
|
2275
|
+
error?: string;
|
|
2276
|
+
}>('/api/extensions/capability-packs/command-prompt', request);
|
|
2277
|
+
if (!result.success) throw new Error(result.error ?? 'Load capability command failed');
|
|
2278
|
+
if (!result.data) throw new Error('Load capability command failed');
|
|
2279
|
+
return result.data;
|
|
2280
|
+
},
|
|
2281
|
+
};
|
|
2282
|
+
|
|
2181
2283
|
skills = {
|
|
2182
2284
|
list: async (projectPath?: string) => {
|
|
2183
2285
|
const params = new URLSearchParams();
|
|
@@ -2305,44 +2407,22 @@ export class HttpAPIClient implements ElectronAPI {
|
|
|
2305
2407
|
getConfig: () => this.get('/api/system-manager/config'),
|
|
2306
2408
|
updateConfig: (patch) => this.put('/api/system-manager/config', patch),
|
|
2307
2409
|
listWorkflowPrompts: (folder) => this.post('/api/system-manager/workflows/list', { folder }),
|
|
2308
|
-
readWorkflowPrompt: (
|
|
2410
|
+
readWorkflowPrompt: (folder, id) =>
|
|
2411
|
+
this.post('/api/system-manager/workflows/read', { folder, id }),
|
|
2309
2412
|
};
|
|
2310
2413
|
|
|
2311
2414
|
// ---------------------------------------------------------------------------
|
|
2312
|
-
// Terminal (
|
|
2415
|
+
// Terminal (system/default terminal)
|
|
2313
2416
|
// ---------------------------------------------------------------------------
|
|
2314
2417
|
|
|
2315
2418
|
terminal: TerminalAPI = {
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
void this.post(`/api/terminal/${encodeURIComponent(ptyId)}/write`, { data });
|
|
2322
|
-
},
|
|
2323
|
-
resize: (ptyId: string, cols: number, rows: number): void => {
|
|
2324
|
-
void this.post(`/api/terminal/${encodeURIComponent(ptyId)}/resize`, { cols, rows });
|
|
2325
|
-
},
|
|
2326
|
-
kill: async (ptyId: string): Promise<void> => {
|
|
2327
|
-
await this.del(`/api/terminal/${encodeURIComponent(ptyId)}`);
|
|
2328
|
-
},
|
|
2329
|
-
openExternal: async (options: { command: string; args?: string[]; cwd?: string }): Promise<void> => {
|
|
2419
|
+
openExternal: async (options: {
|
|
2420
|
+
command: string;
|
|
2421
|
+
args?: string[];
|
|
2422
|
+
cwd?: string;
|
|
2423
|
+
}): Promise<void> => {
|
|
2330
2424
|
await this.post('/api/terminal/open-external', options);
|
|
2331
2425
|
},
|
|
2332
|
-
onData: (callback): (() => void) =>
|
|
2333
|
-
this.addEventListener('terminal:data', (data: unknown) => {
|
|
2334
|
-
const event = data as { ptyId?: string; data?: string };
|
|
2335
|
-
if (event.ptyId && typeof event.data === 'string') {
|
|
2336
|
-
callback(null, event.ptyId, event.data);
|
|
2337
|
-
}
|
|
2338
|
-
}),
|
|
2339
|
-
onExit: (callback): (() => void) =>
|
|
2340
|
-
this.addEventListener('terminal:exit', (data: unknown) => {
|
|
2341
|
-
const event = data as { ptyId?: string; exitCode?: number };
|
|
2342
|
-
if (event.ptyId && typeof event.exitCode === 'number') {
|
|
2343
|
-
callback(null, event.ptyId, event.exitCode);
|
|
2344
|
-
}
|
|
2345
|
-
}),
|
|
2346
2426
|
};
|
|
2347
2427
|
|
|
2348
2428
|
// ---------------------------------------------------------------------------
|
|
@@ -5,11 +5,7 @@
|
|
|
5
5
|
* cc-connect sidecar is the source of truth for provider/channel management.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import type {
|
|
9
|
-
CCSwitchListResponse,
|
|
10
|
-
GlobalProvider,
|
|
11
|
-
ProviderPresetsResponse,
|
|
12
|
-
} from '@shared/types/providers';
|
|
8
|
+
import type { GlobalProvider, ProviderPresetsResponse } from '@shared/types/providers';
|
|
13
9
|
|
|
14
10
|
function stringifyProviderPatch(patch: Partial<GlobalProvider>): string {
|
|
15
11
|
return JSON.stringify(patch, (_key, value: unknown) => (value === undefined ? null : value));
|
|
@@ -45,7 +41,7 @@ async function request<T>(path: string, init?: RequestInit & { timeoutMs?: numbe
|
|
|
45
41
|
if (!contentType.includes('json') || !text.trim().startsWith('{')) {
|
|
46
42
|
throw new Error(
|
|
47
43
|
`Provider API ${path} 返回了非 JSON 响应 (HTTP ${res.status})。` +
|
|
48
|
-
|
|
44
|
+
'请检查 cc-connect 是否正在运行且支持该端点。'
|
|
49
45
|
);
|
|
50
46
|
}
|
|
51
47
|
|
|
@@ -53,7 +49,9 @@ async function request<T>(path: string, init?: RequestInit & { timeoutMs?: numbe
|
|
|
53
49
|
try {
|
|
54
50
|
json = JSON.parse(text) as typeof json;
|
|
55
51
|
} catch (e) {
|
|
56
|
-
throw new Error(
|
|
52
|
+
throw new Error(
|
|
53
|
+
`Provider API ${path} 返回了无效 JSON: ${e instanceof Error ? e.message : String(e)}`
|
|
54
|
+
);
|
|
57
55
|
}
|
|
58
56
|
|
|
59
57
|
if (!res.ok || json.ok === false) {
|
|
@@ -86,13 +84,4 @@ export const providersApi = {
|
|
|
86
84
|
timeoutMs: 20_000,
|
|
87
85
|
});
|
|
88
86
|
},
|
|
89
|
-
listCCSwitch(): Promise<CCSwitchListResponse> {
|
|
90
|
-
return request('/providers/cc-switch');
|
|
91
|
-
},
|
|
92
|
-
importCCSwitch(names: string[]): Promise<{ imported: string[]; skipped: string[] }> {
|
|
93
|
-
return request('/providers/cc-switch', {
|
|
94
|
-
method: 'POST',
|
|
95
|
-
body: JSON.stringify({ names }),
|
|
96
|
-
});
|
|
97
|
-
},
|
|
98
87
|
};
|