@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
|
@@ -15,9 +15,11 @@ import { nameColorSet } from '@renderer/utils/projectColor';
|
|
|
15
15
|
import {
|
|
16
16
|
Activity,
|
|
17
17
|
Bell,
|
|
18
|
+
Bot,
|
|
18
19
|
Calendar,
|
|
19
20
|
FileText,
|
|
20
21
|
LayoutDashboard,
|
|
22
|
+
MessageSquare,
|
|
21
23
|
Network,
|
|
22
24
|
Pin,
|
|
23
25
|
Puzzle,
|
|
@@ -56,6 +58,8 @@ const TAB_ICONS = {
|
|
|
56
58
|
schedules: Calendar,
|
|
57
59
|
tasks: Calendar,
|
|
58
60
|
graph: Network,
|
|
61
|
+
chat: MessageSquare,
|
|
62
|
+
society: Bot,
|
|
59
63
|
} as const;
|
|
60
64
|
|
|
61
65
|
export const SortableTab = ({
|
|
@@ -6,10 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|
import { useMemo, useState } from 'react';
|
|
8
8
|
|
|
9
|
-
import { api } from '@renderer/api';
|
|
10
9
|
import { Tooltip, TooltipContent, TooltipTrigger } from '@renderer/components/ui/tooltip';
|
|
11
10
|
import { useStore } from '@renderer/store';
|
|
12
|
-
import { ListTodo, PanelRight, Puzzle, Users } from 'lucide-react';
|
|
11
|
+
import { ListTodo, MessageCircle, PanelRight, Puzzle, Users } from 'lucide-react';
|
|
13
12
|
import { useShallow } from 'zustand/react/shallow';
|
|
14
13
|
|
|
15
14
|
import { MoreMenu } from './MoreMenu';
|
|
@@ -17,6 +16,7 @@ import { MoreMenu } from './MoreMenu';
|
|
|
17
16
|
export const TabBarActions = (): React.JSX.Element => {
|
|
18
17
|
const {
|
|
19
18
|
unreadCount,
|
|
19
|
+
openChatTab,
|
|
20
20
|
openExtensionsTab,
|
|
21
21
|
openTasksTab,
|
|
22
22
|
openTeamsTab,
|
|
@@ -28,6 +28,7 @@ export const TabBarActions = (): React.JSX.Element => {
|
|
|
28
28
|
} = useStore(
|
|
29
29
|
useShallow((s) => ({
|
|
30
30
|
unreadCount: s.unreadCount,
|
|
31
|
+
openChatTab: s.openChatTab,
|
|
31
32
|
openExtensionsTab: s.openExtensionsTab,
|
|
32
33
|
openTasksTab: s.openTasksTab,
|
|
33
34
|
openTeamsTab: s.openTeamsTab,
|
|
@@ -43,7 +44,7 @@ export const TabBarActions = (): React.JSX.Element => {
|
|
|
43
44
|
const [teamsHover, setTeamsHover] = useState(false);
|
|
44
45
|
const [extensionsHover, setExtensionsHover] = useState(false);
|
|
45
46
|
const [tasksHover, setTasksHover] = useState(false);
|
|
46
|
-
const [
|
|
47
|
+
const [chatHover, setChatHover] = useState(false);
|
|
47
48
|
const [expandHover, setExpandHover] = useState(false);
|
|
48
49
|
|
|
49
50
|
// Derive active tab and session detail for MoreMenu
|
|
@@ -118,28 +119,24 @@ export const TabBarActions = (): React.JSX.Element => {
|
|
|
118
119
|
<TooltipContent side="bottom">任务</TooltipContent>
|
|
119
120
|
</Tooltip>
|
|
120
121
|
|
|
121
|
-
{/*
|
|
122
|
+
{/* Feishu group QR */}
|
|
122
123
|
<Tooltip>
|
|
123
124
|
<TooltipTrigger asChild>
|
|
124
125
|
<button
|
|
125
|
-
onClick={
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
onMouseEnter={() => setGithubHover(true)}
|
|
129
|
-
onMouseLeave={() => setGithubHover(false)}
|
|
126
|
+
onClick={openChatTab}
|
|
127
|
+
onMouseEnter={() => setChatHover(true)}
|
|
128
|
+
onMouseLeave={() => setChatHover(false)}
|
|
130
129
|
className="rounded-md p-2 transition-colors"
|
|
131
130
|
style={{
|
|
132
|
-
color:
|
|
133
|
-
backgroundColor:
|
|
131
|
+
color: chatHover ? 'var(--color-text)' : 'var(--color-text-muted)',
|
|
132
|
+
backgroundColor: chatHover ? 'var(--color-surface-raised)' : 'transparent',
|
|
134
133
|
}}
|
|
135
|
-
aria-label="
|
|
134
|
+
aria-label="加入飞书群"
|
|
136
135
|
>
|
|
137
|
-
<
|
|
138
|
-
<path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12Z" />
|
|
139
|
-
</svg>
|
|
136
|
+
<MessageCircle className="size-4" />
|
|
140
137
|
</button>
|
|
141
138
|
</TooltipTrigger>
|
|
142
|
-
<TooltipContent side="bottom"
|
|
139
|
+
<TooltipContent side="bottom">加入飞书群</TooltipContent>
|
|
143
140
|
</Tooltip>
|
|
144
141
|
|
|
145
142
|
{/* More menu (Notifications, Settings, Search, Export, Analyze) */}
|
|
@@ -16,12 +16,11 @@ import {
|
|
|
16
16
|
import { Input } from '@renderer/components/ui/input';
|
|
17
17
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@renderer/components/ui/tabs';
|
|
18
18
|
import { emitOpenHermitEvent, OPEN_HERMIT_EVENTS } from '@renderer/utils/openHermitEvents';
|
|
19
|
-
import {
|
|
19
|
+
import { Loader2, Pencil, Plus, RefreshCw, Trash2 } from 'lucide-react';
|
|
20
20
|
|
|
21
21
|
import type { CliProviderId, CliProviderStatus } from '@shared/types';
|
|
22
22
|
import type {
|
|
23
23
|
AgentType,
|
|
24
|
-
CCSwitchProvider,
|
|
25
24
|
GlobalProvider,
|
|
26
25
|
ProviderModelEntry,
|
|
27
26
|
ProviderPreset,
|
|
@@ -214,23 +213,6 @@ function formFromPreset(preset: ProviderPreset, fallbackAgentType: AgentType): P
|
|
|
214
213
|
};
|
|
215
214
|
}
|
|
216
215
|
|
|
217
|
-
function formFromCCSwitch(
|
|
218
|
-
provider: CCSwitchProvider,
|
|
219
|
-
fallbackAgentType: AgentType
|
|
220
|
-
): ProviderFormState {
|
|
221
|
-
const agentType = normalizeAgentType(provider.app_type) ?? fallbackAgentType;
|
|
222
|
-
return {
|
|
223
|
-
...emptyForm(agentType),
|
|
224
|
-
name: provider.name,
|
|
225
|
-
apiKey: provider.api_key ?? '',
|
|
226
|
-
baseUrl: provider.base_url ?? '',
|
|
227
|
-
model: provider.model ?? '',
|
|
228
|
-
agentTypes: [agentType],
|
|
229
|
-
agentModels: provider.model ? { [agentType]: provider.model } : {},
|
|
230
|
-
endpoints: provider.base_url ? { [agentType]: provider.base_url } : {},
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
|
|
234
216
|
function formToProvider(form: ProviderFormState, originalName?: string): GlobalProvider {
|
|
235
217
|
const agentTypes = form.agentTypes.length > 0 ? form.agentTypes : undefined;
|
|
236
218
|
const endpoints = Object.fromEntries(
|
|
@@ -271,11 +253,8 @@ export const ProviderRuntimeSettingsDialog = ({
|
|
|
271
253
|
const harnessLabel = CLI_PROVIDER_LABELS[initialProviderId] ?? initialProviderId;
|
|
272
254
|
const [providers, setProviders] = useState<GlobalProvider[]>([]);
|
|
273
255
|
const [presets, setPresets] = useState<ProviderPreset[]>([]);
|
|
274
|
-
const [ccSwitchProviders, setCcSwitchProviders] = useState<CCSwitchProvider[]>([]);
|
|
275
|
-
const [ccSwitchAvailable, setCcSwitchAvailable] = useState<boolean | null>(null);
|
|
276
256
|
const [loading, setLoading] = useState(false);
|
|
277
257
|
const [presetsLoading, setPresetsLoading] = useState(false);
|
|
278
|
-
const [ccSwitchLoading, setCcSwitchLoading] = useState(false);
|
|
279
258
|
const [saving, setSaving] = useState(false);
|
|
280
259
|
const [error, setError] = useState<string | null>(null);
|
|
281
260
|
const [formError, setFormError] = useState<string | null>(null);
|
|
@@ -313,20 +292,6 @@ export const ProviderRuntimeSettingsDialog = ({
|
|
|
313
292
|
}
|
|
314
293
|
}, []);
|
|
315
294
|
|
|
316
|
-
const refreshCCSwitch = useCallback(async (): Promise<void> => {
|
|
317
|
-
setCcSwitchLoading(true);
|
|
318
|
-
try {
|
|
319
|
-
const result = await providersApi.listCCSwitch();
|
|
320
|
-
setCcSwitchProviders(result.providers ?? []);
|
|
321
|
-
setCcSwitchAvailable(result.available);
|
|
322
|
-
} catch {
|
|
323
|
-
setCcSwitchProviders([]);
|
|
324
|
-
setCcSwitchAvailable(false);
|
|
325
|
-
} finally {
|
|
326
|
-
setCcSwitchLoading(false);
|
|
327
|
-
}
|
|
328
|
-
}, []);
|
|
329
|
-
|
|
330
295
|
useEffect(() => {
|
|
331
296
|
if (!open) return;
|
|
332
297
|
setForm(emptyForm(agentType));
|
|
@@ -334,8 +299,7 @@ export const ProviderRuntimeSettingsDialog = ({
|
|
|
334
299
|
setFormError(null);
|
|
335
300
|
void refreshProviders();
|
|
336
301
|
void refreshPresets();
|
|
337
|
-
|
|
338
|
-
}, [agentType, open, refreshCCSwitch, refreshPresets, refreshProviders]);
|
|
302
|
+
}, [agentType, open, refreshPresets, refreshProviders]);
|
|
339
303
|
|
|
340
304
|
const updateForm = (patch: Partial<ProviderFormState>): void => {
|
|
341
305
|
setForm((prev) => ({ ...prev, ...patch }));
|
|
@@ -410,19 +374,6 @@ export const ProviderRuntimeSettingsDialog = ({
|
|
|
410
374
|
}
|
|
411
375
|
};
|
|
412
376
|
|
|
413
|
-
const handleImportCCSwitch = async (providerName: string): Promise<void> => {
|
|
414
|
-
setSaving(true);
|
|
415
|
-
try {
|
|
416
|
-
await providersApi.importCCSwitch([providerName]);
|
|
417
|
-
await refreshProviders();
|
|
418
|
-
emitOpenHermitEvent(OPEN_HERMIT_EVENTS.providersChanged);
|
|
419
|
-
} catch (err) {
|
|
420
|
-
setError(err instanceof Error ? err.message : '导入 cc-switch Provider 失败');
|
|
421
|
-
} finally {
|
|
422
|
-
setSaving(false);
|
|
423
|
-
}
|
|
424
|
-
};
|
|
425
|
-
|
|
426
377
|
return (
|
|
427
378
|
<Dialog open={open} onOpenChange={onOpenChange}>
|
|
428
379
|
<DialogContent className="flex max-h-[88vh] w-[min(96vw,1120px)] max-w-[min(96vw,1120px)] flex-col overflow-hidden">
|
|
@@ -439,7 +390,6 @@ export const ProviderRuntimeSettingsDialog = ({
|
|
|
439
390
|
<TabsList className="mb-3">
|
|
440
391
|
<TabsTrigger value="providers">Provider 库</TabsTrigger>
|
|
441
392
|
<TabsTrigger value="presets">预设</TabsTrigger>
|
|
442
|
-
<TabsTrigger value="cc-switch">cc-switch</TabsTrigger>
|
|
443
393
|
</TabsList>
|
|
444
394
|
|
|
445
395
|
<TabsContent value="providers" className="mt-0 space-y-3">
|
|
@@ -479,7 +429,7 @@ export const ProviderRuntimeSettingsDialog = ({
|
|
|
479
429
|
</div>
|
|
480
430
|
) : providers.length === 0 ? (
|
|
481
431
|
<div className="rounded-xl border border-dashed border-[var(--color-border)] p-6 text-center text-sm text-[var(--color-text-muted)]">
|
|
482
|
-
还没有全局 Provider
|
|
432
|
+
还没有全局 Provider。可以从右侧新建,或从预设导入。
|
|
483
433
|
</div>
|
|
484
434
|
) : (
|
|
485
435
|
<div className="space-y-2">
|
|
@@ -565,7 +515,7 @@ export const ProviderRuntimeSettingsDialog = ({
|
|
|
565
515
|
<div>
|
|
566
516
|
<div className="text-sm font-medium text-[var(--color-text)]">从预设开始</div>
|
|
567
517
|
<div className="text-xs text-[var(--color-text-muted)]">
|
|
568
|
-
|
|
518
|
+
先选网关预设,再补 Key、模型和适用 Harness。
|
|
569
519
|
</div>
|
|
570
520
|
</div>
|
|
571
521
|
<Button
|
|
@@ -625,87 +575,6 @@ export const ProviderRuntimeSettingsDialog = ({
|
|
|
625
575
|
))}
|
|
626
576
|
</div>
|
|
627
577
|
</TabsContent>
|
|
628
|
-
|
|
629
|
-
<TabsContent value="cc-switch" className="mt-0 space-y-3">
|
|
630
|
-
<div className="flex items-center justify-between gap-3">
|
|
631
|
-
<div>
|
|
632
|
-
<div className="text-sm font-medium text-[var(--color-text)]">
|
|
633
|
-
从 cc-switch 导入
|
|
634
|
-
</div>
|
|
635
|
-
<div className="text-xs text-[var(--color-text-muted)]">
|
|
636
|
-
可导入已有 cc-switch Provider,再在右侧按 Hermit 字段调整。
|
|
637
|
-
</div>
|
|
638
|
-
</div>
|
|
639
|
-
<Button
|
|
640
|
-
size="sm"
|
|
641
|
-
variant="outline"
|
|
642
|
-
disabled={ccSwitchLoading}
|
|
643
|
-
onClick={() => void refreshCCSwitch()}
|
|
644
|
-
>
|
|
645
|
-
<RefreshCw
|
|
646
|
-
className={ccSwitchLoading ? 'mr-1 size-3.5 animate-spin' : 'mr-1 size-3.5'}
|
|
647
|
-
/>
|
|
648
|
-
刷新
|
|
649
|
-
</Button>
|
|
650
|
-
</div>
|
|
651
|
-
{ccSwitchAvailable === false ? (
|
|
652
|
-
<div className="rounded-md border border-amber-500/30 bg-amber-500/10 px-3 py-2 text-xs text-amber-300">
|
|
653
|
-
没有检测到可导入的 Provider,或服务未返回导入数据。
|
|
654
|
-
</div>
|
|
655
|
-
) : null}
|
|
656
|
-
<div className="space-y-2">
|
|
657
|
-
{ccSwitchProviders.map((provider) => (
|
|
658
|
-
<div
|
|
659
|
-
key={`${provider.app_type}:${provider.name}`}
|
|
660
|
-
className="rounded-xl border border-[var(--color-border-subtle)] bg-white/[0.025] px-3 py-3"
|
|
661
|
-
>
|
|
662
|
-
<div className="flex flex-wrap items-start justify-between gap-2">
|
|
663
|
-
<div className="min-w-0">
|
|
664
|
-
<div className="flex items-center gap-2 text-sm font-medium text-[var(--color-text)]">
|
|
665
|
-
{provider.is_current ? (
|
|
666
|
-
<CheckCircle2 className="size-3.5 text-emerald-400" />
|
|
667
|
-
) : null}
|
|
668
|
-
{provider.name}
|
|
669
|
-
</div>
|
|
670
|
-
<div className="mt-1 text-[11px] text-[var(--color-text-muted)]">
|
|
671
|
-
{provider.app_type} · {provider.base_url || '默认端点'} ·{' '}
|
|
672
|
-
{provider.model || '未指定模型'}
|
|
673
|
-
</div>
|
|
674
|
-
</div>
|
|
675
|
-
<div className="flex items-center gap-1">
|
|
676
|
-
<Button
|
|
677
|
-
size="sm"
|
|
678
|
-
variant="ghost"
|
|
679
|
-
className="h-7 px-2 text-xs"
|
|
680
|
-
onClick={() => {
|
|
681
|
-
setEditingName(null);
|
|
682
|
-
setForm(formFromCCSwitch(provider, agentType));
|
|
683
|
-
setFormError(null);
|
|
684
|
-
}}
|
|
685
|
-
>
|
|
686
|
-
填入表单
|
|
687
|
-
</Button>
|
|
688
|
-
<Button
|
|
689
|
-
size="sm"
|
|
690
|
-
variant="outline"
|
|
691
|
-
className="h-7 px-2 text-xs"
|
|
692
|
-
disabled={saving}
|
|
693
|
-
onClick={() => void handleImportCCSwitch(provider.name)}
|
|
694
|
-
>
|
|
695
|
-
<Download className="mr-1 size-3" />
|
|
696
|
-
直接导入
|
|
697
|
-
</Button>
|
|
698
|
-
</div>
|
|
699
|
-
</div>
|
|
700
|
-
</div>
|
|
701
|
-
))}
|
|
702
|
-
{ccSwitchProviders.length === 0 && !ccSwitchLoading ? (
|
|
703
|
-
<div className="rounded-xl border border-dashed border-[var(--color-border)] p-5 text-center text-xs text-[var(--color-text-muted)]">
|
|
704
|
-
暂无 cc-switch Provider 可导入。
|
|
705
|
-
</div>
|
|
706
|
-
) : null}
|
|
707
|
-
</div>
|
|
708
|
-
</TabsContent>
|
|
709
578
|
</Tabs>
|
|
710
579
|
</div>
|
|
711
580
|
|
|
@@ -14,13 +14,7 @@ import { CcCronScheduleDialog } from '../team/schedule/CcCronScheduleDialog';
|
|
|
14
14
|
import type { Schedule } from '@shared/types';
|
|
15
15
|
|
|
16
16
|
export const SchedulesView = (): React.JSX.Element => {
|
|
17
|
-
const {
|
|
18
|
-
schedules,
|
|
19
|
-
schedulesLoading,
|
|
20
|
-
fetchSchedules,
|
|
21
|
-
openTeamTab,
|
|
22
|
-
teamByName,
|
|
23
|
-
} = useStore(
|
|
17
|
+
const { schedules, schedulesLoading, fetchSchedules, openTeamTab, teamByName } = useStore(
|
|
24
18
|
useShallow((s) => ({
|
|
25
19
|
schedules: s.schedules,
|
|
26
20
|
schedulesLoading: s.schedulesLoading,
|
|
@@ -93,14 +87,20 @@ export const SchedulesView = (): React.JSX.Element => {
|
|
|
93
87
|
return (
|
|
94
88
|
<div className="flex h-full flex-col bg-[var(--color-surface)]">
|
|
95
89
|
{/* Minimal header */}
|
|
96
|
-
<div className="flex shrink-0 items-center justify-between px-4 pt-4
|
|
90
|
+
<div className="flex shrink-0 items-center justify-between px-4 pb-2 pt-4">
|
|
97
91
|
<div className="flex items-center gap-2">
|
|
98
|
-
<h1
|
|
92
|
+
<h1
|
|
93
|
+
className="flex items-center gap-2 text-xs font-medium uppercase tracking-wider"
|
|
94
|
+
style={{ color: 'var(--color-text-muted)' }}
|
|
95
|
+
>
|
|
99
96
|
<span className="text-cyan-400/40">#</span>
|
|
100
97
|
定时任务
|
|
101
98
|
</h1>
|
|
102
99
|
{schedules.length > 0 && (
|
|
103
|
-
<span
|
|
100
|
+
<span
|
|
101
|
+
className="rounded-full px-2 py-0.5 text-[10px]"
|
|
102
|
+
style={{ color: 'var(--color-text-muted)', background: 'rgba(148,163,184,0.06)' }}
|
|
103
|
+
>
|
|
104
104
|
{schedules.filter((s) => s.status === 'active').length} 运行中
|
|
105
105
|
</span>
|
|
106
106
|
)}
|
|
@@ -112,18 +112,26 @@ export const SchedulesView = (): React.JSX.Element => {
|
|
|
112
112
|
</div>
|
|
113
113
|
|
|
114
114
|
{/* Content — fills remaining space */}
|
|
115
|
-
<div className="
|
|
115
|
+
<div className="min-h-0 flex-1 overflow-auto px-2 pb-4">
|
|
116
116
|
{schedulesLoading && schedules.length === 0 ? (
|
|
117
117
|
<div className="flex items-center justify-center py-24 text-sm text-[var(--color-text-muted)]">
|
|
118
118
|
正在加载计划...
|
|
119
119
|
</div>
|
|
120
120
|
) : schedules.length === 0 ? (
|
|
121
121
|
<div className="flex flex-col items-center justify-center gap-3 rounded-xl border border-dashed border-[var(--color-border)] py-20 text-center">
|
|
122
|
-
<Calendar
|
|
122
|
+
<Calendar
|
|
123
|
+
className="size-6"
|
|
124
|
+
style={{ color: 'var(--color-text-muted)', opacity: 0.4 }}
|
|
125
|
+
/>
|
|
123
126
|
<p className="text-xs" style={{ color: 'var(--color-text-muted)' }}>
|
|
124
|
-
|
|
127
|
+
暂无定时任务。在 Loop workspace 中创建计划即可自动运行。
|
|
125
128
|
</p>
|
|
126
|
-
<Button
|
|
129
|
+
<Button
|
|
130
|
+
size="sm"
|
|
131
|
+
variant="ghost"
|
|
132
|
+
className="mt-1 gap-1.5 text-xs"
|
|
133
|
+
onClick={handleCreate}
|
|
134
|
+
>
|
|
127
135
|
<Plus className="size-3.5" />
|
|
128
136
|
创建计划
|
|
129
137
|
</Button>
|
|
@@ -37,12 +37,15 @@ export const CalendarEventBlock = React.memo(function CalendarEventBlock({
|
|
|
37
37
|
type="button"
|
|
38
38
|
className={cn(
|
|
39
39
|
'flex w-full items-center gap-1 overflow-hidden rounded px-1 py-[1px] text-left transition-opacity hover:opacity-80',
|
|
40
|
-
className
|
|
40
|
+
className
|
|
41
41
|
)}
|
|
42
42
|
style={{ backgroundColor: hexToRgba(occurrence.color, 0.12), ...style }}
|
|
43
43
|
onClick={onClick}
|
|
44
44
|
>
|
|
45
|
-
<span
|
|
45
|
+
<span
|
|
46
|
+
className="size-1.5 shrink-0 rounded-full"
|
|
47
|
+
style={{ backgroundColor: occurrence.color }}
|
|
48
|
+
/>
|
|
46
49
|
<span className="truncate text-[10px] leading-tight" style={{ color: occurrence.color }}>
|
|
47
50
|
{label}
|
|
48
51
|
</span>
|
|
@@ -57,7 +60,7 @@ export const CalendarEventBlock = React.memo(function CalendarEventBlock({
|
|
|
57
60
|
className={cn(
|
|
58
61
|
'group relative flex w-full flex-col overflow-hidden rounded-[3px] px-1.5 py-0.5 text-left transition-opacity hover:opacity-90 focus:outline-none',
|
|
59
62
|
occurrence.status === 'paused' && 'opacity-50',
|
|
60
|
-
className
|
|
63
|
+
className
|
|
61
64
|
)}
|
|
62
65
|
style={{
|
|
63
66
|
backgroundColor: occurrence.color,
|
|
@@ -68,9 +71,7 @@ export const CalendarEventBlock = React.memo(function CalendarEventBlock({
|
|
|
68
71
|
onClick={onClick}
|
|
69
72
|
title={`${label} · ${occurrence.teamDisplayName}\n${timeStr}`}
|
|
70
73
|
>
|
|
71
|
-
<span className="truncate text-[11px] font-medium leading-tight text-white/95">
|
|
72
|
-
{label}
|
|
73
|
-
</span>
|
|
74
|
+
<span className="truncate text-[11px] font-medium leading-tight text-white/95">{label}</span>
|
|
74
75
|
{variant === 'day' && (
|
|
75
76
|
<span className="truncate text-[10px] leading-tight text-white/70">
|
|
76
77
|
{occurrence.teamDisplayName}
|
|
@@ -59,8 +59,14 @@ export const SettingsTabs = ({
|
|
|
59
59
|
|
|
60
60
|
return (
|
|
61
61
|
<TooltipProvider>
|
|
62
|
-
<div
|
|
63
|
-
|
|
62
|
+
<div
|
|
63
|
+
className="inline-flex items-center gap-1 rounded-xl border p-1 shadow-inner shadow-black/10"
|
|
64
|
+
style={{
|
|
65
|
+
backgroundColor: 'var(--color-surface-raised)',
|
|
66
|
+
borderColor: 'var(--color-border-subtle)',
|
|
67
|
+
}}
|
|
68
|
+
>
|
|
69
|
+
{visibleTabs.map((tab) => {
|
|
64
70
|
const Icon = tab.icon;
|
|
65
71
|
const isActive = activeSection === tab.id;
|
|
66
72
|
|
|
@@ -68,33 +74,30 @@ export const SettingsTabs = ({
|
|
|
68
74
|
<button
|
|
69
75
|
key={tab.id}
|
|
70
76
|
onClick={() => onSectionChange(tab.id)}
|
|
71
|
-
className={`flex items-center gap-1.5 px-3
|
|
77
|
+
className={`group relative flex h-8 w-[112px] items-center justify-center gap-1.5 whitespace-nowrap rounded-lg px-3 text-xs transition-all duration-200 ${
|
|
72
78
|
isActive
|
|
73
|
-
? 'font-medium'
|
|
74
|
-
: 'text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]'
|
|
79
|
+
? 'shadow-[var(--color-accent-glow)]/20 font-medium text-[var(--color-accent)] shadow-sm'
|
|
80
|
+
: 'text-[var(--color-text-muted)] hover:bg-[var(--color-accent-soft)] hover:text-[var(--color-text-secondary)]'
|
|
75
81
|
}`}
|
|
76
|
-
style={
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
82
|
+
style={
|
|
83
|
+
isActive
|
|
84
|
+
? {
|
|
85
|
+
backgroundColor: 'var(--color-accent-muted)',
|
|
86
|
+
border: '1px solid var(--color-accent-border)',
|
|
87
|
+
}
|
|
88
|
+
: { border: '1px solid transparent' }
|
|
89
|
+
}
|
|
80
90
|
>
|
|
81
|
-
<Icon
|
|
91
|
+
<Icon
|
|
92
|
+
className={`size-3 transition-opacity ${isActive ? 'opacity-95' : 'opacity-45 group-hover:opacity-70'}`}
|
|
93
|
+
/>
|
|
82
94
|
{tab.label}
|
|
83
95
|
|
|
84
96
|
<Tooltip>
|
|
85
97
|
<TooltipTrigger asChild>
|
|
86
98
|
<span
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
aria-label={`What is ${tab.label}?`}
|
|
90
|
-
onClick={(event) => event.stopPropagation()}
|
|
91
|
-
onMouseDown={(event) => event.stopPropagation()}
|
|
92
|
-
onKeyDown={(event) => {
|
|
93
|
-
if (event.key === 'Enter' || event.key === ' ') {
|
|
94
|
-
event.stopPropagation();
|
|
95
|
-
}
|
|
96
|
-
}}
|
|
97
|
-
className="ml-0.5 inline-flex items-center justify-center rounded-full text-[var(--color-text-muted)] opacity-0 transition-opacity hover:opacity-100"
|
|
99
|
+
aria-hidden="true"
|
|
100
|
+
className="ml-0.5 inline-flex items-center justify-center rounded-full text-[var(--color-text-muted)] opacity-0 transition-opacity hover:text-[var(--color-accent)] group-hover:opacity-100 group-focus-visible:opacity-100"
|
|
98
101
|
>
|
|
99
102
|
<Info className="size-2.5" />
|
|
100
103
|
</span>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { useEffect, useState } from 'react';
|
|
7
7
|
|
|
8
8
|
import { useStore } from '@renderer/store';
|
|
9
|
-
import { Loader2 } from 'lucide-react';
|
|
9
|
+
import { Loader2, SlidersHorizontal } from 'lucide-react';
|
|
10
10
|
import { useShallow } from 'zustand/react/shallow';
|
|
11
11
|
|
|
12
12
|
import { useSettingsConfig, useSettingsHandlers } from './hooks';
|
|
@@ -100,28 +100,37 @@ export const SettingsView = (): React.JSX.Element | null => {
|
|
|
100
100
|
|
|
101
101
|
return (
|
|
102
102
|
<div className="flex-1 overflow-auto" style={{ backgroundColor: 'var(--color-surface)' }}>
|
|
103
|
-
{/*
|
|
103
|
+
{/* Control-console settings shell */}
|
|
104
104
|
<div
|
|
105
|
-
className="mx-auto flex min-h-full max-w-
|
|
105
|
+
className="mx-auto flex min-h-full max-w-4xl flex-col px-6 py-6"
|
|
106
106
|
style={{
|
|
107
107
|
backgroundColor: 'var(--color-surface)',
|
|
108
108
|
}}
|
|
109
109
|
>
|
|
110
|
-
{/* Tabs area */}
|
|
111
110
|
<div
|
|
112
|
-
className="border-
|
|
113
|
-
style={{
|
|
114
|
-
borderColor: 'var(--color-border-subtle)',
|
|
115
|
-
}}
|
|
111
|
+
className="bg-[var(--color-surface-raised)]/60 mb-5 overflow-hidden rounded-2xl border shadow-sm shadow-black/10"
|
|
112
|
+
style={{ borderColor: 'var(--color-border-subtle)' }}
|
|
116
113
|
>
|
|
117
|
-
<
|
|
118
|
-
|
|
119
|
-
<div className="
|
|
120
|
-
|
|
114
|
+
<div className="pointer-events-none h-px bg-gradient-to-r from-transparent via-[var(--color-accent-border)] to-transparent" />
|
|
115
|
+
<div className="flex flex-col gap-4 px-4 py-4 sm:flex-row sm:items-center sm:justify-between">
|
|
116
|
+
<div className="flex items-start gap-3">
|
|
117
|
+
<div className="shadow-[var(--color-accent-glow)]/20 flex size-9 shrink-0 items-center justify-center rounded-xl border border-[var(--color-accent-border)] bg-[var(--color-accent-soft)] text-[var(--color-accent)] shadow-sm">
|
|
118
|
+
<SlidersHorizontal className="size-4" />
|
|
119
|
+
</div>
|
|
120
|
+
<div>
|
|
121
|
+
<h2 className="text-base font-semibold text-[var(--color-text)]">设置 Helm Loop</h2>
|
|
122
|
+
<p className="mt-1 text-xs leading-relaxed text-[var(--color-text-muted)]">
|
|
123
|
+
配置 Hermit 运行时、外观、数字员工渠道和本地控制行为。
|
|
124
|
+
</p>
|
|
125
|
+
</div>
|
|
126
|
+
</div>
|
|
127
|
+
<SettingsTabs activeSection={activeSection} onSectionChange={setActiveSection} />
|
|
128
|
+
</div>
|
|
129
|
+
{error && <div className="px-4 pb-3 text-[10px] text-red-400">{error}</div>}
|
|
121
130
|
</div>
|
|
122
131
|
|
|
123
132
|
{/* Content */}
|
|
124
|
-
<div className="flex-1 overflow-y-auto
|
|
133
|
+
<div className="flex-1 overflow-y-auto duration-200 animate-in fade-in slide-in-from-bottom-1">
|
|
125
134
|
{activeSection === 'general' && (
|
|
126
135
|
<GeneralSection
|
|
127
136
|
safeConfig={safeConfig}
|
|
@@ -18,12 +18,15 @@ export const SettingRow = ({
|
|
|
18
18
|
}: SettingRowProps): React.JSX.Element => {
|
|
19
19
|
return (
|
|
20
20
|
<div
|
|
21
|
-
className="flex items-center justify-between border-b py-3"
|
|
21
|
+
className="group flex items-center justify-between border-b px-3 py-3.5 transition-colors duration-150 last:border-b-0 hover:bg-[var(--color-accent-soft)]"
|
|
22
22
|
style={{ borderColor: 'var(--color-border-subtle)' }}
|
|
23
23
|
>
|
|
24
|
-
<div className="flex items-start gap-
|
|
24
|
+
<div className="flex items-start gap-3">
|
|
25
25
|
{icon ? (
|
|
26
|
-
<div
|
|
26
|
+
<div
|
|
27
|
+
className="mt-0.5 flex size-5 shrink-0 items-center justify-center rounded transition-colors duration-150 group-hover:text-[var(--color-text)]"
|
|
28
|
+
style={{ color: 'var(--color-text-muted)' }}
|
|
29
|
+
>
|
|
27
30
|
{icon}
|
|
28
31
|
</div>
|
|
29
32
|
) : null}
|
|
@@ -32,13 +35,18 @@ export const SettingRow = ({
|
|
|
32
35
|
{label}
|
|
33
36
|
</div>
|
|
34
37
|
{description && (
|
|
35
|
-
<div
|
|
38
|
+
<div
|
|
39
|
+
className="mt-0.5 text-xs leading-relaxed"
|
|
40
|
+
style={{ color: 'var(--color-text-muted)' }}
|
|
41
|
+
>
|
|
36
42
|
{description}
|
|
37
43
|
</div>
|
|
38
44
|
)}
|
|
39
45
|
</div>
|
|
40
46
|
</div>
|
|
41
|
-
<div className="shrink-0">
|
|
47
|
+
<div className="shrink-0 transition-transform duration-100 group-active:scale-[0.97]">
|
|
48
|
+
{children}
|
|
49
|
+
</div>
|
|
42
50
|
</div>
|
|
43
51
|
);
|
|
44
52
|
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SettingsSectionCard - Premium settings panel surface.
|
|
3
|
+
* Adds a subtle accent hairline and glow while preserving Hermit's dense control-console feel.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
interface SettingsSectionCardProps {
|
|
7
|
+
readonly title: string;
|
|
8
|
+
readonly description?: string;
|
|
9
|
+
readonly icon?: React.ReactNode;
|
|
10
|
+
readonly children: React.ReactNode;
|
|
11
|
+
readonly className?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const SettingsSectionCard = ({
|
|
15
|
+
title,
|
|
16
|
+
description,
|
|
17
|
+
icon,
|
|
18
|
+
children,
|
|
19
|
+
className = '',
|
|
20
|
+
}: SettingsSectionCardProps): React.JSX.Element => {
|
|
21
|
+
return (
|
|
22
|
+
<section
|
|
23
|
+
className={`bg-[var(--color-surface-raised)]/55 group relative overflow-hidden rounded-2xl border shadow-sm shadow-black/10 transition-all duration-200 hover:border-[var(--color-border-emphasis)] ${className}`}
|
|
24
|
+
style={{ borderColor: 'var(--color-border-subtle)' }}
|
|
25
|
+
>
|
|
26
|
+
<div className="pointer-events-none absolute inset-x-8 top-0 h-px bg-gradient-to-r from-transparent via-[var(--color-accent-border)] to-transparent opacity-80" />
|
|
27
|
+
<div className="pointer-events-none absolute -right-20 -top-24 size-48 rounded-full bg-[var(--color-accent-soft)] blur-3xl transition-opacity duration-300 group-hover:opacity-80" />
|
|
28
|
+
|
|
29
|
+
<div
|
|
30
|
+
className="relative border-b px-4 py-3"
|
|
31
|
+
style={{ borderColor: 'var(--color-border-subtle)' }}
|
|
32
|
+
>
|
|
33
|
+
<div className="flex items-start gap-3">
|
|
34
|
+
{icon && (
|
|
35
|
+
<div className="shadow-[var(--color-accent-glow)]/20 mt-0.5 flex size-7 shrink-0 items-center justify-center rounded-lg border border-[var(--color-accent-border)] bg-[var(--color-accent-soft)] text-[var(--color-accent)] shadow-sm">
|
|
36
|
+
{icon}
|
|
37
|
+
</div>
|
|
38
|
+
)}
|
|
39
|
+
<div className="min-w-0">
|
|
40
|
+
<h3 className="text-sm font-semibold text-[var(--color-text)]">{title}</h3>
|
|
41
|
+
{description && (
|
|
42
|
+
<p className="mt-0.5 text-xs leading-relaxed text-[var(--color-text-muted)]">
|
|
43
|
+
{description}
|
|
44
|
+
</p>
|
|
45
|
+
)}
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
<div className="relative px-1">{children}</div>
|
|
51
|
+
</section>
|
|
52
|
+
);
|
|
53
|
+
};
|