@yancyyu/openhermit 1.5.8

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 (980) hide show
  1. package/LICENSE +611 -0
  2. package/README.md +220 -0
  3. package/bin/hermit.mjs +364 -0
  4. package/bin/kill-dev.js +20 -0
  5. package/dist-renderer/assets/01-BApSFlV4.png +0 -0
  6. package/dist-renderer/assets/02-CRQGs29u.png +0 -0
  7. package/dist-renderer/assets/03-BFCM2jnD.png +0 -0
  8. package/dist-renderer/assets/04-B2FThbKO.png +0 -0
  9. package/dist-renderer/assets/05-D9p0Znkd.png +0 -0
  10. package/dist-renderer/assets/06-DZAfbDlP.png +0 -0
  11. package/dist-renderer/assets/07-B_PXWGCc.png +0 -0
  12. package/dist-renderer/assets/08-DGRMZ6sl.png +0 -0
  13. package/dist-renderer/assets/09-SGCQvc7U.png +0 -0
  14. package/dist-renderer/assets/10-Cve81Q3W.png +0 -0
  15. package/dist-renderer/assets/11-DGglolDW.png +0 -0
  16. package/dist-renderer/assets/12-C3lnu79c.png +0 -0
  17. package/dist-renderer/assets/13-M59meqdw.png +0 -0
  18. package/dist-renderer/assets/ProjectEditorOverlay-BNoDw9T1.js +57 -0
  19. package/dist-renderer/assets/TeamGraphOverlay-CfGRKQIu.js +1 -0
  20. package/dist-renderer/assets/_basePickBy-Ct8Hm5_h.js +1 -0
  21. package/dist-renderer/assets/_baseUniq-BofrAFBx.js +1 -0
  22. package/dist-renderer/assets/apl-B4CMkyY2.js +1 -0
  23. package/dist-renderer/assets/arc-AbJgatzR.js +1 -0
  24. package/dist-renderer/assets/architectureDiagram-VXUJARFQ-gpniCJVk.js +36 -0
  25. package/dist-renderer/assets/asciiarmor-Df11BRmG.js +1 -0
  26. package/dist-renderer/assets/asn1-EdZsLKOL.js +1 -0
  27. package/dist-renderer/assets/asterisk-B-8jnY81.js +1 -0
  28. package/dist-renderer/assets/blockDiagram-VD42YOAC-aBbbmONC.js +122 -0
  29. package/dist-renderer/assets/brainfuck-C4LP7Hcl.js +1 -0
  30. package/dist-renderer/assets/c4Diagram-YG6GDRKO-DJio1IsU.js +10 -0
  31. package/dist-renderer/assets/channel-CZ8sd5Xf.js +1 -0
  32. package/dist-renderer/assets/chunk-4BX2VUAB-D1_HKao2.js +1 -0
  33. package/dist-renderer/assets/chunk-55IACEB6-NAmVxF4k.js +1 -0
  34. package/dist-renderer/assets/chunk-B4BG7PRW-Ce829laz.js +165 -0
  35. package/dist-renderer/assets/chunk-DI55MBZ5-Ct2Le12y.js +220 -0
  36. package/dist-renderer/assets/chunk-FMBD7UC4-Cie3DzKk.js +15 -0
  37. package/dist-renderer/assets/chunk-QN33PNHL-4f5Yb50e.js +1 -0
  38. package/dist-renderer/assets/chunk-QZHKN3VN-D9ranl9c.js +1 -0
  39. package/dist-renderer/assets/chunk-TZMSLE5B-bdGZWlEy.js +1 -0
  40. package/dist-renderer/assets/classDiagram-2ON5EDUG-CMcfSKj5.js +1 -0
  41. package/dist-renderer/assets/classDiagram-v2-WZHVMYZB-CMcfSKj5.js +1 -0
  42. package/dist-renderer/assets/clike-B9uivgTg.js +1 -0
  43. package/dist-renderer/assets/clojure-BMjYHr_A.js +1 -0
  44. package/dist-renderer/assets/clone-CMuwA8RV.js +1 -0
  45. package/dist-renderer/assets/cmake-BQqOBYOt.js +1 -0
  46. package/dist-renderer/assets/cobol-CWcv1MsR.js +1 -0
  47. package/dist-renderer/assets/coffeescript-S37ZYGWr.js +1 -0
  48. package/dist-renderer/assets/commonlisp-DBKNyK5s.js +1 -0
  49. package/dist-renderer/assets/cose-bilkent-S5V4N54A-C6tvfcVi.js +1 -0
  50. package/dist-renderer/assets/crystal-SjHAIU92.js +1 -0
  51. package/dist-renderer/assets/css-BnMrqG3P.js +1 -0
  52. package/dist-renderer/assets/cypher-C_CwsFkJ.js +1 -0
  53. package/dist-renderer/assets/cytoscape.esm-DsxaTqgk.js +331 -0
  54. package/dist-renderer/assets/d-pRatUO7H.js +1 -0
  55. package/dist-renderer/assets/dagre-6UL2VRFP-B-4qcZam.js +4 -0
  56. package/dist-renderer/assets/defaultLocale-DX6XiGOO.js +1 -0
  57. package/dist-renderer/assets/diagram-PSM6KHXK-CwT3TLjx.js +24 -0
  58. package/dist-renderer/assets/diagram-QEK2KX5R-BWH6-ZFd.js +43 -0
  59. package/dist-renderer/assets/diagram-S2PKOQOG-DfpPnfi1.js +24 -0
  60. package/dist-renderer/assets/diff-DbItnlRl.js +1 -0
  61. package/dist-renderer/assets/dockerfile-BKs6k2Af.js +1 -0
  62. package/dist-renderer/assets/dtd-DF_7sFjM.js +1 -0
  63. package/dist-renderer/assets/dylan-DwRh75JA.js +1 -0
  64. package/dist-renderer/assets/ebnf-CDyGwa7X.js +1 -0
  65. package/dist-renderer/assets/ecl-Cabwm37j.js +1 -0
  66. package/dist-renderer/assets/eiffel-CnydiIhH.js +1 -0
  67. package/dist-renderer/assets/elm-vLlmbW-K.js +1 -0
  68. package/dist-renderer/assets/erDiagram-Q2GNP2WA-BFbEFR4x.js +60 -0
  69. package/dist-renderer/assets/erlang-BNw1qcRV.js +1 -0
  70. package/dist-renderer/assets/factor-kuTfRLto.js +1 -0
  71. package/dist-renderer/assets/favicon-B8xY-GVk.png +0 -0
  72. package/dist-renderer/assets/fcl-Kvtd6kyn.js +1 -0
  73. package/dist-renderer/assets/flowDiagram-NV44I4VS-Dg3cf5hW.js +162 -0
  74. package/dist-renderer/assets/forth-Ffai-XNe.js +1 -0
  75. package/dist-renderer/assets/fortran-DYz_wnZ1.js +1 -0
  76. package/dist-renderer/assets/ganttDiagram-JELNMOA3-B21y55W5.js +267 -0
  77. package/dist-renderer/assets/gas-Bneqetm1.js +1 -0
  78. package/dist-renderer/assets/gherkin-heZmZLOM.js +1 -0
  79. package/dist-renderer/assets/gitGraphDiagram-V2S2FVAM-BDV3BJzn.js +65 -0
  80. package/dist-renderer/assets/graph-BfaZ4hZt.js +1 -0
  81. package/dist-renderer/assets/groovy-D9Dt4D0W.js +1 -0
  82. package/dist-renderer/assets/haskell-BWDZoCOh.js +1 -0
  83. package/dist-renderer/assets/haxe-H-WmDvRZ.js +1 -0
  84. package/dist-renderer/assets/http-DBlCnlav.js +1 -0
  85. package/dist-renderer/assets/idl-BEugSyMb.js +1 -0
  86. package/dist-renderer/assets/index-BMXHMpkG.js +1 -0
  87. package/dist-renderer/assets/index-CCqtDawH.js +1 -0
  88. package/dist-renderer/assets/index-CVMSpK8C.js +1 -0
  89. package/dist-renderer/assets/index-CZltVMDP.js +1844 -0
  90. package/dist-renderer/assets/index-CaG9mf8s.css +1 -0
  91. package/dist-renderer/assets/index-Ct0-y9TF.js +1 -0
  92. package/dist-renderer/assets/index-pMg_LlsS.js +1 -0
  93. package/dist-renderer/assets/infoDiagram-HS3SLOUP-DvMlS0CL.js +2 -0
  94. package/dist-renderer/assets/init-Gi6I4Gst.js +1 -0
  95. package/dist-renderer/assets/javascript-qCveANmP.js +1 -0
  96. package/dist-renderer/assets/journeyDiagram-XKPGCS4Q-DIyMluRv.js +139 -0
  97. package/dist-renderer/assets/julia-DuME0IfC.js +1 -0
  98. package/dist-renderer/assets/kanban-definition-3W4ZIXB7-CVOx8f-7.js +89 -0
  99. package/dist-renderer/assets/katex-DGN8GczM.js +261 -0
  100. package/dist-renderer/assets/layout-BPKIXUf4.js +1 -0
  101. package/dist-renderer/assets/linear-CScZGLr2.js +1 -0
  102. package/dist-renderer/assets/livescript-BwQOo05w.js +1 -0
  103. package/dist-renderer/assets/lua-BgMRiT3U.js +1 -0
  104. package/dist-renderer/assets/mathematica-DTrFuWx2.js +1 -0
  105. package/dist-renderer/assets/mbox-CNhZ1qSd.js +1 -0
  106. package/dist-renderer/assets/mindmap-definition-VGOIOE7T-CmDQ7Wo6.js +68 -0
  107. package/dist-renderer/assets/mirc-CjQqDB4T.js +1 -0
  108. package/dist-renderer/assets/mllike-CXdrOF99.js +1 -0
  109. package/dist-renderer/assets/modelica-Dc1JOy9r.js +1 -0
  110. package/dist-renderer/assets/mscgen-BA5vi2Kp.js +1 -0
  111. package/dist-renderer/assets/mumps-BT43cFF4.js +1 -0
  112. package/dist-renderer/assets/nginx-DdIZxoE0.js +1 -0
  113. package/dist-renderer/assets/nsis-LdVXkNf5.js +1 -0
  114. package/dist-renderer/assets/ntriples-BfvgReVJ.js +1 -0
  115. package/dist-renderer/assets/octave-Ck1zUtKM.js +1 -0
  116. package/dist-renderer/assets/ordinal-Cboi1Yqb.js +1 -0
  117. package/dist-renderer/assets/oz-BzwKVEFT.js +1 -0
  118. package/dist-renderer/assets/pascal--L3eBynH.js +1 -0
  119. package/dist-renderer/assets/perl-CdXCOZ3F.js +1 -0
  120. package/dist-renderer/assets/pieDiagram-ADFJNKIX-DbVClin-.js +30 -0
  121. package/dist-renderer/assets/pig-CevX1Tat.js +1 -0
  122. package/dist-renderer/assets/powershell-CFHJl5sT.js +1 -0
  123. package/dist-renderer/assets/properties-C78fOPTZ.js +1 -0
  124. package/dist-renderer/assets/protobuf-ChK-085T.js +1 -0
  125. package/dist-renderer/assets/pug-DukmZTjD.js +1 -0
  126. package/dist-renderer/assets/puppet-DMA9R1ak.js +1 -0
  127. package/dist-renderer/assets/python-BuPzkPfP.js +1 -0
  128. package/dist-renderer/assets/q-pXgVlZs6.js +1 -0
  129. package/dist-renderer/assets/quadrantDiagram-AYHSOK5B-CAB0MYcW.js +7 -0
  130. package/dist-renderer/assets/r-DUYO_cvP.js +1 -0
  131. package/dist-renderer/assets/requirementDiagram-UZGBJVZJ-w2Lfpg3T.js +64 -0
  132. package/dist-renderer/assets/rpm-CTu-6PCP.js +1 -0
  133. package/dist-renderer/assets/ruby-B2Rjki9n.js +1 -0
  134. package/dist-renderer/assets/sankeyDiagram-TZEHDZUN-kvG1QoKY.js +10 -0
  135. package/dist-renderer/assets/sas-B4kiWyti.js +1 -0
  136. package/dist-renderer/assets/scheme-C41bIUwD.js +1 -0
  137. package/dist-renderer/assets/sequenceDiagram-WL72ISMW-DCVBQ23J.js +145 -0
  138. package/dist-renderer/assets/shell-CjFT_Tl9.js +1 -0
  139. package/dist-renderer/assets/sieve-C3Gn_uJK.js +1 -0
  140. package/dist-renderer/assets/simple-mode-GW_nhZxv.js +1 -0
  141. package/dist-renderer/assets/smalltalk-CnHTOXQT.js +1 -0
  142. package/dist-renderer/assets/solr-DehyRSwq.js +1 -0
  143. package/dist-renderer/assets/sparql-DkYu6x3z.js +1 -0
  144. package/dist-renderer/assets/splashScene-C8lWNnm4.js +1 -0
  145. package/dist-renderer/assets/spreadsheet-BCZA_wO0.js +1 -0
  146. package/dist-renderer/assets/sql-D0XecflT.js +1 -0
  147. package/dist-renderer/assets/stateDiagram-FKZM4ZOC-ItZ0JBvq.js +1 -0
  148. package/dist-renderer/assets/stateDiagram-v2-4FDKWEC3-Hpmw4dMm.js +1 -0
  149. package/dist-renderer/assets/stex-C3f8Ysf7.js +1 -0
  150. package/dist-renderer/assets/stylus-B533Al4x.js +1 -0
  151. package/dist-renderer/assets/swift-BzpIVaGY.js +1 -0
  152. package/dist-renderer/assets/tcl-DVfN8rqt.js +1 -0
  153. package/dist-renderer/assets/textile-CnDTJFAw.js +1 -0
  154. package/dist-renderer/assets/tiddlywiki-DO-Gjzrf.js +1 -0
  155. package/dist-renderer/assets/tiki-DGYXhP31.js +1 -0
  156. package/dist-renderer/assets/timeline-definition-IT6M3QCI-BzSFaAjV.js +61 -0
  157. package/dist-renderer/assets/toml-Bm5Em-hy.js +1 -0
  158. package/dist-renderer/assets/treemap-GDKQZRPO-fSz4hQn0.js +162 -0
  159. package/dist-renderer/assets/troff-wAsdV37c.js +1 -0
  160. package/dist-renderer/assets/ttcn-CfJYG6tj.js +1 -0
  161. package/dist-renderer/assets/ttcn-cfg-B9xdYoR4.js +1 -0
  162. package/dist-renderer/assets/turtle-B1tBg_DP.js +1 -0
  163. package/dist-renderer/assets/vb-CmGdzxic.js +1 -0
  164. package/dist-renderer/assets/vbscript-BuJXcnF6.js +1 -0
  165. package/dist-renderer/assets/velocity-D8B20fx6.js +1 -0
  166. package/dist-renderer/assets/verilog-C6RDOZhf.js +1 -0
  167. package/dist-renderer/assets/vhdl-lSbBsy5d.js +1 -0
  168. package/dist-renderer/assets/webidl-ZXfAyPTL.js +1 -0
  169. package/dist-renderer/assets/xquery-CQfU5ijd.js +1 -0
  170. package/dist-renderer/assets/xychartDiagram-PRI3JC2R-CT1kaGlv.js +7 -0
  171. package/dist-renderer/assets/yacas-BJ4BC0dw.js +1 -0
  172. package/dist-renderer/assets/z80-Hz9HOZM7.js +1 -0
  173. package/dist-renderer/index.html +1274 -0
  174. package/package.json +181 -0
  175. package/src/features/README.md +24 -0
  176. package/src/features/agent-graph/README.md +21 -0
  177. package/src/features/agent-graph/STABLE_SLOT_LAYOUT_PLAN.md +2846 -0
  178. package/src/features/agent-graph/core/domain/buildInlineActivityEntries.ts +416 -0
  179. package/src/features/agent-graph/core/domain/collapseOverflowStacks.ts +126 -0
  180. package/src/features/agent-graph/core/domain/graphOwnerIdentity.ts +55 -0
  181. package/src/features/agent-graph/core/domain/taskGraphSemantics.ts +48 -0
  182. package/src/features/agent-graph/renderer/adapters/TeamGraphAdapter.ts +1400 -0
  183. package/src/features/agent-graph/renderer/hooks/useGraphActivityContext.ts +34 -0
  184. package/src/features/agent-graph/renderer/hooks/useGraphCreateTaskDialog.tsx +126 -0
  185. package/src/features/agent-graph/renderer/hooks/useGraphMemberPopoverContext.ts +34 -0
  186. package/src/features/agent-graph/renderer/hooks/useGraphSidebarVisibility.ts +52 -0
  187. package/src/features/agent-graph/renderer/hooks/useTeamGraphAdapter.ts +173 -0
  188. package/src/features/agent-graph/renderer/hooks/useTeamGraphSurfaceActions.ts +98 -0
  189. package/src/features/agent-graph/renderer/index.ts +14 -0
  190. package/src/features/agent-graph/renderer/ui/GraphActivityCard.tsx +96 -0
  191. package/src/features/agent-graph/renderer/ui/GraphActivityHud.tsx +498 -0
  192. package/src/features/agent-graph/renderer/ui/GraphBlockingEdgePopover.tsx +207 -0
  193. package/src/features/agent-graph/renderer/ui/GraphNodePopover.tsx +573 -0
  194. package/src/features/agent-graph/renderer/ui/GraphProvisioningHud.tsx +113 -0
  195. package/src/features/agent-graph/renderer/ui/GraphTaskCard.tsx +149 -0
  196. package/src/features/agent-graph/renderer/ui/GraphTransientHandoffHud.tsx +176 -0
  197. package/src/features/agent-graph/renderer/ui/TeamGraphOverlay.tsx +224 -0
  198. package/src/features/agent-graph/renderer/ui/TeamGraphTab.tsx +257 -0
  199. package/src/features/agent-graph/renderer/ui/buildTransientHandoffMessage.ts +70 -0
  200. package/src/features/recent-projects/contracts/api.ts +5 -0
  201. package/src/features/recent-projects/contracts/channels.ts +2 -0
  202. package/src/features/recent-projects/contracts/dto.ts +24 -0
  203. package/src/features/recent-projects/contracts/index.ts +4 -0
  204. package/src/features/recent-projects/contracts/normalize.ts +32 -0
  205. package/src/features/recent-projects/core/application/models/ListDashboardRecentProjectsResponse.ts +6 -0
  206. package/src/features/recent-projects/core/application/ports/ClockPort.ts +3 -0
  207. package/src/features/recent-projects/core/application/ports/ListDashboardRecentProjectsOutputPort.ts +5 -0
  208. package/src/features/recent-projects/core/application/ports/LoggerPort.ts +5 -0
  209. package/src/features/recent-projects/core/application/ports/RecentProjectsCachePort.ts +5 -0
  210. package/src/features/recent-projects/core/application/ports/RecentProjectsSourcePort.ts +14 -0
  211. package/src/features/recent-projects/core/application/use-cases/ListDashboardRecentProjectsUseCase.ts +191 -0
  212. package/src/features/recent-projects/core/domain/models/ProviderId.ts +1 -0
  213. package/src/features/recent-projects/core/domain/models/RecentProjectAggregate.ts +14 -0
  214. package/src/features/recent-projects/core/domain/models/RecentProjectCandidate.ts +14 -0
  215. package/src/features/recent-projects/core/domain/models/RecentProjectOpenTarget.ts +3 -0
  216. package/src/features/recent-projects/core/domain/policies/mergeRecentProjectCandidates.ts +88 -0
  217. package/src/features/recent-projects/main/adapters/input/http/registerRecentProjectsHttp.ts +30 -0
  218. package/src/features/recent-projects/main/adapters/output/presenters/DashboardRecentProjectsPresenter.ts +27 -0
  219. package/src/features/recent-projects/main/adapters/output/sources/ClaudeRecentProjectsSourceAdapter.ts +91 -0
  220. package/src/features/recent-projects/main/adapters/output/sources/CodexRecentProjectsSourceAdapter.ts +326 -0
  221. package/src/features/recent-projects/main/composition/createRecentProjectsFeature.ts +43 -0
  222. package/src/features/recent-projects/main/index.ts +3 -0
  223. package/src/features/recent-projects/main/infrastructure/cache/InMemoryRecentProjectsCache.ts +34 -0
  224. package/src/features/recent-projects/main/infrastructure/codex/CodexAppServerClient.ts +116 -0
  225. package/src/features/recent-projects/main/infrastructure/identity/RecentProjectIdentityResolver.ts +20 -0
  226. package/src/features/recent-projects/main/infrastructure/identity/normalizeIdentityPath.ts +10 -0
  227. package/src/features/recent-projects/renderer/adapters/RecentProjectsSectionAdapter.ts +132 -0
  228. package/src/features/recent-projects/renderer/hooks/useOpenRecentProject.ts +143 -0
  229. package/src/features/recent-projects/renderer/hooks/useRecentProjectsSection.ts +289 -0
  230. package/src/features/recent-projects/renderer/index.ts +2 -0
  231. package/src/features/recent-projects/renderer/ui/RecentProjectCard.tsx +221 -0
  232. package/src/features/recent-projects/renderer/ui/RecentProjectsSection.tsx +167 -0
  233. package/src/features/recent-projects/renderer/utils/activeProjectTeams.ts +48 -0
  234. package/src/features/recent-projects/renderer/utils/navigation.ts +65 -0
  235. package/src/features/recent-projects/renderer/utils/projectDecorations.ts +11 -0
  236. package/src/features/recent-projects/renderer/utils/recentProjectOpenHistory.ts +268 -0
  237. package/src/features/recent-projects/renderer/utils/recentProjectsClientCache.ts +78 -0
  238. package/src/main/constants/messageTags.ts +46 -0
  239. package/src/main/constants/worktreePatterns.ts +47 -0
  240. package/src/main/server.ts +3705 -0
  241. package/src/main/services/UpdateService.ts +166 -0
  242. package/src/main/services/ccConnect/CcConnectBridge.ts +313 -0
  243. package/src/main/services/ccConnect/CcConnectClient.ts +397 -0
  244. package/src/main/services/ccConnect/MessageBridge.ts +162 -0
  245. package/src/main/services/ccConnect/ProjectMappingStore.ts +148 -0
  246. package/src/main/services/ccConnect/index.ts +8 -0
  247. package/src/main/services/teams-mvp/TeamProvisioningService.ts +275 -0
  248. package/src/main/services/teams-mvp/TeamWorkspaceService.ts +404 -0
  249. package/src/main/services/teams-mvp/index.ts +26 -0
  250. package/src/main/types/chunks.ts +506 -0
  251. package/src/main/types/domain.ts +342 -0
  252. package/src/main/types/index.ts +24 -0
  253. package/src/main/types/jsonl.ts +355 -0
  254. package/src/main/types/messages.ts +395 -0
  255. package/src/renderer/App.tsx +287 -0
  256. package/src/renderer/api/httpClient.ts +2207 -0
  257. package/src/renderer/api/index.ts +19 -0
  258. package/src/renderer/api/providers.ts +77 -0
  259. package/src/renderer/assets/participant-avatars/01.png +0 -0
  260. package/src/renderer/assets/participant-avatars/02.png +0 -0
  261. package/src/renderer/assets/participant-avatars/03.png +0 -0
  262. package/src/renderer/assets/participant-avatars/04.png +0 -0
  263. package/src/renderer/assets/participant-avatars/05.png +0 -0
  264. package/src/renderer/assets/participant-avatars/06.png +0 -0
  265. package/src/renderer/assets/participant-avatars/07.png +0 -0
  266. package/src/renderer/assets/participant-avatars/08.png +0 -0
  267. package/src/renderer/assets/participant-avatars/09.png +0 -0
  268. package/src/renderer/assets/participant-avatars/10.png +0 -0
  269. package/src/renderer/assets/participant-avatars/11.png +0 -0
  270. package/src/renderer/assets/participant-avatars/12.png +0 -0
  271. package/src/renderer/assets/participant-avatars/13.png +0 -0
  272. package/src/renderer/components/chat/AIChatGroup.tsx +519 -0
  273. package/src/renderer/components/chat/ChatHistory.tsx +1115 -0
  274. package/src/renderer/components/chat/ChatHistoryEmptyState.tsx +15 -0
  275. package/src/renderer/components/chat/ChatHistoryItem.tsx +144 -0
  276. package/src/renderer/components/chat/ChatHistoryLoadingState.tsx +45 -0
  277. package/src/renderer/components/chat/CompactBoundary.tsx +169 -0
  278. package/src/renderer/components/chat/ContextBadge.tsx +582 -0
  279. package/src/renderer/components/chat/DisplayItemList.tsx +431 -0
  280. package/src/renderer/components/chat/LastOutputDisplay.tsx +259 -0
  281. package/src/renderer/components/chat/SessionContextPanel/DirectoryTree/DirectoryTreeNode.tsx +125 -0
  282. package/src/renderer/components/chat/SessionContextPanel/DirectoryTree/buildDirectoryTree.ts +47 -0
  283. package/src/renderer/components/chat/SessionContextPanel/DirectoryTree/types.ts +12 -0
  284. package/src/renderer/components/chat/SessionContextPanel/components/ClaudeMdFilesSection.tsx +90 -0
  285. package/src/renderer/components/chat/SessionContextPanel/components/ClaudeMdSection.tsx +86 -0
  286. package/src/renderer/components/chat/SessionContextPanel/components/CollapsibleSection.tsx +77 -0
  287. package/src/renderer/components/chat/SessionContextPanel/components/FlatInjectionList.tsx +248 -0
  288. package/src/renderer/components/chat/SessionContextPanel/components/MentionedFilesSection.tsx +50 -0
  289. package/src/renderer/components/chat/SessionContextPanel/components/RankedInjectionList.tsx +284 -0
  290. package/src/renderer/components/chat/SessionContextPanel/components/SessionContextHeader.tsx +290 -0
  291. package/src/renderer/components/chat/SessionContextPanel/components/SessionContextHelpTooltip.tsx +165 -0
  292. package/src/renderer/components/chat/SessionContextPanel/components/TaskCoordinationSection.tsx +47 -0
  293. package/src/renderer/components/chat/SessionContextPanel/components/ThinkingTextSection.tsx +47 -0
  294. package/src/renderer/components/chat/SessionContextPanel/components/ToolOutputsSection.tsx +47 -0
  295. package/src/renderer/components/chat/SessionContextPanel/components/UserMessagesSection.tsx +47 -0
  296. package/src/renderer/components/chat/SessionContextPanel/index.tsx +314 -0
  297. package/src/renderer/components/chat/SessionContextPanel/items/ClaudeMdItem.tsx +76 -0
  298. package/src/renderer/components/chat/SessionContextPanel/items/MentionedFileItem.tsx +91 -0
  299. package/src/renderer/components/chat/SessionContextPanel/items/TaskCoordinationItem.tsx +116 -0
  300. package/src/renderer/components/chat/SessionContextPanel/items/ThinkingTextItem.tsx +96 -0
  301. package/src/renderer/components/chat/SessionContextPanel/items/ToolBreakdownItem.tsx +38 -0
  302. package/src/renderer/components/chat/SessionContextPanel/items/ToolOutputItem.tsx +113 -0
  303. package/src/renderer/components/chat/SessionContextPanel/items/UserMessageItem.tsx +69 -0
  304. package/src/renderer/components/chat/SessionContextPanel/types.ts +96 -0
  305. package/src/renderer/components/chat/SessionContextPanel/utils/formatting.ts +6 -0
  306. package/src/renderer/components/chat/SessionContextPanel/utils/pathParsing.ts +23 -0
  307. package/src/renderer/components/chat/SystemChatGroup.tsx +60 -0
  308. package/src/renderer/components/chat/UserChatGroup.tsx +668 -0
  309. package/src/renderer/components/chat/items/BaseItem.tsx +213 -0
  310. package/src/renderer/components/chat/items/ExecutionTrace.tsx +279 -0
  311. package/src/renderer/components/chat/items/LinkedToolItem.tsx +235 -0
  312. package/src/renderer/components/chat/items/MetricsPill.tsx +215 -0
  313. package/src/renderer/components/chat/items/SlashItem.tsx +81 -0
  314. package/src/renderer/components/chat/items/SubagentItem.tsx +592 -0
  315. package/src/renderer/components/chat/items/TeammateMessageItem.tsx +261 -0
  316. package/src/renderer/components/chat/items/TextItem.tsx +82 -0
  317. package/src/renderer/components/chat/items/ThinkingItem.tsx +82 -0
  318. package/src/renderer/components/chat/items/baseItemHelpers.ts +42 -0
  319. package/src/renderer/components/chat/items/linkedTool/CollapsibleOutputSection.tsx +57 -0
  320. package/src/renderer/components/chat/items/linkedTool/DefaultToolViewer.tsx +56 -0
  321. package/src/renderer/components/chat/items/linkedTool/EditToolViewer.tsx +74 -0
  322. package/src/renderer/components/chat/items/linkedTool/ReadToolViewer.tsx +102 -0
  323. package/src/renderer/components/chat/items/linkedTool/SkillToolViewer.tsx +67 -0
  324. package/src/renderer/components/chat/items/linkedTool/ToolErrorDisplay.tsx +43 -0
  325. package/src/renderer/components/chat/items/linkedTool/WriteToolViewer.tsx +66 -0
  326. package/src/renderer/components/chat/items/linkedTool/index.ts +13 -0
  327. package/src/renderer/components/chat/items/linkedTool/renderHelpers.tsx +259 -0
  328. package/src/renderer/components/chat/markdownComponents.tsx +257 -0
  329. package/src/renderer/components/chat/markdownCopyUtils.ts +18 -0
  330. package/src/renderer/components/chat/searchHighlightUtils.ts +166 -0
  331. package/src/renderer/components/chat/viewers/CodeBlockViewer.tsx +244 -0
  332. package/src/renderer/components/chat/viewers/DiffViewer.tsx +459 -0
  333. package/src/renderer/components/chat/viewers/FileLink.tsx +182 -0
  334. package/src/renderer/components/chat/viewers/MarkdownViewer.tsx +1093 -0
  335. package/src/renderer/components/chat/viewers/MermaidDiagram.tsx +116 -0
  336. package/src/renderer/components/chat/viewers/index.ts +3 -0
  337. package/src/renderer/components/chat/viewers/syntaxHighlighter.ts +583 -0
  338. package/src/renderer/components/common/AppLogo.tsx +61 -0
  339. package/src/renderer/components/common/CliInstallWarningBanner.tsx +57 -0
  340. package/src/renderer/components/common/ConfirmDialog.tsx +176 -0
  341. package/src/renderer/components/common/ConnectionStatusBadge.tsx +56 -0
  342. package/src/renderer/components/common/ContextSwitchOverlay.tsx +38 -0
  343. package/src/renderer/components/common/CopyButton.tsx +85 -0
  344. package/src/renderer/components/common/CopyablePath.tsx +68 -0
  345. package/src/renderer/components/common/ErrorBoundary.tsx +211 -0
  346. package/src/renderer/components/common/ExportDropdown.tsx +142 -0
  347. package/src/renderer/components/common/FileTree.tsx +182 -0
  348. package/src/renderer/components/common/GlobalProviderStatusHeader.tsx +316 -0
  349. package/src/renderer/components/common/OngoingIndicator.tsx +67 -0
  350. package/src/renderer/components/common/ProviderBrandLogo.tsx +206 -0
  351. package/src/renderer/components/common/RepositoryDropdown.tsx +230 -0
  352. package/src/renderer/components/common/TokenUsageDisplay.tsx +581 -0
  353. package/src/renderer/components/common/WarningBanner.tsx +25 -0
  354. package/src/renderer/components/common/WorkspaceIndicator.tsx +183 -0
  355. package/src/renderer/components/common/WorktreeBadge.tsx +123 -0
  356. package/src/renderer/components/dashboard/CliStatusBanner.tsx +1845 -0
  357. package/src/renderer/components/dashboard/DashboardView.tsx +274 -0
  358. package/src/renderer/components/extensions/ExtensionStoreView.tsx +591 -0
  359. package/src/renderer/components/extensions/ExtensionsSubTabTrigger.tsx +52 -0
  360. package/src/renderer/components/extensions/apikeys/ApiKeyCard.tsx +143 -0
  361. package/src/renderer/components/extensions/apikeys/ApiKeyFormDialog.tsx +282 -0
  362. package/src/renderer/components/extensions/apikeys/ApiKeysPanel.tsx +280 -0
  363. package/src/renderer/components/extensions/common/InstallButton.tsx +186 -0
  364. package/src/renderer/components/extensions/common/InstallCountBadge.tsx +21 -0
  365. package/src/renderer/components/extensions/common/SearchInput.tsx +70 -0
  366. package/src/renderer/components/extensions/common/SourceBadge.tsx +31 -0
  367. package/src/renderer/components/extensions/mcp/CustomMcpServerDialog.tsx +560 -0
  368. package/src/renderer/components/extensions/mcp/McpServerCard.tsx +314 -0
  369. package/src/renderer/components/extensions/mcp/McpServerDetailDialog.tsx +669 -0
  370. package/src/renderer/components/extensions/mcp/McpServersPanel.tsx +543 -0
  371. package/src/renderer/components/extensions/plugins/CapabilityChips.tsx +70 -0
  372. package/src/renderer/components/extensions/plugins/CategoryChips.tsx +67 -0
  373. package/src/renderer/components/extensions/plugins/PluginCard.tsx +146 -0
  374. package/src/renderer/components/extensions/plugins/PluginDetailDialog.tsx +270 -0
  375. package/src/renderer/components/extensions/plugins/PluginsPanel.tsx +436 -0
  376. package/src/renderer/components/extensions/skills/SkillCodeEditor.tsx +117 -0
  377. package/src/renderer/components/extensions/skills/SkillDetailDialog.tsx +372 -0
  378. package/src/renderer/components/extensions/skills/SkillEditorDialog.tsx +856 -0
  379. package/src/renderer/components/extensions/skills/SkillImportDialog.tsx +343 -0
  380. package/src/renderer/components/extensions/skills/SkillReviewDialog.tsx +166 -0
  381. package/src/renderer/components/extensions/skills/SkillsPanel.tsx +784 -0
  382. package/src/renderer/components/extensions/skills/skillDraftUtils.ts +234 -0
  383. package/src/renderer/components/extensions/skills/skillFolderNameUtils.ts +19 -0
  384. package/src/renderer/components/extensions/skills/skillProjectUtils.ts +13 -0
  385. package/src/renderer/components/extensions/skills/skillValidationUtils.ts +31 -0
  386. package/src/renderer/components/layout/MiddlePanel.tsx +18 -0
  387. package/src/renderer/components/layout/MoreMenu.tsx +243 -0
  388. package/src/renderer/components/layout/PaneContainer.tsx +27 -0
  389. package/src/renderer/components/layout/PaneContent.tsx +84 -0
  390. package/src/renderer/components/layout/PaneResizeHandle.tsx +85 -0
  391. package/src/renderer/components/layout/PaneSplitDropZone.tsx +54 -0
  392. package/src/renderer/components/layout/PaneView.tsx +75 -0
  393. package/src/renderer/components/layout/SessionTabContent.tsx +102 -0
  394. package/src/renderer/components/layout/Sidebar.tsx +205 -0
  395. package/src/renderer/components/layout/SortableTab.tsx +261 -0
  396. package/src/renderer/components/layout/TabBar.tsx +354 -0
  397. package/src/renderer/components/layout/TabBarActions.tsx +176 -0
  398. package/src/renderer/components/layout/TabBarRow.tsx +99 -0
  399. package/src/renderer/components/layout/TabContextMenu.tsx +171 -0
  400. package/src/renderer/components/layout/TabbedLayout.tsx +186 -0
  401. package/src/renderer/components/layout/TeamTabSectionNav.tsx +146 -0
  402. package/src/renderer/components/notifications/NotificationRow.tsx +228 -0
  403. package/src/renderer/components/notifications/NotificationsView.tsx +371 -0
  404. package/src/renderer/components/report/AssessmentBadge.tsx +78 -0
  405. package/src/renderer/components/report/ReportSection.tsx +58 -0
  406. package/src/renderer/components/report/SessionReportTab.tsx +102 -0
  407. package/src/renderer/components/report/sections/CostSection.tsx +259 -0
  408. package/src/renderer/components/report/sections/ErrorSection.tsx +100 -0
  409. package/src/renderer/components/report/sections/FrictionSection.tsx +91 -0
  410. package/src/renderer/components/report/sections/GitSection.tsx +72 -0
  411. package/src/renderer/components/report/sections/InsightsSection.tsx +207 -0
  412. package/src/renderer/components/report/sections/KeyTakeawaysSection.tsx +55 -0
  413. package/src/renderer/components/report/sections/OverviewSection.tsx +64 -0
  414. package/src/renderer/components/report/sections/QualitySection.tsx +151 -0
  415. package/src/renderer/components/report/sections/SubagentSection.tsx +88 -0
  416. package/src/renderer/components/report/sections/TimelineSection.tsx +111 -0
  417. package/src/renderer/components/report/sections/TokenSection.tsx +116 -0
  418. package/src/renderer/components/report/sections/ToolSection.tsx +77 -0
  419. package/src/renderer/components/runtime/ProviderModelBadges.tsx +142 -0
  420. package/src/renderer/components/runtime/ProviderRuntimeBackendSelector.tsx +327 -0
  421. package/src/renderer/components/runtime/ProviderRuntimeSettingsDialog.tsx +288 -0
  422. package/src/renderer/components/runtime/providerConnectionUi.ts +408 -0
  423. package/src/renderer/components/schedules/SchedulesView.tsx +529 -0
  424. package/src/renderer/components/search/CommandPalette.tsx +610 -0
  425. package/src/renderer/components/search/SearchBar.tsx +171 -0
  426. package/src/renderer/components/settings/NotificationTriggerSettings/components/AddTriggerForm.tsx +233 -0
  427. package/src/renderer/components/settings/NotificationTriggerSettings/components/ColorPaletteSelector.tsx +144 -0
  428. package/src/renderer/components/settings/NotificationTriggerSettings/components/DynamicConfigSection.tsx +189 -0
  429. package/src/renderer/components/settings/NotificationTriggerSettings/components/GeneralInfoSection.tsx +68 -0
  430. package/src/renderer/components/settings/NotificationTriggerSettings/components/IgnorePatternsSection.tsx +73 -0
  431. package/src/renderer/components/settings/NotificationTriggerSettings/components/ModeSelector.tsx +45 -0
  432. package/src/renderer/components/settings/NotificationTriggerSettings/components/RepositoryScopeSection.tsx +63 -0
  433. package/src/renderer/components/settings/NotificationTriggerSettings/components/SectionHeader.tsx +15 -0
  434. package/src/renderer/components/settings/NotificationTriggerSettings/components/TriggerCard.tsx +150 -0
  435. package/src/renderer/components/settings/NotificationTriggerSettings/components/TriggerCardHeader.tsx +125 -0
  436. package/src/renderer/components/settings/NotificationTriggerSettings/components/TriggerConfiguration.tsx +342 -0
  437. package/src/renderer/components/settings/NotificationTriggerSettings/components/TriggerPreview.tsx +108 -0
  438. package/src/renderer/components/settings/NotificationTriggerSettings/hooks/useAddTriggerFormHandlers.ts +218 -0
  439. package/src/renderer/components/settings/NotificationTriggerSettings/hooks/useAddTriggerFormState.ts +135 -0
  440. package/src/renderer/components/settings/NotificationTriggerSettings/hooks/useRepositoryLookup.ts +47 -0
  441. package/src/renderer/components/settings/NotificationTriggerSettings/hooks/useTriggerCardState.ts +281 -0
  442. package/src/renderer/components/settings/NotificationTriggerSettings/hooks/useTriggerForm.ts +185 -0
  443. package/src/renderer/components/settings/NotificationTriggerSettings/index.tsx +87 -0
  444. package/src/renderer/components/settings/NotificationTriggerSettings/types.ts +39 -0
  445. package/src/renderer/components/settings/NotificationTriggerSettings/utils/constants.ts +50 -0
  446. package/src/renderer/components/settings/NotificationTriggerSettings/utils/trigger.ts +113 -0
  447. package/src/renderer/components/settings/SettingsTabs.tsx +110 -0
  448. package/src/renderer/components/settings/SettingsView.tsx +153 -0
  449. package/src/renderer/components/settings/components/SettingRow.tsx +44 -0
  450. package/src/renderer/components/settings/components/SettingsSectionHeader.tsx +24 -0
  451. package/src/renderer/components/settings/components/SettingsSelect.tsx +100 -0
  452. package/src/renderer/components/settings/components/SettingsToggle.tsx +45 -0
  453. package/src/renderer/components/settings/components/index.ts +8 -0
  454. package/src/renderer/components/settings/hooks/index.ts +6 -0
  455. package/src/renderer/components/settings/hooks/useSettingsConfig.ts +270 -0
  456. package/src/renderer/components/settings/hooks/useSettingsHandlers.ts +468 -0
  457. package/src/renderer/components/settings/sections/AdvancedSection.tsx +234 -0
  458. package/src/renderer/components/settings/sections/CliStatusSection.tsx +930 -0
  459. package/src/renderer/components/settings/sections/ConfigEditorDialog.tsx +391 -0
  460. package/src/renderer/components/settings/sections/GeneralSection.tsx +665 -0
  461. package/src/renderer/components/settings/sections/HarnessSection.tsx +133 -0
  462. package/src/renderer/components/settings/sections/PlatformsSection.tsx +517 -0
  463. package/src/renderer/components/settings/sections/index.ts +8 -0
  464. package/src/renderer/components/sidebar/DateGroupedSessions.tsx +1115 -0
  465. package/src/renderer/components/sidebar/GlobalTaskList.tsx +853 -0
  466. package/src/renderer/components/sidebar/SessionContextMenu.tsx +182 -0
  467. package/src/renderer/components/sidebar/SessionFiltersPopover.tsx +115 -0
  468. package/src/renderer/components/sidebar/SessionItem.tsx +393 -0
  469. package/src/renderer/components/sidebar/SidebarSessions.tsx +542 -0
  470. package/src/renderer/components/sidebar/SidebarTaskItem.tsx +286 -0
  471. package/src/renderer/components/sidebar/TaskContextMenu.tsx +86 -0
  472. package/src/renderer/components/sidebar/TaskFiltersPopover.tsx +203 -0
  473. package/src/renderer/components/sidebar/WorkspaceBrowser.tsx +370 -0
  474. package/src/renderer/components/sidebar/dateGroupedSessionsSelection.ts +33 -0
  475. package/src/renderer/components/sidebar/projectGroupPagination.ts +89 -0
  476. package/src/renderer/components/sidebar/taskFiltersState.ts +82 -0
  477. package/src/renderer/components/splash/splashScene.ts +979 -0
  478. package/src/renderer/components/team/CcSessionsSection.tsx +202 -0
  479. package/src/renderer/components/team/ClaudeLogsDialog.tsx +71 -0
  480. package/src/renderer/components/team/ClaudeLogsFilterPopover.tsx +213 -0
  481. package/src/renderer/components/team/ClaudeLogsPanel.tsx +170 -0
  482. package/src/renderer/components/team/ClaudeLogsSection.tsx +154 -0
  483. package/src/renderer/components/team/CliLogsRichView.tsx +640 -0
  484. package/src/renderer/components/team/CollapsibleTeamSection.tsx +177 -0
  485. package/src/renderer/components/team/HarnessCards.ts +38 -0
  486. package/src/renderer/components/team/MemberBadge.tsx +117 -0
  487. package/src/renderer/components/team/ProcessesSection.tsx +193 -0
  488. package/src/renderer/components/team/ProvisioningProgressBlock.tsx +389 -0
  489. package/src/renderer/components/team/RoleSelect.tsx +171 -0
  490. package/src/renderer/components/team/StepProgressBar.tsx +165 -0
  491. package/src/renderer/components/team/TaskTooltip.tsx +197 -0
  492. package/src/renderer/components/team/TeamDetailView.tsx +3002 -0
  493. package/src/renderer/components/team/TeamEmptyState.tsx +102 -0
  494. package/src/renderer/components/team/TeamListFilterPopover.tsx +183 -0
  495. package/src/renderer/components/team/TeamListView.tsx +1336 -0
  496. package/src/renderer/components/team/TeamProvisioningBanner.tsx +16 -0
  497. package/src/renderer/components/team/TeamProvisioningPanel.tsx +115 -0
  498. package/src/renderer/components/team/TeamSessionsSection.tsx +267 -0
  499. package/src/renderer/components/team/ToolApprovalDiffPreview.tsx +206 -0
  500. package/src/renderer/components/team/ToolApprovalSheet.tsx +675 -0
  501. package/src/renderer/components/team/UnreadCommentsBadge.tsx +37 -0
  502. package/src/renderer/components/team/activity/ActiveTasksBlock.tsx +191 -0
  503. package/src/renderer/components/team/activity/ActivityItem.tsx +1649 -0
  504. package/src/renderer/components/team/activity/ActivityTimeline.tsx +959 -0
  505. package/src/renderer/components/team/activity/AnimatedHeightReveal.tsx +117 -0
  506. package/src/renderer/components/team/activity/LeadThoughtsGroup.tsx +1152 -0
  507. package/src/renderer/components/team/activity/MessageExpandDialog.tsx +213 -0
  508. package/src/renderer/components/team/activity/PendingRepliesBlock.tsx +275 -0
  509. package/src/renderer/components/team/activity/ReplyQuoteBlock.tsx +79 -0
  510. package/src/renderer/components/team/activity/ThoughtBodyContent.tsx +150 -0
  511. package/src/renderer/components/team/activity/activityMarkdown.ts +36 -0
  512. package/src/renderer/components/team/activity/activityMessageContext.ts +68 -0
  513. package/src/renderer/components/team/activity/collapseState.ts +66 -0
  514. package/src/renderer/components/team/activity/useNewItemKeys.ts +70 -0
  515. package/src/renderer/components/team/attachments/AttachmentDisplay.tsx +132 -0
  516. package/src/renderer/components/team/attachments/AttachmentPreviewItem.tsx +62 -0
  517. package/src/renderer/components/team/attachments/AttachmentPreviewList.tsx +193 -0
  518. package/src/renderer/components/team/attachments/AttachmentThumbnail.tsx +42 -0
  519. package/src/renderer/components/team/attachments/DropZoneOverlay.tsx +54 -0
  520. package/src/renderer/components/team/attachments/ImageLightbox.tsx +132 -0
  521. package/src/renderer/components/team/attachments/SourceMessageAttachments.tsx +70 -0
  522. package/src/renderer/components/team/dialogs/AddMemberDialog.tsx +222 -0
  523. package/src/renderer/components/team/dialogs/AdvancedCliSection.tsx +347 -0
  524. package/src/renderer/components/team/dialogs/AnthropicFastModeSelector.tsx +120 -0
  525. package/src/renderer/components/team/dialogs/CreateTaskDialog.tsx +489 -0
  526. package/src/renderer/components/team/dialogs/CreateTeamDialog.tsx +484 -0
  527. package/src/renderer/components/team/dialogs/EditTeamDialog.tsx +448 -0
  528. package/src/renderer/components/team/dialogs/EffortLevelSelector.tsx +69 -0
  529. package/src/renderer/components/team/dialogs/GlobalTaskDetailDialog.tsx +165 -0
  530. package/src/renderer/components/team/dialogs/LaunchTeamDialog.tsx +2859 -0
  531. package/src/renderer/components/team/dialogs/LimitContextCheckbox.tsx +57 -0
  532. package/src/renderer/components/team/dialogs/MembersJsonEditor.tsx +123 -0
  533. package/src/renderer/components/team/dialogs/OptionalSettingsSection.tsx +124 -0
  534. package/src/renderer/components/team/dialogs/PlatformManualForm.tsx +145 -0
  535. package/src/renderer/components/team/dialogs/PlatformSetupQR.tsx +289 -0
  536. package/src/renderer/components/team/dialogs/ProjectPathSelector.tsx +330 -0
  537. package/src/renderer/components/team/dialogs/ProvisioningProviderStatusList.tsx +744 -0
  538. package/src/renderer/components/team/dialogs/ReviewDialog.tsx +130 -0
  539. package/src/renderer/components/team/dialogs/SendMessageDialog.tsx +530 -0
  540. package/src/renderer/components/team/dialogs/SkipPermissionsCheckbox.tsx +62 -0
  541. package/src/renderer/components/team/dialogs/StatusHistoryTimeline.tsx +229 -0
  542. package/src/renderer/components/team/dialogs/TaskAttachments.tsx +394 -0
  543. package/src/renderer/components/team/dialogs/TaskCommentAwaitingReply.tsx +57 -0
  544. package/src/renderer/components/team/dialogs/TaskCommentInput.tsx +420 -0
  545. package/src/renderer/components/team/dialogs/TaskCommentsSection.tsx +620 -0
  546. package/src/renderer/components/team/dialogs/TaskDetailDialog.tsx +1480 -0
  547. package/src/renderer/components/team/dialogs/TeamModelSelector.tsx +560 -0
  548. package/src/renderer/components/team/dialogs/TeammateRuntimeCompatibilityNotice.tsx +60 -0
  549. package/src/renderer/components/team/dialogs/ToolApprovalSettingsPanel.tsx +173 -0
  550. package/src/renderer/components/team/dialogs/editTeamRuntimeChanges.ts +179 -0
  551. package/src/renderer/components/team/dialogs/globalTaskDetailDialogLoading.ts +34 -0
  552. package/src/renderer/components/team/dialogs/launchDialogPrefill.ts +125 -0
  553. package/src/renderer/components/team/dialogs/memberModelScope.ts +77 -0
  554. package/src/renderer/components/team/dialogs/platformMeta.ts +118 -0
  555. package/src/renderer/components/team/dialogs/projectPathOptions.ts +50 -0
  556. package/src/renderer/components/team/dialogs/providerPrepareDiagnostics.ts +222 -0
  557. package/src/renderer/components/team/dialogs/providerPrepareRequestSignature.ts +122 -0
  558. package/src/renderer/components/team/dialogs/provisioningMemberScope.ts +10 -0
  559. package/src/renderer/components/team/dialogs/provisioningModelIssues.ts +124 -0
  560. package/src/renderer/components/team/dialogs/teamNameSets.ts +67 -0
  561. package/src/renderer/components/team/dialogs/teamRelaunchFlow.ts +30 -0
  562. package/src/renderer/components/team/dialogs/teammateLaunchMode.ts +49 -0
  563. package/src/renderer/components/team/dialogs/teammateRuntimeCompatibility.tsx +101 -0
  564. package/src/renderer/components/team/editor/CodeMirrorEditor.tsx +506 -0
  565. package/src/renderer/components/team/editor/EditorBinaryPlaceholder.tsx +43 -0
  566. package/src/renderer/components/team/editor/EditorBinaryState.tsx +29 -0
  567. package/src/renderer/components/team/editor/EditorBreadcrumb.tsx +84 -0
  568. package/src/renderer/components/team/editor/EditorContextMenu.tsx +213 -0
  569. package/src/renderer/components/team/editor/EditorEmptyState.tsx +35 -0
  570. package/src/renderer/components/team/editor/EditorErrorBoundary.tsx +63 -0
  571. package/src/renderer/components/team/editor/EditorErrorState.tsx +41 -0
  572. package/src/renderer/components/team/editor/EditorFileTree.tsx +903 -0
  573. package/src/renderer/components/team/editor/EditorImagePreview.tsx +138 -0
  574. package/src/renderer/components/team/editor/EditorSearchPanel.tsx +508 -0
  575. package/src/renderer/components/team/editor/EditorSelectionMenu.tsx +112 -0
  576. package/src/renderer/components/team/editor/EditorShortcutsHelp.tsx +125 -0
  577. package/src/renderer/components/team/editor/EditorStatusBar.tsx +72 -0
  578. package/src/renderer/components/team/editor/EditorTabBar.tsx +265 -0
  579. package/src/renderer/components/team/editor/EditorTabContextMenu.tsx +88 -0
  580. package/src/renderer/components/team/editor/EditorToolbar.tsx +163 -0
  581. package/src/renderer/components/team/editor/FileIcon.tsx +66 -0
  582. package/src/renderer/components/team/editor/GitStatusBadge.tsx +47 -0
  583. package/src/renderer/components/team/editor/GoToLineDialog.tsx +186 -0
  584. package/src/renderer/components/team/editor/MarkdownPreviewPane.tsx +57 -0
  585. package/src/renderer/components/team/editor/MarkdownSplitView.tsx +127 -0
  586. package/src/renderer/components/team/editor/NewFileDialog.tsx +131 -0
  587. package/src/renderer/components/team/editor/ProjectEditorOverlay.tsx +924 -0
  588. package/src/renderer/components/team/editor/QuickOpenDialog.tsx +163 -0
  589. package/src/renderer/components/team/editor/SearchInFilesPanel.tsx +358 -0
  590. package/src/renderer/components/team/editor/fileIcons.ts +222 -0
  591. package/src/renderer/components/team/kanban/KanbanBoard.tsx +664 -0
  592. package/src/renderer/components/team/kanban/KanbanColumn.tsx +61 -0
  593. package/src/renderer/components/team/kanban/KanbanFilterPopover.tsx +210 -0
  594. package/src/renderer/components/team/kanban/KanbanGridLayout.tsx +460 -0
  595. package/src/renderer/components/team/kanban/KanbanSearchInput.tsx +284 -0
  596. package/src/renderer/components/team/kanban/KanbanSortPopover.tsx +140 -0
  597. package/src/renderer/components/team/kanban/KanbanTaskCard.test.tsx +199 -0
  598. package/src/renderer/components/team/kanban/KanbanTaskCard.tsx +446 -0
  599. package/src/renderer/components/team/kanban/TrashDialog.tsx +112 -0
  600. package/src/renderer/components/team/members/CurrentTaskIndicator.tsx +56 -0
  601. package/src/renderer/components/team/members/LeadModelRow.test.tsx +133 -0
  602. package/src/renderer/components/team/members/LeadModelRow.tsx +183 -0
  603. package/src/renderer/components/team/members/MemberCard.tsx +665 -0
  604. package/src/renderer/components/team/members/MemberDetailDialog.tsx +309 -0
  605. package/src/renderer/components/team/members/MemberDetailHeader.tsx +183 -0
  606. package/src/renderer/components/team/members/MemberDetailStats.tsx +80 -0
  607. package/src/renderer/components/team/members/MemberDraftRow.test.tsx +184 -0
  608. package/src/renderer/components/team/members/MemberDraftRow.tsx +515 -0
  609. package/src/renderer/components/team/members/MemberExecutionLog.tsx +224 -0
  610. package/src/renderer/components/team/members/MemberHoverCard.tsx +292 -0
  611. package/src/renderer/components/team/members/MemberLaunchDiagnosticsButton.tsx +60 -0
  612. package/src/renderer/components/team/members/MemberList.tsx +405 -0
  613. package/src/renderer/components/team/members/MemberLogsTab.tsx +958 -0
  614. package/src/renderer/components/team/members/MemberMessagesTab.tsx +251 -0
  615. package/src/renderer/components/team/members/MemberPresenceDot.tsx +28 -0
  616. package/src/renderer/components/team/members/MemberRoleEditor.tsx +84 -0
  617. package/src/renderer/components/team/members/MemberStatsTab.tsx +299 -0
  618. package/src/renderer/components/team/members/MemberTasksTab.tsx +87 -0
  619. package/src/renderer/components/team/members/MemberWorkspaceTab.tsx +141 -0
  620. package/src/renderer/components/team/members/MembersEditorSection.tsx +495 -0
  621. package/src/renderer/components/team/members/SubagentRecentMessagesPreview.tsx +125 -0
  622. package/src/renderer/components/team/members/TeamRosterEditorSection.tsx +153 -0
  623. package/src/renderer/components/team/members/memberActivityEntries.ts +42 -0
  624. package/src/renderer/components/team/members/memberDetailTypes.ts +3 -0
  625. package/src/renderer/components/team/members/memberNameSets.ts +65 -0
  626. package/src/renderer/components/team/members/membersEditorTypes.ts +21 -0
  627. package/src/renderer/components/team/members/membersEditorUtils.ts +267 -0
  628. package/src/renderer/components/team/messages/MessageComposer.tsx +939 -0
  629. package/src/renderer/components/team/messages/MessagesFilterPopover.tsx +228 -0
  630. package/src/renderer/components/team/messages/MessagesPanel.tsx +1508 -0
  631. package/src/renderer/components/team/messages/OpenCodeDeliveryWarning.tsx +151 -0
  632. package/src/renderer/components/team/messages/StatusBlock.tsx +126 -0
  633. package/src/renderer/components/team/provisioningSteps.ts +363 -0
  634. package/src/renderer/components/team/review/ChangeReviewDialog.tsx +133 -0
  635. package/src/renderer/components/team/schedule/CcCronScheduleDialog.tsx +218 -0
  636. package/src/renderer/components/team/schedule/CronScheduleInput.tsx +254 -0
  637. package/src/renderer/components/team/schedule/ScheduleEmptyState.tsx +15 -0
  638. package/src/renderer/components/team/schedule/ScheduleRunLogDialog.tsx +277 -0
  639. package/src/renderer/components/team/schedule/ScheduleRunRow.tsx +106 -0
  640. package/src/renderer/components/team/schedule/ScheduleSection.tsx +281 -0
  641. package/src/renderer/components/team/schedule/ScheduleStatusBadge.tsx +55 -0
  642. package/src/renderer/components/team/sidebar/TeamSidebarHost.tsx +76 -0
  643. package/src/renderer/components/team/sidebar/TeamSidebarPortalManager.ts +173 -0
  644. package/src/renderer/components/team/sidebar/TeamSidebarPortalSource.tsx +66 -0
  645. package/src/renderer/components/team/sidebar/TeamSidebarRail.tsx +68 -0
  646. package/src/renderer/components/team/sidebar/teamSidebarUiState.ts +136 -0
  647. package/src/renderer/components/team/taskLogs/ExactTaskLogCard.tsx +132 -0
  648. package/src/renderer/components/team/taskLogs/ExactTaskLogsSection.tsx +258 -0
  649. package/src/renderer/components/team/taskLogs/ExecutionSessionsSection.tsx +48 -0
  650. package/src/renderer/components/team/taskLogs/TaskActivityLinkedToolCard.tsx +31 -0
  651. package/src/renderer/components/team/taskLogs/TaskActivitySection.tsx +462 -0
  652. package/src/renderer/components/team/taskLogs/TaskLogStreamSection.tsx +375 -0
  653. package/src/renderer/components/team/taskLogs/TaskLogsPanel.tsx +294 -0
  654. package/src/renderer/components/team/taskLogs/featureGates.ts +22 -0
  655. package/src/renderer/components/team/tasks/TaskList.tsx +111 -0
  656. package/src/renderer/components/team/tasks/TaskRow.tsx +65 -0
  657. package/src/renderer/components/team/teamProjectSelection.ts +156 -0
  658. package/src/renderer/components/team/teamSessionFetchGuards.ts +26 -0
  659. package/src/renderer/components/team/useClaudeLogsController.ts +668 -0
  660. package/src/renderer/components/team/useTeamProvisioningPresentation.ts +54 -0
  661. package/src/renderer/components/terminal/TerminalLogPanel.tsx +37 -0
  662. package/src/renderer/components/ui/ChipInteractionLayer.tsx +255 -0
  663. package/src/renderer/components/ui/CodeChipBadge.tsx +37 -0
  664. package/src/renderer/components/ui/ExpandableContent.tsx +110 -0
  665. package/src/renderer/components/ui/MemberSelect.tsx +209 -0
  666. package/src/renderer/components/ui/MentionInteractionLayer.tsx +121 -0
  667. package/src/renderer/components/ui/MentionSuggestionList.tsx +274 -0
  668. package/src/renderer/components/ui/MentionableTextarea.tsx +1426 -0
  669. package/src/renderer/components/ui/SlashCommandInteractionLayer.tsx +88 -0
  670. package/src/renderer/components/ui/TaskReferenceInteractionLayer.tsx +101 -0
  671. package/src/renderer/components/ui/UrlInteractionLayer.tsx +102 -0
  672. package/src/renderer/components/ui/alert-dialog.tsx +127 -0
  673. package/src/renderer/components/ui/auto-resize-textarea.tsx +93 -0
  674. package/src/renderer/components/ui/badge.tsx +37 -0
  675. package/src/renderer/components/ui/button.tsx +54 -0
  676. package/src/renderer/components/ui/checkbox.tsx +29 -0
  677. package/src/renderer/components/ui/combobox.tsx +168 -0
  678. package/src/renderer/components/ui/context-menu.tsx +124 -0
  679. package/src/renderer/components/ui/dialog.tsx +114 -0
  680. package/src/renderer/components/ui/hover-card.tsx +30 -0
  681. package/src/renderer/components/ui/input.tsx +22 -0
  682. package/src/renderer/components/ui/label.tsx +21 -0
  683. package/src/renderer/components/ui/popover.tsx +31 -0
  684. package/src/renderer/components/ui/select.tsx +150 -0
  685. package/src/renderer/components/ui/tabs.tsx +52 -0
  686. package/src/renderer/components/ui/textarea.tsx +21 -0
  687. package/src/renderer/components/ui/tiptap/TiptapBubbleMenu.tsx +75 -0
  688. package/src/renderer/components/ui/tiptap/TiptapEditor.tsx +73 -0
  689. package/src/renderer/components/ui/tiptap/TiptapToolbar.tsx +269 -0
  690. package/src/renderer/components/ui/tiptap/index.ts +3 -0
  691. package/src/renderer/components/ui/tiptap/presets.ts +46 -0
  692. package/src/renderer/components/ui/tiptap/tiptapStyles.css +235 -0
  693. package/src/renderer/components/ui/tiptap/types.ts +32 -0
  694. package/src/renderer/components/ui/tiptap/useTiptapEditor.ts +94 -0
  695. package/src/renderer/components/ui/tooltip.tsx +32 -0
  696. package/src/renderer/constants/cssVariables.ts +226 -0
  697. package/src/renderer/constants/layout.ts +6 -0
  698. package/src/renderer/constants/teamColors.ts +397 -0
  699. package/src/renderer/constants/teamRoles.ts +41 -0
  700. package/src/renderer/contexts/TabUIContext.tsx +51 -0
  701. package/src/renderer/contexts/useTabUIContext.ts +18 -0
  702. package/src/renderer/favicon.png +0 -0
  703. package/src/renderer/features/CLAUDE.md +19 -0
  704. package/src/renderer/hooks/navigation/utils.ts +263 -0
  705. package/src/renderer/hooks/useAttachments.ts +312 -0
  706. package/src/renderer/hooks/useAutoScrollBottom.ts +285 -0
  707. package/src/renderer/hooks/useBranchSync.ts +105 -0
  708. package/src/renderer/hooks/useChipDraftPersistence.ts +172 -0
  709. package/src/renderer/hooks/useCliInstaller.ts +106 -0
  710. package/src/renderer/hooks/useCollapsedGroups.ts +71 -0
  711. package/src/renderer/hooks/useComposerDraft.ts +504 -0
  712. package/src/renderer/hooks/useContinuousScrollNav.ts +50 -0
  713. package/src/renderer/hooks/useCreateTeamDraft.ts +280 -0
  714. package/src/renderer/hooks/useDraftPersistence.ts +140 -0
  715. package/src/renderer/hooks/useEditorKeyboardShortcuts.ts +257 -0
  716. package/src/renderer/hooks/useEffectiveCliProviderStatus.ts +66 -0
  717. package/src/renderer/hooks/useExtensionsTabState.ts +206 -0
  718. package/src/renderer/hooks/useFileListCacheWarmer.ts +38 -0
  719. package/src/renderer/hooks/useFileSuggestions.ts +255 -0
  720. package/src/renderer/hooks/useKeyboardShortcuts.ts +363 -0
  721. package/src/renderer/hooks/useLazyFileContent.ts +150 -0
  722. package/src/renderer/hooks/useMarkCommentsRead.ts +27 -0
  723. package/src/renderer/hooks/useMarkdownScrollSync.ts +158 -0
  724. package/src/renderer/hooks/useMemberStats.ts +45 -0
  725. package/src/renderer/hooks/useMentionDetection.ts +375 -0
  726. package/src/renderer/hooks/usePersistedGridLayout.ts +109 -0
  727. package/src/renderer/hooks/useResizableColumns.ts +140 -0
  728. package/src/renderer/hooks/useResizablePanel.ts +144 -0
  729. package/src/renderer/hooks/useStableTeamMentionMeta.ts +68 -0
  730. package/src/renderer/hooks/useSyncedAnimationStyle.ts +29 -0
  731. package/src/renderer/hooks/useTabNavigationController.ts +524 -0
  732. package/src/renderer/hooks/useTabUI.ts +252 -0
  733. package/src/renderer/hooks/useTaskLocalState.ts +163 -0
  734. package/src/renderer/hooks/useTaskSuggestions.ts +131 -0
  735. package/src/renderer/hooks/useTeamMessagesExpanded.ts +34 -0
  736. package/src/renderer/hooks/useTeamMessagesRead.ts +52 -0
  737. package/src/renderer/hooks/useTeamSuggestions.ts +78 -0
  738. package/src/renderer/hooks/useTheme.ts +138 -0
  739. package/src/renderer/hooks/useToolApprovalDiff.ts +212 -0
  740. package/src/renderer/hooks/useUnreadCommentCount.ts +14 -0
  741. package/src/renderer/hooks/useViewedFiles.ts +74 -0
  742. package/src/renderer/hooks/useViewportCommentRead.ts +147 -0
  743. package/src/renderer/hooks/useViewportObserver.ts +138 -0
  744. package/src/renderer/hooks/useVisibleAIGroup.ts +122 -0
  745. package/src/renderer/hooks/useVisibleFileSection.ts +114 -0
  746. package/src/renderer/hooks/useZoomFactor.ts +36 -0
  747. package/src/renderer/index.css +1560 -0
  748. package/src/renderer/index.html +1293 -0
  749. package/src/renderer/lib/utils.ts +6 -0
  750. package/src/renderer/main.tsx +30 -0
  751. package/src/renderer/sentry.ts +104 -0
  752. package/src/renderer/services/__tests__/createTeamPreferences.test.ts +67 -0
  753. package/src/renderer/services/commentReadStorage.ts +349 -0
  754. package/src/renderer/services/composerDraftStorage.ts +271 -0
  755. package/src/renderer/services/contextStorage.ts +201 -0
  756. package/src/renderer/services/createTeamDraftStorage.ts +151 -0
  757. package/src/renderer/services/createTeamPreferences.ts +361 -0
  758. package/src/renderer/services/dashboardCliStatusBannerPreference.ts +20 -0
  759. package/src/renderer/services/draftStorage.ts +128 -0
  760. package/src/renderer/services/layout-system/BrowserGridLayoutRepository.ts +111 -0
  761. package/src/renderer/services/layout-system/GridLayoutRepository.ts +8 -0
  762. package/src/renderer/services/layout-system/gridLayoutSchema.ts +137 -0
  763. package/src/renderer/services/layout-system/gridLayoutTypes.ts +17 -0
  764. package/src/renderer/store/index.ts +1556 -0
  765. package/src/renderer/store/slices/changeReviewSlice.ts +1694 -0
  766. package/src/renderer/store/slices/cliInstallerSlice.ts +689 -0
  767. package/src/renderer/store/slices/configSlice.ts +111 -0
  768. package/src/renderer/store/slices/connectionSlice.ts +221 -0
  769. package/src/renderer/store/slices/contextSlice.ts +394 -0
  770. package/src/renderer/store/slices/conversationSlice.ts +510 -0
  771. package/src/renderer/store/slices/editorSlice.ts +1455 -0
  772. package/src/renderer/store/slices/extensionsSlice.ts +1415 -0
  773. package/src/renderer/store/slices/notificationSlice.ts +277 -0
  774. package/src/renderer/store/slices/paneSlice.ts +357 -0
  775. package/src/renderer/store/slices/projectSlice.ts +70 -0
  776. package/src/renderer/store/slices/repositorySlice.ts +165 -0
  777. package/src/renderer/store/slices/scheduleSlice.ts +246 -0
  778. package/src/renderer/store/slices/sessionDetailSlice.ts +755 -0
  779. package/src/renderer/store/slices/sessionSlice.ts +539 -0
  780. package/src/renderer/store/slices/subagentSlice.ts +145 -0
  781. package/src/renderer/store/slices/tabSlice.ts +842 -0
  782. package/src/renderer/store/slices/tabUISlice.ts +319 -0
  783. package/src/renderer/store/slices/teamSlice.ts +5080 -0
  784. package/src/renderer/store/slices/uiSlice.ts +45 -0
  785. package/src/renderer/store/types.ts +103 -0
  786. package/src/renderer/store/utils/paneHelpers.ts +134 -0
  787. package/src/renderer/store/utils/pathResolution.ts +121 -0
  788. package/src/renderer/store/utils/stateResetHelpers.ts +72 -0
  789. package/src/renderer/types/api.ts +8 -0
  790. package/src/renderer/types/claudeMd.ts +74 -0
  791. package/src/renderer/types/contextInjection.ts +309 -0
  792. package/src/renderer/types/data.ts +144 -0
  793. package/src/renderer/types/groups.ts +406 -0
  794. package/src/renderer/types/inlineChip.ts +110 -0
  795. package/src/renderer/types/mention.ts +38 -0
  796. package/src/renderer/types/notifications.ts +18 -0
  797. package/src/renderer/types/panes.ts +35 -0
  798. package/src/renderer/types/sessionReport.ts +386 -0
  799. package/src/renderer/types/tabs.ts +249 -0
  800. package/src/renderer/types/teamMessagesPanelMode.ts +1 -0
  801. package/src/renderer/utils/__tests__/teamEffortOptions.test.ts +217 -0
  802. package/src/renderer/utils/__tests__/teamModelAvailability.codexCatalog.test.ts +383 -0
  803. package/src/renderer/utils/agentMessageFormatting.ts +139 -0
  804. package/src/renderer/utils/aiGroupEnhancer.ts +78 -0
  805. package/src/renderer/utils/aiGroupHelpers.ts +208 -0
  806. package/src/renderer/utils/attachmentUtils.ts +60 -0
  807. package/src/renderer/utils/bootstrapPromptSanitizer.ts +225 -0
  808. package/src/renderer/utils/bugReportUtils.ts +157 -0
  809. package/src/renderer/utils/buildSelectionAction.ts +116 -0
  810. package/src/renderer/utils/chipUtils.ts +372 -0
  811. package/src/renderer/utils/claudeCodeOnlyProviders.ts +126 -0
  812. package/src/renderer/utils/claudeMdTracker.ts +644 -0
  813. package/src/renderer/utils/codemirrorLanguages.ts +141 -0
  814. package/src/renderer/utils/codemirrorSelectionInfo.ts +41 -0
  815. package/src/renderer/utils/codemirrorTheme.ts +138 -0
  816. package/src/renderer/utils/contextMath.ts +55 -0
  817. package/src/renderer/utils/contextTracker.ts +1100 -0
  818. package/src/renderer/utils/crossTeamPendingReplies.ts +92 -0
  819. package/src/renderer/utils/dateGrouping.ts +91 -0
  820. package/src/renderer/utils/diffViewedStorage.ts +120 -0
  821. package/src/renderer/utils/displayItemBuilder.ts +587 -0
  822. package/src/renderer/utils/displaySummary.ts +74 -0
  823. package/src/renderer/utils/editorBridge.ts +90 -0
  824. package/src/renderer/utils/fileTreeBuilder.ts +110 -0
  825. package/src/renderer/utils/formatAgentRole.ts +24 -0
  826. package/src/renderer/utils/formatters.ts +61 -0
  827. package/src/renderer/utils/groupTransformer.ts +744 -0
  828. package/src/renderer/utils/idleNotificationSemantics.ts +76 -0
  829. package/src/renderer/utils/keyboardUtils.ts +92 -0
  830. package/src/renderer/utils/lastOutputDetector.ts +150 -0
  831. package/src/renderer/utils/markdownPlugins.ts +60 -0
  832. package/src/renderer/utils/memberAvatarCatalog.ts +38 -0
  833. package/src/renderer/utils/memberHelpers.ts +858 -0
  834. package/src/renderer/utils/memberLaunchDiagnostics.ts +216 -0
  835. package/src/renderer/utils/memberRuntimeSummary.ts +122 -0
  836. package/src/renderer/utils/memberSpawnStatusPolling.ts +29 -0
  837. package/src/renderer/utils/mentionLinkify.ts +90 -0
  838. package/src/renderer/utils/mentionSuggestions.ts +34 -0
  839. package/src/renderer/utils/mergeTeamMessages.ts +27 -0
  840. package/src/renderer/utils/messageRenderEquality.ts +158 -0
  841. package/src/renderer/utils/modelExtractor.ts +90 -0
  842. package/src/renderer/utils/multimodelProviderVisibility.ts +32 -0
  843. package/src/renderer/utils/openCodeModelRecommendations.ts +1326 -0
  844. package/src/renderer/utils/openCodeRuntimeDeliveryDiagnostics.ts +79 -0
  845. package/src/renderer/utils/pathDisplay.ts +149 -0
  846. package/src/renderer/utils/pathNormalize.ts +61 -0
  847. package/src/renderer/utils/pathUtils.ts +47 -0
  848. package/src/renderer/utils/platformKeys.ts +24 -0
  849. package/src/renderer/utils/previewRegistry.ts +45 -0
  850. package/src/renderer/utils/projectColor.ts +54 -0
  851. package/src/renderer/utils/projectLookup.ts +64 -0
  852. package/src/renderer/utils/providerBackendIdentity.ts +43 -0
  853. package/src/renderer/utils/providerSlashCommands.ts +122 -0
  854. package/src/renderer/utils/quickOpenCache.ts +40 -0
  855. package/src/renderer/utils/refreshCliStatus.ts +17 -0
  856. package/src/renderer/utils/reportAssessments.ts +555 -0
  857. package/src/renderer/utils/reviewDecisionScope.ts +81 -0
  858. package/src/renderer/utils/reviewKey.ts +132 -0
  859. package/src/renderer/utils/runtimeDisplayName.ts +26 -0
  860. package/src/renderer/utils/scheduleFormatters.ts +45 -0
  861. package/src/renderer/utils/sessionAnalyzer.ts +1346 -0
  862. package/src/renderer/utils/sessionExporter.ts +427 -0
  863. package/src/renderer/utils/sessionTitleParser.ts +69 -0
  864. package/src/renderer/utils/skillCommandSuggestions.ts +77 -0
  865. package/src/renderer/utils/slashCommandExtractor.ts +154 -0
  866. package/src/renderer/utils/streamJsonParser.ts +393 -0
  867. package/src/renderer/utils/stringUtils.ts +50 -0
  868. package/src/renderer/utils/syntaxHighlighter.ts +158 -0
  869. package/src/renderer/utils/tabLabelDisambiguation.ts +99 -0
  870. package/src/renderer/utils/taskChangePresence.ts +19 -0
  871. package/src/renderer/utils/taskChangeRequest.ts +122 -0
  872. package/src/renderer/utils/taskCommentPendingReply.ts +74 -0
  873. package/src/renderer/utils/taskGrouping.ts +151 -0
  874. package/src/renderer/utils/taskReferenceUtils.ts +331 -0
  875. package/src/renderer/utils/teamEffortOptions.ts +150 -0
  876. package/src/renderer/utils/teamLaunchSummaryCopy.ts +17 -0
  877. package/src/renderer/utils/teamMessageExpandStorage.ts +39 -0
  878. package/src/renderer/utils/teamMessageFiltering.ts +95 -0
  879. package/src/renderer/utils/teamMessageKey.ts +14 -0
  880. package/src/renderer/utils/teamMessageReadStorage.ts +49 -0
  881. package/src/renderer/utils/teamModelAvailability.ts +465 -0
  882. package/src/renderer/utils/teamModelCatalog.ts +502 -0
  883. package/src/renderer/utils/teamModelContext.ts +34 -0
  884. package/src/renderer/utils/teamProvisioningPresentation.ts +772 -0
  885. package/src/renderer/utils/teamRuntimeSummary.ts +53 -0
  886. package/src/renderer/utils/toolLinkingEngine.ts +117 -0
  887. package/src/renderer/utils/toolRendering/index.ts +14 -0
  888. package/src/renderer/utils/toolRendering/toolContentChecks.ts +58 -0
  889. package/src/renderer/utils/toolRendering/toolSummaryHelpers.ts +276 -0
  890. package/src/renderer/utils/toolRendering/toolTokens.ts +57 -0
  891. package/src/renderer/utils/unwrapIpc.ts +31 -0
  892. package/src/renderer/utils/urlMatchUtils.ts +45 -0
  893. package/src/renderer/vite-env.d.ts +21 -0
  894. package/src/shared/constants/agentBlocks.ts +129 -0
  895. package/src/shared/constants/attachments.ts +175 -0
  896. package/src/shared/constants/cache.ts +12 -0
  897. package/src/shared/constants/cli.ts +15 -0
  898. package/src/shared/constants/crossTeam.ts +126 -0
  899. package/src/shared/constants/index.ts +15 -0
  900. package/src/shared/constants/kanban.ts +9 -0
  901. package/src/shared/constants/memberColors.ts +140 -0
  902. package/src/shared/constants/opencodeTaskLogAttribution.ts +1 -0
  903. package/src/shared/constants/teamLimits.ts +2 -0
  904. package/src/shared/constants/trafficLights.ts +60 -0
  905. package/src/shared/constants/triggerColors.ts +126 -0
  906. package/src/shared/constants/window.ts +12 -0
  907. package/src/shared/types/api.ts +1062 -0
  908. package/src/shared/types/ccConnect.ts +399 -0
  909. package/src/shared/types/cliInstaller.ts +335 -0
  910. package/src/shared/types/editor.ts +279 -0
  911. package/src/shared/types/extensions/api.ts +90 -0
  912. package/src/shared/types/extensions/apikey.ts +40 -0
  913. package/src/shared/types/extensions/common.ts +16 -0
  914. package/src/shared/types/extensions/index.ts +67 -0
  915. package/src/shared/types/extensions/mcp.ts +132 -0
  916. package/src/shared/types/extensions/plugin.ts +85 -0
  917. package/src/shared/types/extensions/skill.ts +173 -0
  918. package/src/shared/types/index.ts +48 -0
  919. package/src/shared/types/ipc.ts +5 -0
  920. package/src/shared/types/notifications.ts +407 -0
  921. package/src/shared/types/providers.ts +116 -0
  922. package/src/shared/types/review.ts +319 -0
  923. package/src/shared/types/schedule.ts +124 -0
  924. package/src/shared/types/team.ts +1726 -0
  925. package/src/shared/types/terminal.ts +49 -0
  926. package/src/shared/types/visualization.ts +60 -0
  927. package/src/shared/utils/__tests__/contextMetrics.test.ts +260 -0
  928. package/src/shared/utils/__tests__/ephemeralProjectPath.test.ts +42 -0
  929. package/src/shared/utils/__tests__/teamProvider.test.ts +29 -0
  930. package/src/shared/utils/agentLanguage.ts +122 -0
  931. package/src/shared/utils/anthropicLaunchModel.ts +96 -0
  932. package/src/shared/utils/anthropicModelDefaults.ts +3 -0
  933. package/src/shared/utils/apiErrorDetector.ts +13 -0
  934. package/src/shared/utils/boardTaskActivityLabels.ts +128 -0
  935. package/src/shared/utils/boardTaskActivityPresentation.ts +75 -0
  936. package/src/shared/utils/cliArgsParser.ts +129 -0
  937. package/src/shared/utils/contentSanitizer.ts +207 -0
  938. package/src/shared/utils/contextMetrics.ts +236 -0
  939. package/src/shared/utils/costFormatting.ts +45 -0
  940. package/src/shared/utils/diffContextHash.ts +22 -0
  941. package/src/shared/utils/effortLevels.ts +73 -0
  942. package/src/shared/utils/ephemeralProjectPath.ts +41 -0
  943. package/src/shared/utils/errorHandling.ts +26 -0
  944. package/src/shared/utils/extensionNormalizers.ts +336 -0
  945. package/src/shared/utils/idleNotificationSemantics.ts +86 -0
  946. package/src/shared/utils/inboxNoise.ts +158 -0
  947. package/src/shared/utils/leadDetection.ts +63 -0
  948. package/src/shared/utils/logger.ts +69 -0
  949. package/src/shared/utils/markdownTextSearch.ts +210 -0
  950. package/src/shared/utils/mcpScopes.ts +36 -0
  951. package/src/shared/utils/modelParser.ts +158 -0
  952. package/src/shared/utils/opencodeModelRef.ts +78 -0
  953. package/src/shared/utils/platformPath.ts +103 -0
  954. package/src/shared/utils/pricing.ts +129 -0
  955. package/src/shared/utils/providerBackend.ts +90 -0
  956. package/src/shared/utils/providerExtensionCapabilities.ts +92 -0
  957. package/src/shared/utils/providerModelSelection.ts +5 -0
  958. package/src/shared/utils/providerModelVisibility.ts +47 -0
  959. package/src/shared/utils/rateLimitDetector.ts +334 -0
  960. package/src/shared/utils/reviewState.ts +74 -0
  961. package/src/shared/utils/sentryConfig.ts +26 -0
  962. package/src/shared/utils/skillRoots.ts +93 -0
  963. package/src/shared/utils/slashCommands.ts +128 -0
  964. package/src/shared/utils/taskChangePresence.ts +35 -0
  965. package/src/shared/utils/taskChangeSince.ts +51 -0
  966. package/src/shared/utils/taskChangeState.ts +49 -0
  967. package/src/shared/utils/taskHistory.ts +82 -0
  968. package/src/shared/utils/taskIdentity.ts +32 -0
  969. package/src/shared/utils/teamGraphDefaultLayout.ts +97 -0
  970. package/src/shared/utils/teamMemberColors.ts +107 -0
  971. package/src/shared/utils/teamMemberName.ts +77 -0
  972. package/src/shared/utils/teamProvider.ts +73 -0
  973. package/src/shared/utils/teamStableOwnerId.ts +12 -0
  974. package/src/shared/utils/teammateMessageParser.ts +52 -0
  975. package/src/shared/utils/tokenFormatting.ts +91 -0
  976. package/src/shared/utils/toolSummary.ts +279 -0
  977. package/src/shared/utils/version.ts +29 -0
  978. package/src/types/agent-teams-controller.d.ts +163 -0
  979. package/src/types/node-pty.d.ts +22 -0
  980. package/src/types/pidusage.d.ts +23 -0
@@ -0,0 +1,1649 @@
1
+ import { Fragment, memo, useCallback, useMemo } from 'react';
2
+
3
+ import {
4
+ CompactMarkdownPreview,
5
+ MarkdownViewer,
6
+ } from '@renderer/components/chat/viewers/MarkdownViewer';
7
+ import { CopyButton } from '@renderer/components/common/CopyButton';
8
+ import { AttachmentDisplay } from '@renderer/components/team/attachments/AttachmentDisplay';
9
+ import { MemberBadge } from '@renderer/components/team/MemberBadge';
10
+ import { TaskTooltip } from '@renderer/components/team/TaskTooltip';
11
+ import { ExpandableContent } from '@renderer/components/ui/ExpandableContent';
12
+ import {
13
+ Tooltip,
14
+ TooltipContent,
15
+ TooltipProvider,
16
+ TooltipTrigger,
17
+ } from '@renderer/components/ui/tooltip';
18
+ import {
19
+ CARD_BG,
20
+ CARD_BG_ZEBRA,
21
+ CARD_BORDER_STYLE,
22
+ CARD_ICON_MUTED,
23
+ CARD_TEXT_LIGHT,
24
+ } from '@renderer/constants/cssVariables';
25
+ import { getTeamColorSet, getThemedBorder } from '@renderer/constants/teamColors';
26
+ import { useTheme } from '@renderer/hooks/useTheme';
27
+ import { useStore } from '@renderer/store';
28
+ import {
29
+ getMessageTypeLabel,
30
+ getStructuredMessageSummary,
31
+ parseMessageReply,
32
+ parseStructuredAgentMessage,
33
+ } from '@renderer/utils/agentMessageFormatting';
34
+ import {
35
+ getBootstrapAcknowledgementDisplay,
36
+ getBootstrapPromptDisplay,
37
+ getSanitizedInboxMessageSummary,
38
+ getSanitizedInboxMessageText,
39
+ } from '@renderer/utils/bootstrapPromptSanitizer';
40
+ import { formatAgentRole } from '@renderer/utils/formatAgentRole';
41
+ import {
42
+ classifyIdleNotification,
43
+ getIdleNoiseLabel,
44
+ } from '@renderer/utils/idleNotificationSemantics';
45
+ import { linkifyAllMentionsInMarkdown } from '@renderer/utils/mentionLinkify';
46
+ import {
47
+ areInboxMessagesEquivalentForRender,
48
+ areStringArraysEqual,
49
+ areStringMapsEqual,
50
+ } from '@renderer/utils/messageRenderEquality';
51
+ import { linkifyTaskIdsInMarkdown, parseTaskLinkHref } from '@renderer/utils/taskReferenceUtils';
52
+ import { stripAgentBlocks } from '@shared/constants/agentBlocks';
53
+ import {
54
+ CROSS_TEAM_SENT_SOURCE,
55
+ CROSS_TEAM_SOURCE,
56
+ parseCrossTeamPrefix,
57
+ stripCrossTeamPrefix,
58
+ } from '@shared/constants/crossTeam';
59
+ import { extractMarkdownPlainText } from '@shared/utils/markdownTextSearch';
60
+ import { isRateLimitMessage } from '@shared/utils/rateLimitDetector';
61
+ import {
62
+ buildStandaloneSlashCommandMeta,
63
+ getKnownSlashCommand,
64
+ parseStandaloneSlashCommand,
65
+ } from '@shared/utils/slashCommands';
66
+ import { formatTaskDisplayLabel } from '@shared/utils/taskIdentity';
67
+ import {
68
+ AlertTriangle,
69
+ Check,
70
+ ChevronRight,
71
+ Clock,
72
+ Command,
73
+ ListPlus,
74
+ Maximize2,
75
+ MoveRight,
76
+ RefreshCw,
77
+ Reply,
78
+ X,
79
+ } from 'lucide-react';
80
+ import { useShallow } from 'zustand/react/shallow';
81
+
82
+ import { ReplyQuoteBlock } from './ReplyQuoteBlock';
83
+
84
+ import type { TeamColorSet } from '@renderer/constants/teamColors';
85
+ import type { InboxMessage } from '@shared/types';
86
+
87
+ type StructuredMessage = Record<string, unknown>;
88
+
89
+ function parseQualifiedRecipient(
90
+ value: string | undefined
91
+ ): { teamName: string; memberName: string } | null {
92
+ if (typeof value !== 'string') return null;
93
+ const trimmed = value.trim();
94
+ const dot = trimmed.indexOf('.');
95
+ if (dot <= 0 || dot === trimmed.length - 1) return null;
96
+ return {
97
+ teamName: trimmed.slice(0, dot),
98
+ memberName: trimmed.slice(dot + 1),
99
+ };
100
+ }
101
+
102
+ function buildLeadSourceTooltip(message: InboxMessage, leadLabel: string): string {
103
+ const parts = [`发送者:${leadLabel}`, `消息来源:${message.source ?? 'unknown'}`];
104
+ if (message.leadSessionId) {
105
+ parts.push(`Session:${message.leadSessionId}`);
106
+ }
107
+ return parts.join('\n');
108
+ }
109
+
110
+ function parseCrossTeamPseudoRecipient(value: string | undefined): string | null {
111
+ if (typeof value !== 'string') return null;
112
+ const trimmed = value.trim();
113
+ if (!trimmed.startsWith('cross-team:')) return null;
114
+ const teamName = trimmed.slice('cross-team:'.length).trim();
115
+ return teamName.length > 0 ? teamName : null;
116
+ }
117
+
118
+ function getCommandOutputSummary(text: string): string {
119
+ const firstLine = text
120
+ .split(/\r?\n/)
121
+ .map((line) => line.trim())
122
+ .find(Boolean);
123
+
124
+ if (!firstLine) return '';
125
+ return firstLine.length > 120 ? `${firstLine.slice(0, 120)}…` : firstLine;
126
+ }
127
+
128
+ function parseIdlePeerSummaryRoute(summary: string): { recipient: string | null; body: string } {
129
+ const trimmed = summary.trim();
130
+ const match = /^\[to\s+([^\]]+)\]\s*(.*)$/i.exec(trimmed);
131
+ if (!match) {
132
+ return { recipient: null, body: trimmed };
133
+ }
134
+
135
+ const recipient = match[1]?.trim() || null;
136
+ const body = match[2]?.trim() || trimmed;
137
+ return { recipient, body };
138
+ }
139
+
140
+ export function isQualifiedExternalRecipient(
141
+ value: string | undefined,
142
+ teamName: string,
143
+ localMemberNames?: Set<string>
144
+ ): boolean {
145
+ const recipient = parseQualifiedRecipient(value);
146
+ if (!recipient) return false;
147
+ if (recipient.teamName === teamName) return false;
148
+ return !localMemberNames?.has(value?.trim() ?? '');
149
+ }
150
+
151
+ export function getCrossTeamSentTarget(
152
+ value: string | undefined,
153
+ teamName: string,
154
+ localMemberNames?: Set<string>
155
+ ): string | null {
156
+ const pseudoTarget = parseCrossTeamPseudoRecipient(value);
157
+ if (pseudoTarget) return pseudoTarget;
158
+ const recipient = parseQualifiedRecipient(value);
159
+ if (!recipient) return null;
160
+ if (recipient.teamName === teamName) return null;
161
+ if (localMemberNames?.has(value?.trim() ?? '')) return null;
162
+ return recipient.teamName;
163
+ }
164
+
165
+ export function getCrossTeamSentMemberName(value: string | undefined): string | null {
166
+ return parseQualifiedRecipient(value)?.memberName ?? null;
167
+ }
168
+
169
+ const CrossTeamTeamBadge = ({
170
+ teamName,
171
+ onClick,
172
+ }: {
173
+ teamName: string;
174
+ onClick?: (teamName: string) => void;
175
+ }): React.JSX.Element => {
176
+ const displayName = useStore((s) => s.teamByName[teamName]?.displayName || teamName);
177
+ if (onClick) {
178
+ return (
179
+ <button
180
+ type="button"
181
+ className="inline-flex items-center rounded-full px-1.5 py-0.5 text-[10px] font-medium tracking-wide"
182
+ style={{
183
+ backgroundColor: 'rgba(168, 85, 247, 0.15)',
184
+ color: '#c084fc',
185
+ cursor: 'pointer',
186
+ border: 'none',
187
+ padding: '1px 6px',
188
+ }}
189
+ onClick={(e) => {
190
+ e.stopPropagation();
191
+ onClick(teamName);
192
+ }}
193
+ >
194
+ {displayName}
195
+ </button>
196
+ );
197
+ }
198
+ return (
199
+ <span
200
+ className="inline-flex items-center rounded-full px-1.5 py-0.5 text-[10px] font-medium tracking-wide"
201
+ style={{ backgroundColor: 'rgba(168, 85, 247, 0.15)', color: '#c084fc' }}
202
+ >
203
+ {displayName}
204
+ </span>
205
+ );
206
+ };
207
+
208
+ const SessionSourceBadge = ({ message }: { message: InboxMessage }): React.JSX.Element | null => {
209
+ const session = message.session;
210
+ if (!session?.key && !session?.title && !session?.platform) {
211
+ return null;
212
+ }
213
+ const label =
214
+ session?.title || session?.chatName || session?.userName || session?.key || session?.platform || 'Session';
215
+ const platform = session?.platform ? `${session.platform} · ` : '';
216
+ return (
217
+ <span
218
+ className="inline-flex max-w-[180px] items-center truncate rounded-full px-1.5 py-0.5 text-[10px] font-medium"
219
+ title={`${platform}${label}${session?.key ? ` (${session.key})` : ''}`}
220
+ style={{
221
+ backgroundColor: 'rgba(59, 130, 246, 0.12)',
222
+ color: '#93c5fd',
223
+ }}
224
+ >
225
+ {platform}
226
+ {label}
227
+ </span>
228
+ );
229
+ };
230
+
231
+ interface ActivityItemProps {
232
+ message: InboxMessage;
233
+ teamName: string;
234
+ localMemberNames?: Set<string>;
235
+ teamNames?: string[];
236
+ memberRole?: string;
237
+ memberColor?: string;
238
+ recipientColor?: string;
239
+ /** When true, show a blue unread dot. */
240
+ isUnread?: boolean;
241
+ /** Map of member name → color name for @mention badge rendering. */
242
+ memberColorMap?: Map<string, string>;
243
+ /** Team color mapping for team:// links rendered inside markdown. */
244
+ teamColorByName?: ReadonlyMap<string, string>;
245
+ /** Opens a team tab from cross-team badges or team:// links. */
246
+ onTeamClick?: (teamName: string) => void;
247
+ onMemberNameClick?: (memberName: string) => void;
248
+ onCreateTask?: (subject: string, description: string) => void;
249
+ onReply?: (message: InboxMessage) => void;
250
+ /** Called when a task ID link (e.g. #10) is clicked in message text. */
251
+ onTaskIdClick?: (taskId: string) => void;
252
+ /** Called when the user clicks "Restart team" on an auth error message. */
253
+ onRestartTeam?: () => void;
254
+ /** When true, apply a subtle lighter background for zebra-striped lists. */
255
+ zebraShade?: boolean;
256
+ /** Collapsed-mode primitives stabilized by ActivityTimeline. */
257
+ collapseMode?: 'default' | 'managed';
258
+ isCollapsed?: boolean;
259
+ canToggleCollapse?: boolean;
260
+ collapseToggleKey?: string;
261
+ onToggleCollapse?: (key: string) => void;
262
+ /** Compact header mode for narrow message lists. */
263
+ compactHeader?: boolean;
264
+ /** Callback to expand this item into a fullscreen dialog. */
265
+ onExpand?: (key: string) => void;
266
+ /** Stable key for expand identification. */
267
+ expandItemKey?: string;
268
+ /** Called when ExpandableContent is expanded via "Show more". */
269
+ onExpandContent?: () => void;
270
+ }
271
+
272
+ function areMessagesEquivalentForActivityItem(prev: InboxMessage, next: InboxMessage): boolean {
273
+ return areInboxMessagesEquivalentForRender(prev, next);
274
+ }
275
+
276
+ function getStringField(obj: StructuredMessage, key: string): string | null {
277
+ const value = obj[key];
278
+ return typeof value === 'string' && value.trim() !== '' ? value : null;
279
+ }
280
+
281
+ /** Check if a message renders as a compact noise row (idle, shutdown, etc.). */
282
+ export function isNoiseMessage(text: string): boolean {
283
+ return (
284
+ getIdleNoiseLabel(text) !== null ||
285
+ ((): boolean => {
286
+ const parsed = parseStructuredAgentMessage(text);
287
+ return parsed !== null && getNoiseLabel(parsed) !== null;
288
+ })()
289
+ );
290
+ }
291
+
292
+ function getNoiseLabel(parsed: StructuredMessage): string | null {
293
+ const type = getStringField(parsed, 'type');
294
+
295
+ if (type === 'idle_notification') {
296
+ return getIdleNoiseLabel(parsed);
297
+ }
298
+
299
+ if (type === 'shutdown_response') {
300
+ return parsed.approve === true ? 'Shut down' : 'Rejected shutdown';
301
+ }
302
+
303
+ if (type === 'shutdown_request') {
304
+ return 'Shutdown requested';
305
+ }
306
+
307
+ if (type === 'shutdown_approved' || type === 'teammate_terminated') {
308
+ return type === 'shutdown_approved' ? 'Shutdown confirmed' : 'Terminated';
309
+ }
310
+
311
+ if (type === 'task_completed') {
312
+ const rawTaskId = parsed.taskId;
313
+ const taskId =
314
+ typeof rawTaskId === 'string' || typeof rawTaskId === 'number' ? rawTaskId : null;
315
+ return taskId !== null
316
+ ? `已完成任务 ${formatTaskDisplayLabel({ id: String(taskId) })}`
317
+ : '已完成一个任务';
318
+ }
319
+
320
+ if (type === 'permission_request') {
321
+ const toolName = getStringField(parsed, 'tool_name');
322
+ return toolName ? `权限请求:${toolName}` : '权限请求';
323
+ }
324
+
325
+ if (type === 'permission_response') {
326
+ if (parsed.approved === true) return '权限已批准';
327
+ if (parsed.approved === false) return '权限已拒绝';
328
+ return '权限响应';
329
+ }
330
+
331
+ return null;
332
+ }
333
+
334
+ // ---------------------------------------------------------------------------
335
+ // Compact noise row (idle, shutdown, terminated) — minimal dot + name + label
336
+ // ---------------------------------------------------------------------------
337
+
338
+ const NoiseRow = ({
339
+ name,
340
+ label,
341
+ colors,
342
+ icon,
343
+ }: {
344
+ name: string;
345
+ label: string;
346
+ colors: TeamColorSet;
347
+ icon?: React.ReactNode;
348
+ }): React.JSX.Element => (
349
+ <div className="flex items-center gap-2 px-3 py-1" style={{ opacity: 0.45 }}>
350
+ <span className="size-2 shrink-0 rounded-full" style={{ backgroundColor: colors.border }} />
351
+ <span className="text-[11px]" style={{ color: CARD_ICON_MUTED }}>
352
+ {name}
353
+ </span>
354
+ <span className="text-[11px]" style={{ color: CARD_ICON_MUTED }}>
355
+ {label}
356
+ </span>
357
+ {icon}
358
+ </div>
359
+ );
360
+
361
+ const PassiveIdlePeerSummaryRow = ({
362
+ teamName,
363
+ senderName,
364
+ senderColor,
365
+ summary,
366
+ timestamp,
367
+ onMemberNameClick,
368
+ }: {
369
+ teamName: string;
370
+ senderName: string;
371
+ senderColor?: string;
372
+ summary: string;
373
+ timestamp: string;
374
+ onMemberNameClick?: (memberName: string) => void;
375
+ }): React.JSX.Element => {
376
+ const { recipient, body } = parseIdlePeerSummaryRoute(summary);
377
+
378
+ return (
379
+ <div className="flex items-center gap-2 px-3 py-1.5" style={{ opacity: 0.78 }}>
380
+ <span className="bg-sky-500/12 rounded-full px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-sky-300">
381
+ 更新
382
+ </span>
383
+ <MemberBadge
384
+ name={senderName}
385
+ color={senderColor}
386
+ teamName={teamName}
387
+ hideAvatar={false}
388
+ onClick={onMemberNameClick}
389
+ />
390
+ {recipient ? (
391
+ <>
392
+ <MoveRight size={10} style={{ color: CARD_ICON_MUTED }} className="shrink-0" />
393
+ <span
394
+ className="inline-flex shrink-0 items-center rounded-full px-2 py-0.5 text-[10px] font-medium tracking-wide"
395
+ style={{
396
+ backgroundColor: 'rgba(148, 163, 184, 0.12)',
397
+ color: CARD_TEXT_LIGHT,
398
+ }}
399
+ >
400
+ {recipient}
401
+ </span>
402
+ </>
403
+ ) : null}
404
+ <span className="min-w-0 flex-1 truncate text-xs" style={{ color: CARD_TEXT_LIGHT }}>
405
+ {body}
406
+ </span>
407
+ <span className="shrink-0 text-[10px]" style={{ color: CARD_ICON_MUTED }}>
408
+ {timestamp}
409
+ </span>
410
+ </div>
411
+ );
412
+ };
413
+
414
+ const BootstrapSystemRow = ({
415
+ teamName,
416
+ senderName,
417
+ recipientName,
418
+ runtime,
419
+ senderColor,
420
+ recipientColor,
421
+ timestamp,
422
+ onMemberNameClick,
423
+ }: {
424
+ teamName: string;
425
+ senderName: string;
426
+ recipientName: string;
427
+ runtime?: string;
428
+ senderColor?: string;
429
+ recipientColor?: string;
430
+ timestamp: string;
431
+ onMemberNameClick?: (memberName: string) => void;
432
+ }): React.JSX.Element => (
433
+ <div className="flex items-center gap-2 px-3 py-2" style={{ opacity: 0.82 }}>
434
+ <span className="bg-sky-500/12 inline-flex items-center rounded-full px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-sky-300">
435
+ 启动
436
+ </span>
437
+ <MemberBadge
438
+ name={senderName}
439
+ color={senderColor}
440
+ teamName={teamName}
441
+ hideAvatar
442
+ onClick={onMemberNameClick}
443
+ />
444
+ <MoveRight size={10} style={{ color: CARD_ICON_MUTED }} className="shrink-0" />
445
+ <MemberBadge
446
+ name={recipientName}
447
+ color={recipientColor}
448
+ teamName={teamName}
449
+ hideAvatar
450
+ onClick={onMemberNameClick}
451
+ />
452
+ <span className="min-w-0 flex-1 truncate text-[11px]" style={{ color: CARD_ICON_MUTED }}>
453
+ {runtime || '正在启动成员'}
454
+ </span>
455
+ <span className="shrink-0 text-[10px]" style={{ color: CARD_ICON_MUTED }}>
456
+ {timestamp}
457
+ </span>
458
+ </div>
459
+ );
460
+
461
+ const BootstrapAcknowledgementRow = ({
462
+ teamName,
463
+ senderName,
464
+ recipientName,
465
+ senderColor,
466
+ recipientColor,
467
+ timestamp,
468
+ onMemberNameClick,
469
+ }: {
470
+ teamName: string;
471
+ senderName: string;
472
+ recipientName: string;
473
+ senderColor?: string;
474
+ recipientColor?: string;
475
+ timestamp: string;
476
+ onMemberNameClick?: (memberName: string) => void;
477
+ }): React.JSX.Element => (
478
+ <div className="flex items-center gap-2 px-3 py-2" style={{ opacity: 0.72 }}>
479
+ <span className="bg-emerald-500/12 inline-flex items-center rounded-full px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide text-emerald-300">
480
+ 引导
481
+ </span>
482
+ <MemberBadge
483
+ name={senderName}
484
+ color={senderColor}
485
+ teamName={teamName}
486
+ hideAvatar
487
+ onClick={onMemberNameClick}
488
+ />
489
+ <MoveRight size={10} style={{ color: CARD_ICON_MUTED }} className="shrink-0" />
490
+ <MemberBadge
491
+ name={recipientName}
492
+ color={recipientColor}
493
+ teamName={teamName}
494
+ hideAvatar
495
+ onClick={onMemberNameClick}
496
+ />
497
+ <span className="min-w-0 flex-1 truncate text-[11px]" style={{ color: CARD_ICON_MUTED }}>
498
+ 引导已确认
499
+ </span>
500
+ <span className="shrink-0 text-[10px]" style={{ color: CARD_ICON_MUTED }}>
501
+ {timestamp}
502
+ </span>
503
+ </div>
504
+ );
505
+
506
+ // ---------------------------------------------------------------------------
507
+ // Detect historical system/automated messages that should be collapsed by default.
508
+ // These patterns are kept only for legacy compatibility with old inbox/session rows;
509
+ // new runtime behavior must not depend on exact legacy wording.
510
+ // ---------------------------------------------------------------------------
511
+
512
+ const SYSTEM_MESSAGE_PATTERNS: { pattern: RegExp; label: string }[] = [
513
+ { pattern: /^New task assigned to you:/, label: '任务' },
514
+ { pattern: /^Task #[A-Za-z0-9-]+\s+approved/, label: '任务已批准' },
515
+ { pattern: /^Task #[A-Za-z0-9-]+\s+needs fixes/, label: '需要修改' },
516
+ ];
517
+
518
+ export function getSystemMessageLabel(text: string): string | null {
519
+ for (const { pattern, label } of SYSTEM_MESSAGE_PATTERNS) {
520
+ if (pattern.test(text)) return label;
521
+ }
522
+ return null;
523
+ }
524
+
525
+ /** Labels to highlight in task assignment / review messages (bold in markdown). */
526
+ const TASK_MESSAGE_LABELS = [
527
+ 'New task assigned to you:',
528
+ 'Description:',
529
+ 'Task approved',
530
+ 'Task needs fixes',
531
+ 'Review changes requested',
532
+ 'Changes requested:',
533
+ 'Comments:',
534
+ 'Reviewer:',
535
+ 'Related:',
536
+ 'Blocked by:',
537
+ 'Blocks:',
538
+ ];
539
+
540
+ /** Make known structural labels bold in system/task messages. */
541
+ function highlightSystemLabels(text: string, isSystem: boolean): string {
542
+ if (!isSystem) return text;
543
+ let result = text;
544
+ for (const label of TASK_MESSAGE_LABELS) {
545
+ // Escape any regex-special chars in the label, match at line start or after newline
546
+ const escaped = label.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
547
+ result = result.replace(new RegExp(`(^|\\n)(${escaped})`, 'g'), '$1**$2**');
548
+ }
549
+ return result;
550
+ }
551
+
552
+ /** Detect authentication/authorization errors that may be resolved by restarting. */
553
+ const AUTH_ERROR_PATTERNS = [
554
+ /OAuth token has expired/i,
555
+ /API Error:\s*401/i,
556
+ /authentication_error/i,
557
+ /Failed to authenticate/i,
558
+ /invalid.*api.key/i,
559
+ /unauthorized/i,
560
+ ];
561
+
562
+ // ---------------------------------------------------------------------------
563
+ // Full message card — left colored border, name badge, collapsible content
564
+ // ---------------------------------------------------------------------------
565
+
566
+ /** Render `#<task-display-id>` in plain text as clickable inline elements with TaskTooltip. */
567
+ function linkifyTaskIds(text: string, onClick: (taskId: string) => void): React.ReactNode[] {
568
+ return text.split(/(#[A-Za-z0-9-]+\b)/g).map((part, i) => {
569
+ const match = /^#([A-Za-z0-9-]+)$/.exec(part);
570
+ if (!match) return <Fragment key={i}>{part}</Fragment>;
571
+ const taskId = match[1];
572
+ return (
573
+ <TaskTooltip key={i} taskId={taskId}>
574
+ <button
575
+ type="button"
576
+ className="inline cursor-pointer font-medium text-blue-600 hover:underline dark:text-blue-400"
577
+ onClick={(e) => {
578
+ e.stopPropagation();
579
+ onClick(taskId);
580
+ }}
581
+ >
582
+ {part}
583
+ </button>
584
+ </TaskTooltip>
585
+ );
586
+ });
587
+ }
588
+
589
+ /**
590
+ * Render summary text with inline bold markdown and optional task-id linkification.
591
+ * Splits on bold markers first, then linkifies task IDs within each segment.
592
+ */
593
+ function renderInlineBoldSummary(
594
+ text: string,
595
+ onTaskIdClick?: (taskId: string) => void
596
+ ): React.ReactNode {
597
+ // Split by **bold** segments, keeping delimiters
598
+ const boldPattern = /(\*\*[^*]+\*\*)/g;
599
+ const parts = text.split(boldPattern);
600
+ return parts.map((part, i) => {
601
+ const boldContent = /^\*\*(.+)\*\*$/.exec(part);
602
+ if (boldContent) {
603
+ const inner = boldContent[1];
604
+ return (
605
+ <strong key={i} className="font-semibold">
606
+ {onTaskIdClick ? linkifyTaskIds(inner, onTaskIdClick) : inner}
607
+ </strong>
608
+ );
609
+ }
610
+ return onTaskIdClick ? (
611
+ <Fragment key={i}>{linkifyTaskIds(part, onTaskIdClick)}</Fragment>
612
+ ) : (
613
+ <Fragment key={i}>{part}</Fragment>
614
+ );
615
+ });
616
+ }
617
+
618
+ const TaskRecipientBadge = ({
619
+ taskId,
620
+ displayId,
621
+ teamName,
622
+ onTaskIdClick,
623
+ }: Readonly<{
624
+ taskId: string;
625
+ displayId: string;
626
+ teamName?: string;
627
+ onTaskIdClick?: (taskId: string) => void;
628
+ }>): React.JSX.Element => {
629
+ const content = (
630
+ <span
631
+ className="inline-flex items-center rounded px-1.5 py-0.5 text-[10px] font-medium tracking-wide"
632
+ style={{
633
+ backgroundColor: 'rgba(96, 165, 250, 0.14)',
634
+ color: '#60a5fa',
635
+ border: '1px solid rgba(96, 165, 250, 0.3)',
636
+ }}
637
+ >
638
+ {displayId}
639
+ </span>
640
+ );
641
+
642
+ if (!onTaskIdClick) {
643
+ return content;
644
+ }
645
+
646
+ return (
647
+ <TaskTooltip taskId={taskId} teamName={teamName}>
648
+ <button
649
+ type="button"
650
+ className="inline-flex rounded transition-opacity hover:opacity-90 focus:outline-none focus:ring-1 focus:ring-[var(--color-border)]"
651
+ onClick={(e) => {
652
+ e.stopPropagation();
653
+ onTaskIdClick(taskId);
654
+ }}
655
+ >
656
+ {content}
657
+ </button>
658
+ </TaskTooltip>
659
+ );
660
+ };
661
+
662
+ export const ActivityItem = memo(
663
+ ({
664
+ message,
665
+ teamName,
666
+ localMemberNames,
667
+ teamNames = [],
668
+ memberRole,
669
+ memberColor,
670
+ recipientColor,
671
+ isUnread,
672
+ memberColorMap,
673
+ teamColorByName,
674
+ onTeamClick,
675
+ onMemberNameClick,
676
+ onCreateTask,
677
+ onReply,
678
+ onTaskIdClick,
679
+ onRestartTeam,
680
+ zebraShade,
681
+ collapseMode = 'default',
682
+ isCollapsed = false,
683
+ canToggleCollapse = false,
684
+ collapseToggleKey,
685
+ onToggleCollapse,
686
+ compactHeader = false,
687
+ onExpand,
688
+ expandItemKey,
689
+ onExpandContent,
690
+ }: Readonly<ActivityItemProps>): React.JSX.Element => {
691
+ const colors = getTeamColorSet(memberColor ?? message.color ?? '');
692
+ const { isLight } = useTheme();
693
+ // Hide role when it matches the sender name (avoids "lead" badge + "Team Lead" text duplication)
694
+ const formattedRole =
695
+ memberRole && memberRole !== message.from ? formatAgentRole(memberRole) : null;
696
+
697
+ const timestamp = useMemo(() => {
698
+ if (Number.isNaN(Date.parse(message.timestamp))) return message.timestamp;
699
+ const date = new Date(message.timestamp);
700
+ const now = new Date();
701
+ const isToday =
702
+ date.getFullYear() === now.getFullYear() &&
703
+ date.getMonth() === now.getMonth() &&
704
+ date.getDate() === now.getDate();
705
+ return isToday
706
+ ? date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
707
+ : date.toLocaleString();
708
+ }, [message.timestamp]);
709
+
710
+ const structured = parseStructuredAgentMessage(message.text);
711
+ const bootstrapDisplay = getBootstrapPromptDisplay(message);
712
+ const bootstrapAcknowledgement = getBootstrapAcknowledgementDisplay(message);
713
+ // Only flag agent messages as rate-limited, not user's own quotes
714
+ const rateLimited = message.from !== 'user' && isRateLimitMessage(message.text);
715
+ // Highlight messages containing API errors
716
+ const isApiError = message.text.includes('API Error');
717
+ // Detect auth errors that may be resolved by restarting the team
718
+ const isAuthError = isApiError && AUTH_ERROR_PATTERNS.some((p) => p.test(message.text));
719
+ // Never collapse rate limit messages as noise — they must be visible
720
+ const noiseLabel = structured && !rateLimited ? getNoiseLabel(structured) : null;
721
+ const idleSemantic = classifyIdleNotification(message);
722
+
723
+ const systemLabel = !structured && !rateLimited ? getSystemMessageLabel(message.text) : null;
724
+ const isManaged = collapseMode === 'managed';
725
+ const isExpanded = isManaged ? !isCollapsed : true;
726
+
727
+ const parsedCrossTeamPrefix = parseCrossTeamPrefix(message.text);
728
+ const qualifiedRecipient = parseQualifiedRecipient(message.to);
729
+ const crossTeamSentTarget = getCrossTeamSentTarget(message.to, teamName, localMemberNames);
730
+ const crossTeamSentMemberName = getCrossTeamSentMemberName(message.to);
731
+ const isCrossTeam = message.source === CROSS_TEAM_SOURCE || parsedCrossTeamPrefix !== null;
732
+ const isCrossTeamSent =
733
+ message.source === CROSS_TEAM_SENT_SOURCE || crossTeamSentTarget !== null;
734
+ const isCrossTeamAny = isCrossTeam || isCrossTeamSent;
735
+ const crossTeamOrigin = useMemo(() => {
736
+ if (!isCrossTeam) return null;
737
+ const fromValue = parsedCrossTeamPrefix?.from ?? message.from;
738
+ const dot = fromValue.indexOf('.');
739
+ if (dot <= 0 || dot === fromValue.length - 1) return null;
740
+ return {
741
+ teamName: fromValue.substring(0, dot),
742
+ memberName: fromValue.substring(dot + 1),
743
+ };
744
+ }, [isCrossTeam, message.from, parsedCrossTeamPrefix]);
745
+ const crossTeamTarget = useMemo(() => {
746
+ if (!isCrossTeamSent) return null;
747
+ if (crossTeamSentTarget) return crossTeamSentTarget;
748
+ if (qualifiedRecipient) return qualifiedRecipient.teamName;
749
+ if (!message.to) return null;
750
+ const dot = message.to.indexOf('.');
751
+ if (dot <= 0) return message.to;
752
+ return message.to.substring(0, dot);
753
+ }, [crossTeamSentTarget, isCrossTeamSent, message.to, qualifiedRecipient]);
754
+ const senderName = crossTeamOrigin ? crossTeamOrigin.memberName : message.from;
755
+ const senderColor = crossTeamOrigin ? undefined : (memberColor ?? message.color);
756
+ const senderHideAvatar =
757
+ message.from === 'user' ||
758
+ message.from === 'system' ||
759
+ crossTeamOrigin?.memberName === 'user';
760
+ const isUserSent = message.source === 'user_sent' || isCrossTeamSent;
761
+ const isSystemMessage = message.from === 'system';
762
+
763
+ // Strip agent-only blocks + normalize escape sequences (before linkification)
764
+ const strippedText = useMemo(() => {
765
+ if (structured) return null;
766
+ let stripped = getSanitizedInboxMessageText(message).trim();
767
+ if (!bootstrapDisplay) {
768
+ stripped = stripAgentBlocks(stripped).trim();
769
+ }
770
+ if (!stripped) return null; // All content was agent-only blocks → show summary instead
771
+ // Strip cross-team metadata tag (e.g. `<cross-team from="team.lead" depth="0" />\n`)
772
+ // — kept in stored text for CLI agents / durable artifacts.
773
+ if (isCrossTeamAny) {
774
+ stripped = stripCrossTeamPrefix(stripped);
775
+ }
776
+ // Normalize literal \n from historical CLI-produced text to real newlines
777
+ return stripped.replace(/\\n/g, '\n').replace(/\\t/g, '\t');
778
+ }, [structured, message, bootstrapDisplay, isCrossTeamAny]);
779
+ const standaloneSlashCommand = useMemo(
780
+ () => (strippedText ? parseStandaloneSlashCommand(strippedText) : null),
781
+ [strippedText]
782
+ );
783
+ const slashCommandMeta = useMemo(
784
+ () =>
785
+ message.slashCommand ??
786
+ (standaloneSlashCommand
787
+ ? buildStandaloneSlashCommandMeta(standaloneSlashCommand.raw)
788
+ : null),
789
+ [message.slashCommand, standaloneSlashCommand]
790
+ );
791
+ const knownSlashCommand = useMemo(
792
+ () => (slashCommandMeta?.name ? (getKnownSlashCommand(slashCommandMeta.name) ?? null) : null),
793
+ [slashCommandMeta]
794
+ );
795
+ const isSlashCommandResult =
796
+ message.messageKind === 'slash_command_result' && !!message.commandOutput;
797
+ const isSlashCommandMessage =
798
+ !isSlashCommandResult &&
799
+ (message.messageKind === 'slash_command' || (isUserSent && standaloneSlashCommand !== null));
800
+ const isCommandOutputError = isSlashCommandResult && message.commandOutput?.stream === 'stderr';
801
+
802
+ // Parse reply BEFORE linkification — linkifyAllMentionsInMarkdown transforms @name
803
+ // into markdown links which breaks the reply regex matcher
804
+ const parsedReply = useMemo(
805
+ () => (strippedText ? parseMessageReply(strippedText) : null),
806
+ [strippedText]
807
+ );
808
+
809
+ // Linkify task IDs (always, for TaskTooltip) + @mentions for display
810
+ const displayText = useMemo(() => {
811
+ if (!strippedText) return null;
812
+ let result = highlightSystemLabels(strippedText, !!systemLabel);
813
+ result = linkifyTaskIdsInMarkdown(result, message.taskRefs);
814
+ if ((memberColorMap && memberColorMap.size > 0) || teamNames.length > 0)
815
+ result = linkifyAllMentionsInMarkdown(result, memberColorMap ?? new Map(), teamNames);
816
+ return result;
817
+ }, [strippedText, memberColorMap, teamNames, systemLabel]);
818
+
819
+ const crossTeamPreview = useMemo(() => {
820
+ if (!isCrossTeamAny || !strippedText) return '';
821
+ const oneLine = strippedText.replace(/\n+/g, ' ').trim();
822
+ if (!oneLine) return '';
823
+ return oneLine;
824
+ }, [isCrossTeamAny, strippedText]);
825
+
826
+ const rawSummary = useMemo(() => {
827
+ if (idleSemantic?.hasPeerSummary && idleSemantic.peerSummary) {
828
+ return idleSemantic.peerSummary;
829
+ }
830
+ if (isSlashCommandResult && message.commandOutput) {
831
+ return message.summary || getCommandOutputSummary(message.text);
832
+ }
833
+ if (isSlashCommandMessage && slashCommandMeta) {
834
+ if (slashCommandMeta.args) {
835
+ const oneLine = slashCommandMeta.args.replace(/\n+/g, ' ').trim();
836
+ return `${slashCommandMeta.command} ${oneLine}`;
837
+ }
838
+ return slashCommandMeta.command;
839
+ }
840
+ if (crossTeamPreview) return crossTeamPreview;
841
+ const s =
842
+ getSanitizedInboxMessageSummary(message) ||
843
+ (structured ? getStructuredMessageSummary(structured) : '') ||
844
+ '';
845
+ if (s) return s;
846
+ // Fallback: use the beginning of message text as preview for plain-text messages
847
+ const plain = getSanitizedInboxMessageText(message).trim();
848
+ if (!plain) return '';
849
+ return plain.replace(/\n+/g, ' ');
850
+ }, [
851
+ crossTeamPreview,
852
+ isSlashCommandMessage,
853
+ isSlashCommandResult,
854
+ message.commandOutput,
855
+ message,
856
+ idleSemantic,
857
+ slashCommandMeta,
858
+ structured,
859
+ ]);
860
+ const summaryText = extractMarkdownPlainText(rawSummary);
861
+ const compactPreviewMarkdown = useMemo(() => {
862
+ if (idleSemantic?.hasPeerSummary && idleSemantic.peerSummary) {
863
+ return idleSemantic.peerSummary;
864
+ }
865
+ if (isSlashCommandResult && message.commandOutput) {
866
+ return message.summary || getCommandOutputSummary(message.text);
867
+ }
868
+ if (isSlashCommandMessage && slashCommandMeta) {
869
+ if (slashCommandMeta.args) {
870
+ const oneLine = slashCommandMeta.args.replace(/\n+/g, ' ').trim();
871
+ return `${slashCommandMeta.command} ${oneLine}`;
872
+ }
873
+ return slashCommandMeta.command;
874
+ }
875
+ if (crossTeamPreview) return crossTeamPreview;
876
+
877
+ const formattedDisplayText = displayText?.trim() ?? '';
878
+ if (formattedDisplayText) {
879
+ return formattedDisplayText;
880
+ }
881
+
882
+ return summaryText || rawSummary;
883
+ }, [
884
+ crossTeamPreview,
885
+ displayText,
886
+ idleSemantic,
887
+ isSlashCommandMessage,
888
+ isSlashCommandResult,
889
+ message,
890
+ message.commandOutput,
891
+ rawSummary,
892
+ slashCommandMeta,
893
+ summaryText,
894
+ ]);
895
+ const compactPreviewTooltipText = useMemo(() => {
896
+ const normalized = extractMarkdownPlainText(compactPreviewMarkdown)
897
+ .replace(/\n+/g, ' ')
898
+ .trim();
899
+ return normalized || compactPreviewMarkdown;
900
+ }, [compactPreviewMarkdown]);
901
+ const commentTaskRef =
902
+ message.messageKind === 'task_comment_notification' ? (message.taskRefs?.[0] ?? null) : null;
903
+ const commentTaskDisplayId =
904
+ commentTaskRef?.displayId ??
905
+ (commentTaskRef?.taskId ? `#${commentTaskRef.taskId.slice(0, 6)}` : null);
906
+
907
+ // Permission request status icon (check/x/clock)
908
+ const pendingApprovals = useStore(useShallow((s) => s.pendingApprovals));
909
+ const resolvedApprovals = useStore(useShallow((s) => s.resolvedApprovals));
910
+ const permissionIcon = useMemo(() => {
911
+ if (!structured) return null;
912
+ const type = typeof structured.type === 'string' ? structured.type : null;
913
+ if (type !== 'permission_request') return null;
914
+ const requestId = typeof structured.request_id === 'string' ? structured.request_id : null;
915
+ if (!requestId) return null;
916
+
917
+ const resolved = resolvedApprovals.get(requestId);
918
+ if (resolved === true) {
919
+ return <Check size={12} className="text-emerald-400" />;
920
+ }
921
+ if (resolved === false) {
922
+ return <X size={12} className="text-red-400" />;
923
+ }
924
+ const isPending = pendingApprovals.some((a) => a.requestId === requestId);
925
+ if (isPending) {
926
+ return <Clock size={12} className="animate-pulse text-amber-400" />;
927
+ }
928
+ // Not in pending and not resolved — already handled before we started tracking
929
+ return <Check size={12} className="text-emerald-400/50" />;
930
+ }, [structured, pendingApprovals, resolvedApprovals]);
931
+
932
+ // Noise messages: minimal inline row
933
+ if (noiseLabel) {
934
+ return (
935
+ <NoiseRow name={message.from} label={noiseLabel} colors={colors} icon={permissionIcon} />
936
+ );
937
+ }
938
+
939
+ if (idleSemantic?.uiPresentation === 'peer_summary' && idleSemantic.peerSummary) {
940
+ return (
941
+ <PassiveIdlePeerSummaryRow
942
+ teamName={teamName}
943
+ senderName={senderName}
944
+ senderColor={senderColor}
945
+ summary={idleSemantic.peerSummary}
946
+ timestamp={timestamp}
947
+ onMemberNameClick={onMemberNameClick}
948
+ />
949
+ );
950
+ }
951
+
952
+ if (bootstrapDisplay) {
953
+ return (
954
+ <BootstrapSystemRow
955
+ teamName={teamName}
956
+ senderName={senderName}
957
+ recipientName={bootstrapDisplay.teammateName ?? message.to ?? 'teammate'}
958
+ runtime={bootstrapDisplay.runtime}
959
+ senderColor={senderColor}
960
+ recipientColor={recipientColor}
961
+ timestamp={timestamp}
962
+ onMemberNameClick={onMemberNameClick}
963
+ />
964
+ );
965
+ }
966
+
967
+ if (bootstrapAcknowledgement) {
968
+ return (
969
+ <BootstrapAcknowledgementRow
970
+ teamName={teamName}
971
+ senderName={senderName}
972
+ recipientName={message.to ?? 'lead'}
973
+ senderColor={senderColor}
974
+ recipientColor={recipientColor}
975
+ timestamp={timestamp}
976
+ onMemberNameClick={onMemberNameClick}
977
+ />
978
+ );
979
+ }
980
+
981
+ const messageType =
982
+ structured && typeof structured.type === 'string'
983
+ ? getMessageTypeLabel(structured.type)
984
+ : null;
985
+ const autoSummary = structured ? getStructuredMessageSummary(structured) : null;
986
+
987
+ const handleCreateTask = useCallback((): void => {
988
+ const subject = message.summary || autoSummary || `Task from ${message.from}`;
989
+ const plainText = structured
990
+ ? JSON.stringify(structured, null, 2)
991
+ : getSanitizedInboxMessageText(message);
992
+ const description = `From: ${message.from}\nAt: ${timestamp}\n\n${plainText}`.slice(0, 2000);
993
+ onCreateTask?.(subject, description);
994
+ }, [autoSummary, message.from, message.summary, message, onCreateTask, structured, timestamp]);
995
+
996
+ const isHeaderClickable = isManaged && canToggleCollapse;
997
+ const showChevron = isHeaderClickable && !compactHeader;
998
+ const handleHeaderToggle = useCallback(() => {
999
+ if (isHeaderClickable && collapseToggleKey) {
1000
+ onToggleCollapse?.(collapseToggleKey);
1001
+ }
1002
+ }, [collapseToggleKey, isHeaderClickable, onToggleCollapse]);
1003
+ const useCompactCollapsedHeader = compactHeader && !isExpanded;
1004
+
1005
+ const senderBadge = isSlashCommandResult ? (
1006
+ <span className="inline-flex items-center rounded-full bg-amber-500/15 px-2 py-0.5 text-[10px] font-medium uppercase tracking-wide text-amber-300">
1007
+ result
1008
+ </span>
1009
+ ) : (
1010
+ <MemberBadge
1011
+ name={senderName}
1012
+ color={senderColor}
1013
+ teamName={teamName}
1014
+ hideAvatar={senderHideAvatar || compactHeader}
1015
+ onClick={onMemberNameClick}
1016
+ disableHoverCard={crossTeamOrigin != null}
1017
+ />
1018
+ );
1019
+
1020
+ const messageTypeBadge = systemLabel ? (
1021
+ <span className="text-[10px] uppercase tracking-wide" style={{ color: CARD_ICON_MUTED }}>
1022
+ {systemLabel}
1023
+ </span>
1024
+ ) : commentTaskRef ? (
1025
+ <span className="text-[10px] uppercase tracking-wide" style={{ color: CARD_ICON_MUTED }}>
1026
+ Comment
1027
+ </span>
1028
+ ) : isSlashCommandResult && message.commandOutput ? (
1029
+ <span
1030
+ className={[
1031
+ 'inline-flex items-center rounded-full px-1.5 py-0.5 text-[10px] uppercase tracking-wide',
1032
+ isCommandOutputError ? 'bg-rose-500/15 text-rose-300' : 'bg-amber-500/15 text-amber-300',
1033
+ ].join(' ')}
1034
+ >
1035
+ {message.commandOutput.stream}
1036
+ </span>
1037
+ ) : isSlashCommandMessage ? (
1038
+ <span className="text-[10px] uppercase tracking-wide text-amber-400">command</span>
1039
+ ) : messageType ? (
1040
+ <span className="text-[10px] uppercase tracking-wide" style={{ color: CARD_ICON_MUTED }}>
1041
+ {messageType}
1042
+ </span>
1043
+ ) : null;
1044
+
1045
+ const statusBadge = rateLimited ? (
1046
+ <span className="inline-flex items-center gap-1 rounded-full bg-amber-500/15 px-1.5 py-0.5 text-[10px] font-medium text-amber-300">
1047
+ <AlertTriangle size={10} />
1048
+ 请求限流
1049
+ </span>
1050
+ ) : isApiError ? (
1051
+ <span className="inline-flex items-center gap-1 rounded-full bg-red-500/20 px-1.5 py-0.5 text-[10px] font-medium text-red-400">
1052
+ <AlertTriangle size={10} />
1053
+ API 错误
1054
+ </span>
1055
+ ) : null;
1056
+
1057
+ const recipientBadge =
1058
+ commentTaskRef && commentTaskDisplayId ? (
1059
+ <>
1060
+ <MoveRight size={10} style={{ color: CARD_ICON_MUTED }} className="shrink-0" />
1061
+ <TaskRecipientBadge
1062
+ taskId={commentTaskRef.taskId}
1063
+ displayId={commentTaskDisplayId}
1064
+ teamName={commentTaskRef.teamName}
1065
+ onTaskIdClick={onTaskIdClick}
1066
+ />
1067
+ </>
1068
+ ) : message.to && message.to !== message.from ? (
1069
+ <>
1070
+ <MoveRight size={10} style={{ color: CARD_ICON_MUTED }} className="shrink-0" />
1071
+ {crossTeamTarget ? (
1072
+ <CrossTeamTeamBadge teamName={crossTeamTarget} onClick={onTeamClick} />
1073
+ ) : null}
1074
+ {crossTeamSentMemberName || !crossTeamTarget ? (
1075
+ <MemberBadge
1076
+ name={crossTeamSentMemberName ?? qualifiedRecipient?.memberName ?? message.to}
1077
+ color={crossTeamTarget ? undefined : recipientColor}
1078
+ teamName={crossTeamTarget ? undefined : teamName}
1079
+ hideAvatar={
1080
+ compactHeader ||
1081
+ (crossTeamSentMemberName ?? qualifiedRecipient?.memberName ?? message.to) === 'user'
1082
+ }
1083
+ onClick={onMemberNameClick}
1084
+ disableHoverCard={crossTeamTarget != null}
1085
+ />
1086
+ ) : null}
1087
+ </>
1088
+ ) : null;
1089
+
1090
+ const summaryContent =
1091
+ isSlashCommandResult && message.commandOutput ? (
1092
+ <span className="inline-flex min-w-0 items-center gap-1.5">
1093
+ <Command
1094
+ size={12}
1095
+ className={['shrink-0', isCommandOutputError ? 'text-rose-400' : 'text-amber-400'].join(
1096
+ ' '
1097
+ )}
1098
+ />
1099
+ <span
1100
+ className={[
1101
+ 'shrink-0 font-mono text-[11px]',
1102
+ isCommandOutputError ? 'text-rose-300' : 'text-amber-300',
1103
+ ].join(' ')}
1104
+ >
1105
+ {message.commandOutput.commandLabel}
1106
+ </span>
1107
+ <span className="min-w-0 truncate text-[11px] text-[var(--color-text-secondary)]">
1108
+ {message.summary || getCommandOutputSummary(message.text) || rawSummary}
1109
+ </span>
1110
+ </span>
1111
+ ) : isSlashCommandMessage && slashCommandMeta ? (
1112
+ <span className="inline-flex min-w-0 items-center gap-1.5">
1113
+ <Command size={12} className="shrink-0 text-amber-400" />
1114
+ <span className="shrink-0 font-mono text-[11px] text-amber-300">
1115
+ {slashCommandMeta.command}
1116
+ </span>
1117
+ {slashCommandMeta.args ? (
1118
+ <span className="min-w-0 truncate text-[11px] text-[var(--color-text-secondary)]">
1119
+ {slashCommandMeta.args.replace(/\n+/g, ' ')}
1120
+ </span>
1121
+ ) : (slashCommandMeta.knownDescription ?? knownSlashCommand?.description) ? (
1122
+ <span className="min-w-0 truncate text-[11px] text-[var(--color-text-secondary)]">
1123
+ {slashCommandMeta.knownDescription ?? knownSlashCommand?.description}
1124
+ </span>
1125
+ ) : null}
1126
+ </span>
1127
+ ) : onTaskIdClick ? (
1128
+ renderInlineBoldSummary(rawSummary, onTaskIdClick)
1129
+ ) : (
1130
+ renderInlineBoldSummary(rawSummary)
1131
+ );
1132
+
1133
+ return (
1134
+ <article
1135
+ className="group overflow-hidden rounded-md"
1136
+ style={{
1137
+ marginLeft: isSlashCommandResult ? 26 : undefined,
1138
+ backgroundColor:
1139
+ rateLimited || isApiError
1140
+ ? 'var(--tool-result-error-bg)'
1141
+ : isSlashCommandResult
1142
+ ? 'rgba(245, 158, 11, 0.08)'
1143
+ : isSlashCommandMessage
1144
+ ? 'rgba(245, 158, 11, 0.08)'
1145
+ : isCrossTeamAny
1146
+ ? 'var(--cross-team-bg)'
1147
+ : isSystemMessage
1148
+ ? 'var(--system-activity-bg)'
1149
+ : zebraShade
1150
+ ? CARD_BG_ZEBRA
1151
+ : CARD_BG,
1152
+ border:
1153
+ rateLimited || isApiError
1154
+ ? '1px solid var(--tool-result-error-border)'
1155
+ : isSlashCommandResult
1156
+ ? '1px solid rgba(245, 158, 11, 0.22)'
1157
+ : isSlashCommandMessage
1158
+ ? '1px solid rgba(245, 158, 11, 0.22)'
1159
+ : isCrossTeamAny
1160
+ ? '1px solid var(--cross-team-border)'
1161
+ : isSystemMessage
1162
+ ? '1px solid var(--system-activity-border)'
1163
+ : CARD_BORDER_STYLE,
1164
+ borderLeft:
1165
+ rateLimited || isApiError
1166
+ ? '3px solid var(--tool-result-error-text)'
1167
+ : isSlashCommandResult
1168
+ ? '3px solid rgba(245, 158, 11, 0.85)'
1169
+ : isSlashCommandMessage
1170
+ ? '3px solid rgba(245, 158, 11, 0.85)'
1171
+ : isCrossTeamAny
1172
+ ? '3px solid var(--cross-team-accent)'
1173
+ : isSystemMessage
1174
+ ? '3px solid var(--system-activity-accent)'
1175
+ : `3px solid ${getThemedBorder(colors, isLight)}`,
1176
+ }}
1177
+ >
1178
+ {/* Header — div with role=button (cannot use <button> due to nested buttons inside) */}
1179
+ {/* eslint-disable-next-line jsx-a11y/no-static-element-interactions -- role=button, tabIndex, onKeyDown below; nested buttons prevent using native button */}
1180
+ <div
1181
+ role={isHeaderClickable ? 'button' : undefined}
1182
+ tabIndex={isHeaderClickable ? 0 : undefined}
1183
+ className={[
1184
+ useCompactCollapsedHeader
1185
+ ? 'min-w-0 px-3 py-2'
1186
+ : 'flex min-w-0 items-center gap-2 px-3 py-2',
1187
+ isHeaderClickable ? 'cursor-pointer select-none' : '',
1188
+ ].join(' ')}
1189
+ onClick={handleHeaderToggle}
1190
+ onKeyDown={
1191
+ isHeaderClickable
1192
+ ? (e) => {
1193
+ if (e.key === 'Enter' || e.key === ' ') {
1194
+ e.preventDefault();
1195
+ handleHeaderToggle?.();
1196
+ }
1197
+ }
1198
+ : undefined
1199
+ }
1200
+ >
1201
+ {useCompactCollapsedHeader ? (
1202
+ <div className="min-w-0">
1203
+ <div className="flex min-w-0 items-start gap-3">
1204
+ <div className="flex min-w-0 flex-1 items-center gap-2 overflow-hidden">
1205
+ {isUnread ? (
1206
+ <span
1207
+ className="size-2 shrink-0 rounded-full bg-blue-500"
1208
+ title="未读"
1209
+ aria-hidden
1210
+ />
1211
+ ) : null}
1212
+ {crossTeamOrigin ? (
1213
+ <CrossTeamTeamBadge teamName={crossTeamOrigin.teamName} onClick={onTeamClick} />
1214
+ ) : null}
1215
+ {senderBadge}
1216
+ <SessionSourceBadge message={message} />
1217
+ {messageTypeBadge}
1218
+
1219
+ {statusBadge}
1220
+ {recipientBadge}
1221
+ </div>
1222
+ <div className="relative flex shrink-0 items-center">
1223
+ <span
1224
+ className={
1225
+ onExpand && expandItemKey
1226
+ ? 'text-[10px] transition-opacity group-hover:opacity-0'
1227
+ : 'text-[10px]'
1228
+ }
1229
+ style={{ color: CARD_ICON_MUTED }}
1230
+ >
1231
+ {timestamp}
1232
+ </span>
1233
+ {onExpand && expandItemKey && (
1234
+ <button
1235
+ type="button"
1236
+ aria-label="展开消息"
1237
+ className="absolute right-0 top-1/2 -translate-y-1/2 rounded p-0.5 opacity-0 transition-opacity focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-blue-500/50 group-hover:opacity-100"
1238
+ style={{ color: CARD_ICON_MUTED }}
1239
+ onClick={(e) => {
1240
+ e.stopPropagation();
1241
+ onExpand(expandItemKey);
1242
+ }}
1243
+ onKeyDown={(e) => e.stopPropagation()}
1244
+ >
1245
+ <Maximize2 size={12} />
1246
+ </button>
1247
+ )}
1248
+ </div>
1249
+ </div>
1250
+ <TooltipProvider delayDuration={1000}>
1251
+ <Tooltip>
1252
+ <TooltipTrigger asChild>
1253
+ <div>
1254
+ <CompactMarkdownPreview
1255
+ content={compactPreviewMarkdown}
1256
+ className="mt-1 line-clamp-2 w-full min-w-0 max-w-full break-words text-[11px] leading-4"
1257
+ teamColorByName={teamColorByName}
1258
+ onTeamClick={onTeamClick}
1259
+ />
1260
+ </div>
1261
+ </TooltipTrigger>
1262
+ <TooltipContent
1263
+ side="bottom"
1264
+ align="start"
1265
+ className="max-w-sm whitespace-normal break-words"
1266
+ >
1267
+ {compactPreviewTooltipText}
1268
+ </TooltipContent>
1269
+ </Tooltip>
1270
+ </TooltipProvider>
1271
+ </div>
1272
+ ) : !isExpanded ? (
1273
+ <div className="min-w-0 flex-1">
1274
+ <div className="flex min-w-0 items-center gap-2">
1275
+ {isUnread ? (
1276
+ <span
1277
+ className="size-2 shrink-0 rounded-full bg-blue-500"
1278
+ title="未读"
1279
+ aria-hidden
1280
+ />
1281
+ ) : null}
1282
+ {showChevron ? (
1283
+ <ChevronRight
1284
+ className="size-3 shrink-0 transition-transform duration-150"
1285
+ style={{
1286
+ color: CARD_ICON_MUTED,
1287
+ transform: isExpanded ? 'rotate(90deg)' : undefined,
1288
+ }}
1289
+ />
1290
+ ) : null}
1291
+ {crossTeamOrigin ? (
1292
+ <CrossTeamTeamBadge teamName={crossTeamOrigin.teamName} onClick={onTeamClick} />
1293
+ ) : null}
1294
+ {senderBadge}
1295
+ <SessionSourceBadge message={message} />
1296
+ {!compactHeader && formattedRole && !isSlashCommandResult ? (
1297
+ <span className="text-[10px]" style={{ color: CARD_ICON_MUTED }}>
1298
+ {formattedRole}
1299
+ </span>
1300
+ ) : null}
1301
+ {messageTypeBadge}
1302
+
1303
+ {statusBadge}
1304
+ {recipientBadge}
1305
+ <div className="relative ml-auto flex shrink-0 items-center">
1306
+ <span
1307
+ className={
1308
+ onExpand && expandItemKey
1309
+ ? 'text-[10px] transition-opacity group-hover:opacity-0'
1310
+ : 'text-[10px]'
1311
+ }
1312
+ style={{ color: CARD_ICON_MUTED }}
1313
+ >
1314
+ {timestamp}
1315
+ </span>
1316
+ {onExpand && expandItemKey && (
1317
+ <button
1318
+ type="button"
1319
+ aria-label="展开消息"
1320
+ className="absolute right-0 top-1/2 -translate-y-1/2 rounded p-0.5 opacity-0 transition-opacity focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-blue-500/50 group-hover:opacity-100"
1321
+ style={{ color: CARD_ICON_MUTED }}
1322
+ onClick={(e) => {
1323
+ e.stopPropagation();
1324
+ onExpand(expandItemKey);
1325
+ }}
1326
+ onKeyDown={(e) => e.stopPropagation()}
1327
+ >
1328
+ <Maximize2 size={12} />
1329
+ </button>
1330
+ )}
1331
+ </div>
1332
+ </div>
1333
+ <TooltipProvider delayDuration={1000}>
1334
+ <Tooltip>
1335
+ <TooltipTrigger asChild>
1336
+ <div>
1337
+ <CompactMarkdownPreview
1338
+ content={compactPreviewMarkdown}
1339
+ className="mt-1 line-clamp-2 w-full min-w-0 max-w-full break-words text-[11px] leading-4"
1340
+ teamColorByName={teamColorByName}
1341
+ onTeamClick={onTeamClick}
1342
+ />
1343
+ </div>
1344
+ </TooltipTrigger>
1345
+ <TooltipContent
1346
+ side="bottom"
1347
+ align="start"
1348
+ className="max-w-sm whitespace-normal break-words"
1349
+ >
1350
+ {compactPreviewTooltipText}
1351
+ </TooltipContent>
1352
+ </Tooltip>
1353
+ </TooltipProvider>
1354
+ </div>
1355
+ ) : (
1356
+ <>
1357
+ {isUnread ? (
1358
+ <span
1359
+ className="size-2 shrink-0 rounded-full bg-blue-500"
1360
+ title="未读"
1361
+ aria-hidden
1362
+ />
1363
+ ) : null}
1364
+ {showChevron ? (
1365
+ <ChevronRight
1366
+ className="size-3 shrink-0 transition-transform duration-150"
1367
+ style={{
1368
+ color: CARD_ICON_MUTED,
1369
+ transform: isExpanded ? 'rotate(90deg)' : undefined,
1370
+ }}
1371
+ />
1372
+ ) : null}
1373
+ {crossTeamOrigin ? (
1374
+ <CrossTeamTeamBadge teamName={crossTeamOrigin.teamName} onClick={onTeamClick} />
1375
+ ) : null}
1376
+ {senderBadge}
1377
+ <SessionSourceBadge message={message} />
1378
+ {!compactHeader && formattedRole && !isSlashCommandResult ? (
1379
+ <span className="text-[10px]" style={{ color: CARD_ICON_MUTED }}>
1380
+ {formattedRole}
1381
+ </span>
1382
+ ) : null}
1383
+ {messageTypeBadge}
1384
+ {statusBadge}
1385
+ {recipientBadge}
1386
+ <span className="min-w-0 flex-1 truncate text-xs" style={{ color: CARD_TEXT_LIGHT }}>
1387
+ {summaryContent}
1388
+ </span>
1389
+ <div className="relative flex shrink-0 items-center">
1390
+ <span
1391
+ className={
1392
+ onExpand && expandItemKey
1393
+ ? 'text-[10px] transition-opacity group-hover:opacity-0'
1394
+ : 'text-[10px]'
1395
+ }
1396
+ style={{ color: CARD_ICON_MUTED }}
1397
+ >
1398
+ {timestamp}
1399
+ </span>
1400
+ {onExpand && expandItemKey && (
1401
+ <button
1402
+ type="button"
1403
+ aria-label="展开消息"
1404
+ className="absolute right-0 top-1/2 -translate-y-1/2 rounded p-0.5 opacity-0 transition-opacity focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-blue-500/50 group-hover:opacity-100"
1405
+ style={{ color: CARD_ICON_MUTED }}
1406
+ onClick={(e) => {
1407
+ e.stopPropagation();
1408
+ onExpand(expandItemKey);
1409
+ }}
1410
+ onKeyDown={(e) => e.stopPropagation()}
1411
+ >
1412
+ <Maximize2 size={12} />
1413
+ </button>
1414
+ )}
1415
+ </div>
1416
+ </>
1417
+ )}
1418
+ </div>
1419
+
1420
+ {/* Content — collapsed for system messages, expanded for others */}
1421
+ {isExpanded ? (
1422
+ <div className="min-w-0 overflow-hidden px-3 pb-3">
1423
+ {structured ? (
1424
+ <div className="space-y-2">
1425
+ {autoSummary && autoSummary !== messageType ? (
1426
+ <p className="text-xs text-[var(--color-text-secondary)]">{autoSummary}</p>
1427
+ ) : null}
1428
+ <details className="rounded border border-[var(--color-border)] bg-[var(--color-surface)]">
1429
+ <summary className="cursor-pointer px-2 py-1 text-[11px] text-[var(--color-text-muted)]">
1430
+ 原始 JSON
1431
+ </summary>
1432
+ <pre className="overflow-auto px-2 pb-2 text-[11px] leading-relaxed text-[var(--color-text-muted)]">
1433
+ {JSON.stringify(structured, null, 2)}
1434
+ </pre>
1435
+ </details>
1436
+ </div>
1437
+ ) : isSlashCommandResult && message.commandOutput ? (
1438
+ <div
1439
+ className={[
1440
+ 'rounded-md px-3 py-2',
1441
+ isCommandOutputError
1442
+ ? 'border border-rose-400/20 bg-rose-500/5'
1443
+ : 'border border-amber-400/20 bg-amber-500/5',
1444
+ ].join(' ')}
1445
+ >
1446
+ <div className="flex items-center gap-2">
1447
+ <Command
1448
+ size={14}
1449
+ className={[
1450
+ 'shrink-0',
1451
+ isCommandOutputError ? 'text-rose-400' : 'text-amber-400',
1452
+ ].join(' ')}
1453
+ />
1454
+ <span
1455
+ className={[
1456
+ 'font-mono text-xs',
1457
+ isCommandOutputError ? 'text-rose-300' : 'text-amber-300',
1458
+ ].join(' ')}
1459
+ >
1460
+ {message.commandOutput.commandLabel}
1461
+ </span>
1462
+ <span
1463
+ className={[
1464
+ 'rounded-full px-1.5 py-0.5 text-[10px] uppercase tracking-wide',
1465
+ isCommandOutputError
1466
+ ? 'bg-rose-500/15 text-rose-300'
1467
+ : 'bg-amber-500/15 text-amber-300',
1468
+ ].join(' ')}
1469
+ >
1470
+ {message.commandOutput.stream}
1471
+ </span>
1472
+ <div className="ml-auto">
1473
+ <CopyButton text={message.text} inline />
1474
+ </div>
1475
+ </div>
1476
+ <ExpandableContent className="mt-2" collapsedHeight={160}>
1477
+ <pre className="overflow-x-auto whitespace-pre-wrap break-words rounded border border-[var(--color-border)] bg-[var(--color-surface)] px-3 py-2 font-mono text-[11px] leading-relaxed text-[var(--color-text-secondary)]">
1478
+ {message.text}
1479
+ </pre>
1480
+ </ExpandableContent>
1481
+ </div>
1482
+ ) : isSlashCommandMessage && slashCommandMeta ? (
1483
+ <div className="rounded-md border border-amber-400/20 bg-amber-500/5 px-3 py-2">
1484
+ <div className="flex items-center gap-2">
1485
+ <Command size={14} className="shrink-0 text-amber-400" />
1486
+ <span className="font-mono text-xs text-amber-300">
1487
+ {slashCommandMeta.command}
1488
+ </span>
1489
+ </div>
1490
+ {(slashCommandMeta.knownDescription ?? knownSlashCommand?.description) ? (
1491
+ <p className="mt-1 text-[11px] leading-relaxed text-[var(--color-text-secondary)]">
1492
+ {slashCommandMeta.knownDescription ?? knownSlashCommand?.description}
1493
+ </p>
1494
+ ) : null}
1495
+ {slashCommandMeta.args ? (
1496
+ <div className="mt-2 rounded border border-[var(--color-border)] bg-[var(--color-surface)] px-2 py-1.5 font-mono text-[11px] text-[var(--color-text-secondary)]">
1497
+ {slashCommandMeta.args}
1498
+ </div>
1499
+ ) : null}
1500
+ </div>
1501
+ ) : parsedReply ? (
1502
+ <ReplyQuoteBlock
1503
+ reply={parsedReply}
1504
+ memberColor={memberColorMap?.get(parsedReply.agentName)}
1505
+ replyTaskRefs={message.taskRefs}
1506
+ />
1507
+ ) : displayText ? (
1508
+ <div
1509
+ className={`group/message-body relative${isApiError ? '[&_code]:!text-red-400 [&_p]:!text-red-400' : ''}`}
1510
+ style={isApiError ? { color: '#f87171' } : undefined}
1511
+ >
1512
+ <div className="absolute right-1 top-1 z-10 flex items-center gap-0.5 opacity-0 transition-opacity group-hover/message-body:opacity-100">
1513
+ {onReply ? (
1514
+ <Tooltip>
1515
+ <TooltipTrigger asChild>
1516
+ <button
1517
+ type="button"
1518
+ className="rounded p-1 transition-colors hover:bg-[var(--color-surface-raised)]"
1519
+ style={{ color: CARD_ICON_MUTED }}
1520
+ onClick={(e) => {
1521
+ e.stopPropagation();
1522
+ onReply(message);
1523
+ }}
1524
+ >
1525
+ <Reply size={14} />
1526
+ </button>
1527
+ </TooltipTrigger>
1528
+ <TooltipContent side="top">回复消息</TooltipContent>
1529
+ </Tooltip>
1530
+ ) : null}
1531
+ {onCreateTask ? (
1532
+ <Tooltip>
1533
+ <TooltipTrigger asChild>
1534
+ <button
1535
+ type="button"
1536
+ className="rounded p-1 transition-colors hover:bg-[var(--color-surface-raised)]"
1537
+ style={{ color: CARD_ICON_MUTED }}
1538
+ onClick={(e) => {
1539
+ e.stopPropagation();
1540
+ handleCreateTask();
1541
+ }}
1542
+ >
1543
+ <ListPlus size={14} />
1544
+ </button>
1545
+ </TooltipTrigger>
1546
+ <TooltipContent side="top">从消息创建任务</TooltipContent>
1547
+ </Tooltip>
1548
+ ) : null}
1549
+ <CopyButton text={displayText} inline />
1550
+ </div>
1551
+ <ExpandableContent onExpand={onExpandContent}>
1552
+ <span
1553
+ onClickCapture={
1554
+ onTaskIdClick
1555
+ ? (e) => {
1556
+ const link = (e.target as HTMLElement).closest<HTMLAnchorElement>(
1557
+ 'a[href^="task://"]'
1558
+ );
1559
+ if (link) {
1560
+ e.preventDefault();
1561
+ e.stopPropagation();
1562
+ const href = link.getAttribute('href');
1563
+ const parsedTaskLink = href ? parseTaskLinkHref(href) : null;
1564
+ if (parsedTaskLink?.taskId) onTaskIdClick(parsedTaskLink.taskId);
1565
+ }
1566
+ }
1567
+ : undefined
1568
+ }
1569
+ >
1570
+ <MarkdownViewer
1571
+ content={displayText}
1572
+ maxHeight="max-h-none"
1573
+ bare
1574
+ teamColorByName={teamColorByName}
1575
+ onTeamClick={onTeamClick}
1576
+ />
1577
+ </span>
1578
+ </ExpandableContent>
1579
+ </div>
1580
+ ) : summaryText ? (
1581
+ <p className="text-xs italic" style={{ color: CARD_TEXT_LIGHT }}>
1582
+ {summaryText}
1583
+ </p>
1584
+ ) : null}
1585
+ {/* Auth error recovery action */}
1586
+ {isAuthError && onRestartTeam ? (
1587
+ <div className="mt-2 flex items-start gap-2 rounded border border-red-500/30 bg-red-500/5 px-3 py-2">
1588
+ <AlertTriangle size={14} className="mt-0.5 shrink-0 text-red-400" />
1589
+ <div className="flex-1 space-y-1.5">
1590
+ <p className="text-[11px] leading-relaxed text-red-300/90">
1591
+ 认证失败。重启团队会刷新会话,可能解决此问题。如果仍然失败,请检查 API
1592
+ 凭据或稍后重试。
1593
+ </p>
1594
+ <button
1595
+ type="button"
1596
+ className="inline-flex items-center gap-1.5 rounded-md bg-red-500/20 px-2.5 py-1 text-[11px] font-medium text-red-300 transition-colors hover:bg-red-500/30 hover:text-red-200"
1597
+ onClick={(e) => {
1598
+ e.stopPropagation();
1599
+ onRestartTeam();
1600
+ }}
1601
+ >
1602
+ <RefreshCw size={11} />
1603
+ 重启团队
1604
+ </button>
1605
+ </div>
1606
+ </div>
1607
+ ) : null}
1608
+ {message.attachments?.length && message.messageId ? (
1609
+ <AttachmentDisplay
1610
+ teamName={teamName}
1611
+ messageId={message.messageId}
1612
+ attachments={message.attachments}
1613
+ />
1614
+ ) : null}
1615
+ </div>
1616
+ ) : null}
1617
+ </article>
1618
+ );
1619
+ },
1620
+ (prev, next) =>
1621
+ prev.teamName === next.teamName &&
1622
+ prev.localMemberNames === next.localMemberNames &&
1623
+ prev.memberRole === next.memberRole &&
1624
+ prev.memberColor === next.memberColor &&
1625
+ prev.recipientColor === next.recipientColor &&
1626
+ prev.isUnread === next.isUnread &&
1627
+ prev.memberColorMap === next.memberColorMap &&
1628
+ areStringArraysEqual(prev.teamNames, next.teamNames) &&
1629
+ areStringMapsEqual(prev.teamColorByName, next.teamColorByName) &&
1630
+ prev.onTeamClick === next.onTeamClick &&
1631
+ prev.onMemberNameClick === next.onMemberNameClick &&
1632
+ prev.onCreateTask === next.onCreateTask &&
1633
+ prev.onReply === next.onReply &&
1634
+ prev.onTaskIdClick === next.onTaskIdClick &&
1635
+ prev.onRestartTeam === next.onRestartTeam &&
1636
+ prev.zebraShade === next.zebraShade &&
1637
+ prev.collapseMode === next.collapseMode &&
1638
+ prev.isCollapsed === next.isCollapsed &&
1639
+ prev.canToggleCollapse === next.canToggleCollapse &&
1640
+ prev.collapseToggleKey === next.collapseToggleKey &&
1641
+ prev.onToggleCollapse === next.onToggleCollapse &&
1642
+ prev.compactHeader === next.compactHeader &&
1643
+ prev.onExpand === next.onExpand &&
1644
+ prev.expandItemKey === next.expandItemKey &&
1645
+ prev.onExpandContent === next.onExpandContent &&
1646
+ areMessagesEquivalentForActivityItem(prev.message, next.message)
1647
+ );
1648
+
1649
+ ActivityItem.displayName = 'ActivityItem';