@base44/superagent-native 0.0.1 → 0.0.3

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 (332) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +12 -20
  3. package/lib/commonjs/AgentSettingsPanel.js +155 -62
  4. package/lib/commonjs/AgentSettingsPanel.js.map +1 -1
  5. package/lib/commonjs/AgentSphereIcon.js +14 -118
  6. package/lib/commonjs/AgentSphereIcon.js.map +1 -1
  7. package/lib/commonjs/AttachmentPickerStatusModal.js +5 -4
  8. package/lib/commonjs/AttachmentPickerStatusModal.js.map +1 -1
  9. package/lib/commonjs/ChannelsPanel.js +66 -44
  10. package/lib/commonjs/ChannelsPanel.js.map +1 -1
  11. package/lib/commonjs/ConversationChat.js +38 -13
  12. package/lib/commonjs/ConversationChat.js.map +1 -1
  13. package/lib/commonjs/ConversationComposer.js +18 -13
  14. package/lib/commonjs/ConversationComposer.js.map +1 -1
  15. package/lib/commonjs/ConversationScreen.js +4 -0
  16. package/lib/commonjs/ConversationScreen.js.map +1 -1
  17. package/lib/commonjs/EditorDrawer.js +54 -24
  18. package/lib/commonjs/EditorDrawer.js.map +1 -1
  19. package/lib/commonjs/FilesPanel.js +56 -20
  20. package/lib/commonjs/FilesPanel.js.map +1 -1
  21. package/lib/commonjs/MarkdownText.js +1 -1
  22. package/lib/commonjs/MarkdownText.js.map +1 -1
  23. package/lib/commonjs/MessageActionBar.js +10 -3
  24. package/lib/commonjs/MessageActionBar.js.map +1 -1
  25. package/lib/commonjs/RenameAgentModal.js +2 -1
  26. package/lib/commonjs/RenameAgentModal.js.map +1 -1
  27. package/lib/commonjs/ShareAgentModal.js +11 -10
  28. package/lib/commonjs/ShareAgentModal.js.map +1 -1
  29. package/lib/commonjs/ShareAgentModal.styles.js +2 -2
  30. package/lib/commonjs/ShareAgentModal.styles.js.map +1 -1
  31. package/lib/commonjs/SuperagentHomeScreen.js +44 -12
  32. package/lib/commonjs/SuperagentHomeScreen.js.map +1 -1
  33. package/lib/commonjs/ToolApprovalCard.js +73 -15
  34. package/lib/commonjs/ToolApprovalCard.js.map +1 -1
  35. package/lib/commonjs/ToolCallSummary.js +19 -10
  36. package/lib/commonjs/ToolCallSummary.js.map +1 -1
  37. package/lib/commonjs/agentSphereAssets.js +327 -0
  38. package/lib/commonjs/agentSphereAssets.js.map +1 -0
  39. package/lib/commonjs/agentSphereStyles.js +3 -3
  40. package/lib/commonjs/agentSphereStyles.js.map +1 -1
  41. package/lib/commonjs/apiClient.js +7 -0
  42. package/lib/commonjs/apiClient.js.map +1 -1
  43. package/lib/commonjs/attachmentUpload.js +2 -1
  44. package/lib/commonjs/attachmentUpload.js.map +1 -1
  45. package/lib/commonjs/composerStyles.js +2 -2
  46. package/lib/commonjs/composerStyles.js.map +1 -1
  47. package/lib/commonjs/connectorBrandIcons.generated.js +625 -0
  48. package/lib/commonjs/connectorBrandIcons.generated.js.map +1 -0
  49. package/lib/commonjs/connectorBrandIcons.js +3 -55
  50. package/lib/commonjs/connectorBrandIcons.js.map +1 -1
  51. package/lib/commonjs/connectorCatalog.js +19 -1
  52. package/lib/commonjs/connectorCatalog.js.map +1 -1
  53. package/lib/commonjs/conversationParts.js +5 -4
  54. package/lib/commonjs/conversationParts.js.map +1 -1
  55. package/lib/commonjs/conversationRuntime.js +152 -9
  56. package/lib/commonjs/conversationRuntime.js.map +1 -1
  57. package/lib/commonjs/conversationStyles.js +2 -1
  58. package/lib/commonjs/conversationStyles.js.map +1 -1
  59. package/lib/commonjs/editorShellStyles.js +6 -2
  60. package/lib/commonjs/editorShellStyles.js.map +1 -1
  61. package/lib/commonjs/fileTreeUtils.js +7 -0
  62. package/lib/commonjs/fileTreeUtils.js.map +1 -1
  63. package/lib/commonjs/index.js +7 -0
  64. package/lib/commonjs/index.js.map +1 -1
  65. package/lib/commonjs/markdownStyles.js +2 -2
  66. package/lib/commonjs/markdownStyles.js.map +1 -1
  67. package/lib/commonjs/messageActionStyles.js +2 -2
  68. package/lib/commonjs/messageActionStyles.js.map +1 -1
  69. package/lib/commonjs/realtimeClient.js +4 -1
  70. package/lib/commonjs/realtimeClient.js.map +1 -1
  71. package/lib/commonjs/renameAgentModalStyles.js +2 -2
  72. package/lib/commonjs/renameAgentModalStyles.js.map +1 -1
  73. package/lib/commonjs/screenParts.js +24 -41
  74. package/lib/commonjs/screenParts.js.map +1 -1
  75. package/lib/commonjs/styles.js +32 -21
  76. package/lib/commonjs/styles.js.map +1 -1
  77. package/lib/commonjs/superagentApiClient.js +63 -18
  78. package/lib/commonjs/superagentApiClient.js.map +1 -1
  79. package/lib/commonjs/theme.js +249 -0
  80. package/lib/commonjs/theme.js.map +1 -0
  81. package/lib/commonjs/useSuperagentConversation.js +240 -44
  82. package/lib/commonjs/useSuperagentConversation.js.map +1 -1
  83. package/lib/commonjs/useSuperagentRuntime.js +245 -105
  84. package/lib/commonjs/useSuperagentRuntime.js.map +1 -1
  85. package/lib/module/AgentSettingsPanel.js +157 -64
  86. package/lib/module/AgentSettingsPanel.js.map +1 -1
  87. package/lib/module/AgentSphereIcon.js +15 -118
  88. package/lib/module/AgentSphereIcon.js.map +1 -1
  89. package/lib/module/AttachmentPickerStatusModal.js +6 -5
  90. package/lib/module/AttachmentPickerStatusModal.js.map +1 -1
  91. package/lib/module/ChannelsPanel.js +67 -45
  92. package/lib/module/ChannelsPanel.js.map +1 -1
  93. package/lib/module/ConversationChat.js +38 -13
  94. package/lib/module/ConversationChat.js.map +1 -1
  95. package/lib/module/ConversationComposer.js +18 -13
  96. package/lib/module/ConversationComposer.js.map +1 -1
  97. package/lib/module/ConversationScreen.js +4 -0
  98. package/lib/module/ConversationScreen.js.map +1 -1
  99. package/lib/module/EditorDrawer.js +55 -25
  100. package/lib/module/EditorDrawer.js.map +1 -1
  101. package/lib/module/FilesPanel.js +56 -20
  102. package/lib/module/FilesPanel.js.map +1 -1
  103. package/lib/module/MarkdownText.js +1 -1
  104. package/lib/module/MarkdownText.js.map +1 -1
  105. package/lib/module/MessageActionBar.js +10 -3
  106. package/lib/module/MessageActionBar.js.map +1 -1
  107. package/lib/module/RenameAgentModal.js +2 -1
  108. package/lib/module/RenameAgentModal.js.map +1 -1
  109. package/lib/module/ShareAgentModal.js +11 -10
  110. package/lib/module/ShareAgentModal.js.map +1 -1
  111. package/lib/module/ShareAgentModal.styles.js +2 -2
  112. package/lib/module/ShareAgentModal.styles.js.map +1 -1
  113. package/lib/module/SuperagentHomeScreen.js +45 -13
  114. package/lib/module/SuperagentHomeScreen.js.map +1 -1
  115. package/lib/module/ToolApprovalCard.js +73 -15
  116. package/lib/module/ToolApprovalCard.js.map +1 -1
  117. package/lib/module/ToolCallSummary.js +19 -10
  118. package/lib/module/ToolCallSummary.js.map +1 -1
  119. package/lib/module/agentSphereAssets.js +323 -0
  120. package/lib/module/agentSphereAssets.js.map +1 -0
  121. package/lib/module/agentSphereStyles.js +3 -3
  122. package/lib/module/agentSphereStyles.js.map +1 -1
  123. package/lib/module/apiClient.js +7 -0
  124. package/lib/module/apiClient.js.map +1 -1
  125. package/lib/module/attachmentUpload.js +2 -1
  126. package/lib/module/attachmentUpload.js.map +1 -1
  127. package/lib/module/composerStyles.js +2 -2
  128. package/lib/module/composerStyles.js.map +1 -1
  129. package/lib/module/connectorBrandIcons.generated.js +621 -0
  130. package/lib/module/connectorBrandIcons.generated.js.map +1 -0
  131. package/lib/module/connectorBrandIcons.js +1 -53
  132. package/lib/module/connectorBrandIcons.js.map +1 -1
  133. package/lib/module/connectorCatalog.js +17 -0
  134. package/lib/module/connectorCatalog.js.map +1 -1
  135. package/lib/module/conversationParts.js +5 -4
  136. package/lib/module/conversationParts.js.map +1 -1
  137. package/lib/module/conversationRuntime.js +149 -9
  138. package/lib/module/conversationRuntime.js.map +1 -1
  139. package/lib/module/conversationStyles.js +3 -2
  140. package/lib/module/conversationStyles.js.map +1 -1
  141. package/lib/module/editorShellStyles.js +6 -2
  142. package/lib/module/editorShellStyles.js.map +1 -1
  143. package/lib/module/fileTreeUtils.js +6 -0
  144. package/lib/module/fileTreeUtils.js.map +1 -1
  145. package/lib/module/index.js +1 -0
  146. package/lib/module/index.js.map +1 -1
  147. package/lib/module/markdownStyles.js +2 -2
  148. package/lib/module/markdownStyles.js.map +1 -1
  149. package/lib/module/messageActionStyles.js +2 -2
  150. package/lib/module/messageActionStyles.js.map +1 -1
  151. package/lib/module/realtimeClient.js +4 -1
  152. package/lib/module/realtimeClient.js.map +1 -1
  153. package/lib/module/renameAgentModalStyles.js +2 -2
  154. package/lib/module/renameAgentModalStyles.js.map +1 -1
  155. package/lib/module/screenParts.js +25 -42
  156. package/lib/module/screenParts.js.map +1 -1
  157. package/lib/module/styles.js +32 -21
  158. package/lib/module/styles.js.map +1 -1
  159. package/lib/module/superagentApiClient.js +63 -18
  160. package/lib/module/superagentApiClient.js.map +1 -1
  161. package/lib/module/theme.js +239 -0
  162. package/lib/module/theme.js.map +1 -0
  163. package/lib/module/useSuperagentConversation.js +242 -46
  164. package/lib/module/useSuperagentConversation.js.map +1 -1
  165. package/lib/module/useSuperagentRuntime.js +246 -106
  166. package/lib/module/useSuperagentRuntime.js.map +1 -1
  167. package/lib/typescript/commonjs/AgentSettingsPanel.d.ts.map +1 -1
  168. package/lib/typescript/commonjs/AgentSphereIcon.d.ts.map +1 -1
  169. package/lib/typescript/commonjs/AttachmentPickerStatusModal.d.ts.map +1 -1
  170. package/lib/typescript/commonjs/ChannelsPanel.d.ts.map +1 -1
  171. package/lib/typescript/commonjs/ConversationChat.d.ts +1 -1
  172. package/lib/typescript/commonjs/ConversationChat.d.ts.map +1 -1
  173. package/lib/typescript/commonjs/ConversationComposer.d.ts.map +1 -1
  174. package/lib/typescript/commonjs/ConversationMessageList.d.ts +1 -1
  175. package/lib/typescript/commonjs/ConversationMessageList.d.ts.map +1 -1
  176. package/lib/typescript/commonjs/ConversationScreen.d.ts +2 -1
  177. package/lib/typescript/commonjs/ConversationScreen.d.ts.map +1 -1
  178. package/lib/typescript/commonjs/EditorDrawer.d.ts +1 -1
  179. package/lib/typescript/commonjs/EditorDrawer.d.ts.map +1 -1
  180. package/lib/typescript/commonjs/FilesPanel.d.ts.map +1 -1
  181. package/lib/typescript/commonjs/RenameAgentModal.d.ts.map +1 -1
  182. package/lib/typescript/commonjs/ShareAgentModal.d.ts.map +1 -1
  183. package/lib/typescript/commonjs/ShareAgentModal.styles.d.ts.map +1 -1
  184. package/lib/typescript/commonjs/SuperagentHomeScreen.d.ts.map +1 -1
  185. package/lib/typescript/commonjs/ToolApprovalCard.d.ts +3 -3
  186. package/lib/typescript/commonjs/ToolApprovalCard.d.ts.map +1 -1
  187. package/lib/typescript/commonjs/ToolCallSummary.d.ts +1 -1
  188. package/lib/typescript/commonjs/ToolCallSummary.d.ts.map +1 -1
  189. package/lib/typescript/commonjs/agentSphereAssets.d.ts +2 -0
  190. package/lib/typescript/commonjs/agentSphereAssets.d.ts.map +1 -0
  191. package/lib/typescript/commonjs/agentSphereStyles.d.ts.map +1 -1
  192. package/lib/typescript/commonjs/apiClient.d.ts.map +1 -1
  193. package/lib/typescript/commonjs/composerStyles.d.ts.map +1 -1
  194. package/lib/typescript/commonjs/connectorBrandIcons.d.ts.map +1 -1
  195. package/lib/typescript/commonjs/connectorBrandIcons.generated.d.ts +2 -0
  196. package/lib/typescript/commonjs/connectorBrandIcons.generated.d.ts.map +1 -0
  197. package/lib/typescript/commonjs/connectorCatalog.d.ts +2 -0
  198. package/lib/typescript/commonjs/connectorCatalog.d.ts.map +1 -1
  199. package/lib/typescript/commonjs/conversationParts.d.ts +1 -1
  200. package/lib/typescript/commonjs/conversationParts.d.ts.map +1 -1
  201. package/lib/typescript/commonjs/conversationRuntime.d.ts +9 -3
  202. package/lib/typescript/commonjs/conversationRuntime.d.ts.map +1 -1
  203. package/lib/typescript/commonjs/conversationStyles.d.ts.map +1 -1
  204. package/lib/typescript/commonjs/editorShellStyles.d.ts +4 -0
  205. package/lib/typescript/commonjs/editorShellStyles.d.ts.map +1 -1
  206. package/lib/typescript/commonjs/fileTreeUtils.d.ts +1 -0
  207. package/lib/typescript/commonjs/fileTreeUtils.d.ts.map +1 -1
  208. package/lib/typescript/commonjs/index.d.ts +2 -0
  209. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  210. package/lib/typescript/commonjs/markdownStyles.d.ts.map +1 -1
  211. package/lib/typescript/commonjs/messageActionStyles.d.ts.map +1 -1
  212. package/lib/typescript/commonjs/realtimeClient.d.ts.map +1 -1
  213. package/lib/typescript/commonjs/renameAgentModalStyles.d.ts.map +1 -1
  214. package/lib/typescript/commonjs/screenParts.d.ts +1 -1
  215. package/lib/typescript/commonjs/screenParts.d.ts.map +1 -1
  216. package/lib/typescript/commonjs/styles.d.ts +20 -11
  217. package/lib/typescript/commonjs/styles.d.ts.map +1 -1
  218. package/lib/typescript/commonjs/superagentApiClient.d.ts +2 -1
  219. package/lib/typescript/commonjs/superagentApiClient.d.ts.map +1 -1
  220. package/lib/typescript/commonjs/theme.d.ts +36 -0
  221. package/lib/typescript/commonjs/theme.d.ts.map +1 -0
  222. package/lib/typescript/commonjs/types.d.ts +17 -2
  223. package/lib/typescript/commonjs/types.d.ts.map +1 -1
  224. package/lib/typescript/commonjs/useSuperagentConversation.d.ts +3 -2
  225. package/lib/typescript/commonjs/useSuperagentConversation.d.ts.map +1 -1
  226. package/lib/typescript/commonjs/useSuperagentRuntime.d.ts +5 -2
  227. package/lib/typescript/commonjs/useSuperagentRuntime.d.ts.map +1 -1
  228. package/lib/typescript/module/AgentSettingsPanel.d.ts.map +1 -1
  229. package/lib/typescript/module/AgentSphereIcon.d.ts.map +1 -1
  230. package/lib/typescript/module/AttachmentPickerStatusModal.d.ts.map +1 -1
  231. package/lib/typescript/module/ChannelsPanel.d.ts.map +1 -1
  232. package/lib/typescript/module/ConversationChat.d.ts +1 -1
  233. package/lib/typescript/module/ConversationChat.d.ts.map +1 -1
  234. package/lib/typescript/module/ConversationComposer.d.ts.map +1 -1
  235. package/lib/typescript/module/ConversationMessageList.d.ts +1 -1
  236. package/lib/typescript/module/ConversationMessageList.d.ts.map +1 -1
  237. package/lib/typescript/module/ConversationScreen.d.ts +2 -1
  238. package/lib/typescript/module/ConversationScreen.d.ts.map +1 -1
  239. package/lib/typescript/module/EditorDrawer.d.ts +1 -1
  240. package/lib/typescript/module/EditorDrawer.d.ts.map +1 -1
  241. package/lib/typescript/module/FilesPanel.d.ts.map +1 -1
  242. package/lib/typescript/module/RenameAgentModal.d.ts.map +1 -1
  243. package/lib/typescript/module/ShareAgentModal.d.ts.map +1 -1
  244. package/lib/typescript/module/ShareAgentModal.styles.d.ts.map +1 -1
  245. package/lib/typescript/module/SuperagentHomeScreen.d.ts.map +1 -1
  246. package/lib/typescript/module/ToolApprovalCard.d.ts +3 -3
  247. package/lib/typescript/module/ToolApprovalCard.d.ts.map +1 -1
  248. package/lib/typescript/module/ToolCallSummary.d.ts +1 -1
  249. package/lib/typescript/module/ToolCallSummary.d.ts.map +1 -1
  250. package/lib/typescript/module/agentSphereAssets.d.ts +2 -0
  251. package/lib/typescript/module/agentSphereAssets.d.ts.map +1 -0
  252. package/lib/typescript/module/agentSphereStyles.d.ts.map +1 -1
  253. package/lib/typescript/module/apiClient.d.ts.map +1 -1
  254. package/lib/typescript/module/composerStyles.d.ts.map +1 -1
  255. package/lib/typescript/module/connectorBrandIcons.d.ts.map +1 -1
  256. package/lib/typescript/module/connectorBrandIcons.generated.d.ts +2 -0
  257. package/lib/typescript/module/connectorBrandIcons.generated.d.ts.map +1 -0
  258. package/lib/typescript/module/connectorCatalog.d.ts +2 -0
  259. package/lib/typescript/module/connectorCatalog.d.ts.map +1 -1
  260. package/lib/typescript/module/conversationParts.d.ts +1 -1
  261. package/lib/typescript/module/conversationParts.d.ts.map +1 -1
  262. package/lib/typescript/module/conversationRuntime.d.ts +9 -3
  263. package/lib/typescript/module/conversationRuntime.d.ts.map +1 -1
  264. package/lib/typescript/module/conversationStyles.d.ts.map +1 -1
  265. package/lib/typescript/module/editorShellStyles.d.ts +4 -0
  266. package/lib/typescript/module/editorShellStyles.d.ts.map +1 -1
  267. package/lib/typescript/module/fileTreeUtils.d.ts +1 -0
  268. package/lib/typescript/module/fileTreeUtils.d.ts.map +1 -1
  269. package/lib/typescript/module/index.d.ts +2 -0
  270. package/lib/typescript/module/index.d.ts.map +1 -1
  271. package/lib/typescript/module/markdownStyles.d.ts.map +1 -1
  272. package/lib/typescript/module/messageActionStyles.d.ts.map +1 -1
  273. package/lib/typescript/module/realtimeClient.d.ts.map +1 -1
  274. package/lib/typescript/module/renameAgentModalStyles.d.ts.map +1 -1
  275. package/lib/typescript/module/screenParts.d.ts +1 -1
  276. package/lib/typescript/module/screenParts.d.ts.map +1 -1
  277. package/lib/typescript/module/styles.d.ts +20 -11
  278. package/lib/typescript/module/styles.d.ts.map +1 -1
  279. package/lib/typescript/module/superagentApiClient.d.ts +2 -1
  280. package/lib/typescript/module/superagentApiClient.d.ts.map +1 -1
  281. package/lib/typescript/module/theme.d.ts +36 -0
  282. package/lib/typescript/module/theme.d.ts.map +1 -0
  283. package/lib/typescript/module/types.d.ts +17 -2
  284. package/lib/typescript/module/types.d.ts.map +1 -1
  285. package/lib/typescript/module/useSuperagentConversation.d.ts +3 -2
  286. package/lib/typescript/module/useSuperagentConversation.d.ts.map +1 -1
  287. package/lib/typescript/module/useSuperagentRuntime.d.ts +5 -2
  288. package/lib/typescript/module/useSuperagentRuntime.d.ts.map +1 -1
  289. package/package.json +13 -11
  290. package/src/AgentSettingsPanel.tsx +146 -58
  291. package/src/AgentSphereIcon.tsx +11 -62
  292. package/src/AttachmentPickerStatusModal.tsx +6 -5
  293. package/src/ChannelsPanel.tsx +59 -39
  294. package/src/ConversationChat.tsx +49 -12
  295. package/src/ConversationComposer.tsx +18 -12
  296. package/src/ConversationMessageList.tsx +1 -1
  297. package/src/ConversationScreen.tsx +5 -0
  298. package/src/EditorDrawer.tsx +66 -41
  299. package/src/FilesPanel.tsx +48 -20
  300. package/src/MarkdownText.tsx +1 -1
  301. package/src/MessageActionBar.tsx +9 -3
  302. package/src/RenameAgentModal.tsx +2 -1
  303. package/src/ShareAgentModal.styles.ts +2 -1
  304. package/src/ShareAgentModal.tsx +9 -8
  305. package/src/SuperagentHomeScreen.tsx +45 -10
  306. package/src/ToolApprovalCard.tsx +83 -15
  307. package/src/ToolCallSummary.tsx +22 -13
  308. package/src/agentSphereAssets.ts +325 -0
  309. package/src/agentSphereStyles.ts +3 -2
  310. package/src/apiClient.ts +7 -0
  311. package/src/attachmentUpload.ts +2 -1
  312. package/src/composerStyles.ts +2 -1
  313. package/src/connectorBrandIcons.generated.ts +618 -0
  314. package/src/connectorBrandIcons.tsx +1 -53
  315. package/src/connectorCatalog.ts +24 -0
  316. package/src/conversationParts.tsx +6 -5
  317. package/src/conversationRuntime.ts +166 -11
  318. package/src/conversationStyles.ts +2 -1
  319. package/src/editorShellStyles.ts +6 -1
  320. package/src/fileTreeUtils.ts +13 -0
  321. package/src/index.ts +2 -0
  322. package/src/markdownStyles.ts +2 -1
  323. package/src/messageActionStyles.ts +2 -1
  324. package/src/realtimeClient.ts +7 -1
  325. package/src/renameAgentModalStyles.ts +2 -1
  326. package/src/screenParts.tsx +17 -29
  327. package/src/styles.ts +25 -16
  328. package/src/superagentApiClient.ts +68 -18
  329. package/src/theme.ts +254 -0
  330. package/src/types.ts +22 -2
  331. package/src/useSuperagentConversation.ts +247 -45
  332. package/src/useSuperagentRuntime.ts +244 -107
@@ -1,59 +1,7 @@
1
1
  import React from 'react';
2
2
  import { SvgXml } from 'react-native-svg';
3
3
 
4
- const CONNECTOR_BRAND_ICON_XML: Record<string, string> = {
5
- salesforce: `
6
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0.5 -149.38 999 999">
7
- <path fill="#00A1E0" d="M416.224 76.763c32.219-33.57 77.074-54.391 126.682-54.391 65.946 0 123.48 36.772 154.12 91.361 26.626-11.896 56.098-18.514 87.106-18.514 118.94 0 215.368 97.268 215.368 217.247 0 119.993-96.428 217.261-215.368 217.261a213.735 213.735 0 0 1-42.422-4.227c-26.981 48.128-78.397 80.646-137.412 80.646-24.705 0-48.072-5.706-68.877-15.853-27.352 64.337-91.077 109.448-165.348 109.448-77.344 0-143.261-48.939-168.563-117.574-11.057 2.348-22.513 3.572-34.268 3.572C75.155 585.74.5 510.317.5 417.262c0-62.359 33.542-116.807 83.378-145.937-10.26-23.608-15.967-49.665-15.967-77.06C67.911 87.25 154.79.5 261.948.5c62.914 0 118.827 29.913 154.276 76.263"/>
8
- </svg>`,
9
- gmail: `
10
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="2 6 44 36">
11
- <path fill="#4caf50" d="M45,16.2l-5,2.75l-5,4.75L35,40h7c1.657,0,3-1.343,3-3V16.2z"/>
12
- <path fill="#1e88e5" d="M3,16.2l3.614,1.71L13,23.7V40H6c-1.657,0-3-1.343-3-3V16.2z"/>
13
- <polygon fill="#e53935" points="35,11.2 24,19.45 13,11.2 12,17 13,23.7 24,31.95 35,23.7 36,17"/>
14
- <path fill="#c62828" d="M3,12.298V16.2l10,7.5V11.2L9.876,8.859C9.132,8.301,8.228,8,7.298,8C4.924,8,3,9.924,3,12.298z"/>
15
- <path fill="#fbc02d" d="M45,12.298V16.2l-10,7.5V11.2l3.124-2.341C38.868,8.301,39.772,8,40.702,8C43.076,8,45,9.924,45,12.298z"/>
16
- </svg>`,
17
- googlecalendar: `
18
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
19
- <path fill="#fff" d="M195.368 60.632H60.632v134.736h134.736z"/>
20
- <path fill="#ea4335" d="M195.368 256L256 195.368l-30.316-5.172l-30.316 5.172l-5.533 27.73z"/>
21
- <path fill="#188038" d="M0 195.368v40.421C0 246.956 9.044 256 20.21 256h40.422l6.225-30.316l-6.225-30.316l-33.033-5.172z"/>
22
- <path fill="#1967d2" d="M256 60.632V20.21C256 9.044 246.956 0 235.79 0h-40.422q-5.532 22.554-5.533 33.196q0 10.641 5.533 27.436q20.115 5.76 30.316 5.76T256 60.631"/>
23
- <path fill="#fbbc04" d="M256 60.632h-60.632v134.736H256z"/>
24
- <path fill="#34a853" d="M195.368 195.368H60.632V256h134.736z"/>
25
- <path fill="#4285f4" d="M195.368 0H20.211C9.044 0 0 9.044 0 20.21v175.158h60.632V60.632h134.736z"/>
26
- <path fill="#4285f4" d="M88.27 165.154c-5.036-3.402-8.523-8.37-10.426-14.94l11.689-4.816q1.59 6.063 5.558 9.398c2.627 2.223 5.827 3.318 9.566 3.318q5.734 0 9.852-3.487c2.746-2.324 4.127-5.288 4.127-8.875q0-5.508-4.345-8.994c-2.897-2.324-6.535-3.486-10.88-3.486h-6.754v-11.57h6.063q5.608 0 9.448-3.033c2.56-2.02 3.84-4.783 3.84-8.303c0-3.132-1.145-5.625-3.435-7.494c-2.29-1.87-5.188-2.813-8.708-2.813c-3.436 0-6.164.91-8.185 2.745a16.1 16.1 0 0 0-4.413 6.754l-11.57-4.817c1.532-4.345 4.345-8.185 8.471-11.503s9.398-4.985 15.798-4.985c4.733 0 8.994.91 12.767 2.745c3.772 1.836 6.736 4.379 8.875 7.613c2.14 3.25 3.2 6.888 3.2 10.93c0 4.126-.993 7.613-2.98 10.476s-4.43 5.052-7.327 6.585v.69a22.25 22.25 0 0 1 9.398 7.327c2.442 3.284 3.672 7.208 3.672 11.79c0 4.58-1.163 8.673-3.487 12.26c-2.324 3.588-5.54 6.417-9.617 8.472c-4.092 2.055-8.69 3.1-13.793 3.1c-5.912.016-11.369-1.685-16.405-5.087m71.797-58.005l-12.833 9.28l-6.417-9.734l23.023-16.607h8.825v78.333h-12.598z"/>
27
- </svg>`,
28
- googledrive: `
29
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 112 100">
30
- <path d="M8.46154 85.7051L13.3974 94.2308C14.4231 96.0256 15.8974 97.4359 17.6282 98.4615L35.2564 67.9487H0C0 69.9359 0.512821 71.9231 1.53846 73.7179L8.46154 85.7051Z" fill="#0066DA"/>
31
- <path d="M55.9615 32.0513L38.3333 1.53846C36.6026 2.5641 35.1282 3.97436 34.1026 5.76923L1.53846 62.1795C0.531683 63.9357 0.00134047 65.9244 0 67.9487H35.2564L55.9615 32.0513Z" fill="#00AC47"/>
32
- <path d="M94.2949 98.4615C96.0256 97.4359 97.5 96.0256 98.5256 94.2308L100.577 90.7051L110.385 73.7179C111.41 71.9231 111.923 69.9359 111.923 67.9487H76.6641L84.1667 82.6923L94.2949 98.4615Z" fill="#EA4335"/>
33
- <path d="M55.9615 32.0513L73.5898 1.53846C71.859 0.512821 69.8718 0 67.8205 0H44.1026C42.0513 0 40.0641 0.576923 38.3333 1.53846L55.9615 32.0513Z" fill="#00832D"/>
34
- <path d="M76.6667 67.9487H35.2564L17.6282 98.4615C19.359 99.4872 21.3462 100 23.3974 100H88.5256C90.5769 100 92.5641 99.4231 94.2949 98.4615L76.6667 67.9487Z" fill="#2684FC"/>
35
- <path d="M94.1026 33.9744L77.8205 5.76923C76.7949 3.97436 75.3205 2.5641 73.5897 1.53846L55.9615 32.0513L76.6667 67.9487H111.859C111.859 65.9615 111.346 63.9744 110.321 62.1795L94.1026 33.9744Z" fill="#FFBA00"/>
36
- </svg>`,
37
- notion: `
38
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
39
- <path fill="#fff" d="M16.092 11.538L164.09.608c18.179-1.56 22.85-.508 34.28 7.801l47.243 33.282C253.406 47.414 256 48.975 256 55.207v182.527c0 11.439-4.155 18.205-18.696 19.24L65.44 267.378c-10.913.517-16.11-1.043-21.825-8.327L8.826 213.814C2.586 205.487 0 199.254 0 191.97V29.726c0-9.352 4.155-17.153 16.092-18.188"/>
40
- <path fill="#111" d="M164.09.608L16.092 11.538C4.155 12.573 0 20.374 0 29.726v162.245c0 7.284 2.585 13.516 8.826 21.843l34.789 45.237c5.715 7.284 10.912 8.844 21.825 8.327l171.864-10.404c14.532-1.035 18.696-7.801 18.696-19.24V55.207c0-5.911-2.336-7.614-9.21-12.66l-1.185-.856L198.37 8.409C186.94.1 182.27-.952 164.09.608M69.327 52.22c-14.033.945-17.216 1.159-25.186-5.323L23.876 30.778c-2.06-2.086-1.026-4.69 4.163-5.207l142.274-10.395c11.947-1.043 18.17 3.12 22.842 6.758l24.401 17.68c1.043.525 3.638 3.637.517 3.637L71.146 52.095zm-16.36 183.954V81.222c0-6.767 2.077-9.887 8.3-10.413L230.02 60.93c5.724-.517 8.31 3.12 8.31 9.879v153.917c0 6.767-1.044 12.49-10.387 13.008l-161.487 9.361c-9.343.517-13.489-2.594-13.489-10.921M212.377 89.53c1.034 4.681 0 9.362-4.681 9.897l-7.783 1.542v114.404c-6.758 3.637-12.981 5.715-18.18 5.715c-8.308 0-10.386-2.604-16.609-10.396l-50.898-80.079v77.476l16.1 3.646s0 9.362-12.989 9.362l-35.814 2.077c-1.043-2.086 0-7.284 3.63-8.318l9.351-2.595V109.823l-12.98-1.052c-1.044-4.68 1.55-11.439 8.826-11.965l38.426-2.585l52.958 81.113v-71.76l-13.498-1.552c-1.043-5.733 3.111-9.896 8.3-10.404z"/>
41
- </svg>`,
42
- slack: `
43
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
44
- <path fill="#de1c59" d="M27.255 80.719c0 7.33-5.978 13.317-13.309 13.317S.63 88.049.63 80.719s5.987-13.317 13.317-13.317h13.309zm6.709 0c0-7.33 5.987-13.317 13.317-13.317s13.317 5.986 13.317 13.317v33.335c0 7.33-5.986 13.317-13.317 13.317c-7.33 0-13.317-5.987-13.317-13.317zm0 0"/>
45
- <path fill="#35c5f0" d="M47.281 27.255c-7.33 0-13.317-5.978-13.317-13.309S39.951.63 47.281.63s13.317 5.987 13.317 13.317v13.309zm0 6.709c7.33 0 13.317 5.987 13.317 13.317s-5.986 13.317-13.317 13.317H13.946C6.616 60.598.63 54.612.63 47.281c0-7.33 5.987-13.317 13.317-13.317zm0 0"/>
46
- <path fill="#2eb57d" d="M100.745 47.281c0-7.33 5.978-13.317 13.309-13.317s13.317 5.987 13.317 13.317s-5.987 13.317-13.317 13.317h-13.309zm-6.709 0c0 7.33-5.987 13.317-13.317 13.317s-13.317-5.986-13.317-13.317V13.946C67.402 6.616 73.388.63 80.719.63c7.33 0 13.317 5.987 13.317 13.317zm0 0"/>
47
- <path fill="#ebb02e" d="M80.719 100.745c7.33 0 13.317 5.978 13.317 13.309s-5.987 13.317-13.317 13.317s-13.317-5.987-13.317-13.317v-13.309zm0-6.709c-7.33 0-13.317-5.987-13.317-13.317s5.986-13.317 13.317-13.317h33.335c7.33 0 13.317 5.986 13.317 13.317c0 7.33-5.987 13.317-13.317 13.317zm0 0"/>
48
- </svg>`,
49
- slackbot: `
50
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
51
- <path fill="#de1c59" d="M27.255 80.719c0 7.33-5.978 13.317-13.309 13.317S.63 88.049.63 80.719s5.987-13.317 13.317-13.317h13.309zm6.709 0c0-7.33 5.987-13.317 13.317-13.317s13.317 5.986 13.317 13.317v33.335c0 7.33-5.986 13.317-13.317 13.317c-7.33 0-13.317-5.987-13.317-13.317zm0 0"/>
52
- <path fill="#35c5f0" d="M47.281 27.255c-7.33 0-13.317-5.978-13.317-13.309S39.951.63 47.281.63s13.317 5.987 13.317 13.317v13.309zm0 6.709c7.33 0 13.317 5.987 13.317 13.317s-5.986 13.317-13.317 13.317H13.946C6.616 60.598.63 54.612.63 47.281c0-7.33 5.987-13.317 13.317-13.317zm0 0"/>
53
- <path fill="#2eb57d" d="M100.745 47.281c0-7.33 5.978-13.317 13.309-13.317s13.317 5.987 13.317 13.317s-5.987 13.317-13.317 13.317h-13.309zm-6.709 0c0 7.33-5.987 13.317-13.317 13.317s-13.317-5.986-13.317-13.317V13.946C67.402 6.616 73.388.63 80.719.63c7.33 0 13.317 5.987 13.317 13.317zm0 0"/>
54
- <path fill="#ebb02e" d="M80.719 100.745c7.33 0 13.317 5.978 13.317 13.309s-5.987 13.317-13.317 13.317s-13.317-5.987-13.317-13.317v-13.309zm0-6.709c-7.33 0-13.317-5.987-13.317-13.317s5.986-13.317 13.317-13.317h33.335c7.33 0 13.317 5.986 13.317 13.317c0 7.33-5.987 13.317-13.317 13.317zm0 0"/>
55
- </svg>`,
56
- };
4
+ import { CONNECTOR_BRAND_ICON_XML } from './connectorBrandIcons.generated';
57
5
 
58
6
  export function hasConnectorBrandIcon(connectorId: string) {
59
7
  return !!CONNECTOR_BRAND_ICON_XML[connectorId];
@@ -412,3 +412,27 @@ export const SUPERAGENT_CONNECTOR_CATALOG: SuperagentConnector[] = [
412
412
  iconFallbackLabel: 'SB',
413
413
  },
414
414
  ];
415
+
416
+ // Integration types whose backend get_connection_config_fields() includes a
417
+ // REQUIRED user-input field (e.g. subdomain/host). The native approval card can't
418
+ // collect connection_config, so connecting/registering these can only fail backend
419
+ // validation — block them and steer to web. Mirrors the backend integrations
420
+ // (snowflake/databricks are BYO-only and absent from the catalog, so they must be
421
+ // listed explicitly). salesforce/wix/wrike are intentionally excluded: their config
422
+ // is optional or not a connect-time user input. Keep in sync with the backend.
423
+ export const CONNECTION_CONFIG_REQUIRED_INTEGRATION_TYPES = new Set<string>([
424
+ 'bamboohr',
425
+ 'databricks',
426
+ 'share_point',
427
+ 'snowflake',
428
+ ]);
429
+
430
+ // True when the integration requires connection_config — via the explicit set
431
+ // above or a catalog entry's requiresConnectionConfig flag.
432
+ export function connectorRequiresConnectionConfig(integrationType?: string | null): boolean {
433
+ if (!integrationType) return false;
434
+ if (CONNECTION_CONFIG_REQUIRED_INTEGRATION_TYPES.has(integrationType)) return true;
435
+ return Boolean(
436
+ SUPERAGENT_CONNECTOR_CATALOG.find((item) => item.id === integrationType)?.requiresConnectionConfig,
437
+ );
438
+ }
@@ -1,4 +1,5 @@
1
1
  import React, { useEffect, useRef } from 'react';
2
+ import { themedColor } from './theme';
2
3
  import { Animated, Easing, Pressable, Text, View } from 'react-native';
3
4
  import { ChevronLeft, MoreHorizontal, Share2, Sparkles } from 'lucide-react-native';
4
5
 
@@ -41,7 +42,7 @@ export function ConversationHeader({
41
42
  return (
42
43
  <View style={conversationStyles.header}>
43
44
  <Pressable accessibilityLabel="Back" accessibilityRole="button" onPress={onBack} style={conversationStyles.headerIconButton}>
44
- <ChevronLeft color="#F4F4F5" size={34} strokeWidth={2.1} />
45
+ <ChevronLeft color={themedColor('#F4F4F5')} size={34} strokeWidth={2.1} />
45
46
  </Pressable>
46
47
  <Pressable
47
48
  accessibilityHint="Long press to rename this Superagent"
@@ -61,11 +62,11 @@ export function ConversationHeader({
61
62
  <View style={conversationStyles.headerActions}>
62
63
  {onOpenShare ? (
63
64
  <Pressable accessibilityLabel="Share Superagent chat" accessibilityRole="button" onPress={onOpenShare} style={conversationStyles.headerShareButton}>
64
- <Share2 color="#F4F4F5" size={22} strokeWidth={2.4} />
65
+ <Share2 color={themedColor('#F4F4F5')} size={22} strokeWidth={2.4} />
65
66
  </Pressable>
66
67
  ) : null}
67
68
  <Pressable accessibilityLabel="Open Superagent menu" accessibilityRole="button" onPress={onOpenMenu} style={conversationStyles.headerMenuButton}>
68
- <MoreHorizontal color="#F4F4F5" size={28} strokeWidth={2.4} />
69
+ <MoreHorizontal color={themedColor('#F4F4F5')} size={28} strokeWidth={2.4} />
69
70
  </Pressable>
70
71
  </View>
71
72
  </View>
@@ -95,7 +96,7 @@ export function MessageBubble({
95
96
  currentUserAvatarUrl?: string | null;
96
97
  isLastAssistantMessage: boolean;
97
98
  message: SuperagentMessage;
98
- onConnectConnector?: (input: SuperagentConnectorActionInput) => Promise<boolean | void> | boolean | void;
99
+ onConnectConnector?: (input: SuperagentConnectorActionInput) => Promise<boolean | string | void> | boolean | string | void;
99
100
  onCopyMessage?: SuperagentCopyMessageInput;
100
101
  onDeleteMessage?: (messageId: string) => Promise<boolean> | boolean;
101
102
  onReplyMessage?: (message: SuperagentMessage) => void;
@@ -289,7 +290,7 @@ export function TypingIndicator() {
289
290
  conversationStyles.thinkingIcon,
290
291
  { opacity, transform: [{ rotate }, { scale }] },
291
292
  ]}>
292
- <Sparkles color="#FF8A4C" size={16} strokeWidth={2.3} />
293
+ <Sparkles color={themedColor('#FF8A4C')} size={16} strokeWidth={2.3} />
293
294
  </Animated.View>
294
295
  <Text style={[conversationStyles.typingText, conversationStyles.typingTextWrap]}>Thinking</Text>
295
296
  </View>
@@ -1,6 +1,7 @@
1
1
  import type { Dispatch, SetStateAction } from 'react';
2
2
 
3
3
  import { AUTO_GREET_MESSAGE, nextMessageId } from './constants';
4
+ import { getMessageToolCalls } from './messageUtils';
4
5
  import type { SuperagentMessage, SuperagentNativeClient, SuperagentReplyTo } from './types';
5
6
 
6
7
  export function normalizeMessages(messages: SuperagentMessage[]) {
@@ -22,7 +23,17 @@ export function mergeMessage(messages: SuperagentMessage[], nextMessage: Superag
22
23
  const existingIndex = messages.findIndex((message) => message.id === normalized.id);
23
24
  if (existingIndex < 0) return [...messages, normalized];
24
25
 
25
- return messages.map((message, index) => (index === existingIndex ? normalized : message));
26
+ return messages.map((message, index) => {
27
+ if (index !== existingIndex) return message;
28
+ // Don't let a shorter/stale assistant payload overwrite newer streamed text
29
+ // the user is already reading — but still adopt the incoming row's fresh
30
+ // tool_calls/status/metadata (mirrors mergeConversationSnapshot), so a tool
31
+ // flipping to waiting_for_user_input/success isn't masked by the local row.
32
+ if (message.role === 'assistant' && (message.content?.length ?? 0) > (normalized.content?.length ?? 0)) {
33
+ return { ...normalized, content: message.content };
34
+ }
35
+ return normalized;
36
+ });
26
37
  }
27
38
 
28
39
  export function isVisibleMessage(message: SuperagentMessage, index: number) {
@@ -78,14 +89,73 @@ export function hasNewAssistantResponse(messages: SuperagentMessage[], assistant
78
89
  return countAssistantResponses(messages) > assistantCountBefore;
79
90
  }
80
91
 
92
+ // True when any message has a tool call that is actively executing
93
+ // (running/pending) — not just the last row: a tool can still be running on an
94
+ // earlier assistant message while a newer text row already exists. "waiting" is
95
+ // excluded: that means the agent is paused for user input, not still working.
96
+ export function hasRunningToolCall(messages: SuperagentMessage[]) {
97
+ return messages.some((message) =>
98
+ getMessageToolCalls(message).some((toolCall) => {
99
+ const status = (toolCall.status || '').toLowerCase();
100
+ return status === 'running' || status === 'pending';
101
+ }),
102
+ );
103
+ }
104
+
105
+ // Merge an authoritative server snapshot with the current list, keeping a local
106
+ // assistant row when it already has more text than the snapshot copy — so a
107
+ // slightly stale fetch/event can't shorten streamed content the user is reading.
108
+ export function mergeConversationSnapshot(
109
+ current: SuperagentMessage[],
110
+ incoming: SuperagentMessage[],
111
+ ): SuperagentMessage[] {
112
+ const currentById = new Map(current.filter((message) => message.id).map((message) => [message.id, message]));
113
+ const incomingIds = new Set(incoming.map((message) => message.id).filter(Boolean));
114
+ const incomingUserContents = new Set(
115
+ incoming.filter((message) => message.role === 'user').map((message) => (message.content ?? '').trim()),
116
+ );
117
+ const merged = incoming.map((message) => {
118
+ const local = message.id ? currentById.get(message.id) : undefined;
119
+ if (local && local.role === 'assistant' && (local.content?.length ?? 0) > (message.content?.length ?? 0)) {
120
+ // Keep the longer local text, but take the snapshot's fresh tool_calls /
121
+ // status / metadata — otherwise a newly-`waiting_for_user_input` approval or
122
+ // a completed tool would be masked by the stale local row.
123
+ return { ...message, content: local.content };
124
+ }
125
+ return message;
126
+ });
127
+ // Keep local rows the snapshot hasn't caught up to (optimistic sends / messages
128
+ // still streaming in), dropping an optimistic user echo the snapshot already
129
+ // represents by content so it isn't duplicated. Callers that genuinely remove a
130
+ // message (delete) must drop it from local state before refreshing, or it would
131
+ // be resurrected here.
132
+ const pendingLocal = current.filter((message) =>
133
+ message.id
134
+ && !incomingIds.has(message.id)
135
+ && !(message.role === 'user' && incomingUserContents.has((message.content ?? '').trim())),
136
+ );
137
+ // Sort the combined set by chronological cursor instead of appending pendingLocal.
138
+ // Older rows loaded via loadPrevious aren't in the backend's recent-window refresh,
139
+ // so appending them would drop old history below the newest replies and break
140
+ // chat order / autoscroll. Stable sort preserves equal-cursor snapshot order;
141
+ // rows without a cursor (fresh optimistic sends) sort last, as newest.
142
+ return [...merged, ...pendingLocal].sort((a, b) => {
143
+ const ca = getMessageCursor(a);
144
+ const cb = getMessageCursor(b);
145
+ if (ca && cb) return ca < cb ? -1 : ca > cb ? 1 : 0;
146
+ if (!ca && !cb) return 0;
147
+ return ca ? -1 : 1;
148
+ });
149
+ }
150
+
81
151
  export async function refreshConversation(
82
152
  apiClient: SuperagentNativeClient,
83
153
  conversationId: string,
84
- setMessages: (messages: SuperagentMessage[]) => void,
154
+ setMessages: Dispatch<SetStateAction<SuperagentMessage[]>>,
85
155
  ) {
86
156
  const refreshed = await apiClient.getConversation(conversationId);
87
157
  const normalizedMessages = normalizeMessages(refreshed.messages ?? []);
88
- setMessages(normalizedMessages);
158
+ setMessages((current) => mergeConversationSnapshot(current, normalizedMessages));
89
159
  return normalizedMessages;
90
160
  }
91
161
 
@@ -98,16 +168,27 @@ export async function sendWithFallback(
98
168
  Promise<SuperagentMessage | SuperagentMessage[] | void> | SuperagentMessage | SuperagentMessage[] | void,
99
169
  setMessages: Dispatch<SetStateAction<SuperagentMessage[]>>,
100
170
  setIsSending: (value: boolean) => void,
101
- ): Promise<boolean> {
171
+ optimisticMessageId?: string,
172
+ ): Promise<{ delivered: boolean; hasAssistantResponse: boolean }> {
102
173
  try {
103
174
  const response = await onSendMessage({ agentId, fileUrls, message: content, replyTo });
104
175
  const responseMessages = Array.isArray(response) ? response : response ? [response] : [];
105
176
  setMessages((current) => [...current, ...responseMessages]);
106
- return responseMessages.some((message) => message.role === 'assistant');
177
+ // `delivered` (the host handler accepted the send) is distinct from
178
+ // `hasAssistantResponse` (a reply arrived synchronously): a successful send
179
+ // with no immediate assistant reply must NOT look like a failure, or the
180
+ // caller would wrongly restore the composer draft.
181
+ return { delivered: true, hasAssistantResponse: responseMessages.some((message) => message.role === 'assistant') };
107
182
  } catch (error) {
183
+ // The optimistic bubble never reached the host send handler; drop it and
184
+ // surface the error in its place so the turn doesn't look sent. Mirrors the
185
+ // apiClient.addMessage failure path in useSuperagentConversation.
108
186
  const errorMessage = createErrorMessage(error);
109
- setMessages((current) => [...current, errorMessage]);
110
- return false;
187
+ setMessages((current) => [
188
+ ...(optimisticMessageId ? current.filter((message) => message.id !== optimisticMessageId) : current),
189
+ errorMessage,
190
+ ]);
191
+ return { delivered: false, hasAssistantResponse: false };
111
192
  } finally {
112
193
  setIsSending(false);
113
194
  }
@@ -116,31 +197,105 @@ export async function sendWithFallback(
116
197
  export function pollConversation(
117
198
  apiClient: SuperagentNativeClient,
118
199
  conversationId: string,
119
- setMessages: (messages: SuperagentMessage[]) => void,
200
+ setMessages: Dispatch<SetStateAction<SuperagentMessage[]>>,
120
201
  setIsSending: (value: boolean) => void,
121
202
  assistantCountBefore: number,
122
203
  onComplete?: () => Promise<void> | void,
123
204
  onAgentMessageDone?: () => Promise<void> | void,
124
205
  ) {
206
+ // Without realtime we poll for the turn to finish. Stop as soon as a new
207
+ // assistant reply lands. Otherwise stop at the soft cap (~20s) only when the
208
+ // agent no longer appears to be working — if a tool call is still running we
209
+ // keep polling up to a hard cap (~120s) so "sending" isn't cleared mid-turn.
210
+ // (A tool waiting_for_user_input is NOT "working": it needs the user, so we
211
+ // let it stop and surface the approval card.)
212
+ const SOFT_CAP = 10;
213
+ const HARD_CAP = 60;
125
214
  let attempts = 0;
215
+ // Tracks whether a tool was observed running during this poll. A tool-only turn
216
+ // produces no new assistant *text*, so without this it would sit until the soft
217
+ // cap (~20s) even after the tool finished — once we've seen a tool run and it's
218
+ // no longer running, the turn is done.
219
+ let sawRunningTool = false;
126
220
  const interval = setInterval(async () => {
127
221
  attempts += 1;
128
- let shouldStop = attempts >= 10;
129
222
  let foundAssistantResponse = false;
223
+ let agentStillRunning = false;
130
224
 
131
225
  try {
132
226
  const refreshedMessages = await refreshConversation(apiClient, conversationId, setMessages);
133
227
  foundAssistantResponse = hasNewAssistantResponse(refreshedMessages, assistantCountBefore);
134
- shouldStop = shouldStop || foundAssistantResponse;
228
+ agentStillRunning = hasRunningToolCall(refreshedMessages);
229
+ if (agentStillRunning) sawRunningTool = true;
230
+ } catch {
231
+ // Swallow transient poll failures; keep polling until a cap.
135
232
  } finally {
233
+ // A new assistant message alone doesn't mean the turn is done: the same
234
+ // snapshot can still have a running/pending tool call (tool-using turns
235
+ // emit partial assistant text first). Treat the turn complete only once no
236
+ // tool is running, when either new assistant text arrived, a tool ran and
237
+ // has now finished (tool-only turns), or the soft cap is reached. Hard cap
238
+ // is the absolute safety stop.
239
+ const turnComplete = !agentStillRunning && (foundAssistantResponse || sawRunningTool || attempts >= SOFT_CAP);
240
+ const shouldStop = turnComplete || attempts >= HARD_CAP;
136
241
  if (shouldStop) {
137
242
  clearInterval(interval);
138
243
  setIsSending(false);
139
- if (foundAssistantResponse) onAgentMessageDone?.();
244
+ // Fire on a genuinely completed turn (turnComplete), not just when new
245
+ // assistant *text* appeared — a tool-only turn produces no new content but
246
+ // still finished, and host hooks (e.g. automation refresh) hang off this.
247
+ // Skip it on the hard-cap bail-out (shouldStop but !turnComplete).
248
+ if (turnComplete) onAgentMessageDone?.();
140
249
  onComplete?.();
141
250
  }
142
251
  }
143
252
  }, 2000);
253
+
254
+ return interval;
255
+ }
256
+
257
+ export function pollQueuedSend(
258
+ apiClient: SuperagentNativeClient,
259
+ conversationId: string,
260
+ queuedMessageId: string,
261
+ setMessages: Dispatch<SetStateAction<SuperagentMessage[]>>,
262
+ setIsSending: (value: boolean) => void,
263
+ setPollInterval: (interval: ReturnType<typeof setInterval>) => void,
264
+ onComplete?: () => Promise<void> | void,
265
+ onAgentMessageDone?: () => Promise<void> | void,
266
+ ) {
267
+ // A queued send is waiting behind another turn that holds the conversation lock.
268
+ // Don't treat that turn's completion as ours: poll the backend queue until OUR
269
+ // message drains (its own turn starts), then re-baseline the assistant count and
270
+ // hand off to the normal response poll so we settle on THIS send's reply — not
271
+ // one that landed while we were still queued.
272
+ const HARD_CAP = 150; // ~5 min at 2s ticks — safety stop if the queue never drains.
273
+ let attempts = 0;
274
+ const interval = setInterval(async () => {
275
+ attempts += 1;
276
+ let stillQueued = true;
277
+ try {
278
+ const { messages } = await apiClient.getQueuedMessages(conversationId);
279
+ stillQueued = messages.some((message) => message.id === queuedMessageId);
280
+ } catch {
281
+ // Swallow transient failures; keep waiting until drained or the cap.
282
+ }
283
+ if (stillQueued && attempts < HARD_CAP) return;
284
+
285
+ clearInterval(interval);
286
+ // Drained (or cap hit): our turn is now running. Re-baseline the assistant
287
+ // count from the current snapshot so the response poll waits for OUR reply.
288
+ let baseline = 0;
289
+ try {
290
+ baseline = countAssistantResponses(await refreshConversation(apiClient, conversationId, setMessages));
291
+ } catch {
292
+ // Refresh failed — fall back to 0 so the response poll still settles.
293
+ }
294
+ setPollInterval(pollConversation(
295
+ apiClient, conversationId, setMessages, setIsSending, baseline, onComplete, onAgentMessageDone,
296
+ ));
297
+ }, 2000);
298
+ return interval;
144
299
  }
145
300
 
146
301
  export function getMessageCursor(message?: SuperagentMessage) {
@@ -1,6 +1,7 @@
1
1
  import { Platform, StyleSheet } from 'react-native';
2
+ import { createThemedStyles } from './theme';
2
3
 
3
- export const conversationStyles = StyleSheet.create({
4
+ export const conversationStyles = createThemedStyles({
4
5
  safeArea: { flex: 1, backgroundColor: '#000000' },
5
6
  keyboard: { flex: 1 },
6
7
  header: {
@@ -1,6 +1,7 @@
1
1
  import { StyleSheet } from 'react-native';
2
+ import { createThemedStyles } from './theme';
2
3
 
3
- export const editorShellStyles = StyleSheet.create({
4
+ export const editorShellStyles = createThemedStyles({
4
5
  modalRoot: {
5
6
  backgroundColor: '#000000',
6
7
  flex: 1,
@@ -727,6 +728,10 @@ export const editorShellStyles = StyleSheet.create({
727
728
  connectorSvgIcon: {
728
729
  position: 'absolute',
729
730
  },
731
+ connectorIconImage: {
732
+ height: 22,
733
+ width: 22,
734
+ },
730
735
  connectorIconFallbackText: {
731
736
  color: '#111827',
732
737
  fontSize: 11,
@@ -15,6 +15,19 @@ export const DEFAULT_SANDBOX_FILE_PATHS = [
15
15
 
16
16
  export type SuperagentFileCategory = 'code' | 'html' | 'image' | 'markdown' | 'pdf' | 'text';
17
17
 
18
+ export function sanitizeSandboxFilePath(path: string) {
19
+ // Strip absolute / `..` / `.` segments and null bytes so a picked file name can't
20
+ // write outside the sandbox via path traversal (defense in depth, not a substitute
21
+ // for the backend's own validation).
22
+ return path
23
+ .replace(/\\/g, '/')
24
+ .replace(/\0/g, '')
25
+ .split('/')
26
+ .map((segment) => segment.trim())
27
+ .filter((segment) => segment && segment !== '.' && segment !== '..')
28
+ .join('/');
29
+ }
30
+
18
31
  export function normalizeFilePaths(paths: string[] = []) {
19
32
  return paths
20
33
  .filter((path) => typeof path === 'string' && path.trim().length > 0)
package/src/index.ts CHANGED
@@ -10,6 +10,8 @@ export {
10
10
  export { EditorDrawer } from './EditorDrawer';
11
11
  export { EditorTabPanel } from './EditorTabPanel';
12
12
  export { superagentPaperTheme } from './paperTheme';
13
+ export { useSuperagentTheme } from './theme';
14
+ export type { SuperagentColorScheme } from './theme';
13
15
  export { SuperagentHomeScreen } from './SuperagentHomeScreen';
14
16
  export { ToolCallSummary } from './ToolCallSummary';
15
17
  export { useSuperagentAttachmentPicker } from './useSuperagentAttachmentPicker';
@@ -1,6 +1,7 @@
1
1
  import { StyleSheet } from 'react-native';
2
+ import { createThemedStyles } from './theme';
2
3
 
3
- export const markdownStyles = StyleSheet.create({
4
+ export const markdownStyles = createThemedStyles({
4
5
  root: {},
5
6
  wideRoot: { width: '100%' },
6
7
  paragraph: { color: '#F4F4F5', fontSize: 17, lineHeight: 25, marginVertical: 3 },
@@ -1,6 +1,7 @@
1
1
  import { StyleSheet } from 'react-native';
2
+ import { createThemedStyles } from './theme';
2
3
 
3
- export const messageActionStyles = StyleSheet.create({
4
+ export const messageActionStyles = createThemedStyles({
4
5
  bar: {
5
6
  alignItems: 'center',
6
7
  alignSelf: 'flex-start',
@@ -1,4 +1,5 @@
1
1
  import type {
2
+ SuperagentAgentDonePayload,
2
3
  SuperagentConversation,
3
4
  SuperagentMessage,
4
5
  SuperagentRealtimeClient,
@@ -47,7 +48,12 @@ export function createSuperagentSocketClient({
47
48
  const onAgentDone: SocketListener = (raw) => {
48
49
  const envelope = parseEnvelope(raw);
49
50
  if (!envelope || envelope.room !== room) return;
50
- handlers.onAgentDone?.();
51
+ // Forward the parsed payload (sender_platform_user_id / bootstrap_intro) so
52
+ // callers can ignore completions from other collaborators in shared rooms.
53
+ const payload = envelope.data && typeof envelope.data === 'object'
54
+ ? (envelope.data as SuperagentAgentDonePayload)
55
+ : undefined;
56
+ handlers.onAgentDone?.(payload);
51
57
  };
52
58
 
53
59
  const onConnect = () => {
@@ -1,6 +1,7 @@
1
1
  import { StyleSheet } from 'react-native';
2
+ import { createThemedStyles } from './theme';
2
3
 
3
- export const renameAgentModalStyles = StyleSheet.create({
4
+ export const renameAgentModalStyles = createThemedStyles({
4
5
  actions: {
5
6
  flexDirection: 'row',
6
7
  gap: 10,
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
+ import { themedColor } from './theme';
2
3
  import { Pressable, SafeAreaView, Text, View } from 'react-native';
3
- import { ChevronRight, Plus } from 'lucide-react-native';
4
+ import { ChevronRight } from 'lucide-react-native';
4
5
 
5
6
  import { AgentSphereIcon } from './AgentSphereIcon';
6
7
  import { styles } from './styles';
@@ -8,52 +9,40 @@ import type { SuperagentAgent, SuperagentHomeScreenProps } from './types';
8
9
 
9
10
  export function AgentCard({
10
11
  agent,
11
- automationCount = 0,
12
- connectorCount = 0,
13
12
  latestMessages,
14
13
  onPress,
15
14
  }: {
16
15
  agent: SuperagentAgent;
16
+ // Accepted for call-site compatibility; no longer shown (meta pills removed).
17
17
  automationCount?: number;
18
18
  connectorCount?: number;
19
19
  latestMessages: SuperagentHomeScreenProps['latestMessages'];
20
20
  onPress: () => void;
21
21
  }) {
22
22
  const preview = getLatestMessagePreview(latestMessages);
23
- const meta = [
24
- connectorCount > 0 ? `${connectorCount} connected` : 'Tools ready',
25
- automationCount > 0 ? `${automationCount} tasks` : 'No tasks yet',
26
- ];
23
+ const agentName = agent.name || 'Untitled Agent';
27
24
 
28
25
  return (
29
- <Pressable
30
- accessibilityRole="button"
31
- onPress={onPress}
32
- style={({ pressed }) => [styles.heroPanel, pressed && styles.pressed]}
33
- >
34
- <View style={styles.heroTopRow}>
35
- <Text style={styles.heroLabel}>Continue</Text>
36
- </View>
26
+ <View style={styles.heroPanel}>
37
27
  <View style={styles.agentCard}>
38
28
  <View style={styles.avatar}>
39
29
  <AgentSphereIcon agent={agent} size="header" />
40
30
  </View>
41
31
  <View style={styles.agentCardBody}>
42
- <Text style={styles.agentName} numberOfLines={1}>{agent.name || 'Untitled Agent'}</Text>
32
+ <Text style={styles.agentName} numberOfLines={1}>{agentName}</Text>
43
33
  <Text style={styles.agentDescription} numberOfLines={3}>
44
34
  {preview || agent.description || 'Open your latest Superagent conversation.'}
45
35
  </Text>
46
36
  </View>
47
- <ChevronRight color="#8E8E93" size={24} strokeWidth={2.5} />
48
- </View>
49
- <View style={styles.agentMetaRow}>
50
- {meta.map((item) => (
51
- <View key={item} style={styles.agentMetaPill}>
52
- <Text style={styles.agentMetaText}>{item}</Text>
53
- </View>
54
- ))}
55
37
  </View>
56
- </Pressable>
38
+ <Pressable
39
+ accessibilityRole="button"
40
+ onPress={onPress}
41
+ style={({ pressed }) => [styles.primaryButton, styles.heroContinueButton, pressed && styles.pressed]}
42
+ >
43
+ <Text style={styles.primaryButtonText} numberOfLines={1}>Continue with {agentName}</Text>
44
+ </Pressable>
45
+ </View>
57
46
  );
58
47
  }
59
48
 
@@ -118,7 +107,7 @@ export function AgentRow({
118
107
  {preview || agent.description || 'Ready for the next instruction.'}
119
108
  </Text>
120
109
  </View>
121
- <ChevronRight color="#73737A" size={21} strokeWidth={2.5} />
110
+ <ChevronRight color={themedColor('#73737A')} size={21} strokeWidth={2.5} />
122
111
  </Pressable>
123
112
  );
124
113
  }
@@ -143,10 +132,9 @@ export function CreateAgentButton({
143
132
  accessibilityRole="button"
144
133
  disabled={isCreating}
145
134
  onPress={onPress}
146
- style={({ pressed }) => [styles.secondaryButton, pressed && styles.pressed]}
135
+ style={({ pressed }) => [styles.linkButton, pressed && styles.pressed]}
147
136
  >
148
- <Plus color="#F4F4F5" size={18} strokeWidth={2.6} />
149
- <Text style={styles.secondaryButtonText}>{isCreating ? 'Creating...' : 'New Superagent'}</Text>
137
+ <Text style={styles.linkButtonText}>{isCreating ? 'Creating...' : 'Create a new superagent'}</Text>
150
138
  </Pressable>
151
139
  );
152
140
  }