@agent-native/core 0.15.13 → 0.16.0

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 (411) hide show
  1. package/README.md +37 -0
  2. package/dist/agent/app-model-defaults.d.ts +37 -0
  3. package/dist/agent/app-model-defaults.d.ts.map +1 -0
  4. package/dist/agent/app-model-defaults.js +136 -0
  5. package/dist/agent/app-model-defaults.js.map +1 -0
  6. package/dist/agent/engine/registry.d.ts +12 -7
  7. package/dist/agent/engine/registry.d.ts.map +1 -1
  8. package/dist/agent/engine/registry.js +28 -8
  9. package/dist/agent/engine/registry.js.map +1 -1
  10. package/dist/agent/production-agent.d.ts +2 -0
  11. package/dist/agent/production-agent.d.ts.map +1 -1
  12. package/dist/agent/production-agent.js +3 -1
  13. package/dist/agent/production-agent.js.map +1 -1
  14. package/dist/browser-sessions/actions.d.ts +7 -0
  15. package/dist/browser-sessions/actions.d.ts.map +1 -0
  16. package/dist/browser-sessions/actions.js +223 -0
  17. package/dist/browser-sessions/actions.js.map +1 -0
  18. package/dist/browser-sessions/routes.d.ts +7 -0
  19. package/dist/browser-sessions/routes.d.ts.map +1 -0
  20. package/dist/browser-sessions/routes.js +159 -0
  21. package/dist/browser-sessions/routes.js.map +1 -0
  22. package/dist/browser-sessions/store.d.ts +33 -0
  23. package/dist/browser-sessions/store.d.ts.map +1 -0
  24. package/dist/browser-sessions/store.js +506 -0
  25. package/dist/browser-sessions/store.js.map +1 -0
  26. package/dist/browser-sessions/types.d.ts +68 -0
  27. package/dist/browser-sessions/types.d.ts.map +1 -0
  28. package/dist/browser-sessions/types.js +2 -0
  29. package/dist/browser-sessions/types.js.map +1 -0
  30. package/dist/cli/code-agent-commands.d.ts +36 -0
  31. package/dist/cli/code-agent-commands.d.ts.map +1 -0
  32. package/dist/cli/code-agent-commands.js +192 -0
  33. package/dist/cli/code-agent-commands.js.map +1 -0
  34. package/dist/cli/code-agent-connector.d.ts +17 -0
  35. package/dist/cli/code-agent-connector.d.ts.map +1 -0
  36. package/dist/cli/code-agent-connector.js +724 -0
  37. package/dist/cli/code-agent-connector.js.map +1 -0
  38. package/dist/cli/code-agent-executor.d.ts +31 -0
  39. package/dist/cli/code-agent-executor.d.ts.map +1 -0
  40. package/dist/cli/code-agent-executor.js +921 -0
  41. package/dist/cli/code-agent-executor.js.map +1 -0
  42. package/dist/cli/code-agent-runs.d.ts +102 -0
  43. package/dist/cli/code-agent-runs.d.ts.map +1 -0
  44. package/dist/cli/code-agent-runs.js +277 -0
  45. package/dist/cli/code-agent-runs.js.map +1 -0
  46. package/dist/cli/code.d.ts +66 -0
  47. package/dist/cli/code.d.ts.map +1 -0
  48. package/dist/cli/code.js +1306 -0
  49. package/dist/cli/code.js.map +1 -0
  50. package/dist/cli/create.d.ts +2 -1
  51. package/dist/cli/create.d.ts.map +1 -1
  52. package/dist/cli/create.js +11 -1
  53. package/dist/cli/create.js.map +1 -1
  54. package/dist/cli/index.js +26 -1
  55. package/dist/cli/index.js.map +1 -1
  56. package/dist/cli/migrate.d.ts +27 -0
  57. package/dist/cli/migrate.d.ts.map +1 -1
  58. package/dist/cli/migrate.js +1328 -20
  59. package/dist/cli/migrate.js.map +1 -1
  60. package/dist/cli/templates-meta.d.ts.map +1 -1
  61. package/dist/cli/templates-meta.js +26 -2
  62. package/dist/cli/templates-meta.js.map +1 -1
  63. package/dist/cli/workspacify.d.ts +2 -0
  64. package/dist/cli/workspacify.d.ts.map +1 -1
  65. package/dist/cli/workspacify.js +2 -1
  66. package/dist/cli/workspacify.js.map +1 -1
  67. package/dist/client/AgentNative.d.ts +32 -0
  68. package/dist/client/AgentNative.d.ts.map +1 -0
  69. package/dist/client/AgentNative.js +79 -0
  70. package/dist/client/AgentNative.js.map +1 -0
  71. package/dist/client/AgentNativeEmbedded.d.ts +47 -0
  72. package/dist/client/AgentNativeEmbedded.d.ts.map +1 -0
  73. package/dist/client/AgentNativeEmbedded.js +148 -0
  74. package/dist/client/AgentNativeEmbedded.js.map +1 -0
  75. package/dist/client/AgentNativeFrame.d.ts +25 -0
  76. package/dist/client/AgentNativeFrame.d.ts.map +1 -0
  77. package/dist/client/AgentNativeFrame.js +68 -0
  78. package/dist/client/AgentNativeFrame.js.map +1 -0
  79. package/dist/client/AgentPanel.d.ts +19 -2
  80. package/dist/client/AgentPanel.d.ts.map +1 -1
  81. package/dist/client/AgentPanel.js +15 -4
  82. package/dist/client/AgentPanel.js.map +1 -1
  83. package/dist/client/AssistantChat.d.ts +1 -1
  84. package/dist/client/AssistantChat.d.ts.map +1 -1
  85. package/dist/client/AssistantChat.js +79 -48
  86. package/dist/client/AssistantChat.js.map +1 -1
  87. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  88. package/dist/client/MultiTabAssistantChat.js +2 -1
  89. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  90. package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -1
  91. package/dist/client/NewWorkspaceAppFlow.js +3 -2
  92. package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
  93. package/dist/client/browser-session-bridge.d.ts +44 -0
  94. package/dist/client/browser-session-bridge.d.ts.map +1 -0
  95. package/dist/client/browser-session-bridge.js +339 -0
  96. package/dist/client/browser-session-bridge.js.map +1 -0
  97. package/dist/client/client-action.d.ts +7 -0
  98. package/dist/client/client-action.d.ts.map +1 -0
  99. package/dist/client/client-action.js +4 -0
  100. package/dist/client/client-action.js.map +1 -0
  101. package/dist/client/components/ui/tooltip.d.ts.map +1 -1
  102. package/dist/client/components/ui/tooltip.js +1 -1
  103. package/dist/client/components/ui/tooltip.js.map +1 -1
  104. package/dist/client/composer/AgentComposerFrame.d.ts +17 -0
  105. package/dist/client/composer/AgentComposerFrame.d.ts.map +1 -0
  106. package/dist/client/composer/AgentComposerFrame.js +14 -0
  107. package/dist/client/composer/AgentComposerFrame.js.map +1 -0
  108. package/dist/client/composer/MentionPopover.d.ts.map +1 -1
  109. package/dist/client/composer/MentionPopover.js +2 -2
  110. package/dist/client/composer/MentionPopover.js.map +1 -1
  111. package/dist/client/composer/PromptComposer.d.ts +35 -2
  112. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  113. package/dist/client/composer/PromptComposer.js +31 -17
  114. package/dist/client/composer/PromptComposer.js.map +1 -1
  115. package/dist/client/composer/TiptapComposer.d.ts +20 -2
  116. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  117. package/dist/client/composer/TiptapComposer.js +112 -22
  118. package/dist/client/composer/TiptapComposer.js.map +1 -1
  119. package/dist/client/composer/index.d.ts +3 -2
  120. package/dist/client/composer/index.d.ts.map +1 -1
  121. package/dist/client/composer/index.js +1 -0
  122. package/dist/client/composer/index.js.map +1 -1
  123. package/dist/client/composer/types.d.ts +1 -0
  124. package/dist/client/composer/types.d.ts.map +1 -1
  125. package/dist/client/composer/types.js.map +1 -1
  126. package/dist/client/extensions/AgentNativeExtensionFrame.d.ts +58 -0
  127. package/dist/client/extensions/AgentNativeExtensionFrame.d.ts.map +1 -0
  128. package/dist/client/extensions/AgentNativeExtensionFrame.e2e-host.d.ts +2 -0
  129. package/dist/client/extensions/AgentNativeExtensionFrame.e2e-host.d.ts.map +1 -0
  130. package/dist/client/extensions/AgentNativeExtensionFrame.e2e-host.js +110 -0
  131. package/dist/client/extensions/AgentNativeExtensionFrame.e2e-host.js.map +1 -0
  132. package/dist/client/extensions/AgentNativeExtensionFrame.js +354 -0
  133. package/dist/client/extensions/AgentNativeExtensionFrame.js.map +1 -0
  134. package/dist/client/extensions/AgentNativeExtensionFrame.spec.d.ts +2 -0
  135. package/dist/client/extensions/AgentNativeExtensionFrame.spec.d.ts.map +1 -0
  136. package/dist/client/extensions/AgentNativeExtensionFrame.spec.js +68 -0
  137. package/dist/client/extensions/AgentNativeExtensionFrame.spec.js.map +1 -0
  138. package/dist/client/extensions/agent-native-extension-runtime.d.ts +69 -0
  139. package/dist/client/extensions/agent-native-extension-runtime.d.ts.map +1 -0
  140. package/dist/client/extensions/agent-native-extension-runtime.js +348 -0
  141. package/dist/client/extensions/agent-native-extension-runtime.js.map +1 -0
  142. package/dist/client/extensions/index.d.ts +2 -0
  143. package/dist/client/extensions/index.d.ts.map +1 -1
  144. package/dist/client/extensions/index.js +2 -0
  145. package/dist/client/extensions/index.js.map +1 -1
  146. package/dist/client/extensions/portable-extension.d.ts +86 -0
  147. package/dist/client/extensions/portable-extension.d.ts.map +1 -0
  148. package/dist/client/extensions/portable-extension.js +480 -0
  149. package/dist/client/extensions/portable-extension.js.map +1 -0
  150. package/dist/client/host-bridge.d.ts +266 -0
  151. package/dist/client/host-bridge.d.ts.map +1 -0
  152. package/dist/client/host-bridge.js +745 -0
  153. package/dist/client/host-bridge.js.map +1 -0
  154. package/dist/client/host-tools.d.ts +40 -0
  155. package/dist/client/host-tools.d.ts.map +1 -0
  156. package/dist/client/host-tools.js +94 -0
  157. package/dist/client/host-tools.js.map +1 -0
  158. package/dist/client/index.d.ts +13 -2
  159. package/dist/client/index.d.ts.map +1 -1
  160. package/dist/client/index.js +11 -2
  161. package/dist/client/index.js.map +1 -1
  162. package/dist/client/resources/BuiltinCapabilityDetail.d.ts +10 -0
  163. package/dist/client/resources/BuiltinCapabilityDetail.d.ts.map +1 -0
  164. package/dist/client/resources/BuiltinCapabilityDetail.js +51 -0
  165. package/dist/client/resources/BuiltinCapabilityDetail.js.map +1 -0
  166. package/dist/client/resources/ResourceEditor.d.ts +3 -1
  167. package/dist/client/resources/ResourceEditor.d.ts.map +1 -1
  168. package/dist/client/resources/ResourceEditor.js +40 -17
  169. package/dist/client/resources/ResourceEditor.js.map +1 -1
  170. package/dist/client/resources/ResourceTree.d.ts.map +1 -1
  171. package/dist/client/resources/ResourceTree.js +23 -2
  172. package/dist/client/resources/ResourceTree.js.map +1 -1
  173. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  174. package/dist/client/resources/ResourcesPanel.js +77 -17
  175. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  176. package/dist/client/resources/index.d.ts +1 -0
  177. package/dist/client/resources/index.d.ts.map +1 -1
  178. package/dist/client/resources/index.js +1 -0
  179. package/dist/client/resources/index.js.map +1 -1
  180. package/dist/client/resources/use-builtin-capabilities.d.ts +62 -0
  181. package/dist/client/resources/use-builtin-capabilities.d.ts.map +1 -0
  182. package/dist/client/resources/use-builtin-capabilities.js +54 -0
  183. package/dist/client/resources/use-builtin-capabilities.js.map +1 -0
  184. package/dist/client/resources/use-resources.d.ts +30 -2
  185. package/dist/client/resources/use-resources.d.ts.map +1 -1
  186. package/dist/client/resources/use-resources.js +42 -1
  187. package/dist/client/resources/use-resources.js.map +1 -1
  188. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  189. package/dist/client/settings/SettingsPanel.js +151 -2
  190. package/dist/client/settings/SettingsPanel.js.map +1 -1
  191. package/dist/client/use-chat-models.d.ts.map +1 -1
  192. package/dist/client/use-chat-models.js +20 -0
  193. package/dist/client/use-chat-models.js.map +1 -1
  194. package/dist/client/use-chat-threads.d.ts.map +1 -1
  195. package/dist/client/use-chat-threads.js +46 -2
  196. package/dist/client/use-chat-threads.js.map +1 -1
  197. package/dist/client/use-chat-threads.spec.js +77 -0
  198. package/dist/client/use-chat-threads.spec.js.map +1 -1
  199. package/dist/code-agents/index.d.ts +4 -0
  200. package/dist/code-agents/index.d.ts.map +1 -0
  201. package/dist/code-agents/index.js +4 -0
  202. package/dist/code-agents/index.js.map +1 -0
  203. package/dist/connections/catalog.d.ts +134 -0
  204. package/dist/connections/catalog.d.ts.map +1 -0
  205. package/dist/connections/catalog.js +180 -0
  206. package/dist/connections/catalog.js.map +1 -0
  207. package/dist/connections/index.d.ts +2 -0
  208. package/dist/connections/index.d.ts.map +1 -0
  209. package/dist/connections/index.js +2 -0
  210. package/dist/connections/index.js.map +1 -0
  211. package/dist/extensions/change-marker.d.ts +10 -0
  212. package/dist/extensions/change-marker.d.ts.map +1 -0
  213. package/dist/extensions/change-marker.js +42 -0
  214. package/dist/extensions/change-marker.js.map +1 -0
  215. package/dist/extensions/routes.d.ts.map +1 -1
  216. package/dist/extensions/routes.js +1 -7
  217. package/dist/extensions/routes.js.map +1 -1
  218. package/dist/extensions/schema.d.ts +1 -0
  219. package/dist/extensions/schema.d.ts.map +1 -1
  220. package/dist/extensions/schema.js +1 -0
  221. package/dist/extensions/schema.js.map +1 -1
  222. package/dist/extensions/slots/routes.js +1 -1
  223. package/dist/extensions/slots/routes.js.map +1 -1
  224. package/dist/extensions/store.d.ts +3 -0
  225. package/dist/extensions/store.d.ts.map +1 -1
  226. package/dist/extensions/store.js +112 -4
  227. package/dist/extensions/store.js.map +1 -1
  228. package/dist/index.d.ts +4 -1
  229. package/dist/index.d.ts.map +1 -1
  230. package/dist/index.js +6 -1
  231. package/dist/index.js.map +1 -1
  232. package/dist/integrations/adapters/telegram.d.ts.map +1 -1
  233. package/dist/integrations/adapters/telegram.js +1 -0
  234. package/dist/integrations/adapters/telegram.js.map +1 -1
  235. package/dist/integrations/index.d.ts +5 -1
  236. package/dist/integrations/index.d.ts.map +1 -1
  237. package/dist/integrations/index.js +4 -1
  238. package/dist/integrations/index.js.map +1 -1
  239. package/dist/integrations/plugin.d.ts +8 -0
  240. package/dist/integrations/plugin.d.ts.map +1 -1
  241. package/dist/integrations/plugin.js +760 -32
  242. package/dist/integrations/plugin.js.map +1 -1
  243. package/dist/integrations/remote-commands-store.d.ts +36 -0
  244. package/dist/integrations/remote-commands-store.d.ts.map +1 -0
  245. package/dist/integrations/remote-commands-store.js +273 -0
  246. package/dist/integrations/remote-commands-store.js.map +1 -0
  247. package/dist/integrations/remote-devices-store.d.ts +43 -0
  248. package/dist/integrations/remote-devices-store.d.ts.map +1 -0
  249. package/dist/integrations/remote-devices-store.js +315 -0
  250. package/dist/integrations/remote-devices-store.js.map +1 -0
  251. package/dist/integrations/remote-push-store.d.ts +37 -0
  252. package/dist/integrations/remote-push-store.d.ts.map +1 -0
  253. package/dist/integrations/remote-push-store.js +299 -0
  254. package/dist/integrations/remote-push-store.js.map +1 -0
  255. package/dist/integrations/remote-retry-job.d.ts +7 -0
  256. package/dist/integrations/remote-retry-job.d.ts.map +1 -0
  257. package/dist/integrations/remote-retry-job.js +45 -0
  258. package/dist/integrations/remote-retry-job.js.map +1 -0
  259. package/dist/integrations/remote-run-events-store.d.ts +18 -0
  260. package/dist/integrations/remote-run-events-store.d.ts.map +1 -0
  261. package/dist/integrations/remote-run-events-store.js +82 -0
  262. package/dist/integrations/remote-run-events-store.js.map +1 -0
  263. package/dist/integrations/remote-types.d.ts +101 -0
  264. package/dist/integrations/remote-types.d.ts.map +1 -0
  265. package/dist/integrations/remote-types.js +2 -0
  266. package/dist/integrations/remote-types.js.map +1 -0
  267. package/dist/integrations/webhook-handler.d.ts +2 -0
  268. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  269. package/dist/integrations/webhook-handler.js +4 -1
  270. package/dist/integrations/webhook-handler.js.map +1 -1
  271. package/dist/jobs/scheduler.d.ts +4 -2
  272. package/dist/jobs/scheduler.d.ts.map +1 -1
  273. package/dist/jobs/scheduler.js +9 -3
  274. package/dist/jobs/scheduler.js.map +1 -1
  275. package/dist/mcp-client/builtin-capabilities.d.ts +20 -0
  276. package/dist/mcp-client/builtin-capabilities.d.ts.map +1 -0
  277. package/dist/mcp-client/builtin-capabilities.js +75 -0
  278. package/dist/mcp-client/builtin-capabilities.js.map +1 -0
  279. package/dist/mcp-client/builtin-store.d.ts +10 -0
  280. package/dist/mcp-client/builtin-store.d.ts.map +1 -0
  281. package/dist/mcp-client/builtin-store.js +55 -0
  282. package/dist/mcp-client/builtin-store.js.map +1 -0
  283. package/dist/mcp-client/index.d.ts +3 -1
  284. package/dist/mcp-client/index.d.ts.map +1 -1
  285. package/dist/mcp-client/index.js +3 -1
  286. package/dist/mcp-client/index.js.map +1 -1
  287. package/dist/mcp-client/routes.d.ts +28 -0
  288. package/dist/mcp-client/routes.d.ts.map +1 -1
  289. package/dist/mcp-client/routes.js +195 -1
  290. package/dist/mcp-client/routes.js.map +1 -1
  291. package/dist/org/context.d.ts.map +1 -1
  292. package/dist/org/context.js +34 -0
  293. package/dist/org/context.js.map +1 -1
  294. package/dist/resources/handlers.d.ts +4 -0
  295. package/dist/resources/handlers.d.ts.map +1 -1
  296. package/dist/resources/handlers.js +46 -7
  297. package/dist/resources/handlers.js.map +1 -1
  298. package/dist/resources/script-helpers.d.ts +8 -1
  299. package/dist/resources/script-helpers.d.ts.map +1 -1
  300. package/dist/resources/script-helpers.js +18 -8
  301. package/dist/resources/script-helpers.js.map +1 -1
  302. package/dist/resources/store.d.ts +19 -0
  303. package/dist/resources/store.d.ts.map +1 -1
  304. package/dist/resources/store.js +86 -3
  305. package/dist/resources/store.js.map +1 -1
  306. package/dist/scripts/agent-engines/list-agent-engines.d.ts +1 -1
  307. package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -1
  308. package/dist/scripts/agent-engines/list-agent-engines.js +18 -7
  309. package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -1
  310. package/dist/scripts/agent-engines/manage-agent-engine.d.ts.map +1 -1
  311. package/dist/scripts/agent-engines/manage-agent-engine.js +100 -7
  312. package/dist/scripts/agent-engines/manage-agent-engine.js.map +1 -1
  313. package/dist/scripts/resources/delete.d.ts.map +1 -1
  314. package/dist/scripts/resources/delete.js +4 -1
  315. package/dist/scripts/resources/delete.js.map +1 -1
  316. package/dist/scripts/resources/effective.d.ts +11 -0
  317. package/dist/scripts/resources/effective.d.ts.map +1 -0
  318. package/dist/scripts/resources/effective.js +54 -0
  319. package/dist/scripts/resources/effective.js.map +1 -0
  320. package/dist/scripts/resources/index.d.ts.map +1 -1
  321. package/dist/scripts/resources/index.js +1 -0
  322. package/dist/scripts/resources/index.js.map +1 -1
  323. package/dist/scripts/resources/list.d.ts +1 -1
  324. package/dist/scripts/resources/list.d.ts.map +1 -1
  325. package/dist/scripts/resources/list.js +17 -5
  326. package/dist/scripts/resources/list.js.map +1 -1
  327. package/dist/scripts/resources/read.d.ts +1 -1
  328. package/dist/scripts/resources/read.d.ts.map +1 -1
  329. package/dist/scripts/resources/read.js +20 -5
  330. package/dist/scripts/resources/read.js.map +1 -1
  331. package/dist/scripts/resources/write.d.ts.map +1 -1
  332. package/dist/scripts/resources/write.js +4 -1
  333. package/dist/scripts/resources/write.js.map +1 -1
  334. package/dist/scripts/runner.d.ts +11 -1
  335. package/dist/scripts/runner.d.ts.map +1 -1
  336. package/dist/scripts/runner.js +75 -27
  337. package/dist/scripts/runner.js.map +1 -1
  338. package/dist/server/action-discovery.d.ts.map +1 -1
  339. package/dist/server/action-discovery.js +5 -0
  340. package/dist/server/action-discovery.js.map +1 -1
  341. package/dist/server/agent-chat-plugin.d.ts +24 -0
  342. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  343. package/dist/server/agent-chat-plugin.js +608 -54
  344. package/dist/server/agent-chat-plugin.js.map +1 -1
  345. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  346. package/dist/server/core-routes-plugin.js +2 -0
  347. package/dist/server/core-routes-plugin.js.map +1 -1
  348. package/dist/server/embedded.d.ts +72 -0
  349. package/dist/server/embedded.d.ts.map +1 -0
  350. package/dist/server/embedded.js +119 -0
  351. package/dist/server/embedded.js.map +1 -0
  352. package/dist/server/index.d.ts +8 -1
  353. package/dist/server/index.d.ts.map +1 -1
  354. package/dist/server/index.js +7 -1
  355. package/dist/server/index.js.map +1 -1
  356. package/dist/server/poll.d.ts.map +1 -1
  357. package/dist/server/poll.js +184 -13
  358. package/dist/server/poll.js.map +1 -1
  359. package/dist/server/resources-plugin.d.ts.map +1 -1
  360. package/dist/server/resources-plugin.js +11 -2
  361. package/dist/server/resources-plugin.js.map +1 -1
  362. package/dist/sharing/actions/extension-change.d.ts +4 -0
  363. package/dist/sharing/actions/extension-change.d.ts.map +1 -0
  364. package/dist/sharing/actions/extension-change.js +13 -0
  365. package/dist/sharing/actions/extension-change.js.map +1 -0
  366. package/dist/sharing/actions/set-resource-visibility.d.ts.map +1 -1
  367. package/dist/sharing/actions/set-resource-visibility.js +3 -0
  368. package/dist/sharing/actions/set-resource-visibility.js.map +1 -1
  369. package/dist/sharing/actions/share-resource.d.ts.map +1 -1
  370. package/dist/sharing/actions/share-resource.js +4 -0
  371. package/dist/sharing/actions/share-resource.js.map +1 -1
  372. package/dist/sharing/actions/unshare-resource.d.ts.map +1 -1
  373. package/dist/sharing/actions/unshare-resource.js +3 -0
  374. package/dist/sharing/actions/unshare-resource.js.map +1 -1
  375. package/dist/templates/default/AGENTS.md +3 -3
  376. package/dist/templates/workspace-core/AGENTS.md +7 -0
  377. package/dist/templates/workspace-root/AGENTS.md +7 -0
  378. package/dist/templates/workspace-root/README.md +25 -0
  379. package/dist/triggers/dispatcher.d.ts +3 -1
  380. package/dist/triggers/dispatcher.d.ts.map +1 -1
  381. package/dist/triggers/dispatcher.js +9 -3
  382. package/dist/triggers/dispatcher.js.map +1 -1
  383. package/dist/workspace-connections/index.d.ts +2 -0
  384. package/dist/workspace-connections/index.d.ts.map +1 -0
  385. package/dist/workspace-connections/index.js +2 -0
  386. package/dist/workspace-connections/index.js.map +1 -0
  387. package/dist/workspace-connections/store.d.ts +229 -0
  388. package/dist/workspace-connections/store.d.ts.map +1 -0
  389. package/dist/workspace-connections/store.js +938 -0
  390. package/dist/workspace-connections/store.js.map +1 -0
  391. package/docs/content/agent-teams.md +6 -0
  392. package/docs/content/cloneable-saas.md +1 -0
  393. package/docs/content/code-agents-ui.md +261 -0
  394. package/docs/content/dispatch.md +40 -3
  395. package/docs/content/embedding-sdk.md +459 -0
  396. package/docs/content/faq.md +1 -0
  397. package/docs/content/getting-started.md +1 -0
  398. package/docs/content/mcp-clients.md +41 -3
  399. package/docs/content/migration-workbench.md +237 -54
  400. package/docs/content/multi-app-workspace.md +41 -0
  401. package/docs/content/multi-tenancy.md +1 -1
  402. package/docs/content/template-brain.md +418 -0
  403. package/docs/content/template-dispatch.md +30 -0
  404. package/docs/content/workspace-connections.md +509 -0
  405. package/docs/content/workspace-management.md +12 -12
  406. package/docs/content/workspace.md +180 -40
  407. package/package.json +7 -2
  408. package/src/templates/default/AGENTS.md +3 -3
  409. package/src/templates/workspace-core/AGENTS.md +7 -0
  410. package/src/templates/workspace-root/AGENTS.md +7 -0
  411. package/src/templates/workspace-root/README.md +25 -0
@@ -1,4 +1,4 @@
1
- import { defineEventHandler, setResponseStatus, getMethod } from "h3";
1
+ import { defineEventHandler, setResponseStatus, getMethod, getQuery } from "h3";
2
2
  import { createRemoteJWKSet, jwtVerify } from "jose";
3
3
  import { FRAMEWORK_ROUTE_PREFIX } from "../server/core-routes-plugin.js";
4
4
  import { getH3App, markDefaultPluginProvided, } from "../server/framework-request-handler.js";
@@ -16,11 +16,16 @@ import { emailAdapter } from "./adapters/email.js";
16
16
  import { startGoogleDocsPoller, handlePushNotification, } from "./google-docs-poller.js";
17
17
  import { startPendingTasksRetryJob } from "./pending-tasks-retry-job.js";
18
18
  import { processA2AContinuationById, processDueA2AContinuations, } from "./a2a-continuation-processor.js";
19
- import { resourceGetByPath, SHARED_OWNER } from "../resources/store.js";
19
+ import { loadResourcesForPrompt } from "../server/agent-chat-plugin.js";
20
20
  import { getTaskQueueStats } from "./task-queue-stats.js";
21
21
  import { getSession } from "../server/auth.js";
22
22
  import { getOrgContext } from "../org/context.js";
23
23
  import { withConfiguredAppBasePath } from "../server/app-base-path.js";
24
+ import { authenticateRemoteDeviceToken, createRemoteDevice, getRemoteDeviceForOwner, listRemoteDevicesForOwner, revokeRemoteDeviceForOwner, toPublicRemoteDevice, unregisterRemoteDevice, updateRemoteDeviceDetails, } from "./remote-devices-store.js";
25
+ import { claimNextRemoteCommand, enqueueRemoteCommand as enqueueRemoteCommandRow, isRemoteCommandKind, listRemoteCommandsForOwner, updateRemoteCommandResult, } from "./remote-commands-store.js";
26
+ import { insertRemoteRunEvents, listRemoteRunEvents, } from "./remote-run-events-store.js";
27
+ import { listRemotePushNotificationsForOwner, listRemotePushRegistrationsForOwner, queueRemotePushNotifications, toPublicRemotePushRegistration, unregisterRemotePushRegistrationForOwner, upsertRemotePushRegistration, } from "./remote-push-store.js";
28
+ import { startRemoteCommandsRetryJob } from "./remote-retry-job.js";
24
29
  let a2aContinuationRetryInterval = null;
25
30
  function startA2AContinuationRetryJob(adapters) {
26
31
  if (a2aContinuationRetryInterval)
@@ -87,36 +92,6 @@ function getDefaultAdapters() {
87
92
  emailAdapter(),
88
93
  ];
89
94
  }
90
- /**
91
- * Load resources for the integration agent's system prompt.
92
- * Mirrors the pattern from agent-chat-plugin.ts.
93
- */
94
- async function loadResourcesForPrompt(owner) {
95
- const resourceNames = ["AGENTS.md", "LEARNINGS.md"];
96
- const sections = [];
97
- for (const name of resourceNames) {
98
- try {
99
- const shared = await resourceGetByPath(SHARED_OWNER, name);
100
- if (shared?.content?.trim()) {
101
- sections.push(`<resource name="${name}" scope="shared">\n${shared.content.trim()}\n</resource>`);
102
- }
103
- }
104
- catch { }
105
- if (owner !== SHARED_OWNER) {
106
- try {
107
- const personal = await resourceGetByPath(owner, name);
108
- if (personal?.content?.trim()) {
109
- sections.push(`<resource name="${name}" scope="personal">\n${personal.content.trim()}\n</resource>`);
110
- }
111
- }
112
- catch { }
113
- }
114
- }
115
- if (sections.length === 0)
116
- return "";
117
- return ("\n\nThe following resources contain template-specific instructions and user context.\n\n" +
118
- sections.join("\n\n"));
119
- }
120
95
  const INTEGRATION_SYSTEM_PROMPT = `You are an AI agent responding via a messaging platform integration (Slack, Telegram, WhatsApp, etc.).
121
96
 
122
97
  You have the same capabilities as the web chat agent. Use your tools to help the user.
@@ -124,6 +99,280 @@ You have the same capabilities as the web chat agent. Use your tools to help the
124
99
  Keep responses concise — messaging platforms have character limits and users expect shorter replies than in a web interface. Use markdown sparingly (bold and lists are fine, but avoid complex formatting that may not render well on all platforms).
125
100
 
126
101
  If a task requires many steps, summarize what you did rather than streaming every detail.`;
102
+ const REMOTE_DEVICE_ONLINE_MS = 90_000;
103
+ export async function enqueueRemoteCommand(envelope) {
104
+ const ownerEmail = readString(envelope.ownerEmail);
105
+ if (!ownerEmail)
106
+ throw new Error("ownerEmail is required");
107
+ const hasOrgId = Object.prototype.hasOwnProperty.call(envelope, "orgId");
108
+ const orgId = hasOrgId ? (readString(envelope.orgId) ?? null) : undefined;
109
+ const command = readObject(envelope.command);
110
+ if (!command)
111
+ throw new Error("command is required");
112
+ const commandType = readString(command.type);
113
+ const commands = await listRemoteCommandsForOwner({
114
+ ownerEmail,
115
+ ...(hasOrgId ? { orgId } : {}),
116
+ limit: 50,
117
+ });
118
+ if (commandType === "list") {
119
+ return {
120
+ ok: true,
121
+ runs: commands.map(remoteCommandToRunSummary).filter(Boolean),
122
+ hostOnline: await hasOnlineRemoteDevice(ownerEmail, orgId),
123
+ };
124
+ }
125
+ if (commandType === "status") {
126
+ const runRef = readString(command.runRef);
127
+ const run = runRef
128
+ ? commands.map(remoteCommandToRunSummary).find((item) => {
129
+ const candidate = item;
130
+ return candidate.id === runRef || candidate.runId === runRef;
131
+ })
132
+ : undefined;
133
+ const hostOnline = await hasOnlineRemoteDevice(ownerEmail, orgId);
134
+ return {
135
+ ok: true,
136
+ hostOnline,
137
+ hostStatus: hostOnline ? "online" : "offline",
138
+ ...(run ? { run } : {}),
139
+ };
140
+ }
141
+ const devices = await listRemoteDevicesForOwner({
142
+ ownerEmail,
143
+ ...(hasOrgId ? { orgId } : {}),
144
+ status: "active",
145
+ limit: 10,
146
+ });
147
+ const requestedDeviceId = readString(command.hostId) ?? readString(command.deviceId);
148
+ const device = (requestedDeviceId
149
+ ? devices.find((candidate) => candidate.id === requestedDeviceId)
150
+ : undefined) ?? devices[0];
151
+ if (!device) {
152
+ return {
153
+ ok: false,
154
+ hostOnline: false,
155
+ hostStatus: "offline",
156
+ error: "No paired computer is available for code-agent commands.",
157
+ };
158
+ }
159
+ const source = readObject(envelope.source);
160
+ const kind = remoteCodeCommandKind(commandType);
161
+ if (!kind)
162
+ throw new Error(`Unsupported code-agent command: ${commandType}`);
163
+ const row = await enqueueRemoteCommandRow({
164
+ deviceId: device.id,
165
+ ownerEmail,
166
+ orgId: device.orgId ?? orgId ?? null,
167
+ kind,
168
+ params: remoteCodeCommandParams(command),
169
+ platform: readString(source?.platform) ?? null,
170
+ externalThreadId: readString(source?.externalThreadId) ?? null,
171
+ });
172
+ const hostOnline = isRemoteDeviceOnline(device);
173
+ return {
174
+ ok: true,
175
+ commandId: row.id,
176
+ requestId: row.id,
177
+ hostOnline,
178
+ hostStatus: hostOnline ? "online" : "offline",
179
+ message: commandType === "create"
180
+ ? hostOnline
181
+ ? `Queued code run (${row.id}).`
182
+ : `Queued code run (${row.id}). Your computer looks offline or asleep, so it will pick this up when it wakes.`
183
+ : undefined,
184
+ };
185
+ }
186
+ function remoteCodeCommandKind(commandType) {
187
+ switch (commandType) {
188
+ case "create":
189
+ return "create-run";
190
+ case "continue":
191
+ return "append-followup";
192
+ case "approve":
193
+ return "approve";
194
+ case "deny":
195
+ return "deny";
196
+ case "stop":
197
+ return "stop";
198
+ default:
199
+ return null;
200
+ }
201
+ }
202
+ function remoteCodeCommandParams(command) {
203
+ const type = readString(command.type);
204
+ if (type === "create") {
205
+ return {
206
+ prompt: readString(command.prompt) ?? "",
207
+ title: readString(command.title),
208
+ cwd: readString(command.cwd),
209
+ goalId: readString(command.goalId) ?? "task",
210
+ permissionMode: readString(command.permissionMode),
211
+ };
212
+ }
213
+ if (type === "continue") {
214
+ return {
215
+ runId: readString(command.runRef) ?? readString(command.runId),
216
+ prompt: readString(command.text) ?? readString(command.prompt),
217
+ };
218
+ }
219
+ if (type === "approve" || type === "deny") {
220
+ const id = readString(command.approvalId) ?? readString(command.runId);
221
+ return { runId: id, approvalId: id };
222
+ }
223
+ if (type === "stop") {
224
+ return { runId: readString(command.runRef) ?? readString(command.runId) };
225
+ }
226
+ return {};
227
+ }
228
+ function enqueueBodyToRemoteCodeCommand(body) {
229
+ const direct = readObject(body.command);
230
+ if (body.kind === "code-agent" && direct)
231
+ return direct;
232
+ const operation = readString(body.operation) ?? readString(body.type);
233
+ const payload = readObject(body.payload) ?? body;
234
+ if (!operation?.startsWith("code-agent."))
235
+ return null;
236
+ if (operation === "code-agent.run.create") {
237
+ return {
238
+ type: "create",
239
+ prompt: payload.prompt,
240
+ title: payload.title,
241
+ hostId: payload.hostId,
242
+ deviceId: payload.deviceId,
243
+ cwd: payload.cwd,
244
+ goalId: payload.goalId,
245
+ permissionMode: payload.permissionMode,
246
+ };
247
+ }
248
+ if (operation === "code-agent.run.follow-up") {
249
+ return {
250
+ type: "continue",
251
+ runRef: payload.runId,
252
+ text: payload.prompt ?? payload.message,
253
+ hostId: payload.hostId,
254
+ deviceId: payload.deviceId,
255
+ };
256
+ }
257
+ if (operation === "code-agent.pending-command.decide") {
258
+ return {
259
+ type: payload.decision === "deny" ? "deny" : "approve",
260
+ approvalId: payload.commandId ?? payload.runId,
261
+ runId: payload.runId,
262
+ hostId: payload.hostId,
263
+ deviceId: payload.deviceId,
264
+ };
265
+ }
266
+ if (operation === "code-agent.run.stop") {
267
+ return {
268
+ type: "stop",
269
+ runRef: payload.runId,
270
+ hostId: payload.hostId,
271
+ deviceId: payload.deviceId,
272
+ };
273
+ }
274
+ return null;
275
+ }
276
+ function remoteCommandToRunSummary(command) {
277
+ const result = readObject(command.result);
278
+ const nestedResult = readObject(result?.result) ?? result;
279
+ const run = readObject(nestedResult?.run);
280
+ if (run) {
281
+ return {
282
+ ...run,
283
+ commandId: command.id,
284
+ hostId: command.deviceId,
285
+ status: readString(run.status) ?? command.status,
286
+ updatedAt: readString(run.updatedAt) ?? command.updatedAt,
287
+ };
288
+ }
289
+ if (command.kind !== "create-run")
290
+ return null;
291
+ const params = readObject(command.params) ?? {};
292
+ return {
293
+ id: command.id,
294
+ runId: command.id,
295
+ hostId: command.deviceId,
296
+ title: readString(params.title) ?? readString(params.prompt) ?? "Queued run",
297
+ prompt: readString(params.prompt),
298
+ status: command.status === "failed" ? "errored" : "queued",
299
+ createdAt: command.createdAt,
300
+ updatedAt: command.updatedAt,
301
+ metadata: { remoteCommandId: command.id },
302
+ };
303
+ }
304
+ function readObject(value) {
305
+ return value && typeof value === "object" && !Array.isArray(value)
306
+ ? value
307
+ : null;
308
+ }
309
+ function readString(value) {
310
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
311
+ }
312
+ function isRemoteDeviceOnline(device) {
313
+ return typeof device.lastSeenAt === "number"
314
+ ? Date.now() - device.lastSeenAt <= REMOTE_DEVICE_ONLINE_MS
315
+ : false;
316
+ }
317
+ async function hasOnlineRemoteDevice(ownerEmail, orgId) {
318
+ const hasOrgId = orgId !== undefined;
319
+ const devices = await listRemoteDevicesForOwner({
320
+ ownerEmail,
321
+ ...(hasOrgId ? { orgId } : {}),
322
+ status: "active",
323
+ limit: 10,
324
+ });
325
+ return devices.some(isRemoteDeviceOnline);
326
+ }
327
+ function remoteDeviceToHost(device) {
328
+ const online = device.status === "active" && isRemoteDeviceOnline(device);
329
+ return {
330
+ id: device.id,
331
+ name: device.label,
332
+ label: device.label,
333
+ status: device.status === "active" ? (online ? "online" : "offline") : "revoked",
334
+ lastSeenAt: device.lastSeenAt
335
+ ? new Date(device.lastSeenAt).toISOString()
336
+ : undefined,
337
+ platform: device.platform ?? "desktop",
338
+ appVersion: device.appVersion ?? undefined,
339
+ hostName: device.hostName ?? undefined,
340
+ metadata: device.metadata ?? undefined,
341
+ device: toPublicRemoteDevice(device),
342
+ };
343
+ }
344
+ function mountedPathParts(event, mountSuffix) {
345
+ const rawPath = String(event.path ?? event.url?.pathname ?? event.node?.req?.url ?? "/").split("?")[0];
346
+ const normalized = rawPath.replace(/^\/+/, "");
347
+ const marker = mountSuffix.replace(/^\/+/, "");
348
+ const markerIndex = normalized.indexOf(marker);
349
+ const suffix = markerIndex >= 0
350
+ ? normalized.slice(markerIndex + marker.length)
351
+ : normalized;
352
+ return suffix
353
+ .split("/")
354
+ .filter(Boolean)
355
+ .map((part) => decodeURIComponent(part));
356
+ }
357
+ function remoteCommandPushPayload(command) {
358
+ const result = readObject(command.result);
359
+ const status = command.status;
360
+ const title = status === "completed"
361
+ ? "Remote run completed"
362
+ : status === "failed"
363
+ ? "Remote run failed"
364
+ : "Remote run updated";
365
+ return {
366
+ title,
367
+ body: command.errorMessage ?? readString(result?.message),
368
+ commandId: command.id,
369
+ hostId: command.deviceId,
370
+ kind: command.kind,
371
+ status,
372
+ result: command.result,
373
+ updatedAt: command.updatedAt,
374
+ };
375
+ }
127
376
  /**
128
377
  * Creates a Nitro plugin that mounts messaging platform integration webhook routes.
129
378
  *
@@ -182,6 +431,26 @@ export function createIntegrationsPlugin(options) {
182
431
  setResponseStatus(event, 401);
183
432
  return false;
184
433
  }
434
+ async function requireSessionContext(event) {
435
+ const session = await getSession(event).catch(() => null);
436
+ if (!session?.email) {
437
+ setResponseStatus(event, 401);
438
+ return null;
439
+ }
440
+ const orgCtx = await getOrgContext(event).catch(() => null);
441
+ return {
442
+ ownerEmail: session.email,
443
+ orgId: orgCtx?.orgId ?? session.orgId ?? null,
444
+ };
445
+ }
446
+ async function requireRemoteDevice(event) {
447
+ const token = extractBearerToken(getRequestHeader(event, "authorization"));
448
+ const device = await authenticateRemoteDeviceToken(token);
449
+ if (device)
450
+ return device;
451
+ setResponseStatus(event, 401);
452
+ return null;
453
+ }
185
454
  /**
186
455
  * Gate destructive integration writes (enable/disable, setup,
187
456
  * setIntegrationConfig…) behind an org-owner/admin check.
@@ -268,6 +537,457 @@ export function createIntegrationsPlugin(options) {
268
537
  return { error: err?.message ?? String(err) };
269
538
  }
270
539
  }));
540
+ // ─── Remote relay endpoints ──────────────────────────────────
541
+ // These routes allow a signed-in browser session to enqueue work for a
542
+ // registered remote device, and the device to claim/complete that work
543
+ // using its one-time-issued bearer token. State lives entirely in SQL so
544
+ // long polling can safely degrade to short polling on serverless hosts.
545
+ h3.use(`${P}/remote/register`, defineEventHandler(async (event) => {
546
+ if (getMethod(event) !== "POST") {
547
+ setResponseStatus(event, 405);
548
+ return { error: "Method not allowed" };
549
+ }
550
+ const ctx = await requireSessionContext(event);
551
+ if (!ctx)
552
+ return { error: "unauthorized" };
553
+ const body = (await readBody(event));
554
+ const label = typeof body.label === "string" && body.label.trim()
555
+ ? body.label.trim().slice(0, 200)
556
+ : "Remote device";
557
+ const { device, token } = await createRemoteDevice({
558
+ ownerEmail: ctx.ownerEmail,
559
+ orgId: ctx.orgId,
560
+ label,
561
+ platform: readString(body.platform),
562
+ appVersion: readString(body.appVersion) ?? readString(body.version),
563
+ hostName: readString(body.hostName) ?? readString(body.hostname),
564
+ metadata: readObject(body.metadata),
565
+ });
566
+ return { device: toPublicRemoteDevice(device), token };
567
+ }));
568
+ h3.use(`${P}/remote/hosts`, defineEventHandler(async (event) => {
569
+ if (getMethod(event) !== "GET") {
570
+ setResponseStatus(event, 405);
571
+ return { error: "Method not allowed" };
572
+ }
573
+ const ctx = await requireSessionContext(event);
574
+ if (!ctx)
575
+ return { error: "unauthorized" };
576
+ const devices = await listRemoteDevicesForOwner({
577
+ ownerEmail: ctx.ownerEmail,
578
+ orgId: ctx.orgId,
579
+ limit: 50,
580
+ });
581
+ const hosts = devices.map(remoteDeviceToHost);
582
+ const parts = mountedPathParts(event, "remote/hosts");
583
+ if (parts[0]) {
584
+ const host = hosts.find((candidate) => candidate.id === parts[0]);
585
+ if (!host) {
586
+ setResponseStatus(event, 404);
587
+ return { error: "host not found" };
588
+ }
589
+ return { host, device: host.device };
590
+ }
591
+ return { hosts, devices: hosts };
592
+ }));
593
+ h3.use(`${P}/remote/devices`, defineEventHandler(async (event) => {
594
+ const method = getMethod(event);
595
+ if (method !== "GET" && method !== "DELETE" && method !== "POST") {
596
+ setResponseStatus(event, 405);
597
+ return { error: "Method not allowed" };
598
+ }
599
+ const ctx = await requireSessionContext(event);
600
+ if (!ctx)
601
+ return { error: "unauthorized" };
602
+ const parts = mountedPathParts(event, "remote/devices");
603
+ if (method === "GET") {
604
+ if (!parts[0]) {
605
+ const devices = await listRemoteDevicesForOwner({
606
+ ownerEmail: ctx.ownerEmail,
607
+ orgId: ctx.orgId,
608
+ limit: 100,
609
+ });
610
+ return {
611
+ devices: devices.map(toPublicRemoteDevice),
612
+ hosts: devices.map(remoteDeviceToHost),
613
+ };
614
+ }
615
+ const device = await getRemoteDeviceForOwner({
616
+ id: parts[0],
617
+ ownerEmail: ctx.ownerEmail,
618
+ orgId: ctx.orgId,
619
+ });
620
+ if (!device) {
621
+ setResponseStatus(event, 404);
622
+ return { error: "device not found" };
623
+ }
624
+ return {
625
+ device: toPublicRemoteDevice(device),
626
+ host: remoteDeviceToHost(device),
627
+ };
628
+ }
629
+ const id = parts[0];
630
+ const action = parts[1];
631
+ if (!id || (method === "POST" && action !== "revoke")) {
632
+ setResponseStatus(event, 404);
633
+ return { error: "not found" };
634
+ }
635
+ const device = await revokeRemoteDeviceForOwner({
636
+ id,
637
+ ownerEmail: ctx.ownerEmail,
638
+ orgId: ctx.orgId,
639
+ });
640
+ if (!device) {
641
+ setResponseStatus(event, 404);
642
+ return { error: "device not found" };
643
+ }
644
+ return { ok: true, device: toPublicRemoteDevice(device) };
645
+ }));
646
+ h3.use(`${P}/remote/unregister`, defineEventHandler(async (event) => {
647
+ if (getMethod(event) !== "POST" && getMethod(event) !== "DELETE") {
648
+ setResponseStatus(event, 405);
649
+ return { error: "Method not allowed" };
650
+ }
651
+ const device = await requireRemoteDevice(event);
652
+ if (!device)
653
+ return { error: "unauthorized" };
654
+ await unregisterRemoteDevice(device.id);
655
+ return { ok: true, deviceId: device.id };
656
+ }));
657
+ h3.use(`${P}/remote/heartbeat`, defineEventHandler(async (event) => {
658
+ if (getMethod(event) !== "POST") {
659
+ setResponseStatus(event, 405);
660
+ return { error: "Method not allowed" };
661
+ }
662
+ const device = await requireRemoteDevice(event);
663
+ if (!device)
664
+ return { error: "unauthorized" };
665
+ const body = (await readBody(event));
666
+ const updated = await updateRemoteDeviceDetails({
667
+ id: device.id,
668
+ label: readString(body.label),
669
+ platform: readString(body.platform),
670
+ appVersion: readString(body.appVersion) ?? readString(body.version),
671
+ hostName: readString(body.hostName) ?? readString(body.hostname),
672
+ metadata: readObject(body.metadata),
673
+ });
674
+ return {
675
+ ok: true,
676
+ device: updated ? toPublicRemoteDevice(updated) : null,
677
+ };
678
+ }));
679
+ h3.use(`${P}/remote/push/register`, defineEventHandler(async (event) => {
680
+ if (getMethod(event) !== "POST") {
681
+ setResponseStatus(event, 405);
682
+ return { error: "Method not allowed" };
683
+ }
684
+ const ctx = await requireSessionContext(event);
685
+ if (!ctx)
686
+ return { error: "unauthorized" };
687
+ const body = (await readBody(event));
688
+ const token = readString(body.token);
689
+ if (!token) {
690
+ setResponseStatus(event, 400);
691
+ return { error: "token required" };
692
+ }
693
+ const registration = await upsertRemotePushRegistration({
694
+ ownerEmail: ctx.ownerEmail,
695
+ orgId: ctx.orgId,
696
+ provider: readString(body.provider) ?? "unknown",
697
+ token,
698
+ platform: readString(body.platform),
699
+ clientDeviceId: readString(body.clientDeviceId) ?? readString(body.deviceId),
700
+ label: readString(body.label),
701
+ });
702
+ return {
703
+ registration: toPublicRemotePushRegistration(registration),
704
+ };
705
+ }));
706
+ h3.use(`${P}/remote/push/registrations`, defineEventHandler(async (event) => {
707
+ if (getMethod(event) !== "GET") {
708
+ setResponseStatus(event, 405);
709
+ return { error: "Method not allowed" };
710
+ }
711
+ const ctx = await requireSessionContext(event);
712
+ if (!ctx)
713
+ return { error: "unauthorized" };
714
+ const registrations = await listRemotePushRegistrationsForOwner({
715
+ ownerEmail: ctx.ownerEmail,
716
+ orgId: ctx.orgId,
717
+ includeInactive: getQuery(event).includeInactive === "true",
718
+ limit: 100,
719
+ });
720
+ return {
721
+ registrations: registrations.map(toPublicRemotePushRegistration),
722
+ };
723
+ }));
724
+ h3.use(`${P}/remote/push/unregister`, defineEventHandler(async (event) => {
725
+ const method = getMethod(event);
726
+ if (method !== "POST" && method !== "DELETE") {
727
+ setResponseStatus(event, 405);
728
+ return { error: "Method not allowed" };
729
+ }
730
+ const ctx = await requireSessionContext(event);
731
+ if (!ctx)
732
+ return { error: "unauthorized" };
733
+ const body = (await readBody(event));
734
+ const removed = await unregisterRemotePushRegistrationForOwner({
735
+ ownerEmail: ctx.ownerEmail,
736
+ orgId: ctx.orgId,
737
+ id: readString(body.id) ?? readString(body.registrationId),
738
+ token: readString(body.token),
739
+ });
740
+ if (!removed) {
741
+ setResponseStatus(event, 404);
742
+ return { error: "registration not found" };
743
+ }
744
+ return { ok: true };
745
+ }));
746
+ h3.use(`${P}/remote/push/notifications`, defineEventHandler(async (event) => {
747
+ if (getMethod(event) !== "GET") {
748
+ setResponseStatus(event, 405);
749
+ return { error: "Method not allowed" };
750
+ }
751
+ const ctx = await requireSessionContext(event);
752
+ if (!ctx)
753
+ return { error: "unauthorized" };
754
+ const query = getQuery(event);
755
+ const status = query.status === "delivered" ||
756
+ query.status === "failed" ||
757
+ query.status === "pending"
758
+ ? query.status
759
+ : undefined;
760
+ const notifications = await listRemotePushNotificationsForOwner({
761
+ ownerEmail: ctx.ownerEmail,
762
+ orgId: ctx.orgId,
763
+ status,
764
+ limit: Number(query.limit ?? 50) || 50,
765
+ });
766
+ return { notifications };
767
+ }));
768
+ h3.use(`${P}/remote/runs`, defineEventHandler(async (event) => {
769
+ if (getMethod(event) !== "GET") {
770
+ setResponseStatus(event, 405);
771
+ return { error: "Method not allowed" };
772
+ }
773
+ const ctx = await requireSessionContext(event);
774
+ if (!ctx)
775
+ return { error: "unauthorized" };
776
+ const parts = mountedPathParts(event, "remote/runs");
777
+ const commands = await listRemoteCommandsForOwner({
778
+ ownerEmail: ctx.ownerEmail,
779
+ orgId: ctx.orgId,
780
+ limit: 100,
781
+ });
782
+ if (parts.length === 0) {
783
+ return {
784
+ runs: commands.map(remoteCommandToRunSummary).filter(Boolean),
785
+ };
786
+ }
787
+ const runId = decodeURIComponent(parts[0] ?? "");
788
+ const match = commands.find((command) => {
789
+ const run = remoteCommandToRunSummary(command);
790
+ return (command.id === runId || run?.id === runId || run?.runId === runId);
791
+ });
792
+ if (!match) {
793
+ setResponseStatus(event, 404);
794
+ return { error: "run not found" };
795
+ }
796
+ const run = remoteCommandToRunSummary(match);
797
+ if (parts[1] === "transcript") {
798
+ const remoteRunId = readString(run?.runId) ??
799
+ readString(run?.id) ??
800
+ readString(match.id);
801
+ const events = remoteRunId
802
+ ? await listRemoteRunEvents({
803
+ deviceId: match.deviceId,
804
+ remoteRunId,
805
+ limit: 1000,
806
+ })
807
+ : [];
808
+ return {
809
+ run,
810
+ events: events.map((event) => event.event),
811
+ };
812
+ }
813
+ if (parts.length === 1)
814
+ return { run };
815
+ setResponseStatus(event, 404);
816
+ return { error: "not found" };
817
+ }));
818
+ h3.use(`${P}/remote/enqueue`, defineEventHandler(async (event) => {
819
+ if (getMethod(event) !== "POST") {
820
+ setResponseStatus(event, 405);
821
+ return { error: "Method not allowed" };
822
+ }
823
+ const ctx = await requireSessionContext(event);
824
+ if (!ctx)
825
+ return { error: "unauthorized" };
826
+ const body = (await readBody(event));
827
+ const highLevel = enqueueBodyToRemoteCodeCommand(body);
828
+ if (highLevel) {
829
+ return enqueueRemoteCommand({
830
+ kind: "code-agent",
831
+ ownerEmail: ctx.ownerEmail,
832
+ orgId: ctx.orgId ?? undefined,
833
+ command: highLevel,
834
+ source: body.source ?? {
835
+ platform: typeof body.platform === "string" ? body.platform : "mobile",
836
+ externalThreadId: typeof body.externalThreadId === "string"
837
+ ? body.externalThreadId
838
+ : "mobile",
839
+ },
840
+ });
841
+ }
842
+ if (typeof body.deviceId !== "string" || !body.deviceId.trim()) {
843
+ setResponseStatus(event, 400);
844
+ return { error: "deviceId required" };
845
+ }
846
+ if (!isRemoteCommandKind(body.kind)) {
847
+ setResponseStatus(event, 400);
848
+ return { error: "invalid command kind" };
849
+ }
850
+ const device = await getRemoteDeviceForOwner({
851
+ id: body.deviceId,
852
+ ownerEmail: ctx.ownerEmail,
853
+ orgId: ctx.orgId,
854
+ });
855
+ if (!device) {
856
+ setResponseStatus(event, 404);
857
+ return { error: "device not found" };
858
+ }
859
+ if (device.status !== "active") {
860
+ setResponseStatus(event, 410);
861
+ return { error: "device revoked" };
862
+ }
863
+ const command = await enqueueRemoteCommandRow({
864
+ deviceId: device.id,
865
+ ownerEmail: ctx.ownerEmail,
866
+ orgId: ctx.orgId,
867
+ kind: body.kind,
868
+ params: body.params ?? {},
869
+ platform: typeof body.platform === "string" ? body.platform : null,
870
+ externalThreadId: typeof body.externalThreadId === "string"
871
+ ? body.externalThreadId
872
+ : null,
873
+ });
874
+ return { command };
875
+ }));
876
+ h3.use(`${P}/remote/poll`, defineEventHandler(async (event) => {
877
+ const method = getMethod(event);
878
+ if (method !== "POST" && method !== "GET") {
879
+ setResponseStatus(event, 405);
880
+ return { error: "Method not allowed" };
881
+ }
882
+ const device = await requireRemoteDevice(event);
883
+ if (!device)
884
+ return { error: "unauthorized" };
885
+ const query = getQuery(event);
886
+ const body = method === "POST"
887
+ ? (await readBody(event))
888
+ : {};
889
+ const requestedWait = Number(body.waitMs ?? query.waitMs ?? query.wait_ms ?? 25_000) || 0;
890
+ const waitMs = Math.max(0, Math.min(25_000, requestedWait));
891
+ const deadline = Date.now() + waitMs;
892
+ while (true) {
893
+ const command = await claimNextRemoteCommand(device.id);
894
+ if (command)
895
+ return { command };
896
+ const remaining = deadline - Date.now();
897
+ if (remaining <= 0)
898
+ return { command: null };
899
+ await sleep(Math.min(1000, remaining));
900
+ }
901
+ }));
902
+ h3.use(`${P}/remote/result`, defineEventHandler(async (event) => {
903
+ if (getMethod(event) !== "POST") {
904
+ setResponseStatus(event, 405);
905
+ return { error: "Method not allowed" };
906
+ }
907
+ const device = await requireRemoteDevice(event);
908
+ if (!device)
909
+ return { error: "unauthorized" };
910
+ const body = (await readBody(event));
911
+ if (typeof body.commandId !== "string" || !body.commandId.trim()) {
912
+ setResponseStatus(event, 400);
913
+ return { error: "commandId required" };
914
+ }
915
+ if (body.status !== "running" &&
916
+ body.status !== "completed" &&
917
+ body.status !== "failed") {
918
+ setResponseStatus(event, 400);
919
+ return { error: "invalid command status" };
920
+ }
921
+ const command = await updateRemoteCommandResult({
922
+ deviceId: device.id,
923
+ commandId: body.commandId,
924
+ status: body.status,
925
+ result: body.result,
926
+ errorMessage: typeof body.errorMessage === "string" ? body.errorMessage : null,
927
+ });
928
+ if (!command) {
929
+ setResponseStatus(event, 404);
930
+ return { error: "command not found" };
931
+ }
932
+ if (command.status === "completed" || command.status === "failed") {
933
+ await queueRemotePushNotifications({
934
+ ownerEmail: device.ownerEmail,
935
+ orgId: device.orgId,
936
+ payload: remoteCommandPushPayload(command),
937
+ }).catch((err) => {
938
+ console.error("[integrations] remote push queue failed:", err);
939
+ });
940
+ }
941
+ return { command };
942
+ }));
943
+ h3.use(`${P}/remote/run-events`, defineEventHandler(async (event) => {
944
+ if (getMethod(event) !== "POST") {
945
+ setResponseStatus(event, 405);
946
+ return { error: "Method not allowed" };
947
+ }
948
+ const device = await requireRemoteDevice(event);
949
+ if (!device)
950
+ return { error: "unauthorized" };
951
+ const body = (await readBody(event));
952
+ const remoteRunId = typeof body.remoteRunId === "string" && body.remoteRunId.trim()
953
+ ? body.remoteRunId.trim()
954
+ : typeof body.runId === "string" && body.runId.trim()
955
+ ? body.runId.trim()
956
+ : "";
957
+ if (!remoteRunId) {
958
+ setResponseStatus(event, 400);
959
+ return { error: "remoteRunId required" };
960
+ }
961
+ if (!Array.isArray(body.events)) {
962
+ setResponseStatus(event, 400);
963
+ return { error: "events required" };
964
+ }
965
+ const events = body.events
966
+ .slice(0, 1000)
967
+ .map((entry, index) => {
968
+ const value = entry;
969
+ const rawEvent = value && typeof value === "object" && "event" in value
970
+ ? value.event
971
+ : entry;
972
+ return {
973
+ seq: value && typeof value === "object" && "seq" in value
974
+ ? Number(value.seq)
975
+ : index,
976
+ event: rawEvent ?? null,
977
+ };
978
+ })
979
+ .filter((entry) => Number.isInteger(entry.seq) && entry.seq >= 0);
980
+ if (events.length !== body.events.length) {
981
+ setResponseStatus(event, 400);
982
+ return { error: "invalid event sequence" };
983
+ }
984
+ const result = await insertRemoteRunEvents({
985
+ deviceId: device.id,
986
+ remoteRunId,
987
+ events,
988
+ });
989
+ return { ok: true, ...result };
990
+ }));
271
991
  // ─── Process pending task (cross-platform task queue) ────────
272
992
  // POST /_agent-native/integrations/process-task
273
993
  // Internal endpoint invoked via fire-and-forget self-webhook from the
@@ -403,6 +1123,9 @@ export function createIntegrationsPlugin(options) {
403
1123
  // Already handled by the dedicated /task-queue/status route above
404
1124
  if (parts[0] === "task-queue")
405
1125
  return;
1126
+ // Already handled by the dedicated /remote/* routes above
1127
+ if (parts[0] === "remote")
1128
+ return;
406
1129
  // Already handled by the dedicated /process-task route above
407
1130
  if (parts[0] === "process-task")
408
1131
  return;
@@ -531,6 +1254,7 @@ export function createIntegrationsPlugin(options) {
531
1254
  model,
532
1255
  apiKey: getApiKey(),
533
1256
  engine: options?.engine,
1257
+ appId: options?.appId,
534
1258
  ownerEmail: owner,
535
1259
  beforeProcess: options?.beforeProcess,
536
1260
  incoming,
@@ -600,6 +1324,7 @@ export function createIntegrationsPlugin(options) {
600
1324
  webhookBaseUrl: process.env.WEBHOOK_BASE_URL,
601
1325
  });
602
1326
  startA2AContinuationRetryJob(adapterMap);
1327
+ startRemoteCommandsRetryJob();
603
1328
  // ─── Start Google Docs poller/push ────────────────────────────
604
1329
  if (adapterMap.has("google-docs")) {
605
1330
  // Defer startup slightly so the server is fully ready
@@ -646,4 +1371,7 @@ function getBaseUrl(event) {
646
1371
  return withConfiguredAppBasePath("http://localhost:3000");
647
1372
  }
648
1373
  }
1374
+ function sleep(ms) {
1375
+ return new Promise((resolve) => setTimeout(resolve, ms));
1376
+ }
649
1377
  //# sourceMappingURL=plugin.js.map