@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.
Files changed (281) hide show
  1. package/README.md +98 -89
  2. package/bin/hermit.mjs +96 -0
  3. package/dist-renderer/assets/{ProjectEditorOverlay-Br0X83Jf.js → ProjectEditorOverlay-C98qSs7-.js} +1 -1
  4. package/dist-renderer/assets/{TeamGraphOverlay-DHMTbZPZ.js → TeamGraphOverlay-CsBbZwcL.js} +1 -1
  5. package/dist-renderer/assets/{_basePickBy-DzIiX7yH.js → _basePickBy-ZOyLWjMK.js} +1 -1
  6. package/dist-renderer/assets/{_baseUniq-6hZuzTLU.js → _baseUniq-DBb726rt.js} +1 -1
  7. package/dist-renderer/assets/{arc-CXgO6fx_.js → arc-CdiTaR_R.js} +1 -1
  8. package/dist-renderer/assets/{architectureDiagram-VXUJARFQ-DKWgtDHr.js → architectureDiagram-VXUJARFQ-Cz3sc5TH.js} +1 -1
  9. package/dist-renderer/assets/{blockDiagram-VD42YOAC-DOMUcC40.js → blockDiagram-VD42YOAC-DE4c-KJ3.js} +1 -1
  10. package/dist-renderer/assets/{c4Diagram-YG6GDRKO-B_k2L7qX.js → c4Diagram-YG6GDRKO-CmTMDTrV.js} +1 -1
  11. package/dist-renderer/assets/channel-KTpqi9eT.js +1 -0
  12. package/dist-renderer/assets/{chunk-4BX2VUAB-BeD_ccFy.js → chunk-4BX2VUAB-rhHy3tFl.js} +1 -1
  13. package/dist-renderer/assets/{chunk-55IACEB6-ClZfkA5w.js → chunk-55IACEB6-fLZBzuo_.js} +1 -1
  14. package/dist-renderer/assets/{chunk-B4BG7PRW-5XluxXsn.js → chunk-B4BG7PRW-DOzxQhim.js} +1 -1
  15. package/dist-renderer/assets/{chunk-DI55MBZ5-BzIjjNVm.js → chunk-DI55MBZ5-COQCcXC5.js} +1 -1
  16. package/dist-renderer/assets/{chunk-FMBD7UC4-HgH3MK_H.js → chunk-FMBD7UC4-IKU9U_Y4.js} +1 -1
  17. package/dist-renderer/assets/{chunk-QN33PNHL-WeC5T3Ba.js → chunk-QN33PNHL-D6WV154X.js} +1 -1
  18. package/dist-renderer/assets/{chunk-QZHKN3VN-Cu1ApHfW.js → chunk-QZHKN3VN-D90_2DQp.js} +1 -1
  19. package/dist-renderer/assets/{chunk-TZMSLE5B-BOhlynJM.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-DGZSihDQ.js → cose-bilkent-S5V4N54A-6WiK6U2P.js} +1 -1
  24. package/dist-renderer/assets/{dagre-6UL2VRFP-CnxwCbku.js → dagre-6UL2VRFP-DF4MMuTn.js} +1 -1
  25. package/dist-renderer/assets/{diagram-PSM6KHXK-DsIhoxdI.js → diagram-PSM6KHXK-CcF1eZ7E.js} +1 -1
  26. package/dist-renderer/assets/{diagram-QEK2KX5R-Cmh9KUF5.js → diagram-QEK2KX5R-DYlOVPQB.js} +1 -1
  27. package/dist-renderer/assets/{diagram-S2PKOQOG-CKxV456A.js → diagram-S2PKOQOG-BHXWsZOP.js} +1 -1
  28. package/dist-renderer/assets/{erDiagram-Q2GNP2WA-EnvYjOjc.js → erDiagram-Q2GNP2WA-GjmuBx8d.js} +1 -1
  29. package/dist-renderer/assets/{flowDiagram-NV44I4VS-BmNeWY_A.js → flowDiagram-NV44I4VS-BuS7YVHk.js} +1 -1
  30. package/dist-renderer/assets/{ganttDiagram-JELNMOA3-D30fyK-u.js → ganttDiagram-JELNMOA3-3Teu5tAa.js} +1 -1
  31. package/dist-renderer/assets/{gitGraphDiagram-V2S2FVAM-CrUNiYg1.js → gitGraphDiagram-V2S2FVAM-BiLdCYu5.js} +1 -1
  32. package/dist-renderer/assets/{graph-CY1gTfTb.js → graph-CDP_R8ct.js} +1 -1
  33. package/dist-renderer/assets/{index-CaEbzwAU.js → index-BSZdT-g-.js} +1 -1
  34. package/dist-renderer/assets/{index-D5K-SjBG.js → index-BhWvMqsz.js} +1 -1
  35. package/dist-renderer/assets/{index-9_hO4N1e.js → index-C2_AupSj.js} +1 -1
  36. package/dist-renderer/assets/{index-59r209c1.js → index-C5ujiwAR.js} +580 -588
  37. package/dist-renderer/assets/index-CIS2CTK9.css +1 -0
  38. package/dist-renderer/assets/{index-DMR9B1UP.js → index-CVNjLwkq.js} +1 -1
  39. package/dist-renderer/assets/{index-BC2hXmg_.js → index-CwG3se0q.js} +1 -1
  40. package/dist-renderer/assets/{infoDiagram-HS3SLOUP-By_XUlcD.js → infoDiagram-HS3SLOUP-DLHUFo72.js} +1 -1
  41. package/dist-renderer/assets/{journeyDiagram-XKPGCS4Q-BM1LJE9m.js → journeyDiagram-XKPGCS4Q-BE07RpJD.js} +1 -1
  42. package/dist-renderer/assets/{kanban-definition-3W4ZIXB7-DHIW3aTA.js → kanban-definition-3W4ZIXB7-DDHZy4NB.js} +1 -1
  43. package/dist-renderer/assets/{layout-DAKiL_Mo.js → layout-5nA5wUxO.js} +1 -1
  44. package/dist-renderer/assets/{linear-DwOaRYea.js → linear-BtF1i2qN.js} +1 -1
  45. package/dist-renderer/assets/{mindmap-definition-VGOIOE7T-b7bJ2cha.js → mindmap-definition-VGOIOE7T-Z1Ui9Sqy.js} +1 -1
  46. package/dist-renderer/assets/{pieDiagram-ADFJNKIX-DxyL9Zr2.js → pieDiagram-ADFJNKIX-LCjxckWv.js} +1 -1
  47. package/dist-renderer/assets/{quadrantDiagram-AYHSOK5B-CR33pHlF.js → quadrantDiagram-AYHSOK5B-BOwKjSco.js} +1 -1
  48. package/dist-renderer/assets/{requirementDiagram-UZGBJVZJ-BAiSRSlh.js → requirementDiagram-UZGBJVZJ-pChP8Znd.js} +1 -1
  49. package/dist-renderer/assets/{sankeyDiagram-TZEHDZUN-C8JmDjoa.js → sankeyDiagram-TZEHDZUN-DifZ2qpo.js} +1 -1
  50. package/dist-renderer/assets/{sequenceDiagram-WL72ISMW-c1d0Wi1m.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-nT8BiH2O.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-DpoRepUA.js → timeline-definition-IT6M3QCI-CPgokIo8.js} +1 -1
  55. package/dist-renderer/assets/{treemap-GDKQZRPO-C41UJeIH.js → treemap-GDKQZRPO-DAVqSR9L.js} +1 -1
  56. package/dist-renderer/assets/{xychartDiagram-PRI3JC2R-KMjGARKN.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 +1731 -539
  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 +744 -0
  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 +132 -52
  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 +144 -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 +189 -57
  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 +43 -3
  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-D0XS_akr.js +0 -1
  274. package/dist-renderer/assets/classDiagram-2ON5EDUG-D13Ffs0U.js +0 -1
  275. package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-D13Ffs0U.js +0 -1
  276. package/dist-renderer/assets/clone-B1ZrxI1D.js +0 -1
  277. package/dist-renderer/assets/index-iyjkpSus.css +0 -32
  278. package/dist-renderer/assets/stateDiagram-v2-4FDKWEC3-Dmibmlso.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
@@ -0,0 +1,496 @@
1
+ /**
2
+ * Worker Society — 领域策略(纯函数,零副作用,可单测)
3
+ *
4
+ * 所有需要时间戳的函数都通过 `now` 参数注入时钟,保证 core 确定性。
5
+ * 不读写 FS/网络,不调用 new Date()。
6
+ */
7
+
8
+ import type {
9
+ PublishedNeed,
10
+ Relationship,
11
+ Volunteer,
12
+ WorkerDiscoveryQuery,
13
+ WorkerProfile,
14
+ } from '../models/society';
15
+
16
+ // ── 常量 ────────────────────────────────────────────────────────────
17
+
18
+ export const DEFAULT_REPUTATION = 50;
19
+ export const REPUTATION_MIN = 0;
20
+ export const REPUTATION_MAX = 100;
21
+ export const REVISION_LIMIT = 3;
22
+
23
+ export interface FitWeights {
24
+ capability: number;
25
+ loadFairness: number;
26
+ reputation: number;
27
+ relationship: number;
28
+ interest: number;
29
+ }
30
+
31
+ /** 默认适配度权重,五项之和 = 1。 */
32
+ export const DEFAULT_FIT_WEIGHTS: FitWeights = {
33
+ capability: 0.45,
34
+ loadFairness: 0.2,
35
+ reputation: 0.2,
36
+ relationship: 0.1,
37
+ interest: 0.05,
38
+ };
39
+
40
+ export interface FitBreakdown {
41
+ capability: number;
42
+ loadFairness: number;
43
+ reputation: number;
44
+ relationshipBonus: number;
45
+ interest: number;
46
+ score: number;
47
+ }
48
+
49
+ // ── 能力 / 容量 ─────────────────────────────────────────────────────
50
+
51
+ /** 所需能力在 worker 身上的覆盖率(0..1)。无要求时返回 1(任意 worker 适配)。 */
52
+ export function capabilityMatchScore(required: string[], worker: WorkerProfile): number {
53
+ if (required.length === 0) return 1;
54
+ const skills = new Set(worker.capabilities.map((c) => c.skill.toLowerCase()));
55
+ let matched = 0;
56
+ for (const r of required) {
57
+ if (skills.has(r.toLowerCase())) matched += 1;
58
+ }
59
+ return matched / required.length;
60
+ }
61
+
62
+ /** 兴趣与所需能力的重合度(0..1)。 */
63
+ export function interestOverlap(required: string[], interests: string[]): number {
64
+ if (required.length === 0) return 0;
65
+ const want = new Set(interests.map((i) => i.toLowerCase()));
66
+ let hit = 0;
67
+ for (const r of required) {
68
+ if (want.has(r.toLowerCase())) hit += 1;
69
+ }
70
+ return hit / required.length;
71
+ }
72
+
73
+ /** worker 是否已达并发上限。 */
74
+ export function isAtCapacity(worker: WorkerProfile): boolean {
75
+ return worker.activeTaskCount >= worker.maxConcurrent;
76
+ }
77
+
78
+ /** 是否能对某 Need 自荐:广场仍开放 + 未超载 + 非自发自选 + 有能力。 */
79
+ export function canVolunteer(need: PublishedNeed, worker: WorkerProfile): boolean {
80
+ if (need.status !== 'open') return false;
81
+ if (isAtCapacity(worker)) return false;
82
+ if (need.postedBy === worker.workerId) return false;
83
+ // 必须至少满足一项所需能力(无要求时视为适配)。
84
+ return capabilityMatchScore(need.requiredCapabilities, worker) > 0;
85
+ }
86
+
87
+ /**
88
+ * 开放需求「为何无人自荐」的停滞归因(供弹卡给用户可操作的反馈,而非让 need 永远卡 open)。
89
+ * 复用 canVolunteer 判「是否还有人能接」;无人能接时再区分:没人有能力 vs 有能力但都满载。
90
+ * 返回 null = 未停滞(非 open / 已有自荐者 / 仍有 worker 可接,只是还没触发自治)。
91
+ */
92
+ export type NeedStallReason = 'no_matching_worker' | 'workers_at_capacity';
93
+
94
+ export function classifyOpenNeedStall(
95
+ need: PublishedNeed,
96
+ workers: readonly WorkerProfile[]
97
+ ): NeedStallReason | null {
98
+ if (need.status !== 'open' || need.volunteers.length > 0) return null;
99
+ if (workers.some((w) => canVolunteer(need, w))) return null;
100
+ const capable = workers.filter(
101
+ (w) => w.workerId !== need.postedBy && capabilityMatchScore(need.requiredCapabilities, w) > 0
102
+ );
103
+ return capable.length > 0 ? 'workers_at_capacity' : 'no_matching_worker';
104
+ }
105
+
106
+ // ── 适配度 ──────────────────────────────────────────────────────────
107
+
108
+ /**
109
+ * 计算 worker 对某 Need 的综合适配度。
110
+ * 各因子 ∈ [0,1],按权重加权,score ∈ [0,1]。
111
+ * relationshipBonus = worker→postedBy 的信任度(无关系则 0)。
112
+ */
113
+ export function computeFitScore(
114
+ need: PublishedNeed,
115
+ worker: WorkerProfile,
116
+ relationships: Relationship[] = [],
117
+ weights: FitWeights = DEFAULT_FIT_WEIGHTS
118
+ ): FitBreakdown {
119
+ const capability = capabilityMatchScore(need.requiredCapabilities, worker);
120
+ const loadFairness =
121
+ worker.maxConcurrent > 0 ? Math.max(0, 1 - worker.activeTaskCount / worker.maxConcurrent) : 0;
122
+ const reputation = clamp01(worker.reputation / REPUTATION_MAX);
123
+ const relToPoster =
124
+ relationships.find((r) => r.fromWorker === worker.workerId && r.toWorker === need.postedBy)
125
+ ?.trust ?? 0;
126
+ const relationshipBonus = relToPoster;
127
+ const interest = interestOverlap(need.requiredCapabilities, worker.interests);
128
+
129
+ const score =
130
+ weights.capability * capability +
131
+ weights.loadFairness * loadFairness +
132
+ weights.reputation * reputation +
133
+ weights.relationship * relationshipBonus +
134
+ weights.interest * interest;
135
+
136
+ return {
137
+ capability,
138
+ loadFairness,
139
+ reputation,
140
+ relationshipBonus,
141
+ interest,
142
+ score,
143
+ };
144
+ }
145
+
146
+ // ── 选择 / 发现 ─────────────────────────────────────────────────────
147
+
148
+ /**
149
+ * 在自荐者中选出执行者。
150
+ * 规则:取适配度最高者;同分按声誉高者;再同分按负载低者;仍同分取 workerId 字典序(稳定)。
151
+ * 返回 null 表示无可选者(自荐为空或全部无效)。
152
+ */
153
+ export function selectAssignee(
154
+ need: PublishedNeed,
155
+ workersById: ReadonlyMap<string, WorkerProfile>,
156
+ relationships: Relationship[] = [],
157
+ weights: FitWeights = DEFAULT_FIT_WEIGHTS
158
+ ): Volunteer | null {
159
+ const eligible = need.volunteers.filter((v) => {
160
+ const w = workersById.get(v.workerId);
161
+ return w && !isAtCapacity(w) && need.postedBy !== v.workerId;
162
+ });
163
+ if (eligible.length === 0) return null;
164
+
165
+ const scored = eligible.map((v) => {
166
+ const w = workersById.get(v.workerId)!;
167
+ return { v, fit: computeFitScore(need, w, relationships, weights) };
168
+ });
169
+
170
+ scored.sort((a, b) => {
171
+ if (b.fit.score !== a.fit.score) return b.fit.score - a.fit.score;
172
+ const wa = workersById.get(a.v.workerId)!;
173
+ const wb = workersById.get(b.v.workerId)!;
174
+ if (wb.reputation !== wa.reputation) return wb.reputation - wa.reputation;
175
+ if (wa.activeTaskCount !== wb.activeTaskCount) return wa.activeTaskCount - wb.activeTaskCount;
176
+ return a.v.workerId.localeCompare(b.v.workerId);
177
+ });
178
+
179
+ return scored[0].v;
180
+ }
181
+
182
+ // ── 自组织驱动(自治大脑)──────────────────────────────────────────
183
+
184
+ export interface AutonomousVolunteerDecision {
185
+ needId: string;
186
+ workerId: string;
187
+ fitScore: number;
188
+ }
189
+
190
+ export interface AutonomyOptions {
191
+ /** 每个需求本轮最多收多少个自荐者(含已存在的自荐者)。 */
192
+ maxVolunteersPerNeed?: number;
193
+ /** 每个 worker 本轮最多主动认领多少个需求。 */
194
+ maxNeedsPerWorker?: number;
195
+ }
196
+
197
+ const DEFAULT_MAX_VOLUNTEERS_PER_NEED = 3;
198
+ const DEFAULT_MAX_NEEDS_PER_WORKER = 1;
199
+
200
+ /**
201
+ * 自组织驱动(纯函数):给定当前 open 需求与 worker 花名册,决定本轮「谁去自荐哪个需求」。
202
+ *
203
+ * 这是「worker 自治」替代「派单」的核心:没有中心 dispatcher,能干且在线的 worker
204
+ * 主动认领自己擅长的事,模拟社会中人对机会的自发响应。
205
+ *
206
+ * 候选条件(在 canVolunteer 之上再加自治约束):
207
+ * - 需求状态为 open;
208
+ * - worker 在线(离线者不主动行动);
209
+ * - 该 worker 尚未自荐过此需求(避免重复);
210
+ * - canVolunteer(广场开放 + 未超载 + 非自发 + 有能力)。
211
+ *
212
+ * 分配:把所有「(需求, worker) 候选对」按适配度降序贪心匹配,受双向配额约束——
213
+ * 每个 worker 每轮最多认领 maxNeedsPerWorker 个(默认 1,专注),
214
+ * 每个需求最多收 maxVolunteersPerNeed 个自荐者(含已存在的,默认 3)。
215
+ *
216
+ * 纯函数:不读时钟、不落盘、不改入参。
217
+ */
218
+ export function autonomousVolunteers(
219
+ openNeeds: readonly PublishedNeed[],
220
+ workers: readonly WorkerProfile[],
221
+ relationships: readonly Relationship[] = [],
222
+ opts: AutonomyOptions = {}
223
+ ): AutonomousVolunteerDecision[] {
224
+ const maxPerNeed = opts.maxVolunteersPerNeed ?? DEFAULT_MAX_VOLUNTEERS_PER_NEED;
225
+ const maxPerWorker = opts.maxNeedsPerWorker ?? DEFAULT_MAX_NEEDS_PER_WORKER;
226
+ // 入参声明为 readonly(纯函数契约:不改入参);这里取一份可变引用供下游 computeFitScore 复用。
227
+ const rels = [...relationships];
228
+
229
+ // 收集所有候选对,并按适配度降序排(稳定排序,同分保持输入顺序)。
230
+ const pairs: AutonomousVolunteerDecision[] = [];
231
+ for (const need of openNeeds) {
232
+ if (need.status !== 'open') continue;
233
+ const already = new Set(need.volunteers.map((v) => v.workerId));
234
+ for (const w of workers) {
235
+ if (w.status === 'offline') continue;
236
+ if (already.has(w.workerId)) continue;
237
+ if (!canVolunteer(need, w)) continue;
238
+ pairs.push({
239
+ needId: need.needId,
240
+ workerId: w.workerId,
241
+ fitScore: computeFitScore(need, w, rels).score,
242
+ });
243
+ }
244
+ }
245
+ pairs.sort((a, b) => b.fitScore - a.fitScore);
246
+
247
+ // 贪心分配,受双向配额约束。needCount 以「已存在的自荐者数」为起点,
248
+ // 这样 per-need 上限会把历史自荐者一并计入。
249
+ const needCount = new Map<string, number>(openNeeds.map((n) => [n.needId, n.volunteers.length]));
250
+ const workerCount = new Map<string, number>();
251
+ const decisions: AutonomousVolunteerDecision[] = [];
252
+ for (const p of pairs) {
253
+ const wUsed = workerCount.get(p.workerId) ?? 0;
254
+ const nUsed = needCount.get(p.needId) ?? 0;
255
+ if (wUsed >= maxPerWorker) continue;
256
+ if (nUsed >= maxPerNeed) continue;
257
+ decisions.push(p);
258
+ workerCount.set(p.workerId, wUsed + 1);
259
+ needCount.set(p.needId, nUsed + 1);
260
+ }
261
+ return decisions;
262
+ }
263
+
264
+ /**
265
+ * 按能力查询 worker 花名册,按声誉降序、负载升序排序。
266
+ * onlineOnly 默认 true;返回前 limit 条(默认全部)。
267
+ */
268
+ export function discoverWorkers(
269
+ workers: readonly WorkerProfile[],
270
+ query: WorkerDiscoveryQuery = {}
271
+ ): WorkerProfile[] {
272
+ const onlineOnly = query.onlineOnly ?? true;
273
+ const required = (query.anyCapability ?? []).map((s) => s.toLowerCase());
274
+ const requireSet = new Set(required);
275
+
276
+ const filtered = workers.filter((w) => {
277
+ if (onlineOnly && w.status === 'offline') return false;
278
+ if (requireSet.size === 0) return true;
279
+ const skills = new Set(w.capabilities.map((c) => c.skill.toLowerCase()));
280
+ for (const r of requireSet) {
281
+ if (skills.has(r)) return true;
282
+ }
283
+ return false;
284
+ });
285
+
286
+ filtered.sort((a, b) => {
287
+ if (b.reputation !== a.reputation) return b.reputation - a.reputation;
288
+ if (a.activeTaskCount !== b.activeTaskCount) return a.activeTaskCount - b.activeTaskCount;
289
+ return a.workerId.localeCompare(b.workerId);
290
+ });
291
+
292
+ const limit = query.limit;
293
+ return typeof limit === 'number' && limit > 0 ? filtered.slice(0, limit) : filtered;
294
+ }
295
+
296
+ // ── 自荐(守卫式,不可变) ─────────────────────────────────────────
297
+
298
+ export interface VolunteerOutcome {
299
+ ok: boolean;
300
+ need: PublishedNeed;
301
+ volunteer?: Volunteer;
302
+ reason?: string;
303
+ }
304
+
305
+ /**
306
+ * worker 对 Need 自荐。返回带守卫结果的(不可变)新 Need。
307
+ * 失败原因:not_open / at_capacity / self_assign / no_capability / already_volunteered。
308
+ */
309
+ export function volunteerFor(
310
+ need: PublishedNeed,
311
+ worker: WorkerProfile,
312
+ now: string,
313
+ relationships: Relationship[] = [],
314
+ weights: FitWeights = DEFAULT_FIT_WEIGHTS
315
+ ): VolunteerOutcome {
316
+ if (need.status !== 'open') {
317
+ return { ok: false, need, reason: 'not_open' };
318
+ }
319
+ if (need.postedBy === worker.workerId) {
320
+ return { ok: false, need, reason: 'self_assign' };
321
+ }
322
+ if (isAtCapacity(worker)) {
323
+ return { ok: false, need, reason: 'at_capacity' };
324
+ }
325
+ if (need.volunteers.some((v) => v.workerId === worker.workerId)) {
326
+ return { ok: false, need, reason: 'already_volunteered' };
327
+ }
328
+ if (capabilityMatchScore(need.requiredCapabilities, worker) <= 0) {
329
+ return { ok: false, need, reason: 'no_capability' };
330
+ }
331
+ const fit = computeFitScore(need, worker, relationships, weights);
332
+ const volunteer: Volunteer = {
333
+ workerId: worker.workerId,
334
+ needId: need.needId,
335
+ fitScore: fit.score,
336
+ volunteeredAt: now,
337
+ };
338
+ return {
339
+ ok: true,
340
+ need: { ...need, volunteers: [...need.volunteers, volunteer] },
341
+ volunteer,
342
+ };
343
+ }
344
+
345
+ // ── Need 状态机(不可变转换) ──────────────────────────────────────
346
+
347
+ export interface NeedTransition {
348
+ ok: boolean;
349
+ need: PublishedNeed;
350
+ reason?: string;
351
+ }
352
+
353
+ /** 合法的正向转换表。 */
354
+ const ALLOWED_TRANSITIONS: Record<NeedStatusKey, NeedStatusKey[]> = {
355
+ open: ['assigned', 'expired', 'cancelled'],
356
+ assigned: ['in_progress', 'cancelled'],
357
+ in_progress: ['delivered'],
358
+ delivered: ['closed', 'in_progress'],
359
+ closed: [],
360
+ expired: [],
361
+ cancelled: [],
362
+ };
363
+ type NeedStatusKey = PublishedNeed['status'];
364
+
365
+ /**
366
+ * 对 Need 做状态转换。非法转换返回 ok:false 且 Need 不变。
367
+ * `assignee` 仅在 assigned 时写入;`result` 仅在 delivered 时写入。
368
+ */
369
+ export function transitionNeed(
370
+ need: PublishedNeed,
371
+ next: PublishedNeed['status'],
372
+ now: string,
373
+ patch: { assignee?: string; result?: string } = {}
374
+ ): NeedTransition {
375
+ const allowed = ALLOWED_TRANSITIONS[need.status] ?? [];
376
+ if (!allowed.includes(next)) {
377
+ return { ok: false, need, reason: `illegal:${need.status}->${next}` };
378
+ }
379
+ const updated: PublishedNeed = { ...need, status: next };
380
+ if (next === 'assigned') {
381
+ if (!patch.assignee) return { ok: false, need, reason: 'missing_assignee' };
382
+ updated.assignee = patch.assignee;
383
+ updated.assignedAt = now;
384
+ }
385
+ if (next === 'in_progress') {
386
+ updated.startedAt = now;
387
+ }
388
+ if (next === 'delivered') {
389
+ updated.result = patch.result ?? updated.result;
390
+ updated.deliveredAt = now;
391
+ updated.revisionCount = need.revisionCount; // 退回重做不增加;显式 revision 才增加
392
+ }
393
+ if (next === 'closed') {
394
+ updated.closedAt = now;
395
+ }
396
+ return { ok: true, need: updated };
397
+ }
398
+
399
+ /** 审核退回:delivered → in_progress,并递增 revisionCount;超 REVISION_LIMIT 触发 escalate。 */
400
+ export function requestRevision(need: PublishedNeed, now: string): NeedTransition {
401
+ if (need.status !== 'delivered') {
402
+ return { ok: false, need, reason: `illegal:${need.status}->revision` };
403
+ }
404
+ const revisionCount = need.revisionCount + 1;
405
+ return {
406
+ ok: true,
407
+ need: {
408
+ ...need,
409
+ status: 'in_progress',
410
+ startedAt: now,
411
+ revisionCount,
412
+ },
413
+ reason: revisionCount > REVISION_LIMIT ? 'revision_limit_exceeded' : undefined,
414
+ };
415
+ }
416
+
417
+ // ── 关系 / 声誉 ─────────────────────────────────────────────────────
418
+
419
+ /**
420
+ * 记录一次协作结果,返回更新后的关系集合(不可变)。
421
+ * - 新关系:collaborations=1, successes = success?1:0, trust=success?1:0。
422
+ * - 已有关系:累加,trust 重算 = successes/collaborations。
423
+ * 关系是有向的:a→b 与 b→a 各自独立记录。
424
+ */
425
+ export function recordCollaboration(
426
+ relationships: readonly Relationship[],
427
+ fromWorker: string,
428
+ toWorker: string,
429
+ success: boolean,
430
+ now: string
431
+ ): Relationship[] {
432
+ const idx = relationships.findIndex(
433
+ (r) => r.fromWorker === fromWorker && r.toWorker === toWorker
434
+ );
435
+ if (idx < 0) {
436
+ const rel: Relationship = {
437
+ fromWorker,
438
+ toWorker,
439
+ collaborations: 1,
440
+ successes: success ? 1 : 0,
441
+ trust: success ? 1 : 0,
442
+ lastInteractedAt: now,
443
+ };
444
+ return [...relationships, rel];
445
+ }
446
+ const prev = relationships[idx];
447
+ const collaborations = prev.collaborations + 1;
448
+ const successes = prev.successes + (success ? 1 : 0);
449
+ const next: Relationship = {
450
+ ...prev,
451
+ collaborations,
452
+ successes,
453
+ trust: collaborations > 0 ? successes / collaborations : 0,
454
+ lastInteractedAt: now,
455
+ };
456
+ return relationships.map((r, i) => (i === idx ? next : r));
457
+ }
458
+
459
+ /** 把声誉值夹取到领域不变量 [REPUTATION_MIN, REPUTATION_MAX]。 */
460
+ export function clampReputation(value: number): number {
461
+ return clamp(value, REPUTATION_MIN, REPUTATION_MAX);
462
+ }
463
+
464
+ /** 声誉增量,夹取到 [0,100]。 */
465
+ export function applyReputationDelta(profile: WorkerProfile, delta: number): WorkerProfile {
466
+ return {
467
+ ...profile,
468
+ reputation: clampReputation(profile.reputation + delta),
469
+ };
470
+ }
471
+
472
+ /** 协作成功/失败对应的声誉增量(成功 +2,失败 -5,可调)。 */
473
+ export function reputationDeltaForOutcome(success: boolean): number {
474
+ return success ? 2 : -5;
475
+ }
476
+
477
+ /**
478
+ * 仍在交互生命周期内(未终结)的需求状态。
479
+ * 画布据此展示 worker 跑向/停在任务:覆盖 open→assigned→in_progress→delivered,
480
+ * 仅排除已终结(closed/expired/cancelled)——这样 worker 选派后不会丢下任务飘走。
481
+ */
482
+ export const ACTIVE_NEED_STATUSES: PublishedNeed['status'][] = [
483
+ 'open',
484
+ 'assigned',
485
+ 'in_progress',
486
+ 'delivered',
487
+ ];
488
+
489
+ // ── helpers ────────────────────────────────────────────────────────
490
+
491
+ function clamp(n: number, min: number, max: number): number {
492
+ return Math.max(min, Math.min(max, n));
493
+ }
494
+ function clamp01(n: number): number {
495
+ return clamp(n, 0, 1);
496
+ }