@yancyyu/openhermit 1.6.42 → 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.
Files changed (281) hide show
  1. package/README.md +98 -89
  2. package/bin/hermit.mjs +96 -0
  3. package/dist-renderer/assets/{ProjectEditorOverlay-DlFQ6mai.js → ProjectEditorOverlay-C98qSs7-.js} +1 -1
  4. package/dist-renderer/assets/{TeamGraphOverlay-D2TPMPGR.js → TeamGraphOverlay-CsBbZwcL.js} +1 -1
  5. package/dist-renderer/assets/{_basePickBy-Cmd0RHLQ.js → _basePickBy-ZOyLWjMK.js} +1 -1
  6. package/dist-renderer/assets/{_baseUniq-BI_iy8ea.js → _baseUniq-DBb726rt.js} +1 -1
  7. package/dist-renderer/assets/{arc-NzW2mjTP.js → arc-CdiTaR_R.js} +1 -1
  8. package/dist-renderer/assets/{architectureDiagram-VXUJARFQ-Bzq85AYv.js → architectureDiagram-VXUJARFQ-Cz3sc5TH.js} +1 -1
  9. package/dist-renderer/assets/{blockDiagram-VD42YOAC-D1PvYS-b.js → blockDiagram-VD42YOAC-DE4c-KJ3.js} +1 -1
  10. package/dist-renderer/assets/{c4Diagram-YG6GDRKO-D49RKzPC.js → c4Diagram-YG6GDRKO-CmTMDTrV.js} +1 -1
  11. package/dist-renderer/assets/channel-KTpqi9eT.js +1 -0
  12. package/dist-renderer/assets/{chunk-4BX2VUAB-fmI_MQmQ.js → chunk-4BX2VUAB-rhHy3tFl.js} +1 -1
  13. package/dist-renderer/assets/{chunk-55IACEB6-Xsv9RCXZ.js → chunk-55IACEB6-fLZBzuo_.js} +1 -1
  14. package/dist-renderer/assets/{chunk-B4BG7PRW-BE1KO8Um.js → chunk-B4BG7PRW-DOzxQhim.js} +1 -1
  15. package/dist-renderer/assets/{chunk-DI55MBZ5-tqJ7Mv7f.js → chunk-DI55MBZ5-COQCcXC5.js} +1 -1
  16. package/dist-renderer/assets/{chunk-FMBD7UC4-DMD45MVJ.js → chunk-FMBD7UC4-IKU9U_Y4.js} +1 -1
  17. package/dist-renderer/assets/{chunk-QN33PNHL-DOhGrz-q.js → chunk-QN33PNHL-D6WV154X.js} +1 -1
  18. package/dist-renderer/assets/{chunk-QZHKN3VN-D8yDgJdD.js → chunk-QZHKN3VN-D90_2DQp.js} +1 -1
  19. package/dist-renderer/assets/{chunk-TZMSLE5B-BcsEDu7A.js → chunk-TZMSLE5B-BQEil57G.js} +1 -1
  20. package/dist-renderer/assets/classDiagram-2ON5EDUG-lpzulY5X.js +1 -0
  21. package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-lpzulY5X.js +1 -0
  22. package/dist-renderer/assets/clone-CriGymY9.js +1 -0
  23. package/dist-renderer/assets/{cose-bilkent-S5V4N54A-DlSqGHMX.js → cose-bilkent-S5V4N54A-6WiK6U2P.js} +1 -1
  24. package/dist-renderer/assets/{dagre-6UL2VRFP-BTT9tSAx.js → dagre-6UL2VRFP-DF4MMuTn.js} +1 -1
  25. package/dist-renderer/assets/{diagram-PSM6KHXK-Du-U-mK2.js → diagram-PSM6KHXK-CcF1eZ7E.js} +1 -1
  26. package/dist-renderer/assets/{diagram-QEK2KX5R-jFdHeKas.js → diagram-QEK2KX5R-DYlOVPQB.js} +1 -1
  27. package/dist-renderer/assets/{diagram-S2PKOQOG-DKLNK2bu.js → diagram-S2PKOQOG-BHXWsZOP.js} +1 -1
  28. package/dist-renderer/assets/{erDiagram-Q2GNP2WA-CZxHgIIo.js → erDiagram-Q2GNP2WA-GjmuBx8d.js} +1 -1
  29. package/dist-renderer/assets/{flowDiagram-NV44I4VS-v4XStCD0.js → flowDiagram-NV44I4VS-BuS7YVHk.js} +1 -1
  30. package/dist-renderer/assets/{ganttDiagram-JELNMOA3-DJjD_BEL.js → ganttDiagram-JELNMOA3-3Teu5tAa.js} +1 -1
  31. package/dist-renderer/assets/{gitGraphDiagram-V2S2FVAM-BNy-jr03.js → gitGraphDiagram-V2S2FVAM-BiLdCYu5.js} +1 -1
  32. package/dist-renderer/assets/{graph-DDTrn6je.js → graph-CDP_R8ct.js} +1 -1
  33. package/dist-renderer/assets/{index-BBp78BAu.js → index-BSZdT-g-.js} +1 -1
  34. package/dist-renderer/assets/{index-eotrJaYy.js → index-BhWvMqsz.js} +1 -1
  35. package/dist-renderer/assets/{index-D8_B-cfs.js → index-C2_AupSj.js} +1 -1
  36. package/dist-renderer/assets/{index-BQrwHZ-k.js → index-C5ujiwAR.js} +580 -588
  37. package/dist-renderer/assets/index-CIS2CTK9.css +1 -0
  38. package/dist-renderer/assets/{index-CRKQSG9S.js → index-CVNjLwkq.js} +1 -1
  39. package/dist-renderer/assets/{index-DR6Wz52b.js → index-CwG3se0q.js} +1 -1
  40. package/dist-renderer/assets/{infoDiagram-HS3SLOUP-DqnOsuza.js → infoDiagram-HS3SLOUP-DLHUFo72.js} +1 -1
  41. package/dist-renderer/assets/{journeyDiagram-XKPGCS4Q-DTobaO1d.js → journeyDiagram-XKPGCS4Q-BE07RpJD.js} +1 -1
  42. package/dist-renderer/assets/{kanban-definition-3W4ZIXB7-HbwVOvWc.js → kanban-definition-3W4ZIXB7-DDHZy4NB.js} +1 -1
  43. package/dist-renderer/assets/{layout--VYmTcw2.js → layout-5nA5wUxO.js} +1 -1
  44. package/dist-renderer/assets/{linear-BsJh89Mr.js → linear-BtF1i2qN.js} +1 -1
  45. package/dist-renderer/assets/{mindmap-definition-VGOIOE7T-BZqUZePd.js → mindmap-definition-VGOIOE7T-Z1Ui9Sqy.js} +1 -1
  46. package/dist-renderer/assets/{pieDiagram-ADFJNKIX-B1q_nH6P.js → pieDiagram-ADFJNKIX-LCjxckWv.js} +1 -1
  47. package/dist-renderer/assets/{quadrantDiagram-AYHSOK5B-UD8QhSEu.js → quadrantDiagram-AYHSOK5B-BOwKjSco.js} +1 -1
  48. package/dist-renderer/assets/{requirementDiagram-UZGBJVZJ-BA_i7Nw8.js → requirementDiagram-UZGBJVZJ-pChP8Znd.js} +1 -1
  49. package/dist-renderer/assets/{sankeyDiagram-TZEHDZUN-CMTnX-2d.js → sankeyDiagram-TZEHDZUN-DifZ2qpo.js} +1 -1
  50. package/dist-renderer/assets/{sequenceDiagram-WL72ISMW-BQXDB615.js → sequenceDiagram-WL72ISMW-CJg-WYyY.js} +1 -1
  51. package/dist-renderer/assets/{splashScene-D0YB9uxm.js → splashScene-94xWCzLA.js} +1 -1
  52. package/dist-renderer/assets/{stateDiagram-FKZM4ZOC-BAsPXy6X.js → stateDiagram-FKZM4ZOC-DWHOoFdv.js} +1 -1
  53. package/dist-renderer/assets/stateDiagram-v2-4FDKWEC3-CGYZOoMb.js +1 -0
  54. package/dist-renderer/assets/{timeline-definition-IT6M3QCI-BdasmVkC.js → timeline-definition-IT6M3QCI-CPgokIo8.js} +1 -1
  55. package/dist-renderer/assets/{treemap-GDKQZRPO-BkKQqIui.js → treemap-GDKQZRPO-DAVqSR9L.js} +1 -1
  56. package/dist-renderer/assets/{xychartDiagram-PRI3JC2R-EAlPHOdx.js → xychartDiagram-PRI3JC2R-CCOcGbrD.js} +1 -1
  57. package/dist-renderer/chat-community-qr.jpg +0 -0
  58. package/dist-renderer/fonts/Agave-Bold.ttf +0 -0
  59. package/dist-renderer/fonts/Agave-Regular.ttf +0 -0
  60. package/dist-renderer/icon.png +0 -0
  61. package/dist-renderer/icon.rar +0 -0
  62. package/dist-renderer/index.html +3 -3
  63. package/package.json +21 -26
  64. package/src/features/worker-society/core/application/WorkerSocietyService.test.ts +802 -0
  65. package/src/features/worker-society/core/application/WorkerSocietyService.ts +428 -0
  66. package/src/features/worker-society/core/application/fakes.ts +101 -0
  67. package/src/features/worker-society/core/application/ports.ts +70 -0
  68. package/src/features/worker-society/core/domain/models/society.ts +141 -0
  69. package/src/features/worker-society/core/domain/policies/societyPolicies.test.ts +739 -0
  70. package/src/features/worker-society/core/domain/policies/societyPolicies.ts +496 -0
  71. package/src/features/worker-society/main/adapters/input/societyMcp.test.ts +317 -0
  72. package/src/features/worker-society/main/adapters/input/societyMcp.ts +257 -0
  73. package/src/features/worker-society/main/adapters/input/societyRoutes.test.ts +695 -0
  74. package/src/features/worker-society/main/adapters/input/societyRoutes.ts +194 -0
  75. package/src/features/worker-society/main/composition/societyComposition.test.ts +74 -0
  76. package/src/features/worker-society/main/composition/societyComposition.ts +70 -0
  77. package/src/features/worker-society/main/composition/workerSocietyPlugin.test.ts +69 -0
  78. package/src/features/worker-society/main/composition/workerSocietyPlugin.ts +67 -0
  79. package/src/features/worker-society/main/infrastructure/crossTeamMessageGateway.test.ts +132 -0
  80. package/src/features/worker-society/main/infrastructure/crossTeamMessageGateway.ts +84 -0
  81. package/src/features/worker-society/main/infrastructure/fsStores.test.ts +216 -0
  82. package/src/features/worker-society/main/infrastructure/fsStores.ts +113 -0
  83. package/src/features/worker-society/main/infrastructure/mergingProfileStore.test.ts +195 -0
  84. package/src/features/worker-society/main/infrastructure/mergingProfileStore.ts +96 -0
  85. package/src/features/worker-society/renderer/SocietyGraph.tsx +166 -0
  86. package/src/features/worker-society/renderer/SocietyNodeLabels.tsx +139 -0
  87. package/src/features/worker-society/renderer/SocietyNodeOverlay.tsx +339 -0
  88. package/src/features/worker-society/renderer/SocietyView.tsx +437 -0
  89. package/src/features/worker-society/renderer/index.ts +11 -0
  90. package/src/features/worker-society/renderer/societyApi.test.ts +259 -0
  91. package/src/features/worker-society/renderer/societyApi.ts +144 -0
  92. package/src/features/worker-society/renderer/societyGraphAdapter.test.ts +321 -0
  93. package/src/features/worker-society/renderer/societyGraphAdapter.ts +240 -0
  94. package/src/features/worker-society/renderer/societyOverlayActions.test.ts +57 -0
  95. package/src/features/worker-society/renderer/societyOverlayActions.ts +49 -0
  96. package/src/features/worker-society/renderer/societyStore.test.ts +218 -0
  97. package/src/features/worker-society/renderer/societyStore.ts +146 -0
  98. package/src/features/worker-society/renderer/societyViewUtils.test.ts +81 -0
  99. package/src/features/worker-society/renderer/societyViewUtils.ts +68 -0
  100. package/src/main/ipc/extensions.ts +27 -0
  101. package/src/main/server.ts +1709 -534
  102. package/src/main/services/ccConnect/CcConnectBridge.ts +26 -11
  103. package/src/main/services/ccConnect/CcConnectClient.ts +9 -2
  104. package/src/main/services/ccConnect/workDirReconcile.test.ts +57 -0
  105. package/src/main/services/ccConnect/workDirReconcile.ts +36 -0
  106. package/src/main/services/direct-cli/DirectCliSessionManager.test.ts +397 -0
  107. package/src/main/services/direct-cli/DirectCliSessionManager.ts +508 -0
  108. package/src/main/services/direct-cli/DirectCliSessionStore.test.ts +79 -0
  109. package/src/main/services/direct-cli/DirectCliSessionStore.ts +97 -0
  110. package/src/main/services/direct-cli/__tests__/directCliMessageId.test.ts +40 -0
  111. package/src/main/services/direct-cli/directCliMessageId.ts +21 -0
  112. package/src/main/services/direct-cli/index.ts +17 -0
  113. package/src/main/services/extensions/capability-packs/CapabilityPackLoaderService.ts +637 -0
  114. package/src/main/services/extensions/catalog/PluginCatalogService.ts +2 -2
  115. package/src/main/services/loop-assets/LoopAssetsScannerService.ts +657 -0
  116. package/src/main/services/runtime/providerAwareCliEnv.ts +33 -5
  117. package/src/main/services/session-intelligence/LocalSessionScanner.ts +156 -71
  118. package/src/main/services/session-intelligence/SessionUsageParser.ts +103 -8
  119. package/src/main/services/session-intelligence/UsageTelemetryService.ts +11 -0
  120. package/src/main/services/session-intelligence/__tests__/teamSessionListMapper.test.ts +104 -0
  121. package/src/main/services/session-intelligence/teamSessionListMapper.ts +78 -0
  122. package/src/main/services/system-manager/AdminLoopInitializer.ts +95 -0
  123. package/src/main/services/system-manager/BuiltinWorkflowSeeder.ts +679 -74
  124. package/src/main/services/system-manager/SystemManagerConfigService.ts +19 -1
  125. package/src/main/services/system-manager/WorkflowPromptService.ts +58 -5
  126. package/src/main/services/system-manager/__tests__/AdminLoopInitializer.test.ts +129 -0
  127. package/src/main/services/system-manager/__tests__/SystemManagerConfigService.test.ts +60 -0
  128. package/src/main/services/teams-mvp/CollaborationBoardService.ts +2 -0
  129. package/src/main/services/teams-mvp/OpsRunbookContext.ts +60 -0
  130. package/src/main/services/teams-mvp/TaskDispatchService.test.ts +305 -0
  131. package/src/main/services/teams-mvp/TaskDispatchService.ts +250 -131
  132. package/src/main/services/teams-mvp/TeamProvisioningService.ts +12 -2
  133. package/src/main/services/teams-mvp/TeamWorkspaceService.test.ts +207 -0
  134. package/src/main/services/teams-mvp/TeamWorkspaceService.ts +104 -51
  135. package/src/main/services/teams-mvp/index.ts +6 -0
  136. package/src/main/utils/externalPlatformSessionRouting.ts +92 -0
  137. package/src/main/utils/toolApprovalRules.ts +151 -0
  138. package/src/renderer/App.tsx +24 -89
  139. package/src/renderer/api/httpClient.ts +115 -37
  140. package/src/renderer/api/providers.ts +5 -16
  141. package/src/renderer/components/chat/CommunityChatView.tsx +81 -0
  142. package/src/renderer/components/dashboard/DashboardView.tsx +130 -84
  143. package/src/renderer/components/extensions/ExtensionStoreView.tsx +39 -5
  144. package/src/renderer/components/extensions/ExtensionsSubTabTrigger.tsx +2 -1
  145. package/src/renderer/components/extensions/capability-packs/CapabilityPacksPanel.tsx +170 -0
  146. package/src/renderer/components/layout/PaneContent.tsx +10 -2
  147. package/src/renderer/components/layout/SortableTab.tsx +4 -0
  148. package/src/renderer/components/layout/TabBarActions.tsx +13 -16
  149. package/src/renderer/components/runtime/ProviderRuntimeSettingsDialog.tsx +4 -135
  150. package/src/renderer/components/schedules/SchedulesView.tsx +22 -14
  151. package/src/renderer/components/schedules/calendar/CalendarEventBlock.tsx +7 -6
  152. package/src/renderer/components/settings/SettingsTabs.tsx +24 -21
  153. package/src/renderer/components/settings/SettingsView.tsx +22 -13
  154. package/src/renderer/components/settings/components/SettingRow.tsx +13 -5
  155. package/src/renderer/components/settings/components/SettingsSectionCard.tsx +53 -0
  156. package/src/renderer/components/settings/components/SettingsSectionHeader.tsx +10 -6
  157. package/src/renderer/components/settings/components/SettingsSelect.tsx +12 -9
  158. package/src/renderer/components/settings/components/SettingsToggle.tsx +6 -5
  159. package/src/renderer/components/settings/components/index.ts +1 -0
  160. package/src/renderer/components/settings/sections/AdvancedSection.tsx +78 -59
  161. package/src/renderer/components/settings/sections/CliStatusSection.tsx +32 -44
  162. package/src/renderer/components/settings/sections/ConfigEditorDialog.tsx +1 -1
  163. package/src/renderer/components/settings/sections/GeneralSection.tsx +216 -186
  164. package/src/renderer/components/settings/sections/PlatformsSection.tsx +25 -17
  165. package/src/renderer/components/settings/sections/TaskBusSection.tsx +63 -22
  166. package/src/renderer/components/sidebar/SidebarSessions.tsx +120 -80
  167. package/src/renderer/components/sidebar/SidebarTaskItem.tsx +1 -1
  168. package/src/renderer/components/splash/splashScene.ts +6 -2
  169. package/src/renderer/components/system-manager/SystemManagerView.tsx +169 -255
  170. package/src/renderer/components/tasks/TasksView.tsx +63 -37
  171. package/src/renderer/components/team/CcSessionsSection.tsx +124 -89
  172. package/src/renderer/components/team/HarnessBrandLogos.tsx +318 -0
  173. package/src/renderer/components/team/HarnessSelect.tsx +25 -26
  174. package/src/renderer/components/team/TeamDetailView.tsx +137 -153
  175. package/src/renderer/components/team/TeamEmptyState.tsx +9 -37
  176. package/src/renderer/components/team/TeamListView.tsx +143 -30
  177. package/src/renderer/components/team/__tests__/CcSessionsSection.hasLocalFile.test.tsx +128 -0
  178. package/src/renderer/components/team/activity/ActivityItem.tsx +21 -9
  179. package/src/renderer/components/team/activity/ActivityTimeline.tsx +2 -2
  180. package/src/renderer/components/team/dialogs/AdvancedCliSection.tsx +1 -1
  181. package/src/renderer/components/team/dialogs/CreateTaskDialog.tsx +13 -10
  182. package/src/renderer/components/team/dialogs/CreateTeamDialog.tsx +156 -83
  183. package/src/renderer/components/team/dialogs/EditTeamDialog.tsx +9 -157
  184. package/src/renderer/components/team/dialogs/LaunchTeamDialog.tsx +19 -15
  185. package/src/renderer/components/team/dialogs/PlatformBindingDialog.tsx +48 -10
  186. package/src/renderer/components/team/dialogs/PlatformManualForm.tsx +11 -12
  187. package/src/renderer/components/team/dialogs/PlatformSetupQR.tsx +39 -37
  188. package/src/renderer/components/team/dialogs/RuntimeConfigDialog.tsx +434 -64
  189. package/src/renderer/components/team/dialogs/SendMessageDialog.tsx +12 -10
  190. package/src/renderer/components/team/dialogs/TaskDetailDialog.tsx +2 -2
  191. package/src/renderer/components/team/dialogs/__tests__/CreateTeamDialog.bindProject.test.tsx +399 -0
  192. package/src/renderer/components/team/dialogs/__tests__/CreateTeamDialog.chineseRepro.test.tsx +253 -0
  193. package/src/renderer/components/team/dialogs/platformAllowUtils.ts +91 -0
  194. package/src/renderer/components/team/dialogs/teammateRuntimeCompatibility.tsx +1 -1
  195. package/src/renderer/components/team/kanban/KanbanTaskCard.test.tsx +41 -0
  196. package/src/renderer/components/team/kanban/KanbanTaskCard.tsx +41 -86
  197. package/src/renderer/components/team/loop-console/LoopCommandComposer.tsx +310 -0
  198. package/src/renderer/components/team/loop-console/LoopConsolePanel.tsx +372 -0
  199. package/src/renderer/components/team/loop-console/loopSendIntent.test.ts +85 -0
  200. package/src/renderer/components/team/loop-console/loopSendIntent.ts +221 -0
  201. package/src/renderer/components/team/loop-console/useLeadSessionToolActivity.ts +74 -0
  202. package/src/renderer/components/team/loop-console/useLoopCommandSuggestions.ts +165 -0
  203. package/src/renderer/components/team/loop-console/useLoopConsoleController.ts +266 -0
  204. package/src/renderer/components/team/members/LeadModelRow.test.tsx +1 -1
  205. package/src/renderer/components/team/members/LeadModelRow.tsx +5 -3
  206. package/src/renderer/components/team/members/MemberDetailDialog.tsx +11 -0
  207. package/src/renderer/components/team/members/MemberDetailStats.tsx +13 -3
  208. package/src/renderer/components/team/members/MemberDraftRow.test.tsx +1 -1
  209. package/src/renderer/components/team/members/MemberDraftRow.tsx +1 -1
  210. package/src/renderer/components/team/members/MemberMessagesTab.tsx +2 -2
  211. package/src/renderer/components/team/members/MemberStatsTab.tsx +1 -1
  212. package/src/renderer/components/team/messages/MessageComposer.tsx +150 -44
  213. package/src/renderer/components/team/messages/MessagesFilterPopover.tsx +2 -2
  214. package/src/renderer/components/team/messages/MessagesPanel.tsx +34 -28
  215. package/src/renderer/components/team/schedule/CcCronScheduleDialog.tsx +6 -6
  216. package/src/renderer/components/team/taskLogs/ExactTaskLogCard.tsx +2 -2
  217. package/src/renderer/components/team/taskLogs/TaskLogStreamSection.tsx +1 -1
  218. package/src/renderer/components/terminal/TerminalPanel.tsx +2 -3
  219. package/src/renderer/components/ui/MentionableTextarea.tsx +5 -1
  220. package/src/renderer/constants/teamColors.ts +5 -5
  221. package/src/renderer/hooks/useExtensionsTabState.ts +1 -1
  222. package/src/renderer/hooks/useMentionDetection.ts +5 -1
  223. package/src/renderer/hooks/useProjectWorkflowCommands.ts +57 -0
  224. package/src/renderer/hooks/useTeamSuggestions.ts +2 -0
  225. package/src/renderer/index.css +19 -2
  226. package/src/renderer/main.tsx +7 -1
  227. package/src/renderer/store/index.ts +18 -1
  228. package/src/renderer/store/slices/extensionsSlice.ts +83 -0
  229. package/src/renderer/store/slices/tabSlice.ts +61 -0
  230. package/src/renderer/store/slices/teamSlice.ts +138 -9
  231. package/src/renderer/types/mention.ts +8 -0
  232. package/src/renderer/types/tabs.ts +3 -1
  233. package/src/renderer/utils/__tests__/bindProjectSlug.test.ts +69 -0
  234. package/src/renderer/utils/__tests__/groupTransformer.test.ts +148 -0
  235. package/src/renderer/utils/__tests__/initialRoute.test.ts +101 -0
  236. package/src/renderer/utils/__tests__/leadToolActivity.test.ts +124 -0
  237. package/src/renderer/utils/__tests__/mergeTeamMessages.test.ts +81 -0
  238. package/src/renderer/utils/__tests__/teamMessageFiltering.test.ts +213 -0
  239. package/src/renderer/utils/__tests__/teamMessageKey.test.ts +75 -0
  240. package/src/renderer/utils/__tests__/workflowCommandExecution.test.ts +173 -0
  241. package/src/renderer/utils/__tests__/workflowCommandSuggestions.test.ts +59 -0
  242. package/src/renderer/utils/bindProjectSlug.ts +57 -0
  243. package/src/renderer/utils/capabilityCommandExecution.ts +113 -0
  244. package/src/renderer/utils/initialRoute.ts +89 -0
  245. package/src/renderer/utils/leadToolActivity.ts +117 -0
  246. package/src/renderer/utils/loopShortcutSuggestions.ts +106 -0
  247. package/src/renderer/utils/mentionSuggestions.ts +1 -1
  248. package/src/renderer/utils/slashCommandRegistry.ts +231 -0
  249. package/src/renderer/utils/teamMentionDirective.ts +31 -0
  250. package/src/renderer/utils/workflowCommandExecution.ts +96 -0
  251. package/src/renderer/utils/workflowCommandSuggestions.ts +49 -0
  252. package/src/shared/types/api.ts +79 -4
  253. package/src/shared/types/ccConnect.ts +1 -0
  254. package/src/shared/types/extensions/api.ts +19 -0
  255. package/src/shared/types/extensions/capabilityPack.ts +118 -0
  256. package/src/shared/types/extensions/index.ts +29 -1
  257. package/src/shared/types/index.ts +6 -0
  258. package/src/shared/types/loopAssets.ts +54 -0
  259. package/src/shared/types/providers.ts +0 -16
  260. package/src/shared/types/systemManager.ts +26 -1
  261. package/src/shared/types/team.ts +41 -5
  262. package/src/shared/types/terminal.ts +2 -36
  263. package/src/shared/types/worker.test.ts +28 -0
  264. package/src/shared/types/worker.ts +3 -0
  265. package/src/shared/utils/__tests__/effortLevels.test.ts +88 -0
  266. package/src/shared/utils/__tests__/providerBackend.test.ts +88 -0
  267. package/src/shared/utils/__tests__/providerLaunchArgs.test.ts +220 -0
  268. package/src/shared/utils/claudeStreamJson.test.ts +187 -0
  269. package/src/shared/utils/claudeStreamJson.ts +153 -0
  270. package/src/shared/utils/providerLaunchArgs.ts +217 -0
  271. package/src/shared/utils/slashCommands.ts +10 -0
  272. package/src/types/node-pty.d.ts +8 -0
  273. package/dist-renderer/assets/channel-Ch7JrfUu.js +0 -1
  274. package/dist-renderer/assets/classDiagram-2ON5EDUG-z9I4AnFy.js +0 -1
  275. package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-z9I4AnFy.js +0 -1
  276. package/dist-renderer/assets/clone-Dfi1Jx6l.js +0 -1
  277. package/dist-renderer/assets/index-iyjkpSus.css +0 -32
  278. package/dist-renderer/assets/stateDiagram-v2-4FDKWEC3-DTUIBfce.js +0 -1
  279. package/src/main/services/system-manager/SystemManagerPtyService.ts +0 -233
  280. package/src/renderer/components/common/TerminalPane.tsx +0 -213
  281. package/src/renderer/components/team/dialogs/useTeamEditForm.ts +0 -292
@@ -8,12 +8,24 @@ import type {
8
8
  SystemManagerStatus,
9
9
  } from '@shared/types/systemManager';
10
10
 
11
+ import { getGlobalHermitWorkflowDir } from './BuiltinWorkflowSeeder';
12
+
11
13
  const CONFIG_FILE = 'system-manager.json';
12
14
 
13
15
  function hermitHome(): string {
14
16
  return process.env.HERMIT_HOME || path.join(os.homedir(), '.hermit');
15
17
  }
16
18
 
19
+ /**
20
+ * Canonical, isolated runtime path for the Helm Loop. Dedicated (never shared
21
+ * with another team/project) so the admin agent can bootstrap its own CLAUDE.md
22
+ * here without colliding with project work. Single source of truth — reused by
23
+ * `getSystemManagerWorkDir` (runtime) and `getStatus` (UI scope display).
24
+ */
25
+ export function adminWorkDir(): string {
26
+ return path.join(hermitHome(), 'admin-workspace');
27
+ }
28
+
17
29
  function expandHome(input: string): string {
18
30
  const normalized = input.trim().replace(/^~/, '~');
19
31
  if (normalized === '~') return os.homedir();
@@ -62,6 +74,7 @@ export class SystemManagerConfigService {
62
74
  schemaVersion: 1,
63
75
  selectedWorkDir,
64
76
  ...(workflowFolder ? { workflowFolder } : {}),
77
+ ...(parsed.adminInitialized ? { adminInitialized: true } : {}),
65
78
  updatedAt:
66
79
  typeof parsed.updatedAt === 'string' ? parsed.updatedAt : new Date().toISOString(),
67
80
  };
@@ -92,6 +105,9 @@ export class SystemManagerConfigService {
92
105
  } else if (typeof patch.workflowFolder === 'string') {
93
106
  next.workflowFolder = await this.normalizeDirectory(patch.workflowFolder, 'workflowFolder');
94
107
  }
108
+ if (typeof patch.adminInitialized === 'boolean') {
109
+ next.adminInitialized = patch.adminInitialized;
110
+ }
95
111
 
96
112
  await mkdir(path.dirname(this.configPath), { recursive: true });
97
113
  await writeFile(this.configPath, JSON.stringify(next, null, 2), 'utf-8');
@@ -102,10 +118,12 @@ export class SystemManagerConfigService {
102
118
  const config = await this.getConfig();
103
119
  const hasClaude = await commandExists('claude');
104
120
  return {
105
- displayName: '控制台',
121
+ displayName: 'Helm Loop',
122
+ adminWorkDir: adminWorkDir(),
106
123
  defaultWorkDir: this.defaultWorkDir,
107
124
  selectedWorkDir: config.selectedWorkDir,
108
125
  ...(config.workflowFolder ? { workflowFolder: config.workflowFolder } : {}),
126
+ globalHermitWorkflowFolder: getGlobalHermitWorkflowDir(),
109
127
  claudeCommand: 'claude',
110
128
  localStatus: hasClaude ? 'ready' : 'missing-claude',
111
129
  ...(hasClaude ? {} : { error: '未在 PATH 中找到 claude 命令' }),
@@ -9,6 +9,11 @@ import type {
9
9
  WorkflowPromptSummary,
10
10
  } from '@shared/types/systemManager';
11
11
 
12
+ import {
13
+ getBuiltinWorkflowByFilename,
14
+ type BuiltinWorkflowDefinition,
15
+ } from './BuiltinWorkflowSeeder';
16
+
12
17
  const SUPPORTED_EXTENSIONS = new Set(['.md', '.txt', '.prompt', '.workflow']);
13
18
  const MAX_PROMPT_BYTES = 256 * 1024;
14
19
 
@@ -27,17 +32,49 @@ function labelFromFilename(filename: string): string {
27
32
  return path.basename(filename, path.extname(filename)).replace(/[-_]+/g, ' ').trim() || filename;
28
33
  }
29
34
 
35
+ function getClaudeCommandRoot(folder: string): string | null {
36
+ const normalized = path.normalize(folder);
37
+ const commandsSuffix = path.join('.claude', 'commands');
38
+ if (normalized.endsWith(commandsSuffix)) return normalized;
39
+ const parent = path.dirname(normalized);
40
+ return parent.endsWith(commandsSuffix) ? parent : null;
41
+ }
42
+
43
+ function commandNameFromRelativePath(relativePath: string): `/${string}` {
44
+ const withoutExt = relativePath.slice(0, -path.extname(relativePath).length);
45
+ const commandName = withoutExt.split(path.sep).filter(Boolean).join(':');
46
+ return `/${commandName}`;
47
+ }
48
+
49
+ function applyBuiltinMetadata(
50
+ summary: WorkflowPromptSummary,
51
+ builtin: BuiltinWorkflowDefinition | undefined
52
+ ): WorkflowPromptSummary {
53
+ if (!builtin) return summary;
54
+ return {
55
+ ...summary,
56
+ label: builtin.label,
57
+ commandName: summary.commandName ?? builtin.commandName,
58
+ description: builtin.description,
59
+ category: builtin.category,
60
+ safety: builtin.safety,
61
+ builtin: true,
62
+ order: builtin.order,
63
+ };
64
+ }
65
+
30
66
  export class WorkflowPromptService {
31
67
  async list(folderInput: string): Promise<WorkflowPromptListResponse> {
32
68
  const folder = path.resolve(expandHome(folderInput));
33
69
  const folderStat = await stat(folder);
34
70
  if (!folderStat.isDirectory()) {
35
- throw new Error(`workflow folder 不是有效目录: ${folder}`);
71
+ throw new Error(`Loop command folder 不是有效目录: ${folder}`);
36
72
  }
37
73
 
38
74
  const warnings: string[] = [];
39
75
  const prompts: WorkflowPromptSummary[] = [];
40
76
  const entries = await readdir(folder, { withFileTypes: true });
77
+ const commandRoot = getClaudeCommandRoot(folder);
41
78
 
42
79
  for (const entry of entries) {
43
80
  if (!entry.isFile() || entry.name.startsWith('.')) continue;
@@ -49,17 +86,33 @@ export class WorkflowPromptService {
49
86
  warnings.push(`${entry.name} 超过 256 KiB,已跳过`);
50
87
  continue;
51
88
  }
52
- prompts.push({
89
+
90
+ const relativeCommandPath = commandRoot ? path.relative(commandRoot, filePath) : entry.name;
91
+ const commandName = commandRoot
92
+ ? commandNameFromRelativePath(relativeCommandPath)
93
+ : undefined;
94
+ const builtin = commandRoot ? getBuiltinWorkflowByFilename(entry.name) : undefined;
95
+ const summary: WorkflowPromptSummary = {
53
96
  id: promptId(filePath),
54
97
  label: labelFromFilename(entry.name),
55
98
  filename: entry.name,
56
99
  path: filePath,
100
+ folder,
57
101
  sizeBytes: fileStat.size,
58
102
  updatedAt: fileStat.mtime.toISOString(),
59
- });
103
+ source: commandRoot ? 'claude-command' : 'workflow-folder',
104
+ commandName,
105
+ safety: commandRoot ? 'unknown' : undefined,
106
+ };
107
+ prompts.push(applyBuiltinMetadata(summary, builtin));
60
108
  }
61
109
 
62
- prompts.sort((a, b) => a.filename.localeCompare(b.filename));
110
+ prompts.sort((a, b) => {
111
+ const orderA = a.order ?? Number.MAX_SAFE_INTEGER;
112
+ const orderB = b.order ?? Number.MAX_SAFE_INTEGER;
113
+ if (orderA !== orderB) return orderA - orderB;
114
+ return a.filename.localeCompare(b.filename);
115
+ });
63
116
  return { folder, prompts, warnings };
64
117
  }
65
118
 
@@ -67,7 +120,7 @@ export class WorkflowPromptService {
67
120
  const list = await this.list(folderInput);
68
121
  const prompt = list.prompts.find((item) => item.id === id || item.filename === id);
69
122
  if (!prompt) {
70
- throw new Error(`未找到 workflow: ${id}`);
123
+ throw new Error(`未找到 Loop workflow: ${id}`);
71
124
  }
72
125
  const content = await readFile(prompt.path, 'utf-8');
73
126
  return { prompt, content };
@@ -0,0 +1,129 @@
1
+ import { afterEach, describe, expect, it, vi } from 'vitest';
2
+
3
+ import {
4
+ ADMIN_INIT_MESSAGE_ID,
5
+ buildAdminInitMessage,
6
+ ensureAdminLoopInitialized,
7
+ htmlToPlainText,
8
+ type AdminLoopInitDeps,
9
+ } from '../AdminLoopInitializer';
10
+ import type { SystemManagerConfig, SystemManagerConfigPatch } from '@shared/types/systemManager';
11
+
12
+ interface Recorder {
13
+ getConfig: ReturnType<typeof vi.fn>;
14
+ updateConfig: ReturnType<typeof vi.fn>;
15
+ fetchGuide: ReturnType<typeof vi.fn>;
16
+ dispatch: ReturnType<typeof vi.fn>;
17
+ log: ReturnType<typeof vi.fn>;
18
+ }
19
+
20
+ function makeDeps(overrides?: Partial<Recorder>): Recorder & AdminLoopInitDeps {
21
+ const r: Recorder = {
22
+ getConfig: vi.fn(async () => ({ schemaVersion: 1, selectedWorkDir: '/x', updatedAt: 't' })),
23
+ updateConfig: vi.fn(
24
+ async (patch: SystemManagerConfigPatch) =>
25
+ ({
26
+ schemaVersion: 1,
27
+ selectedWorkDir: '/x',
28
+ updatedAt: 't',
29
+ ...patch,
30
+ }) as SystemManagerConfig
31
+ ),
32
+ fetchGuide: vi.fn(async () => ({ statusCode: 200, body: '<p>hello manual</p>' })),
33
+ dispatch: vi.fn(async () => undefined),
34
+ log: vi.fn(),
35
+ ...overrides,
36
+ };
37
+ return r as Recorder & AdminLoopInitDeps;
38
+ }
39
+
40
+ describe('htmlToPlainText', () => {
41
+ it('strips script/style and tags, decodes entities, collapses whitespace', () => {
42
+ const html =
43
+ '<style>.x{}</style><script>alert(1)</script><h1>Title</h1><p>a&nbsp;&amp;b</p><!--c-->';
44
+ expect(htmlToPlainText(html)).toBe('Title\na &b');
45
+ });
46
+
47
+ it('returns empty string for whitespace-only input', () => {
48
+ expect(htmlToPlainText(' \n ')).toBe('');
49
+ });
50
+ });
51
+
52
+ describe('buildAdminInitMessage', () => {
53
+ it('wraps the guide text with the bootstrap instructions', () => {
54
+ const msg = buildAdminInitMessage('MANUAL_BODY');
55
+ expect(msg).toContain('Helm Loop 初始化');
56
+ expect(msg).toContain('MANUAL_BODY');
57
+ expect(msg).toContain('/workers');
58
+ });
59
+ });
60
+
61
+ describe('ensureAdminLoopInitialized', () => {
62
+ afterEach(() => vi.clearAllMocks());
63
+
64
+ it('is idempotent: skips fetch + dispatch + updateConfig when already initialized', async () => {
65
+ const deps = makeDeps({
66
+ getConfig: vi.fn(async () => ({
67
+ schemaVersion: 1,
68
+ selectedWorkDir: '/x',
69
+ updatedAt: 't',
70
+ adminInitialized: true,
71
+ })),
72
+ });
73
+
74
+ await ensureAdminLoopInitialized(deps);
75
+
76
+ expect(deps.fetchGuide).not.toHaveBeenCalled();
77
+ expect(deps.dispatch).not.toHaveBeenCalled();
78
+ expect(deps.updateConfig).not.toHaveBeenCalled();
79
+ });
80
+
81
+ it('does NOT set the marker when the guide fetch rejects', async () => {
82
+ const deps = makeDeps({
83
+ fetchGuide: vi.fn(async () => {
84
+ throw new Error('network down');
85
+ }),
86
+ });
87
+
88
+ await ensureAdminLoopInitialized(deps);
89
+
90
+ expect(deps.dispatch).not.toHaveBeenCalled();
91
+ expect(deps.updateConfig).not.toHaveBeenCalled();
92
+ expect(deps.log).toHaveBeenCalled();
93
+ });
94
+
95
+ it('does NOT set the marker on non-2xx status', async () => {
96
+ const deps = makeDeps({
97
+ fetchGuide: vi.fn(async () => ({ statusCode: 503, body: 'unavailable' })),
98
+ });
99
+
100
+ await ensureAdminLoopInitialized(deps);
101
+
102
+ expect(deps.dispatch).not.toHaveBeenCalled();
103
+ expect(deps.updateConfig).not.toHaveBeenCalled();
104
+ });
105
+
106
+ it('does NOT set the marker when the body is empty', async () => {
107
+ const deps = makeDeps({
108
+ fetchGuide: vi.fn(async () => ({ statusCode: 200, body: '<script>x</script>' })),
109
+ });
110
+
111
+ await ensureAdminLoopInitialized(deps);
112
+
113
+ expect(deps.dispatch).not.toHaveBeenCalled();
114
+ expect(deps.updateConfig).not.toHaveBeenCalled();
115
+ });
116
+
117
+ it('on success dispatches the wrapped guide and sets adminInitialized=true', async () => {
118
+ const deps = makeDeps();
119
+
120
+ await ensureAdminLoopInitialized(deps);
121
+
122
+ expect(deps.fetchGuide).toHaveBeenCalledTimes(1);
123
+ expect(deps.dispatch).toHaveBeenCalledWith({
124
+ text: buildAdminInitMessage('hello manual'),
125
+ messageId: ADMIN_INIT_MESSAGE_ID,
126
+ });
127
+ expect(deps.updateConfig).toHaveBeenCalledWith({ adminInitialized: true });
128
+ });
129
+ });
@@ -0,0 +1,60 @@
1
+ import { afterAll, beforeAll, describe, expect, it } from 'vitest';
2
+ import { mkdtemp, rm } from 'node:fs/promises';
3
+ import { tmpdir } from 'node:os';
4
+ import path from 'node:path';
5
+
6
+ import { SystemManagerConfigService, adminWorkDir } from '../SystemManagerConfigService';
7
+
8
+ const PREV_HERMIT_HOME = process.env.HERMIT_HOME;
9
+ let workdir: string;
10
+
11
+ beforeAll(async () => {
12
+ workdir = await mkdtemp(path.join(tmpdir(), 'hermit-admin-cfg-'));
13
+ process.env.HERMIT_HOME = workdir;
14
+ });
15
+
16
+ afterAll(() => {
17
+ if (PREV_HERMIT_HOME === undefined) delete process.env.HERMIT_HOME;
18
+ else process.env.HERMIT_HOME = PREV_HERMIT_HOME;
19
+ void rm(workdir, { recursive: true, force: true });
20
+ });
21
+
22
+ describe('adminWorkDir', () => {
23
+ it('points at <hermit-home>/admin-workspace', () => {
24
+ expect(adminWorkDir()).toBe(path.join(workdir, 'admin-workspace'));
25
+ });
26
+ });
27
+
28
+ describe('SystemManagerConfigService.adminInitialized', () => {
29
+ it('round-trips the marker and persists it across instances', async () => {
30
+ const svc = new SystemManagerConfigService(workdir);
31
+
32
+ expect((await svc.getConfig()).adminInitialized).toBeUndefined();
33
+
34
+ await svc.updateConfig({ adminInitialized: true });
35
+ expect((await svc.getConfig()).adminInitialized).toBe(true);
36
+
37
+ // A fresh instance reads the same file → marker survives a restart.
38
+ const reopened = new SystemManagerConfigService(workdir);
39
+ expect((await reopened.getConfig()).adminInitialized).toBe(true);
40
+ });
41
+
42
+ it('preserves adminInitialized when patching an unrelated field', async () => {
43
+ const svc = new SystemManagerConfigService(workdir);
44
+ await svc.updateConfig({ adminInitialized: true });
45
+ await svc.updateConfig({ selectedWorkDir: workdir });
46
+
47
+ const config = await svc.getConfig();
48
+ expect(config.selectedWorkDir).toBe(workdir);
49
+ expect(config.adminInitialized).toBe(true);
50
+ });
51
+ });
52
+
53
+ describe('SystemManagerConfigService.getStatus', () => {
54
+ it('reports the Helm Loop identity and the admin workDir', async () => {
55
+ const svc = new SystemManagerConfigService(workdir);
56
+ const status = await svc.getStatus();
57
+ expect(status.displayName).toBe('Helm Loop');
58
+ expect(status.adminWorkDir).toBe(path.join(workdir, 'admin-workspace'));
59
+ });
60
+ });
@@ -50,8 +50,10 @@ function normalizeTask(task: CollabTask): CollabTask {
50
50
  function eventTypeForStatus(status: CollabTaskStatus): CollabTaskEventType {
51
51
  switch (status) {
52
52
  case 'pending_accept':
53
+ case 'received':
53
54
  return 'task_sent';
54
55
  case 'accepted':
56
+ case 'in_progress':
55
57
  return 'task_accepted';
56
58
  case 'delivered':
57
59
  return 'task_delivered';
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Compact Hermit operations context injected into managed agent instructions.
3
+ *
4
+ * Keep this short: agents need the stable runbook boundary and pointers, not the
5
+ * full public guide copied into every session.
6
+ */
7
+
8
+ export const HERMIT_OPS_GUIDE_URL = 'https://yancyuu.github.io/Hermit/';
9
+
10
+ const OPS_CONTEXT_BEGIN = '<!-- hermit:ops-runbook-context:start -->';
11
+ const OPS_CONTEXT_END = '<!-- hermit:ops-runbook-context:end -->';
12
+
13
+ const OPS_RUNBOOK_CONTEXT = `## Hermit Ops Runbook Context
14
+
15
+ Public operations guide: ${HERMIT_OPS_GUIDE_URL}
16
+ Local canonical docs: README.md, docs/README.md, docs/team-management/README.md
17
+
18
+ Hermit/openHermit is a local-first Loop Engineering control plane. Use /teams as the
19
+ main operations surface and treat ~/.hermit/ as the default local data directory.
20
+ Hermit coordinates teams, tasks, message routing, channel allowlists, audit trails,
21
+ and Loop workflows; actual runtime execution is delegated to the local Agent CLI /
22
+ cc-connect Bridge / Management API.
23
+
24
+ Common ops workflows to suggest or use when appropriate. Hermit preinstalls them as
25
+ user-level Claude commands under ~/.claude/commands/hermit/ so every team can run
26
+ the same namespaced commands from its own cwd:
27
+ - /hermit:doctor — diagnose install/runtime/config health.
28
+ - /hermit:loop-scan — inspect Loop assets and recommended recurring loops.
29
+ - /hermit:summary — summarize team/session status and next actions.
30
+ - /hermit:daily-folder-hygiene — check temporary files, stale reports, and workspace clutter.
31
+ - /hermit:daily-memory-conflict-check — check CLAUDE/AGENTS/memory/settings conflicts.
32
+ - /hermit:daily-workflow-extraction — extract reusable prompts/workflows from recent work.
33
+ - /hermit:worktree-scan — inspect dirty or stale worktrees before cleanup decisions.
34
+
35
+ Safety boundary for operations workflows:
36
+ - Default to read-only diagnosis. Do not modify, delete, move, format, commit, push,
37
+ publish, deploy, or run destructive commands unless the user explicitly approves.
38
+ - Explain the purpose before commands; prefer read-only commands for diagnostics.
39
+ - Do not expose secrets, tokens, cookies, private keys, or full sensitive paths.
40
+ - If a fix is needed, report recommendations, verification steps, and an optional
41
+ patch plan before applying changes.
42
+ - Treat the public guide and local docs as operational references; verify against
43
+ the current repository/config before making exact claims.`;
44
+
45
+ export function buildHermitOpsRunbookContext(): string {
46
+ return `${OPS_CONTEXT_BEGIN}\n\n${OPS_RUNBOOK_CONTEXT}\n\n${OPS_CONTEXT_END}`;
47
+ }
48
+
49
+ export function removeHermitOpsRunbookContext(content: string): string {
50
+ return content
51
+ .replace(new RegExp(`\\n{0,2}${OPS_CONTEXT_BEGIN}[\\s\\S]*?${OPS_CONTEXT_END}\\n?`, 'g'), '\n')
52
+ .replace(/\n{3,}/g, '\n\n')
53
+ .trimEnd();
54
+ }
55
+
56
+ export function buildMemberWorkflowWithOpsContext(memberWorkflow?: string): string {
57
+ const workflow = removeHermitOpsRunbookContext(memberWorkflow ?? '').trim();
58
+ const context = buildHermitOpsRunbookContext();
59
+ return workflow ? `${workflow}\n\n${context}` : context;
60
+ }