@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
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.useSuperagentRuntime = useSuperagentRuntime;
7
7
  var _react = require("react");
8
+ var _reactNative = require("react-native");
8
9
  var _apiClient = require("./apiClient.js");
9
10
  var _fileTreeUtils = require("./fileTreeUtils.js");
10
11
  var _realtimeClient = require("./realtimeClient.js");
@@ -22,6 +23,10 @@ function useSuperagentRuntime({
22
23
  }), [config.baseUrl, config.currentUserId, config.getAccessToken, config.getHeaders]);
23
24
  const [agents, setAgents] = (0, _react.useState)([]);
24
25
  const [activeAgentId, setActiveAgentId] = (0, _react.useState)(initialAgentId ?? null);
26
+ // Always-latest active agent id, so a slow load for a previous agent can detect
27
+ // that the user has since switched and skip applying its (now stale) result.
28
+ const activeAgentIdRef = (0, _react.useRef)(activeAgentId);
29
+ activeAgentIdRef.current = activeAgentId;
25
30
  const [currentRoute, setCurrentRoute] = (0, _react.useState)(initialAgentId ? {
26
31
  name: 'agent',
27
32
  agentId: initialAgentId
@@ -48,6 +53,11 @@ function useSuperagentRuntime({
48
53
  const [isLoading, setIsLoading] = (0, _react.useState)(true);
49
54
  const [loadError, setLoadError] = (0, _react.useState)(null);
50
55
  const [runtimeAuthToken, setRuntimeAuthToken] = (0, _react.useState)(null);
56
+ // Caches the resolved runtime token keyed by the agent it belongs to. The
57
+ // runtimeAuthToken state lags an agent switch (it's cleared in a later effect),
58
+ // so resolveRuntimeToken must not trust it as a cache — this ref can never hand
59
+ // back a different agent's token.
60
+ const runtimeTokenRef = (0, _react.useRef)(null);
51
61
  const [realtimeClient, setRealtimeClient] = (0, _react.useState)();
52
62
  const [secrets, setSecrets] = (0, _react.useState)([]);
53
63
  const connectorFlowRef = (0, _react.useRef)(null);
@@ -82,31 +92,37 @@ function useSuperagentRuntime({
82
92
  setIsLoadingConnectors(true);
83
93
  try {
84
94
  const connectors = await superagentService.listConnectors(agentId);
95
+ if (activeAgentIdRef.current !== agentId) return;
85
96
  setAvailableConnectors(connectors.availableConnectors);
86
97
  setConnectedConnectors(connectors.connectedConnectors);
87
98
  } catch {
99
+ if (activeAgentIdRef.current !== agentId) return;
88
100
  setAvailableConnectors([]);
89
101
  setConnectedConnectors([]);
90
102
  } finally {
91
- setIsLoadingConnectors(false);
103
+ if (activeAgentIdRef.current === agentId) setIsLoadingConnectors(false);
92
104
  }
93
105
  }, [superagentService]);
94
106
  const loadAutomations = (0, _react.useCallback)(async agentId => {
95
107
  setIsLoadingAutomations(true);
96
108
  try {
97
109
  const loadedAutomations = await superagentService.listAutomations(agentId);
110
+ if (activeAgentIdRef.current !== agentId) return;
98
111
  setAutomations(loadedAutomations);
99
112
  } catch {
113
+ if (activeAgentIdRef.current !== agentId) return;
100
114
  setAutomations([]);
101
115
  } finally {
102
- setIsLoadingAutomations(false);
116
+ if (activeAgentIdRef.current === agentId) setIsLoadingAutomations(false);
103
117
  }
104
118
  }, [superagentService]);
105
119
  const loadAutomationCredits = (0, _react.useCallback)(async agentId => {
106
120
  try {
107
121
  const loadedCredits = await superagentService.listAutomationCredits(agentId);
122
+ if (activeAgentIdRef.current !== agentId) return;
108
123
  setAutomationCredits(loadedCredits);
109
124
  } catch {
125
+ if (activeAgentIdRef.current !== agentId) return;
110
126
  setAutomationCredits({});
111
127
  }
112
128
  }, [superagentService]);
@@ -114,55 +130,74 @@ function useSuperagentRuntime({
114
130
  setIsLoadingFiles(true);
115
131
  try {
116
132
  const loadedFilePaths = await superagentService.listSandboxFiles(agentId);
133
+ if (activeAgentIdRef.current !== agentId) return;
117
134
  const normalizedFilePaths = (0, _fileTreeUtils.normalizeFilePaths)(loadedFilePaths);
118
135
  setFilePaths(normalizedFilePaths.length > 0 ? normalizedFilePaths : _fileTreeUtils.DEFAULT_SANDBOX_FILE_PATHS);
119
136
  setFileLoadError(null);
120
137
  setFileLoadFailed(false);
121
138
  } catch (error) {
139
+ if (activeAgentIdRef.current !== agentId) return;
122
140
  setFilePaths(_fileTreeUtils.DEFAULT_SANDBOX_FILE_PATHS);
123
141
  setFileLoadError(getErrorMessage(error));
124
142
  setFileLoadFailed(true);
125
143
  } finally {
126
- setIsLoadingFiles(false);
144
+ if (activeAgentIdRef.current === agentId) setIsLoadingFiles(false);
127
145
  }
128
146
  }, [superagentService]);
129
147
  const loadAgentSettings = (0, _react.useCallback)(async agentId => {
130
148
  setIsLoadingAgentSettings(true);
131
149
  try {
132
150
  const loadedSecrets = await superagentService.listSecrets(agentId);
151
+ if (activeAgentIdRef.current !== agentId) return;
133
152
  setSecrets(loadedSecrets);
134
153
  } catch {
154
+ if (activeAgentIdRef.current !== agentId) return;
135
155
  setSecrets([]);
136
156
  } finally {
137
- setIsLoadingAgentSettings(false);
157
+ if (activeAgentIdRef.current === agentId) setIsLoadingAgentSettings(false);
138
158
  }
139
159
  }, [superagentService]);
140
160
  const loadCollaborators = (0, _react.useCallback)(async agentId => {
141
161
  setIsLoadingCollaborators(true);
142
162
  try {
143
163
  const loadedCollaborators = await superagentService.listCollaborators(agentId);
164
+ if (activeAgentIdRef.current !== agentId) return;
144
165
  setCollaborators(loadedCollaborators);
145
166
  } catch {
167
+ if (activeAgentIdRef.current !== agentId) return;
146
168
  setCollaborators([]);
147
169
  } finally {
148
- setIsLoadingCollaborators(false);
170
+ if (activeAgentIdRef.current === agentId) setIsLoadingCollaborators(false);
149
171
  }
150
172
  }, [superagentService]);
151
173
  const resolveRuntimeToken = (0, _react.useCallback)(async agentId => {
152
- if (agentId === activeAgentId && runtimeAuthToken) {
153
- return runtimeAuthToken;
174
+ // Use the agent-keyed ref, not the runtimeAuthToken state: the state still
175
+ // holds the previous agent's token during a switch (it's cleared in a later
176
+ // effect), so trusting it could return the wrong agent's token here.
177
+ const cached = runtimeTokenRef.current;
178
+ if (cached && cached.agentId === agentId) {
179
+ return cached.token;
154
180
  }
155
181
  const token = await superagentService.getRuntimeAuthToken(agentId);
156
- if (agentId === activeAgentId) {
182
+ runtimeTokenRef.current = {
183
+ agentId,
184
+ token
185
+ };
186
+ // Compare against the latest active agent (ref), not the closure-captured
187
+ // activeAgentId: the user may have switched agents while the fetch was in
188
+ // flight, and writing a stale agent's token into shared state would point
189
+ // realtime/channel calls at the wrong agent.
190
+ if (agentId === activeAgentIdRef.current) {
157
191
  setRuntimeAuthToken(token);
158
192
  }
159
193
  return token;
160
- }, [activeAgentId, runtimeAuthToken, superagentService]);
194
+ }, [superagentService]);
161
195
  const loadChannels = (0, _react.useCallback)(async agentId => {
162
196
  setIsLoadingChannels(true);
163
197
  try {
164
198
  const token = await resolveRuntimeToken(agentId);
165
199
  const status = await superagentService.getChannelStatus(agentId, token);
200
+ if (activeAgentIdRef.current !== agentId) return;
166
201
  setChannelStatus(current => ({
167
202
  ...status,
168
203
  imessage: {
@@ -175,25 +210,33 @@ function useSuperagentRuntime({
175
210
  }
176
211
  }));
177
212
  } catch {
213
+ if (activeAgentIdRef.current !== agentId) return;
178
214
  setChannelStatus({});
179
215
  } finally {
180
- setIsLoadingChannels(false);
216
+ if (activeAgentIdRef.current === agentId) setIsLoadingChannels(false);
181
217
  }
182
218
  }, [resolveRuntimeToken, superagentService]);
183
219
  const refreshAutomations = (0, _react.useCallback)(async agentId => {
184
220
  await Promise.all([loadAutomations(agentId), loadAutomationCredits(agentId)]);
185
221
  }, [loadAutomationCredits, loadAutomations]);
186
222
  (0, _react.useEffect)(() => {
223
+ // Reset per-agent state on every active-agent change (not just when it goes
224
+ // null) so the drawer never shows the previous agent's secrets/connectors/
225
+ // files/collaborators/automations during the new agent's load window — which
226
+ // could otherwise let a destructive action target the wrong agent.
227
+ setAvailableConnectors([]);
228
+ setAutomationCredits({});
229
+ setAutomations([]);
230
+ setChannelStatus({});
231
+ setCollaborators([]);
232
+ setConnectingChannelId(null);
233
+ setConnectingConnectorId(null);
234
+ setConnectedConnectors([]);
235
+ setFilePaths([]);
236
+ setFileLoadError(null);
237
+ setFileLoadFailed(false);
238
+ setSecrets([]);
187
239
  if (!activeAgentId) {
188
- setAvailableConnectors([]);
189
- setAutomationCredits({});
190
- setAutomations([]);
191
- setChannelStatus({});
192
- setCollaborators([]);
193
- setConnectingChannelId(null);
194
- setConnectedConnectors([]);
195
- setFilePaths([]);
196
- setSecrets([]);
197
240
  return;
198
241
  }
199
242
  loadAgentSettings(activeAgentId);
@@ -231,23 +274,17 @@ function useSuperagentRuntime({
231
274
  if (!flow || flow.cancelled) {
232
275
  return;
233
276
  }
234
- if (event.status === 'success') {
235
- flow.cancelled = true;
236
- connectorFlowRef.current = null;
237
- setConnectingConnectorId(null);
238
- await loadConnectors(flow.agentId);
239
- return;
240
- }
241
- if (event.status === 'error') {
242
- flow.cancelled = true;
243
- connectorFlowRef.current = null;
244
- setConnectingConnectorId(null);
277
+
278
+ // The callback event carries no connection/connector identifier, so it can't
279
+ // be reliably attributed to this flow — a late callback from a superseded
280
+ // connect could otherwise mark the wrong flow. Don't mutate flow state here;
281
+ // waitForConnectorAuthorization polls the authoritative per-connection status
282
+ // (it detects ACTIVE/FAILED on its own). Just refresh the connector list so
283
+ // the UI reflects the latest state.
284
+ if (event.status === 'success' || event.status === 'error') {
245
285
  await loadConnectors(flow.agentId);
246
- showAlert(nativeAdapters, 'Connector failed', 'OAuth authorization did not complete. Please try connecting again.');
247
- return;
248
286
  }
249
- await loadConnectors(flow.agentId);
250
- }, [loadConnectors, nativeAdapters]);
287
+ }, [loadConnectors]);
251
288
  (0, _react.useEffect)(() => {
252
289
  return nativeAdapters.subscribeToExternalAuthCallbacks?.(completePendingConnectorFromCallback);
253
290
  }, [completePendingConnectorFromCallback, nativeAdapters]);
@@ -374,6 +411,9 @@ function useSuperagentRuntime({
374
411
  } : agent));
375
412
  } catch (error) {
376
413
  showAlert(nativeAdapters, 'Permissions update failed', getErrorMessage(error));
414
+ // Rethrow so optimistic callers (the permission toggle) can revert; the
415
+ // guard-config caller wraps this in try/catch since the alert already fired.
416
+ throw error;
377
417
  }
378
418
  }, [nativeAdapters, superagentService]);
379
419
  const onSaveSecret = (0, _react.useCallback)(async ({
@@ -386,6 +426,9 @@ function useSuperagentRuntime({
386
426
  await loadAgentSettings(agentId);
387
427
  } catch (error) {
388
428
  showAlert(nativeAdapters, 'Secret save failed', getErrorMessage(error));
429
+ // Rethrow so the form keeps the user's input instead of clearing on a
430
+ // failed save.
431
+ throw error;
389
432
  }
390
433
  }, [loadAgentSettings, nativeAdapters, superagentService]);
391
434
  const onDeleteSecret = (0, _react.useCallback)(async ({
@@ -448,7 +491,10 @@ function useSuperagentRuntime({
448
491
  const onCloneAgent = (0, _react.useCallback)(({
449
492
  agentId
450
493
  }) => {
451
- nativeAdapters.openWebUrl?.(buildWebUrl(config.webUrl ?? config.baseUrl, `/remix-app/${encodeURIComponent(agentId)}?clone_history=true`));
494
+ // Use the Superagent clone route — /remix-app is an app route that the web
495
+ // builder redirects back to /superagent/:id for user_agent apps (reopening the
496
+ // original instead of cloning). /clone-superagent/:id is the agent clone flow.
497
+ nativeAdapters.openWebUrl?.(buildWebUrl(config.webUrl ?? config.baseUrl, `/clone-superagent/${encodeURIComponent(agentId)}`));
452
498
  }, [config.baseUrl, config.webUrl, nativeAdapters]);
453
499
  const onDeleteAgent = (0, _react.useCallback)(async ({
454
500
  agentId
@@ -571,7 +617,7 @@ function useSuperagentRuntime({
571
617
  agentId,
572
618
  path
573
619
  }) => {
574
- return superagentService.readSandboxFile(agentId, path);
620
+ return superagentService.readSandboxFile(agentId, (0, _fileTreeUtils.sanitizeSandboxFilePath)(path));
575
621
  }, [superagentService]);
576
622
  const onSaveSandboxFile = (0, _react.useCallback)(async ({
577
623
  agentId,
@@ -579,7 +625,7 @@ function useSuperagentRuntime({
579
625
  path
580
626
  }) => {
581
627
  try {
582
- await superagentService.writeSandboxFile(agentId, path, content);
628
+ await superagentService.writeSandboxFile(agentId, (0, _fileTreeUtils.sanitizeSandboxFilePath)(path), content);
583
629
  await loadFiles(agentId);
584
630
  } catch (error) {
585
631
  showAlert(nativeAdapters, 'Save failed', getErrorMessage(error));
@@ -594,12 +640,18 @@ function useSuperagentRuntime({
594
640
  if (!files?.length) {
595
641
  return [];
596
642
  }
643
+ const writtenPaths = [];
597
644
  for (const file of files) {
598
- await superagentService.writeSandboxFile(agentId, file.name, file.content);
645
+ const safeName = (0, _fileTreeUtils.sanitizeSandboxFilePath)(file.name) || 'upload';
646
+ // Stage uploads under a dedicated folder so a picked file named like a
647
+ // generated-app file (package.json, README.md, ...) can't overwrite it.
648
+ const safePath = `incoming_files/${safeName}`;
649
+ await superagentService.writeSandboxFile(agentId, safePath, file.content);
650
+ writtenPaths.push(safePath);
599
651
  }
600
652
  await loadFiles(agentId);
601
- return files.map(file => ({
602
- path: file.name
653
+ return writtenPaths.map(path => ({
654
+ path
603
655
  }));
604
656
  } catch (error) {
605
657
  if (nativeAdapters.isAttachmentPickerCancel?.(error)) {
@@ -629,19 +681,31 @@ function useSuperagentRuntime({
629
681
  setConnectingChannelId('whatsapp');
630
682
  try {
631
683
  const token = await resolveRuntimeToken(agentId);
684
+ // Editor gate: the connect redirect only authenticates the app-user token and
685
+ // does not re-check live editor access, so a downgraded viewer could otherwise
686
+ // open it. /whatsapp/status enforces the two-layer editor check and throws
687
+ // (403) for viewers — require it to pass before opening the setup page.
688
+ await superagentService.getWhatsAppStatus(agentId, token);
632
689
  const connectUrl = superagentService.getWhatsAppConnectUrl(agentId, token);
633
- setChannelStatus(current => ({
634
- ...current,
635
- whatsapp: {
636
- ...current.whatsapp,
637
- connectUrl
638
- }
639
- }));
640
- await nativeAdapters.openUrl?.(connectUrl);
690
+ if (activeAgentIdRef.current === agentId) {
691
+ setChannelStatus(current => ({
692
+ ...current,
693
+ whatsapp: {
694
+ ...current.whatsapp,
695
+ connectUrl
696
+ }
697
+ }));
698
+ }
699
+ if (!nativeAdapters.openUrl) {
700
+ // Without a URL opener the setup page never launches; surface an error
701
+ // instead of completing silently (mirrors the connector OAuth flow).
702
+ throw new Error('This app cannot open the WhatsApp setup page. Connect WhatsApp from the web app.');
703
+ }
704
+ await nativeAdapters.openUrl(connectUrl);
641
705
  } catch (error) {
642
706
  showAlert(nativeAdapters, 'WhatsApp setup failed', getErrorMessage(error));
643
707
  } finally {
644
- setConnectingChannelId(null);
708
+ if (activeAgentIdRef.current === agentId) setConnectingChannelId(null);
645
709
  }
646
710
  }, [nativeAdapters, resolveRuntimeToken, superagentService]);
647
711
  const onSetupTelegram = (0, _react.useCallback)(async ({
@@ -652,12 +716,14 @@ function useSuperagentRuntime({
652
716
  try {
653
717
  const runtimeToken = await resolveRuntimeToken(agentId);
654
718
  const telegram = await superagentService.setupTelegram(agentId, runtimeToken, token);
655
- setChannelStatus(current => ({
656
- ...current,
657
- telegram
658
- }));
719
+ if (activeAgentIdRef.current === agentId) {
720
+ setChannelStatus(current => ({
721
+ ...current,
722
+ telegram
723
+ }));
724
+ }
659
725
  } finally {
660
- setConnectingChannelId(null);
726
+ if (activeAgentIdRef.current === agentId) setConnectingChannelId(null);
661
727
  }
662
728
  }, [resolveRuntimeToken, superagentService]);
663
729
  const onDisconnectTelegram = (0, _react.useCallback)(async ({
@@ -676,16 +742,18 @@ function useSuperagentRuntime({
676
742
  try {
677
743
  const token = await resolveRuntimeToken(agentId);
678
744
  await superagentService.disconnectTelegram(agentId, token);
679
- setChannelStatus(current => ({
680
- ...current,
681
- telegram: {
682
- connected: false
683
- }
684
- }));
745
+ if (activeAgentIdRef.current === agentId) {
746
+ setChannelStatus(current => ({
747
+ ...current,
748
+ telegram: {
749
+ connected: false
750
+ }
751
+ }));
752
+ }
685
753
  } catch (error) {
686
754
  showAlert(nativeAdapters, 'Telegram disconnect failed', getErrorMessage(error));
687
755
  } finally {
688
- setConnectingChannelId(null);
756
+ if (activeAgentIdRef.current === agentId) setConnectingChannelId(null);
689
757
  }
690
758
  }, [nativeAdapters, resolveRuntimeToken, superagentService]);
691
759
  const onGenerateLineCode = (0, _react.useCallback)(async ({
@@ -695,18 +763,20 @@ function useSuperagentRuntime({
695
763
  try {
696
764
  const token = await resolveRuntimeToken(agentId);
697
765
  const activation = await superagentService.generateLineCode(agentId, token);
698
- setChannelStatus(current => ({
699
- ...current,
700
- line: {
701
- ...current.line,
702
- activation,
703
- connected: false
704
- }
705
- }));
766
+ if (activeAgentIdRef.current === agentId) {
767
+ setChannelStatus(current => ({
768
+ ...current,
769
+ line: {
770
+ ...current.line,
771
+ activation,
772
+ connected: false
773
+ }
774
+ }));
775
+ }
706
776
  } catch (error) {
707
777
  showAlert(nativeAdapters, 'LINE setup failed', getErrorMessage(error));
708
778
  } finally {
709
- setConnectingChannelId(null);
779
+ if (activeAgentIdRef.current === agentId) setConnectingChannelId(null);
710
780
  }
711
781
  }, [nativeAdapters, resolveRuntimeToken, superagentService]);
712
782
  const onGenerateIMessageCode = (0, _react.useCallback)(async ({
@@ -716,20 +786,22 @@ function useSuperagentRuntime({
716
786
  try {
717
787
  const token = await resolveRuntimeToken(agentId);
718
788
  const activation = await superagentService.generateIMessageCode(agentId, token);
719
- setChannelStatus(current => ({
720
- ...current,
721
- imessage: {
722
- ...current.imessage,
723
- activation,
724
- connected: current.imessage?.connected ?? false
725
- }
726
- }));
789
+ if (activeAgentIdRef.current === agentId) {
790
+ setChannelStatus(current => ({
791
+ ...current,
792
+ imessage: {
793
+ ...current.imessage,
794
+ activation,
795
+ connected: current.imessage?.connected ?? false
796
+ }
797
+ }));
798
+ }
727
799
  return activation;
728
800
  } catch (error) {
729
801
  showAlert(nativeAdapters, 'iMessage setup failed', getErrorMessage(error));
730
802
  throw error;
731
803
  } finally {
732
- setConnectingChannelId(null);
804
+ if (activeAgentIdRef.current === agentId) setConnectingChannelId(null);
733
805
  }
734
806
  }, [nativeAdapters, resolveRuntimeToken, superagentService]);
735
807
  const onDisconnectIMessage = (0, _react.useCallback)(async ({
@@ -748,14 +820,16 @@ function useSuperagentRuntime({
748
820
  try {
749
821
  const token = await resolveRuntimeToken(agentId);
750
822
  const imessage = await superagentService.disconnectIMessage(agentId, token);
751
- setChannelStatus(current => ({
752
- ...current,
753
- imessage
754
- }));
823
+ if (activeAgentIdRef.current === agentId) {
824
+ setChannelStatus(current => ({
825
+ ...current,
826
+ imessage
827
+ }));
828
+ }
755
829
  } catch (error) {
756
830
  showAlert(nativeAdapters, 'iMessage disconnect failed', getErrorMessage(error));
757
831
  } finally {
758
- setConnectingChannelId(null);
832
+ if (activeAgentIdRef.current === agentId) setConnectingChannelId(null);
759
833
  }
760
834
  }, [nativeAdapters, resolveRuntimeToken, superagentService]);
761
835
  const onOpenIMessage = (0, _react.useCallback)(async ({
@@ -763,7 +837,10 @@ function useSuperagentRuntime({
763
837
  phoneNumber
764
838
  }) => {
765
839
  try {
766
- await nativeAdapters.openUrl?.(buildIMessageUrl(phoneNumber, code));
840
+ if (!nativeAdapters.openUrl) {
841
+ throw new Error('This app cannot open Messages. Use the web app to share the iMessage code.');
842
+ }
843
+ await nativeAdapters.openUrl(buildIMessageUrl(phoneNumber, code));
767
844
  } catch (error) {
768
845
  showAlert(nativeAdapters, 'iMessage link unavailable', getErrorMessage(error));
769
846
  }
@@ -782,7 +859,11 @@ function useSuperagentRuntime({
782
859
  addFriendUrl,
783
860
  code
784
861
  }) => {
785
- await nativeAdapters.share?.({
862
+ if (!nativeAdapters.share) {
863
+ showAlert(nativeAdapters, 'Sharing unavailable', 'This app cannot share the activation code. Copy it manually instead.');
864
+ return;
865
+ }
866
+ await nativeAdapters.share({
786
867
  message: `LINE activation code: ${code}\n${addFriendUrl}`,
787
868
  title: 'LINE activation code',
788
869
  url: addFriendUrl
@@ -792,7 +873,11 @@ function useSuperagentRuntime({
792
873
  code,
793
874
  phoneNumber
794
875
  }) => {
795
- await nativeAdapters.share?.({
876
+ if (!nativeAdapters.share) {
877
+ showAlert(nativeAdapters, 'Sharing unavailable', 'This app cannot share the activation code. Copy it manually instead.');
878
+ return;
879
+ }
880
+ await nativeAdapters.share({
796
881
  message: `Text ${code} to ${phoneNumber} to connect this Superagent on iMessage.`,
797
882
  title: 'iMessage activation code',
798
883
  url: buildIMessageUrl(phoneNumber, code)
@@ -828,22 +913,35 @@ function useSuperagentRuntime({
828
913
  connectorFlowRef.current = null;
829
914
  setConnectingConnectorId(null);
830
915
  await loadConnectors(agentId);
831
- return true;
916
+ // Return the connection_id (string) so the connector tool-approval can
917
+ // submit it; fall back to `true` when the backend omits it.
918
+ return connection.connection_id ?? true;
832
919
  }
833
920
  if (!connection.redirect_url || !connection.connection_id) {
834
921
  throw new Error('The backend did not return an authorization URL for this connector.');
835
922
  }
836
- await nativeAdapters.openUrl?.(connection.redirect_url);
837
- await waitForConnectorAuthorization(superagentService, agentId, connectorId, connection.connection_id, flow);
838
- if (!flow.cancelled) {
923
+ if (!nativeAdapters.openUrl) {
924
+ // Without a URL opener the browser never launches, so polling would just
925
+ // time out after ~2 minutes. Fail immediately with an actionable error.
926
+ throw new Error('This app cannot open the authorization page. Connect this integration from the web app.');
927
+ }
928
+ await nativeAdapters.openUrl(connection.redirect_url);
929
+ const connected = await waitForConnectorAuthorization(superagentService, agentId, connectorId, connection.connection_id, flow);
930
+
931
+ // Only clear shared state if this flow is still the active one — a newer
932
+ // connect may have superseded it (and owns connectorFlowRef now).
933
+ if (connectorFlowRef.current === flow) {
839
934
  connectorFlowRef.current = null;
840
935
  setConnectingConnectorId(null);
936
+ }
937
+ if (connected) {
841
938
  await loadConnectors(agentId);
842
- return true;
843
939
  }
844
- return false;
940
+ // On success return the connection_id so the connector tool-approval can
941
+ // submit it for backend verification; `false` on failure.
942
+ return connected ? connection.connection_id : false;
845
943
  } catch (error) {
846
- if (!flow.cancelled) {
944
+ if (connectorFlowRef.current === flow) {
847
945
  connectorFlowRef.current = null;
848
946
  setConnectingConnectorId(null);
849
947
  showAlert(nativeAdapters, 'Connector failed', getErrorMessage(error));
@@ -905,6 +1003,7 @@ function useSuperagentRuntime({
905
1003
  }
906
1004
  }, [loadConnectors, nativeAdapters, superagentService]);
907
1005
  return {
1006
+ activeAgentId,
908
1007
  agents,
909
1008
  apiClient,
910
1009
  availableConnectors,
@@ -916,7 +1015,12 @@ function useSuperagentRuntime({
916
1015
  connectingConnectorId,
917
1016
  connectedConnectors,
918
1017
  currentRoute,
1018
+ // Also expose as initialRoute, the prop SuperagentHomeScreen actually consumes,
1019
+ // so spreading the runtime opens on the deep-linked agent (initialAgentId)
1020
+ // instead of defaulting to the home route.
1021
+ initialRoute: currentRoute,
919
1022
  currentUserAvatarUrl: config.currentUserAvatarUrl,
1023
+ currentUserId: config.currentUserId,
920
1024
  currentUserName: config.currentUserName,
921
1025
  fileLoadError,
922
1026
  fileLoadFailed,
@@ -969,7 +1073,10 @@ function useSuperagentRuntime({
969
1073
  onShareAgentLink,
970
1074
  onShareIMessageCode,
971
1075
  onShareLineCode,
972
- onStartLiveVoice,
1076
+ // Only expose Live Voice when the native audio adapter is actually installed;
1077
+ // otherwise the composer would prefer it and fail on tap ("audio callbacks are
1078
+ // not installed") instead of falling back to onStartVoiceInput.
1079
+ onStartLiveVoice: nativeAdapters.liveVoiceAudio?.startAudioCapture ? onStartLiveVoice : undefined,
973
1080
  onSetupTelegram,
974
1081
  onToggleAutomation,
975
1082
  onUpdateAgentModel,
@@ -980,22 +1087,27 @@ function useSuperagentRuntime({
980
1087
  };
981
1088
  }
982
1089
  async function waitForConnectorAuthorization(superagentService, agentId, connectorId, connectionId, flow) {
1090
+ // The connection status (scoped to this flow's connectionId) is the
1091
+ // authoritative source of truth — not a global callback flag, which can't be
1092
+ // attributed to a specific flow. Returns whether the connector ended up ACTIVE.
1093
+ const isActive = async () => (await superagentService.getConnectorConnectionStatus(agentId, connectorId, connectionId)) === 'ACTIVE';
983
1094
  const maxAttempts = 40;
984
1095
  for (let attempt = 0; attempt < maxAttempts; attempt++) {
985
1096
  if (flow.cancelled) {
986
- return;
1097
+ // Cancelled — but OAuth may have already completed; confirm with the
1098
+ // authoritative status before reporting not-connected.
1099
+ return isActive().catch(() => false);
987
1100
  }
988
1101
  await delay(3000);
989
- if (flow.cancelled) {
990
- return;
991
- }
992
1102
  const status = await superagentService.getConnectorConnectionStatus(agentId, connectorId, connectionId);
993
1103
  if (status === 'ACTIVE') {
994
- return;
1104
+ return true;
995
1105
  }
996
1106
  if (status === 'FAILED') {
997
1107
  throw new Error('OAuth connection failed.');
998
1108
  }
1109
+ // If the user cancelled during the delay, the next iteration's top-of-loop
1110
+ // check re-confirms via the authoritative status before returning.
999
1111
  }
1000
1112
  throw new Error('Connection timed out after 2 minutes.');
1001
1113
  }
@@ -1004,20 +1116,48 @@ async function openAllowedExternalUrl(nativeAdapters, url, allowedHosts, fallbac
1004
1116
  showAlert(nativeAdapters, fallbackMessage, 'The backend returned a channel link that cannot be opened safely.');
1005
1117
  return;
1006
1118
  }
1119
+ if (!nativeAdapters.openUrl) {
1120
+ // No URL opener: surface it instead of passing the host check and then
1121
+ // silently doing nothing.
1122
+ showAlert(nativeAdapters, fallbackMessage, 'This app cannot open external links. Use the web app instead.');
1123
+ return;
1124
+ }
1007
1125
  try {
1008
- await nativeAdapters.openUrl?.(url);
1126
+ await nativeAdapters.openUrl(url);
1009
1127
  } catch (error) {
1010
1128
  showAlert(nativeAdapters, fallbackMessage, getErrorMessage(error));
1011
1129
  }
1012
1130
  }
1013
1131
  function showAlert(nativeAdapters, title, message) {
1014
- nativeAdapters.alert?.(title, message);
1132
+ if (nativeAdapters.alert) {
1133
+ nativeAdapters.alert(title, message);
1134
+ return;
1135
+ }
1136
+ // No host alert adapter — fall back to React Native's Alert (as confirmAction
1137
+ // does) so connector/channel/file/model errors aren't silently swallowed.
1138
+ _reactNative.Alert.alert(title, message);
1015
1139
  }
1016
1140
  async function confirmAction(nativeAdapters, input) {
1017
- if (!nativeAdapters.confirm) {
1018
- return true;
1141
+ if (nativeAdapters.confirm) {
1142
+ return nativeAdapters.confirm(input);
1019
1143
  }
1020
- return nativeAdapters.confirm(input);
1144
+
1145
+ // No host confirm adapter — fall back to a native prompt so destructive actions
1146
+ // still require explicit confirmation instead of silently proceeding.
1147
+ return new Promise(resolve => {
1148
+ _reactNative.Alert.alert(input.title, input.message, [{
1149
+ onPress: () => resolve(false),
1150
+ style: 'cancel',
1151
+ text: 'Cancel'
1152
+ }, {
1153
+ onPress: () => resolve(true),
1154
+ style: input.destructive ? 'destructive' : 'default',
1155
+ text: input.confirmText ?? 'Confirm'
1156
+ }], {
1157
+ cancelable: true,
1158
+ onDismiss: () => resolve(false)
1159
+ });
1160
+ });
1021
1161
  }
1022
1162
  function buildWebUrl(baseUrl, path) {
1023
1163
  return `${normalizeBaseUrl(baseUrl)}${path.startsWith('/') ? path : `/${path}`}`;