@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
@@ -0,0 +1,273 @@
1
+ import { getDbExec, intType, isPostgres, retryOnDdlRace, } from "../db/client.js";
2
+ let _initPromise;
3
+ const REMOTE_COMMAND_KINDS = [
4
+ "create-run",
5
+ "list-runs",
6
+ "get-run",
7
+ "append-followup",
8
+ "approve",
9
+ "deny",
10
+ "stop",
11
+ "status",
12
+ ];
13
+ const TERMINAL_STATUSES = new Set(["completed", "failed"]);
14
+ async function ensureTable() {
15
+ if (!_initPromise) {
16
+ _initPromise = (async () => {
17
+ const client = getDbExec();
18
+ await retryOnDdlRace(() => client.execute(`
19
+ CREATE TABLE IF NOT EXISTS integration_remote_commands (
20
+ id TEXT PRIMARY KEY,
21
+ device_id TEXT NOT NULL,
22
+ owner_email TEXT NOT NULL,
23
+ org_id TEXT,
24
+ kind TEXT NOT NULL,
25
+ params_json TEXT NOT NULL,
26
+ status TEXT NOT NULL,
27
+ result_json TEXT,
28
+ platform TEXT,
29
+ external_thread_id TEXT,
30
+ attempts ${intType()} NOT NULL DEFAULT 0,
31
+ next_check_at ${intType()} NOT NULL,
32
+ claimed_at ${intType()},
33
+ completed_at ${intType()},
34
+ error_message TEXT,
35
+ created_at ${intType()} NOT NULL,
36
+ updated_at ${intType()} NOT NULL
37
+ )
38
+ `));
39
+ await retryOnDdlRace(() => client.execute(`CREATE INDEX IF NOT EXISTS idx_remote_commands_device_status_next ON integration_remote_commands(device_id, status, next_check_at)`));
40
+ await retryOnDdlRace(() => client.execute(`CREATE INDEX IF NOT EXISTS idx_remote_commands_owner ON integration_remote_commands(owner_email, org_id)`));
41
+ })();
42
+ }
43
+ return _initPromise;
44
+ }
45
+ function rowToCommand(row) {
46
+ return {
47
+ id: row.id,
48
+ deviceId: row.device_id,
49
+ ownerEmail: row.owner_email,
50
+ orgId: row.org_id ?? null,
51
+ kind: row.kind,
52
+ params: parseJson(row.params_json, {}),
53
+ status: row.status,
54
+ result: parseJson(row.result_json, null),
55
+ platform: row.platform ?? null,
56
+ externalThreadId: row.external_thread_id ?? null,
57
+ attempts: Number(row.attempts ?? 0),
58
+ nextCheckAt: Number(row.next_check_at ?? 0),
59
+ claimedAt: row.claimed_at == null ? null : Number(row.claimed_at),
60
+ completedAt: row.completed_at == null ? null : Number(row.completed_at),
61
+ errorMessage: row.error_message ?? null,
62
+ createdAt: Number(row.created_at ?? 0),
63
+ updatedAt: Number(row.updated_at ?? 0),
64
+ };
65
+ }
66
+ export function isRemoteCommandKind(value) {
67
+ return (typeof value === "string" &&
68
+ REMOTE_COMMAND_KINDS.includes(value));
69
+ }
70
+ export async function enqueueRemoteCommand(input) {
71
+ await ensureTable();
72
+ const client = getDbExec();
73
+ const now = Date.now();
74
+ const id = `remote-command-${now}-${randomHex(8)}`;
75
+ await client.execute({
76
+ sql: `INSERT INTO integration_remote_commands
77
+ (id, device_id, owner_email, org_id, kind, params_json, status, result_json,
78
+ platform, external_thread_id, attempts, next_check_at, created_at, updated_at)
79
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
80
+ args: [
81
+ id,
82
+ input.deviceId,
83
+ input.ownerEmail,
84
+ input.orgId ?? null,
85
+ input.kind,
86
+ JSON.stringify(input.params ?? {}),
87
+ "pending",
88
+ null,
89
+ input.platform ?? null,
90
+ input.externalThreadId ?? null,
91
+ 0,
92
+ input.nextCheckAt ?? now,
93
+ now,
94
+ now,
95
+ ],
96
+ });
97
+ const command = await getRemoteCommand(id);
98
+ if (!command)
99
+ throw new Error("remote command insert failed");
100
+ return command;
101
+ }
102
+ export async function getRemoteCommand(id) {
103
+ await ensureTable();
104
+ const { rows } = await getDbExec().execute({
105
+ sql: `SELECT * FROM integration_remote_commands WHERE id = ? LIMIT 1`,
106
+ args: [id],
107
+ });
108
+ return rows[0] ? rowToCommand(rows[0]) : null;
109
+ }
110
+ export async function listRemoteCommandsForOwner(input) {
111
+ await ensureTable();
112
+ const limit = Math.max(1, Math.min(input.limit ?? 100, 250));
113
+ if (!Object.prototype.hasOwnProperty.call(input, "orgId")) {
114
+ const { rows } = await getDbExec().execute({
115
+ sql: `SELECT * FROM integration_remote_commands
116
+ WHERE owner_email = ?
117
+ ORDER BY updated_at DESC
118
+ LIMIT ?`,
119
+ args: [input.ownerEmail, limit],
120
+ });
121
+ return rows.map((row) => rowToCommand(row));
122
+ }
123
+ const { rows } = await getDbExec().execute({
124
+ sql: `SELECT * FROM integration_remote_commands
125
+ WHERE owner_email = ?
126
+ AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)
127
+ ORDER BY updated_at DESC
128
+ LIMIT ?`,
129
+ args: [input.ownerEmail, input.orgId ?? null, input.orgId ?? null, limit],
130
+ });
131
+ return rows.map((row) => rowToCommand(row));
132
+ }
133
+ export async function claimNextRemoteCommand(deviceId) {
134
+ await ensureTable();
135
+ const client = getDbExec();
136
+ const now = Date.now();
137
+ const { rows } = await client.execute({
138
+ sql: `SELECT id FROM integration_remote_commands
139
+ WHERE device_id = ?
140
+ AND status = 'pending'
141
+ AND next_check_at <= ?
142
+ ORDER BY created_at ASC
143
+ LIMIT 1`,
144
+ args: [deviceId, now],
145
+ });
146
+ const id = rows[0]?.id;
147
+ if (!id)
148
+ return null;
149
+ const result = await client.execute({
150
+ sql: isPostgres()
151
+ ? `UPDATE integration_remote_commands
152
+ SET status = ?, attempts = attempts + 1, claimed_at = ?, updated_at = ?
153
+ WHERE id = ? AND device_id = ? AND status = 'pending'
154
+ RETURNING *`
155
+ : `UPDATE integration_remote_commands
156
+ SET status = ?, attempts = attempts + 1, claimed_at = ?, updated_at = ?
157
+ WHERE id = ? AND device_id = ? AND status = 'pending'`,
158
+ args: ["claimed", now, now, id, deviceId],
159
+ });
160
+ if (isPostgres()) {
161
+ const row = result.rows?.[0];
162
+ return row ? rowToCommand(row) : null;
163
+ }
164
+ const affected = result.rowsAffected ?? result.rowCount;
165
+ if (affected === 0)
166
+ return null;
167
+ const command = await getRemoteCommand(id);
168
+ if (!command || command.status !== "claimed")
169
+ return null;
170
+ return command;
171
+ }
172
+ export async function updateRemoteCommandResult(input) {
173
+ await ensureTable();
174
+ const client = getDbExec();
175
+ const now = Date.now();
176
+ const completedAt = TERMINAL_STATUSES.has(input.status) ? now : null;
177
+ const resultJson = input.result === undefined ? undefined : JSON.stringify(input.result);
178
+ await client.execute({
179
+ sql: `UPDATE integration_remote_commands
180
+ SET status = ?,
181
+ result_json = COALESCE(?, result_json),
182
+ error_message = ?,
183
+ completed_at = COALESCE(?, completed_at),
184
+ updated_at = ?
185
+ WHERE id = ? AND device_id = ?`,
186
+ args: [
187
+ input.status,
188
+ resultJson ?? null,
189
+ input.errorMessage ? input.errorMessage.slice(0, 2000) : null,
190
+ completedAt,
191
+ now,
192
+ input.commandId,
193
+ input.deviceId,
194
+ ],
195
+ });
196
+ const command = await getRemoteCommand(input.commandId);
197
+ if (!command || command.deviceId !== input.deviceId)
198
+ return null;
199
+ return command;
200
+ }
201
+ export async function retryStaleRemoteCommands(options) {
202
+ await ensureTable();
203
+ const client = getDbExec();
204
+ const now = Date.now();
205
+ const claimedCutoff = now - (options?.claimedStaleAfterMs ?? 75_000);
206
+ const runningCutoff = now - (options?.runningStaleAfterMs ?? 5 * 60_000);
207
+ const maxAttempts = options?.maxAttempts ?? 3;
208
+ const limit = options?.limit ?? 50;
209
+ const { rows } = await client.execute({
210
+ sql: `SELECT id, status, attempts FROM integration_remote_commands
211
+ WHERE (status = 'claimed' AND updated_at <= ?)
212
+ OR (status = 'running' AND updated_at <= ?)
213
+ ORDER BY updated_at ASC
214
+ LIMIT ?`,
215
+ args: [claimedCutoff, runningCutoff, limit],
216
+ });
217
+ let retried = 0;
218
+ let failed = 0;
219
+ for (const row of rows) {
220
+ const id = row.id;
221
+ const status = row.status;
222
+ const attempts = Number(row.attempts ?? 0);
223
+ if (attempts >= maxAttempts) {
224
+ const result = await client.execute({
225
+ sql: `UPDATE integration_remote_commands
226
+ SET status = 'failed',
227
+ error_message = COALESCE(error_message, ?),
228
+ completed_at = ?,
229
+ updated_at = ?
230
+ WHERE id = ? AND status = ?`,
231
+ args: [
232
+ `Retry job: exceeded ${maxAttempts} attempts`,
233
+ now,
234
+ now,
235
+ id,
236
+ status,
237
+ ],
238
+ });
239
+ if ((result.rowsAffected ?? result.rowCount) > 0)
240
+ failed++;
241
+ continue;
242
+ }
243
+ const result = await client.execute({
244
+ sql: `UPDATE integration_remote_commands
245
+ SET status = 'pending',
246
+ next_check_at = ?,
247
+ updated_at = ?
248
+ WHERE id = ? AND status = ?`,
249
+ args: [now, now, id, status],
250
+ });
251
+ if ((result.rowsAffected ?? result.rowCount) > 0)
252
+ retried++;
253
+ }
254
+ return { retried, failed };
255
+ }
256
+ function parseJson(value, fallback) {
257
+ if (value == null)
258
+ return fallback;
259
+ try {
260
+ return JSON.parse(String(value));
261
+ }
262
+ catch {
263
+ return fallback;
264
+ }
265
+ }
266
+ function randomHex(byteLength) {
267
+ const bytes = new Uint8Array(byteLength);
268
+ globalThis.crypto.getRandomValues(bytes);
269
+ return Array.from(bytes)
270
+ .map((byte) => byte.toString(16).padStart(2, "0"))
271
+ .join("");
272
+ }
273
+ //# sourceMappingURL=remote-commands-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-commands-store.js","sourceRoot":"","sources":["../../src/integrations/remote-commands-store.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n getDbExec,\n intType,\n isPostgres,\n retryOnDdlRace,\n} from \"../db/client.js\";\nimport type {\n RemoteCommand,\n RemoteCommandKind,\n RemoteCommandStatus,\n} from \"./remote-types.js\";\n\nlet _initPromise: Promise<void> | undefined;\n\nconst REMOTE_COMMAND_KINDS: RemoteCommandKind[] = [\n \"create-run\",\n \"list-runs\",\n \"get-run\",\n \"append-followup\",\n \"approve\",\n \"deny\",\n \"stop\",\n \"status\",\n];\n\nconst TERMINAL_STATUSES = new Set<RemoteCommandStatus>([\"completed\", \"failed\"]);\n\nasync function ensureTable(): Promise<void> {\n if (!_initPromise) {\n _initPromise = (async () => {\n const client = getDbExec();\n await retryOnDdlRace(() =>\n client.execute(`\n CREATE TABLE IF NOT EXISTS integration_remote_commands (\n id TEXT PRIMARY KEY,\n device_id TEXT NOT NULL,\n owner_email TEXT NOT NULL,\n org_id TEXT,\n kind TEXT NOT NULL,\n params_json TEXT NOT NULL,\n status TEXT NOT NULL,\n result_json TEXT,\n platform TEXT,\n external_thread_id TEXT,\n attempts ${intType()} NOT NULL DEFAULT 0,\n next_check_at ${intType()} NOT NULL,\n claimed_at ${intType()},\n completed_at ${intType()},\n error_message TEXT,\n created_at ${intType()} NOT NULL,\n updated_at ${intType()} NOT NULL\n )\n `),\n );\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE INDEX IF NOT EXISTS idx_remote_commands_device_status_next ON integration_remote_commands(device_id, status, next_check_at)`,\n ),\n );\n await retryOnDdlRace(() =>\n client.execute(\n `CREATE INDEX IF NOT EXISTS idx_remote_commands_owner ON integration_remote_commands(owner_email, org_id)`,\n ),\n );\n })();\n }\n return _initPromise;\n}\n\nfunction rowToCommand(row: Record<string, unknown>): RemoteCommand {\n return {\n id: row.id as string,\n deviceId: row.device_id as string,\n ownerEmail: row.owner_email as string,\n orgId: (row.org_id as string | null) ?? null,\n kind: row.kind as RemoteCommandKind,\n params: parseJson(row.params_json, {}),\n status: row.status as RemoteCommandStatus,\n result: parseJson(row.result_json, null),\n platform: (row.platform as string | null) ?? null,\n externalThreadId: (row.external_thread_id as string | null) ?? null,\n attempts: Number(row.attempts ?? 0),\n nextCheckAt: Number(row.next_check_at ?? 0),\n claimedAt: row.claimed_at == null ? null : Number(row.claimed_at as number),\n completedAt:\n row.completed_at == null ? null : Number(row.completed_at as number),\n errorMessage: (row.error_message as string | null) ?? null,\n createdAt: Number(row.created_at ?? 0),\n updatedAt: Number(row.updated_at ?? 0),\n };\n}\n\nexport function isRemoteCommandKind(\n value: unknown,\n): value is RemoteCommandKind {\n return (\n typeof value === \"string\" &&\n REMOTE_COMMAND_KINDS.includes(value as RemoteCommandKind)\n );\n}\n\nexport async function enqueueRemoteCommand(input: {\n deviceId: string;\n ownerEmail: string;\n orgId?: string | null;\n kind: RemoteCommandKind;\n params?: unknown;\n platform?: string | null;\n externalThreadId?: string | null;\n nextCheckAt?: number;\n}): Promise<RemoteCommand> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const id = `remote-command-${now}-${randomHex(8)}`;\n\n await client.execute({\n sql: `INSERT INTO integration_remote_commands\n (id, device_id, owner_email, org_id, kind, params_json, status, result_json,\n platform, external_thread_id, attempts, next_check_at, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n args: [\n id,\n input.deviceId,\n input.ownerEmail,\n input.orgId ?? null,\n input.kind,\n JSON.stringify(input.params ?? {}),\n \"pending\",\n null,\n input.platform ?? null,\n input.externalThreadId ?? null,\n 0,\n input.nextCheckAt ?? now,\n now,\n now,\n ],\n });\n\n const command = await getRemoteCommand(id);\n if (!command) throw new Error(\"remote command insert failed\");\n return command;\n}\n\nexport async function getRemoteCommand(\n id: string,\n): Promise<RemoteCommand | null> {\n await ensureTable();\n const { rows } = await getDbExec().execute({\n sql: `SELECT * FROM integration_remote_commands WHERE id = ? LIMIT 1`,\n args: [id],\n });\n return rows[0] ? rowToCommand(rows[0] as Record<string, unknown>) : null;\n}\n\nexport async function listRemoteCommandsForOwner(input: {\n ownerEmail: string;\n orgId?: string | null;\n limit?: number;\n}): Promise<RemoteCommand[]> {\n await ensureTable();\n const limit = Math.max(1, Math.min(input.limit ?? 100, 250));\n if (!Object.prototype.hasOwnProperty.call(input, \"orgId\")) {\n const { rows } = await getDbExec().execute({\n sql: `SELECT * FROM integration_remote_commands\n WHERE owner_email = ?\n ORDER BY updated_at DESC\n LIMIT ?`,\n args: [input.ownerEmail, limit],\n });\n return rows.map((row) => rowToCommand(row as Record<string, unknown>));\n }\n const { rows } = await getDbExec().execute({\n sql: `SELECT * FROM integration_remote_commands\n WHERE owner_email = ?\n AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)\n ORDER BY updated_at DESC\n LIMIT ?`,\n args: [input.ownerEmail, input.orgId ?? null, input.orgId ?? null, limit],\n });\n return rows.map((row) => rowToCommand(row as Record<string, unknown>));\n}\n\nexport async function claimNextRemoteCommand(\n deviceId: string,\n): Promise<RemoteCommand | null> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const { rows } = await client.execute({\n sql: `SELECT id FROM integration_remote_commands\n WHERE device_id = ?\n AND status = 'pending'\n AND next_check_at <= ?\n ORDER BY created_at ASC\n LIMIT 1`,\n args: [deviceId, now],\n });\n const id = rows[0]?.id as string | undefined;\n if (!id) return null;\n\n const result = await client.execute({\n sql: isPostgres()\n ? `UPDATE integration_remote_commands\n SET status = ?, attempts = attempts + 1, claimed_at = ?, updated_at = ?\n WHERE id = ? AND device_id = ? AND status = 'pending'\n RETURNING *`\n : `UPDATE integration_remote_commands\n SET status = ?, attempts = attempts + 1, claimed_at = ?, updated_at = ?\n WHERE id = ? AND device_id = ? AND status = 'pending'`,\n args: [\"claimed\", now, now, id, deviceId],\n });\n if (isPostgres()) {\n const row = result.rows?.[0];\n return row ? rowToCommand(row as Record<string, unknown>) : null;\n }\n const affected = result.rowsAffected ?? (result as any).rowCount;\n if (affected === 0) return null;\n\n const command = await getRemoteCommand(id);\n if (!command || command.status !== \"claimed\") return null;\n return command;\n}\n\nexport async function updateRemoteCommandResult(input: {\n deviceId: string;\n commandId: string;\n status: \"running\" | \"completed\" | \"failed\";\n result?: unknown;\n errorMessage?: string | null;\n}): Promise<RemoteCommand | null> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const completedAt = TERMINAL_STATUSES.has(input.status) ? now : null;\n const resultJson =\n input.result === undefined ? undefined : JSON.stringify(input.result);\n\n await client.execute({\n sql: `UPDATE integration_remote_commands\n SET status = ?,\n result_json = COALESCE(?, result_json),\n error_message = ?,\n completed_at = COALESCE(?, completed_at),\n updated_at = ?\n WHERE id = ? AND device_id = ?`,\n args: [\n input.status,\n resultJson ?? null,\n input.errorMessage ? input.errorMessage.slice(0, 2000) : null,\n completedAt,\n now,\n input.commandId,\n input.deviceId,\n ],\n });\n\n const command = await getRemoteCommand(input.commandId);\n if (!command || command.deviceId !== input.deviceId) return null;\n return command;\n}\n\nexport async function retryStaleRemoteCommands(options?: {\n claimedStaleAfterMs?: number;\n runningStaleAfterMs?: number;\n maxAttempts?: number;\n limit?: number;\n}): Promise<{ retried: number; failed: number }> {\n await ensureTable();\n const client = getDbExec();\n const now = Date.now();\n const claimedCutoff = now - (options?.claimedStaleAfterMs ?? 75_000);\n const runningCutoff = now - (options?.runningStaleAfterMs ?? 5 * 60_000);\n const maxAttempts = options?.maxAttempts ?? 3;\n const limit = options?.limit ?? 50;\n\n const { rows } = await client.execute({\n sql: `SELECT id, status, attempts FROM integration_remote_commands\n WHERE (status = 'claimed' AND updated_at <= ?)\n OR (status = 'running' AND updated_at <= ?)\n ORDER BY updated_at ASC\n LIMIT ?`,\n args: [claimedCutoff, runningCutoff, limit],\n });\n\n let retried = 0;\n let failed = 0;\n for (const row of rows) {\n const id = row.id as string;\n const status = row.status as RemoteCommandStatus;\n const attempts = Number(row.attempts ?? 0);\n if (attempts >= maxAttempts) {\n const result = await client.execute({\n sql: `UPDATE integration_remote_commands\n SET status = 'failed',\n error_message = COALESCE(error_message, ?),\n completed_at = ?,\n updated_at = ?\n WHERE id = ? AND status = ?`,\n args: [\n `Retry job: exceeded ${maxAttempts} attempts`,\n now,\n now,\n id,\n status,\n ],\n });\n if ((result.rowsAffected ?? (result as any).rowCount) > 0) failed++;\n continue;\n }\n\n const result = await client.execute({\n sql: `UPDATE integration_remote_commands\n SET status = 'pending',\n next_check_at = ?,\n updated_at = ?\n WHERE id = ? AND status = ?`,\n args: [now, now, id, status],\n });\n if ((result.rowsAffected ?? (result as any).rowCount) > 0) retried++;\n }\n\n return { retried, failed };\n}\n\nfunction parseJson(value: unknown, fallback: unknown): unknown {\n if (value == null) return fallback;\n try {\n return JSON.parse(String(value));\n } catch {\n return fallback;\n }\n}\n\nfunction randomHex(byteLength: number): string {\n const bytes = new Uint8Array(byteLength);\n globalThis.crypto.getRandomValues(bytes);\n return Array.from(bytes)\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n"]}
@@ -0,0 +1,43 @@
1
+ import type { PublicRemoteDevice, RemoteDevice } from "./remote-types.js";
2
+ export declare function toPublicRemoteDevice(device: RemoteDevice): PublicRemoteDevice;
3
+ export declare function createRemoteDevice(input: {
4
+ ownerEmail: string;
5
+ orgId?: string | null;
6
+ label: string;
7
+ platform?: string | null;
8
+ appVersion?: string | null;
9
+ hostName?: string | null;
10
+ metadata?: Record<string, unknown> | null;
11
+ }): Promise<{
12
+ device: RemoteDevice;
13
+ token: string;
14
+ }>;
15
+ export declare function getRemoteDevice(id: string): Promise<RemoteDevice | null>;
16
+ export declare function getRemoteDeviceForOwner(input: {
17
+ id: string;
18
+ ownerEmail: string;
19
+ orgId?: string | null;
20
+ }): Promise<RemoteDevice | null>;
21
+ export declare function listRemoteDevicesForOwner(input: {
22
+ ownerEmail: string;
23
+ orgId?: string | null;
24
+ status?: RemoteDevice["status"];
25
+ limit?: number;
26
+ }): Promise<RemoteDevice[]>;
27
+ export declare function authenticateRemoteDeviceToken(rawToken: string | null | undefined): Promise<RemoteDevice | null>;
28
+ export declare function updateRemoteDeviceDetails(input: {
29
+ id: string;
30
+ label?: string | null;
31
+ platform?: string | null;
32
+ appVersion?: string | null;
33
+ hostName?: string | null;
34
+ metadata?: Record<string, unknown> | null;
35
+ }): Promise<RemoteDevice | null>;
36
+ export declare function revokeRemoteDeviceForOwner(input: {
37
+ id: string;
38
+ ownerEmail: string;
39
+ orgId?: string | null;
40
+ }): Promise<RemoteDevice | null>;
41
+ export declare function unregisterRemoteDevice(id: string): Promise<boolean>;
42
+ export declare function hashRemoteDeviceToken(token: string): Promise<string>;
43
+ //# sourceMappingURL=remote-devices-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-devices-store.d.ts","sourceRoot":"","sources":["../../src/integrations/remote-devices-store.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAkG1E,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,GAAG,kBAAkB,CAgB7E;AAED,wBAAsB,kBAAkB,CAAC,KAAK,EAAE;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC3C,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAkCnD;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAO9B;AAED,wBAAsB,uBAAuB,CAAC,KAAK,EAAE;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAgB/B;AAED,wBAAsB,yBAAyB,CAAC,KAAK,EAAE;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAiC1B;AAED,wBAAsB,6BAA6B,CACjD,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAClC,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAqB9B;AAED,wBAAsB,yBAAyB,CAAC,KAAK,EAAE;IACrD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC3C,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAoC/B;AAED,wBAAsB,0BAA0B,CAAC,KAAK,EAAE;IACtD,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAqB/B;AAED,wBAAsB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAYzE;AAED,wBAAsB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAI1E"}
@@ -0,0 +1,315 @@
1
+ import { getDbExec, intType, isPostgres, retryOnDdlRace, } from "../db/client.js";
2
+ let _initPromise;
3
+ async function ensureTable() {
4
+ if (!_initPromise) {
5
+ _initPromise = (async () => {
6
+ const client = getDbExec();
7
+ await retryOnDdlRace(() => client.execute(`
8
+ CREATE TABLE IF NOT EXISTS integration_remote_devices (
9
+ id TEXT PRIMARY KEY,
10
+ owner_email TEXT NOT NULL,
11
+ org_id TEXT,
12
+ label TEXT NOT NULL,
13
+ platform TEXT,
14
+ app_version TEXT,
15
+ host_name TEXT,
16
+ metadata_json TEXT,
17
+ device_token_hash TEXT NOT NULL,
18
+ last_seen_at ${intType()},
19
+ status TEXT NOT NULL,
20
+ revoked_at ${intType()},
21
+ created_at ${intType()} NOT NULL,
22
+ updated_at ${intType()} NOT NULL
23
+ )
24
+ `));
25
+ await addColumnIfMissing("platform", "TEXT");
26
+ await addColumnIfMissing("app_version", "TEXT");
27
+ await addColumnIfMissing("host_name", "TEXT");
28
+ await addColumnIfMissing("metadata_json", "TEXT");
29
+ await addColumnIfMissing("revoked_at", intType());
30
+ await retryOnDdlRace(() => client.execute(`CREATE UNIQUE INDEX IF NOT EXISTS idx_remote_devices_token_hash ON integration_remote_devices(device_token_hash)`));
31
+ await retryOnDdlRace(() => client.execute(`CREATE INDEX IF NOT EXISTS idx_remote_devices_owner ON integration_remote_devices(owner_email, org_id)`));
32
+ })();
33
+ }
34
+ return _initPromise;
35
+ }
36
+ async function addColumnIfMissing(name, definition) {
37
+ const sql = isPostgres()
38
+ ? `ALTER TABLE integration_remote_devices ADD COLUMN IF NOT EXISTS ${name} ${definition}`
39
+ : `ALTER TABLE integration_remote_devices ADD COLUMN ${name} ${definition}`;
40
+ try {
41
+ await retryOnDdlRace(() => getDbExec().execute(sql));
42
+ }
43
+ catch (err) {
44
+ if (isDuplicateColumnError(err))
45
+ return;
46
+ throw err;
47
+ }
48
+ }
49
+ function isDuplicateColumnError(err) {
50
+ const code = String(err?.code ?? "");
51
+ const message = String(err?.message ?? err)
52
+ .toLowerCase()
53
+ .trim();
54
+ return (code === "42701" ||
55
+ message.includes("duplicate column") ||
56
+ message.includes("already exists"));
57
+ }
58
+ function rowToDevice(row) {
59
+ return {
60
+ id: row.id,
61
+ ownerEmail: row.owner_email,
62
+ orgId: row.org_id ?? null,
63
+ label: row.label,
64
+ platform: row.platform ?? null,
65
+ appVersion: row.app_version ?? null,
66
+ hostName: row.host_name ?? null,
67
+ metadata: parseJson(row.metadata_json, null),
68
+ deviceTokenHash: row.device_token_hash,
69
+ lastSeenAt: row.last_seen_at == null ? null : Number(row.last_seen_at),
70
+ status: row.status,
71
+ revokedAt: row.revoked_at == null ? null : Number(row.revoked_at),
72
+ createdAt: Number(row.created_at ?? 0),
73
+ updatedAt: Number(row.updated_at ?? 0),
74
+ };
75
+ }
76
+ export function toPublicRemoteDevice(device) {
77
+ return {
78
+ id: device.id,
79
+ ownerEmail: device.ownerEmail,
80
+ orgId: device.orgId,
81
+ label: device.label,
82
+ platform: device.platform,
83
+ appVersion: device.appVersion,
84
+ hostName: device.hostName,
85
+ metadata: device.metadata,
86
+ lastSeenAt: device.lastSeenAt,
87
+ status: device.status,
88
+ revokedAt: device.revokedAt,
89
+ createdAt: device.createdAt,
90
+ updatedAt: device.updatedAt,
91
+ };
92
+ }
93
+ export async function createRemoteDevice(input) {
94
+ await ensureTable();
95
+ const client = getDbExec();
96
+ const now = Date.now();
97
+ const id = `remote-device-${now}-${randomHex(8)}`;
98
+ const token = `anr_${randomHex(32)}`;
99
+ const tokenHash = await hashRemoteDeviceToken(token);
100
+ await client.execute({
101
+ sql: `INSERT INTO integration_remote_devices
102
+ (id, owner_email, org_id, label, platform, app_version, host_name, metadata_json,
103
+ device_token_hash, last_seen_at, status, revoked_at, created_at, updated_at)
104
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
105
+ args: [
106
+ id,
107
+ input.ownerEmail,
108
+ input.orgId ?? null,
109
+ input.label.trim() || "Remote device",
110
+ sanitizeOptionalString(input.platform, 80),
111
+ sanitizeOptionalString(input.appVersion, 120),
112
+ sanitizeOptionalString(input.hostName, 200),
113
+ input.metadata ? JSON.stringify(input.metadata) : null,
114
+ tokenHash,
115
+ now,
116
+ "active",
117
+ null,
118
+ now,
119
+ now,
120
+ ],
121
+ });
122
+ const device = await getRemoteDevice(id);
123
+ if (!device)
124
+ throw new Error("remote device insert failed");
125
+ return { device, token };
126
+ }
127
+ export async function getRemoteDevice(id) {
128
+ await ensureTable();
129
+ const { rows } = await getDbExec().execute({
130
+ sql: `SELECT * FROM integration_remote_devices WHERE id = ? LIMIT 1`,
131
+ args: [id],
132
+ });
133
+ return rows[0] ? rowToDevice(rows[0]) : null;
134
+ }
135
+ export async function getRemoteDeviceForOwner(input) {
136
+ await ensureTable();
137
+ const { rows } = await getDbExec().execute({
138
+ sql: `SELECT * FROM integration_remote_devices
139
+ WHERE id = ?
140
+ AND owner_email = ?
141
+ AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)
142
+ LIMIT 1`,
143
+ args: [
144
+ input.id,
145
+ input.ownerEmail,
146
+ input.orgId ?? null,
147
+ input.orgId ?? null,
148
+ ],
149
+ });
150
+ return rows[0] ? rowToDevice(rows[0]) : null;
151
+ }
152
+ export async function listRemoteDevicesForOwner(input) {
153
+ await ensureTable();
154
+ const limit = Math.max(1, Math.min(input.limit ?? 50, 100));
155
+ const statusClause = input.status ? " AND status = ?" : "";
156
+ if (!Object.prototype.hasOwnProperty.call(input, "orgId")) {
157
+ const args = [input.ownerEmail];
158
+ if (input.status)
159
+ args.push(input.status);
160
+ args.push(limit);
161
+ const { rows } = await getDbExec().execute({
162
+ sql: `SELECT * FROM integration_remote_devices
163
+ WHERE owner_email = ?${statusClause}
164
+ ORDER BY COALESCE(last_seen_at, updated_at) DESC
165
+ LIMIT ?`,
166
+ args,
167
+ });
168
+ return rows.map((row) => rowToDevice(row));
169
+ }
170
+ const args = [
171
+ input.ownerEmail,
172
+ input.orgId ?? null,
173
+ input.orgId ?? null,
174
+ ];
175
+ if (input.status)
176
+ args.push(input.status);
177
+ args.push(limit);
178
+ const { rows } = await getDbExec().execute({
179
+ sql: `SELECT * FROM integration_remote_devices
180
+ WHERE owner_email = ?
181
+ AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)${statusClause}
182
+ ORDER BY COALESCE(last_seen_at, updated_at) DESC
183
+ LIMIT ?`,
184
+ args,
185
+ });
186
+ return rows.map((row) => rowToDevice(row));
187
+ }
188
+ export async function authenticateRemoteDeviceToken(rawToken) {
189
+ if (!rawToken)
190
+ return null;
191
+ await ensureTable();
192
+ const tokenHash = await hashRemoteDeviceToken(rawToken);
193
+ const now = Date.now();
194
+ const client = getDbExec();
195
+ const { rows } = await client.execute({
196
+ sql: `SELECT * FROM integration_remote_devices
197
+ WHERE device_token_hash = ? AND status = 'active'
198
+ LIMIT 1`,
199
+ args: [tokenHash],
200
+ });
201
+ if (!rows[0])
202
+ return null;
203
+ const device = rowToDevice(rows[0]);
204
+ await client.execute({
205
+ sql: `UPDATE integration_remote_devices
206
+ SET last_seen_at = ?, updated_at = ?
207
+ WHERE id = ?`,
208
+ args: [now, now, device.id],
209
+ });
210
+ return { ...device, lastSeenAt: now, updatedAt: now };
211
+ }
212
+ export async function updateRemoteDeviceDetails(input) {
213
+ await ensureTable();
214
+ const now = Date.now();
215
+ const updates = [];
216
+ const args = [];
217
+ if (input.label !== undefined) {
218
+ updates.push("label = ?");
219
+ args.push(sanitizeOptionalString(input.label, 200) ?? "Remote device");
220
+ }
221
+ if (input.platform !== undefined) {
222
+ updates.push("platform = ?");
223
+ args.push(sanitizeOptionalString(input.platform, 80));
224
+ }
225
+ if (input.appVersion !== undefined) {
226
+ updates.push("app_version = ?");
227
+ args.push(sanitizeOptionalString(input.appVersion, 120));
228
+ }
229
+ if (input.hostName !== undefined) {
230
+ updates.push("host_name = ?");
231
+ args.push(sanitizeOptionalString(input.hostName, 200));
232
+ }
233
+ if (input.metadata !== undefined) {
234
+ updates.push("metadata_json = ?");
235
+ args.push(input.metadata ? JSON.stringify(input.metadata) : null);
236
+ }
237
+ if (updates.length === 0)
238
+ return getRemoteDevice(input.id);
239
+ updates.push("updated_at = ?");
240
+ args.push(now, input.id);
241
+ await getDbExec().execute({
242
+ sql: `UPDATE integration_remote_devices
243
+ SET ${updates.join(", ")}
244
+ WHERE id = ? AND status = 'active'`,
245
+ args,
246
+ });
247
+ return getRemoteDevice(input.id);
248
+ }
249
+ export async function revokeRemoteDeviceForOwner(input) {
250
+ await ensureTable();
251
+ const now = Date.now();
252
+ await getDbExec().execute({
253
+ sql: `UPDATE integration_remote_devices
254
+ SET status = 'inactive',
255
+ revoked_at = COALESCE(revoked_at, ?),
256
+ updated_at = ?
257
+ WHERE id = ?
258
+ AND owner_email = ?
259
+ AND ((org_id IS NULL AND ? IS NULL) OR org_id = ?)`,
260
+ args: [
261
+ now,
262
+ now,
263
+ input.id,
264
+ input.ownerEmail,
265
+ input.orgId ?? null,
266
+ input.orgId ?? null,
267
+ ],
268
+ });
269
+ return getRemoteDeviceForOwner(input);
270
+ }
271
+ export async function unregisterRemoteDevice(id) {
272
+ await ensureTable();
273
+ const now = Date.now();
274
+ const result = await getDbExec().execute({
275
+ sql: `UPDATE integration_remote_devices
276
+ SET status = 'inactive',
277
+ revoked_at = COALESCE(revoked_at, ?),
278
+ updated_at = ?
279
+ WHERE id = ? AND status = 'active'`,
280
+ args: [now, now, id],
281
+ });
282
+ return (result.rowsAffected ?? result.rowCount ?? 0) > 0;
283
+ }
284
+ export async function hashRemoteDeviceToken(token) {
285
+ const bytes = new TextEncoder().encode(token);
286
+ const digest = await globalThis.crypto.subtle.digest("SHA-256", bytes);
287
+ return bytesToHex(new Uint8Array(digest));
288
+ }
289
+ function sanitizeOptionalString(value, max) {
290
+ if (typeof value !== "string")
291
+ return null;
292
+ const trimmed = value.trim();
293
+ return trimmed ? trimmed.slice(0, max) : null;
294
+ }
295
+ function parseJson(value, fallback) {
296
+ if (value == null)
297
+ return fallback;
298
+ try {
299
+ return JSON.parse(String(value));
300
+ }
301
+ catch {
302
+ return fallback;
303
+ }
304
+ }
305
+ function randomHex(byteLength) {
306
+ const bytes = new Uint8Array(byteLength);
307
+ globalThis.crypto.getRandomValues(bytes);
308
+ return bytesToHex(bytes);
309
+ }
310
+ function bytesToHex(bytes) {
311
+ return Array.from(bytes)
312
+ .map((byte) => byte.toString(16).padStart(2, "0"))
313
+ .join("");
314
+ }
315
+ //# sourceMappingURL=remote-devices-store.js.map