@agent-native/core 0.7.13 → 0.7.14

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 (381) hide show
  1. package/dist/a2a/client.d.ts +44 -1
  2. package/dist/a2a/client.d.ts.map +1 -1
  3. package/dist/a2a/client.js +88 -11
  4. package/dist/a2a/client.js.map +1 -1
  5. package/dist/a2a/handlers.d.ts +10 -0
  6. package/dist/a2a/handlers.d.ts.map +1 -1
  7. package/dist/a2a/handlers.js +287 -62
  8. package/dist/a2a/handlers.js.map +1 -1
  9. package/dist/a2a/server.d.ts.map +1 -1
  10. package/dist/a2a/server.js +95 -17
  11. package/dist/a2a/server.js.map +1 -1
  12. package/dist/a2a/task-store.d.ts +11 -1
  13. package/dist/a2a/task-store.d.ts.map +1 -1
  14. package/dist/a2a/task-store.js +38 -2
  15. package/dist/a2a/task-store.js.map +1 -1
  16. package/dist/agent/engine/builder-engine.d.ts +1 -1
  17. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  18. package/dist/agent/engine/builder-engine.js +7 -25
  19. package/dist/agent/engine/builder-engine.js.map +1 -1
  20. package/dist/agent/engine/builtin.js +1 -1
  21. package/dist/agent/engine/builtin.js.map +1 -1
  22. package/dist/chat-threads/store.d.ts +3 -0
  23. package/dist/chat-threads/store.d.ts.map +1 -1
  24. package/dist/chat-threads/store.js +32 -0
  25. package/dist/chat-threads/store.js.map +1 -1
  26. package/dist/cli/templates-meta.d.ts.map +1 -1
  27. package/dist/cli/templates-meta.js +11 -0
  28. package/dist/cli/templates-meta.js.map +1 -1
  29. package/dist/client/AgentPanel.d.ts +3 -1
  30. package/dist/client/AgentPanel.d.ts.map +1 -1
  31. package/dist/client/AgentPanel.js +21 -10
  32. package/dist/client/AgentPanel.js.map +1 -1
  33. package/dist/client/AgentTaskCard.d.ts.map +1 -1
  34. package/dist/client/AgentTaskCard.js +2 -0
  35. package/dist/client/AgentTaskCard.js.map +1 -1
  36. package/dist/client/AssistantChat.d.ts +2 -0
  37. package/dist/client/AssistantChat.d.ts.map +1 -1
  38. package/dist/client/AssistantChat.js +111 -75
  39. package/dist/client/AssistantChat.js.map +1 -1
  40. package/dist/client/ErrorBoundary.d.ts +1 -3
  41. package/dist/client/ErrorBoundary.d.ts.map +1 -1
  42. package/dist/client/ErrorBoundary.js +37 -9
  43. package/dist/client/ErrorBoundary.js.map +1 -1
  44. package/dist/client/FeedbackButton.d.ts.map +1 -1
  45. package/dist/client/FeedbackButton.js +4 -3
  46. package/dist/client/FeedbackButton.js.map +1 -1
  47. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  48. package/dist/client/MultiTabAssistantChat.js +145 -49
  49. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  50. package/dist/client/agent-chat.d.ts +11 -0
  51. package/dist/client/agent-chat.d.ts.map +1 -1
  52. package/dist/client/agent-chat.js +1 -1
  53. package/dist/client/agent-chat.js.map +1 -1
  54. package/dist/client/components/AgentPresenceChip.d.ts +12 -0
  55. package/dist/client/components/AgentPresenceChip.d.ts.map +1 -0
  56. package/dist/client/components/AgentPresenceChip.js +42 -0
  57. package/dist/client/components/AgentPresenceChip.js.map +1 -0
  58. package/dist/client/components/PresenceBar.d.ts +17 -0
  59. package/dist/client/components/PresenceBar.d.ts.map +1 -0
  60. package/dist/client/components/PresenceBar.js +118 -0
  61. package/dist/client/components/PresenceBar.js.map +1 -0
  62. package/dist/client/composer/ComposerPlusMenu.d.ts +6 -1
  63. package/dist/client/composer/ComposerPlusMenu.d.ts.map +1 -1
  64. package/dist/client/composer/ComposerPlusMenu.js +22 -83
  65. package/dist/client/composer/ComposerPlusMenu.js.map +1 -1
  66. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  67. package/dist/client/composer/TiptapComposer.js +237 -16
  68. package/dist/client/composer/TiptapComposer.js.map +1 -1
  69. package/dist/client/composer/types.d.ts +1 -0
  70. package/dist/client/composer/types.d.ts.map +1 -1
  71. package/dist/client/composer/useVoiceDictation.d.ts +2 -0
  72. package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
  73. package/dist/client/composer/useVoiceDictation.js +85 -10
  74. package/dist/client/composer/useVoiceDictation.js.map +1 -1
  75. package/dist/client/index.d.ts +3 -0
  76. package/dist/client/index.d.ts.map +1 -1
  77. package/dist/client/index.js +5 -0
  78. package/dist/client/index.js.map +1 -1
  79. package/dist/client/org/RequireActiveOrg.d.ts.map +1 -1
  80. package/dist/client/org/RequireActiveOrg.js +15 -10
  81. package/dist/client/org/RequireActiveOrg.js.map +1 -1
  82. package/dist/client/org/TeamPage.d.ts.map +1 -1
  83. package/dist/client/org/TeamPage.js +125 -4
  84. package/dist/client/org/TeamPage.js.map +1 -1
  85. package/dist/client/org/hooks.d.ts +30 -0
  86. package/dist/client/org/hooks.d.ts.map +1 -1
  87. package/dist/client/org/hooks.js +65 -0
  88. package/dist/client/org/hooks.js.map +1 -1
  89. package/dist/client/org/index.d.ts +2 -2
  90. package/dist/client/org/index.d.ts.map +1 -1
  91. package/dist/client/org/index.js +1 -1
  92. package/dist/client/org/index.js.map +1 -1
  93. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  94. package/dist/client/resources/ResourcesPanel.js +5 -1
  95. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  96. package/dist/client/settings/AutomationsSection.d.ts.map +1 -1
  97. package/dist/client/settings/AutomationsSection.js +1 -0
  98. package/dist/client/settings/AutomationsSection.js.map +1 -1
  99. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  100. package/dist/client/settings/SettingsPanel.js +24 -11
  101. package/dist/client/settings/SettingsPanel.js.map +1 -1
  102. package/dist/client/sse-event-processor.d.ts.map +1 -1
  103. package/dist/client/sse-event-processor.js +10 -0
  104. package/dist/client/sse-event-processor.js.map +1 -1
  105. package/dist/client/tools/ToolEditor.d.ts +5 -0
  106. package/dist/client/tools/ToolEditor.d.ts.map +1 -0
  107. package/dist/client/tools/ToolEditor.js +98 -0
  108. package/dist/client/tools/ToolEditor.js.map +1 -0
  109. package/dist/client/tools/ToolViewer.d.ts +5 -0
  110. package/dist/client/tools/ToolViewer.d.ts.map +1 -0
  111. package/dist/client/tools/ToolViewer.js +309 -0
  112. package/dist/client/tools/ToolViewer.js.map +1 -0
  113. package/dist/client/tools/ToolViewerPage.d.ts +2 -0
  114. package/dist/client/tools/ToolViewerPage.d.ts.map +1 -0
  115. package/dist/client/tools/ToolViewerPage.js +23 -0
  116. package/dist/client/tools/ToolViewerPage.js.map +1 -0
  117. package/dist/client/tools/ToolsListPage.d.ts +2 -0
  118. package/dist/client/tools/ToolsListPage.d.ts.map +1 -0
  119. package/dist/client/tools/ToolsListPage.js +72 -0
  120. package/dist/client/tools/ToolsListPage.js.map +1 -0
  121. package/dist/client/tools/ToolsSidebarSection.d.ts +2 -0
  122. package/dist/client/tools/ToolsSidebarSection.d.ts.map +1 -0
  123. package/dist/client/tools/ToolsSidebarSection.js +188 -0
  124. package/dist/client/tools/ToolsSidebarSection.js.map +1 -0
  125. package/dist/client/tools/index.d.ts +6 -0
  126. package/dist/client/tools/index.d.ts.map +1 -0
  127. package/dist/client/tools/index.js +6 -0
  128. package/dist/client/tools/index.js.map +1 -0
  129. package/dist/client/use-chat-threads.d.ts +1 -0
  130. package/dist/client/use-chat-threads.d.ts.map +1 -1
  131. package/dist/client/use-chat-threads.js +29 -0
  132. package/dist/client/use-chat-threads.js.map +1 -1
  133. package/dist/client/use-db-sync.js +6 -6
  134. package/dist/client/use-db-sync.js.map +1 -1
  135. package/dist/collab/agent-identity.d.ts +15 -0
  136. package/dist/collab/agent-identity.d.ts.map +1 -0
  137. package/dist/collab/agent-identity.js +14 -0
  138. package/dist/collab/agent-identity.js.map +1 -0
  139. package/dist/collab/agent-presence.d.ts +59 -0
  140. package/dist/collab/agent-presence.d.ts.map +1 -0
  141. package/dist/collab/agent-presence.js +165 -0
  142. package/dist/collab/agent-presence.js.map +1 -0
  143. package/dist/collab/awareness.d.ts +7 -0
  144. package/dist/collab/awareness.d.ts.map +1 -1
  145. package/dist/collab/awareness.js +2 -2
  146. package/dist/collab/awareness.js.map +1 -1
  147. package/dist/collab/client-struct.d.ts +43 -0
  148. package/dist/collab/client-struct.d.ts.map +1 -0
  149. package/dist/collab/client-struct.js +272 -0
  150. package/dist/collab/client-struct.js.map +1 -0
  151. package/dist/collab/client.d.ts +2 -0
  152. package/dist/collab/client.d.ts.map +1 -1
  153. package/dist/collab/client.js +15 -1
  154. package/dist/collab/client.js.map +1 -1
  155. package/dist/collab/index.d.ts +6 -1
  156. package/dist/collab/index.d.ts.map +1 -1
  157. package/dist/collab/index.js +11 -1
  158. package/dist/collab/index.js.map +1 -1
  159. package/dist/collab/json-to-yjs.d.ts +72 -0
  160. package/dist/collab/json-to-yjs.d.ts.map +1 -0
  161. package/dist/collab/json-to-yjs.js +456 -0
  162. package/dist/collab/json-to-yjs.js.map +1 -0
  163. package/dist/collab/struct-routes.d.ts +52 -0
  164. package/dist/collab/struct-routes.d.ts.map +1 -0
  165. package/dist/collab/struct-routes.js +74 -0
  166. package/dist/collab/struct-routes.js.map +1 -0
  167. package/dist/collab/ydoc-manager.d.ts +19 -0
  168. package/dist/collab/ydoc-manager.d.ts.map +1 -1
  169. package/dist/collab/ydoc-manager.js +49 -0
  170. package/dist/collab/ydoc-manager.js.map +1 -1
  171. package/dist/deploy/build.js +1 -1
  172. package/dist/file-upload/builder.d.ts.map +1 -1
  173. package/dist/file-upload/builder.js +2 -1
  174. package/dist/file-upload/builder.js.map +1 -1
  175. package/dist/integrations/adapters/email.d.ts +17 -0
  176. package/dist/integrations/adapters/email.d.ts.map +1 -0
  177. package/dist/integrations/adapters/email.js +620 -0
  178. package/dist/integrations/adapters/email.js.map +1 -0
  179. package/dist/integrations/adapters/telegram.d.ts.map +1 -1
  180. package/dist/integrations/adapters/telegram.js +19 -3
  181. package/dist/integrations/adapters/telegram.js.map +1 -1
  182. package/dist/integrations/index.d.ts +1 -0
  183. package/dist/integrations/index.d.ts.map +1 -1
  184. package/dist/integrations/index.js +1 -0
  185. package/dist/integrations/index.js.map +1 -1
  186. package/dist/integrations/internal-token.d.ts +18 -0
  187. package/dist/integrations/internal-token.d.ts.map +1 -0
  188. package/dist/integrations/internal-token.js +86 -0
  189. package/dist/integrations/internal-token.js.map +1 -0
  190. package/dist/integrations/pending-tasks-retry-job.d.ts +15 -0
  191. package/dist/integrations/pending-tasks-retry-job.d.ts.map +1 -0
  192. package/dist/integrations/pending-tasks-retry-job.js +199 -0
  193. package/dist/integrations/pending-tasks-retry-job.js.map +1 -0
  194. package/dist/integrations/pending-tasks-store.d.ts +40 -0
  195. package/dist/integrations/pending-tasks-store.d.ts.map +1 -0
  196. package/dist/integrations/pending-tasks-store.js +151 -0
  197. package/dist/integrations/pending-tasks-store.js.map +1 -0
  198. package/dist/integrations/plugin.d.ts.map +1 -1
  199. package/dist/integrations/plugin.js +151 -9
  200. package/dist/integrations/plugin.js.map +1 -1
  201. package/dist/integrations/task-queue-stats.d.ts +22 -0
  202. package/dist/integrations/task-queue-stats.d.ts.map +1 -0
  203. package/dist/integrations/task-queue-stats.js +117 -0
  204. package/dist/integrations/task-queue-stats.js.map +1 -0
  205. package/dist/integrations/types.d.ts +2 -0
  206. package/dist/integrations/types.d.ts.map +1 -1
  207. package/dist/integrations/webhook-handler.d.ts +23 -4
  208. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  209. package/dist/integrations/webhook-handler.js +217 -59
  210. package/dist/integrations/webhook-handler.js.map +1 -1
  211. package/dist/mcp-client/manager.d.ts +3 -0
  212. package/dist/mcp-client/manager.d.ts.map +1 -1
  213. package/dist/mcp-client/manager.js +5 -0
  214. package/dist/mcp-client/manager.js.map +1 -1
  215. package/dist/oauth-tokens/google-refresh.d.ts.map +1 -1
  216. package/dist/oauth-tokens/google-refresh.js +6 -0
  217. package/dist/oauth-tokens/google-refresh.js.map +1 -1
  218. package/dist/onboarding/default-steps.d.ts.map +1 -1
  219. package/dist/onboarding/default-steps.js +10 -3
  220. package/dist/onboarding/default-steps.js.map +1 -1
  221. package/dist/org/context.d.ts +35 -0
  222. package/dist/org/context.d.ts.map +1 -1
  223. package/dist/org/context.js +136 -0
  224. package/dist/org/context.js.map +1 -1
  225. package/dist/org/handlers.d.ts +76 -0
  226. package/dist/org/handlers.d.ts.map +1 -1
  227. package/dist/org/handlers.js +411 -2
  228. package/dist/org/handlers.js.map +1 -1
  229. package/dist/org/index.d.ts +2 -2
  230. package/dist/org/index.d.ts.map +1 -1
  231. package/dist/org/index.js +2 -2
  232. package/dist/org/index.js.map +1 -1
  233. package/dist/org/migrations.d.ts.map +1 -1
  234. package/dist/org/migrations.js +8 -0
  235. package/dist/org/migrations.js.map +1 -1
  236. package/dist/org/plugin.d.ts +6 -0
  237. package/dist/org/plugin.d.ts.map +1 -1
  238. package/dist/org/plugin.js +71 -7
  239. package/dist/org/plugin.js.map +1 -1
  240. package/dist/org/schema.d.ts +38 -0
  241. package/dist/org/schema.d.ts.map +1 -1
  242. package/dist/org/schema.js +2 -0
  243. package/dist/org/schema.js.map +1 -1
  244. package/dist/org/types.d.ts +7 -0
  245. package/dist/org/types.d.ts.map +1 -1
  246. package/dist/scripts/call-agent.d.ts.map +1 -1
  247. package/dist/scripts/call-agent.js +90 -18
  248. package/dist/scripts/call-agent.js.map +1 -1
  249. package/dist/scripts/db/index.d.ts.map +1 -1
  250. package/dist/scripts/db/index.js +2 -0
  251. package/dist/scripts/db/index.js.map +1 -1
  252. package/dist/scripts/db/migrate-user-api-keys.d.ts +24 -0
  253. package/dist/scripts/db/migrate-user-api-keys.d.ts.map +1 -0
  254. package/dist/scripts/db/migrate-user-api-keys.js +224 -0
  255. package/dist/scripts/db/migrate-user-api-keys.js.map +1 -0
  256. package/dist/scripts/db/wipe-leaked-builder-keys.d.ts +27 -0
  257. package/dist/scripts/db/wipe-leaked-builder-keys.d.ts.map +1 -0
  258. package/dist/scripts/db/wipe-leaked-builder-keys.js +163 -0
  259. package/dist/scripts/db/wipe-leaked-builder-keys.js.map +1 -0
  260. package/dist/secrets/register-framework-secrets.d.ts +5 -0
  261. package/dist/secrets/register-framework-secrets.d.ts.map +1 -1
  262. package/dist/secrets/register-framework-secrets.js +7 -44
  263. package/dist/secrets/register-framework-secrets.js.map +1 -1
  264. package/dist/secrets/substitution.d.ts.map +1 -1
  265. package/dist/secrets/substitution.js +14 -2
  266. package/dist/secrets/substitution.js.map +1 -1
  267. package/dist/server/action-discovery.d.ts.map +1 -1
  268. package/dist/server/action-discovery.js +39 -0
  269. package/dist/server/action-discovery.js.map +1 -1
  270. package/dist/server/action-routes.js +1 -1
  271. package/dist/server/action-routes.js.map +1 -1
  272. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  273. package/dist/server/agent-chat-plugin.js +192 -45
  274. package/dist/server/agent-chat-plugin.js.map +1 -1
  275. package/dist/server/auth.d.ts +14 -0
  276. package/dist/server/auth.d.ts.map +1 -1
  277. package/dist/server/auth.js +232 -17
  278. package/dist/server/auth.js.map +1 -1
  279. package/dist/server/builder-browser.d.ts +1 -1
  280. package/dist/server/builder-browser.d.ts.map +1 -1
  281. package/dist/server/builder-browser.js +12 -12
  282. package/dist/server/builder-browser.js.map +1 -1
  283. package/dist/server/collab-plugin.d.ts +4 -0
  284. package/dist/server/collab-plugin.d.ts.map +1 -1
  285. package/dist/server/collab-plugin.js +30 -4
  286. package/dist/server/collab-plugin.js.map +1 -1
  287. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  288. package/dist/server/core-routes-plugin.js +106 -100
  289. package/dist/server/core-routes-plugin.js.map +1 -1
  290. package/dist/server/credential-provider.d.ts +43 -2
  291. package/dist/server/credential-provider.d.ts.map +1 -1
  292. package/dist/server/credential-provider.js +115 -2
  293. package/dist/server/credential-provider.js.map +1 -1
  294. package/dist/server/design-token-utils.d.ts +132 -0
  295. package/dist/server/design-token-utils.d.ts.map +1 -0
  296. package/dist/server/design-token-utils.js +714 -0
  297. package/dist/server/design-token-utils.js.map +1 -0
  298. package/dist/server/email.d.ts +10 -0
  299. package/dist/server/email.d.ts.map +1 -1
  300. package/dist/server/email.js +63 -16
  301. package/dist/server/email.js.map +1 -1
  302. package/dist/server/framework-request-handler.d.ts.map +1 -1
  303. package/dist/server/framework-request-handler.js +38 -3
  304. package/dist/server/framework-request-handler.js.map +1 -1
  305. package/dist/server/google-oauth.d.ts +18 -1
  306. package/dist/server/google-oauth.d.ts.map +1 -1
  307. package/dist/server/google-oauth.js +21 -4
  308. package/dist/server/google-oauth.js.map +1 -1
  309. package/dist/server/index.d.ts +3 -3
  310. package/dist/server/index.d.ts.map +1 -1
  311. package/dist/server/index.js +3 -3
  312. package/dist/server/index.js.map +1 -1
  313. package/dist/server/onboarding-html.d.ts.map +1 -1
  314. package/dist/server/onboarding-html.js +14 -1
  315. package/dist/server/onboarding-html.js.map +1 -1
  316. package/dist/server/transcribe-voice.d.ts.map +1 -1
  317. package/dist/server/transcribe-voice.js +89 -24
  318. package/dist/server/transcribe-voice.js.map +1 -1
  319. package/dist/sharing/schema.d.ts +1 -1
  320. package/dist/styles/agent-native.css +5 -0
  321. package/dist/templates/default/app/root.tsx +50 -13
  322. package/dist/templates/default/react-router.config.ts +3 -0
  323. package/dist/terminal/terminal-plugin.d.ts.map +1 -1
  324. package/dist/terminal/terminal-plugin.js +23 -3
  325. package/dist/terminal/terminal-plugin.js.map +1 -1
  326. package/dist/tools/actions.d.ts +3 -0
  327. package/dist/tools/actions.d.ts.map +1 -0
  328. package/dist/tools/actions.js +140 -0
  329. package/dist/tools/actions.js.map +1 -0
  330. package/dist/tools/fetch-tool.js +1 -1
  331. package/dist/tools/fetch-tool.js.map +1 -1
  332. package/dist/tools/html-shell.d.ts +2 -0
  333. package/dist/tools/html-shell.d.ts.map +1 -0
  334. package/dist/tools/html-shell.js +387 -0
  335. package/dist/tools/html-shell.js.map +1 -0
  336. package/dist/tools/routes.d.ts +2 -0
  337. package/dist/tools/routes.d.ts.map +1 -0
  338. package/dist/tools/routes.js +576 -0
  339. package/dist/tools/routes.js.map +1 -0
  340. package/dist/tools/schema.d.ts +575 -0
  341. package/dist/tools/schema.d.ts.map +1 -0
  342. package/dist/tools/schema.js +112 -0
  343. package/dist/tools/schema.js.map +1 -0
  344. package/dist/tools/store.d.ts +40 -0
  345. package/dist/tools/store.d.ts.map +1 -0
  346. package/dist/tools/store.js +190 -0
  347. package/dist/tools/store.js.map +1 -0
  348. package/dist/tools/theme.d.ts +2 -0
  349. package/dist/tools/theme.d.ts.map +1 -0
  350. package/dist/tools/theme.js +67 -0
  351. package/dist/tools/theme.js.map +1 -0
  352. package/dist/transcription/builder-transcription.d.ts.map +1 -1
  353. package/dist/transcription/builder-transcription.js +26 -14
  354. package/dist/transcription/builder-transcription.js.map +1 -1
  355. package/dist/vite/action-types-plugin.d.ts.map +1 -1
  356. package/dist/vite/action-types-plugin.js +10 -2
  357. package/dist/vite/action-types-plugin.js.map +1 -1
  358. package/dist/vite/client.d.ts.map +1 -1
  359. package/dist/vite/client.js +26 -6
  360. package/dist/vite/client.js.map +1 -1
  361. package/docs/content/a2a-protocol.md +2 -2
  362. package/docs/content/authentication.md +51 -0
  363. package/docs/content/cloneable-saas.md +59 -62
  364. package/docs/content/faq.md +73 -43
  365. package/docs/content/getting-started.md +37 -61
  366. package/docs/content/mcp-clients.md +14 -1
  367. package/docs/content/messaging.md +284 -0
  368. package/docs/content/pure-agent-apps.md +55 -28
  369. package/docs/content/template-calendar.md +61 -56
  370. package/docs/content/template-clips.md +22 -18
  371. package/docs/content/template-content.md +36 -26
  372. package/docs/content/template-dispatch.md +2 -1
  373. package/docs/content/template-forms.md +13 -11
  374. package/docs/content/template-slides.md +43 -31
  375. package/docs/content/template-video.md +49 -22
  376. package/docs/content/tools.md +107 -0
  377. package/docs/content/what-is-agent-native.md +89 -105
  378. package/package.json +4 -1
  379. package/src/templates/default/app/root.tsx +50 -13
  380. package/src/templates/default/react-router.config.ts +3 -0
  381. package/docs/content/integrations.md +0 -198
@@ -0,0 +1,224 @@
1
+ /**
2
+ * Core script: db-migrate-user-api-keys
3
+ *
4
+ * One-shot migration: copy legacy `user-api-key:<provider>:<email>` and
5
+ * `user-anthropic-api-key:<email>` rows from the unscoped `settings` table
6
+ * into `app_secrets` (encrypted, scope=user, scopeId=email), then delete
7
+ * the legacy rows.
8
+ *
9
+ * Background. The pre-secrets-migration `agent-chat-plugin` save-key endpoint
10
+ * persisted user-pasted LLM API keys to `settings` under email-prefixed
11
+ * keys. The `app_secrets` system (encrypted, properly scoped) now owns
12
+ * user-pasted credentials. `getOwnerApiKey()` reads `app_secrets` first
13
+ * and falls back to the legacy settings rows for compat. This script
14
+ * clears that compat tail so the legacy rows don't sit around indefinitely.
15
+ *
16
+ * Idempotent — re-running on an already-migrated DB is a no-op.
17
+ *
18
+ * Usage:
19
+ * DATABASE_URL=postgres://... pnpm action db-migrate-user-api-keys
20
+ * pnpm action db-migrate-user-api-keys --db ./data/app.db
21
+ * pnpm action db-migrate-user-api-keys --dry-run
22
+ */
23
+ import path from "path";
24
+ import { createClient } from "@libsql/client";
25
+ import { getDatabaseUrl, getDatabaseAuthToken } from "../../db/client.js";
26
+ import { parseArgs } from "../utils.js";
27
+ import { PROVIDER_TO_ENV } from "../../agent/engine/provider-env-vars.js";
28
+ function isPostgresUrl(url) {
29
+ return url.startsWith("postgres://") || url.startsWith("postgresql://");
30
+ }
31
+ function parseLegacyKey(settingsKey) {
32
+ // user-api-key:<provider>:<email>
33
+ // (email may itself contain `:` if someone has a weird local-part — split
34
+ // on the first two segments only.)
35
+ if (settingsKey.startsWith("user-api-key:")) {
36
+ const rest = settingsKey.slice("user-api-key:".length);
37
+ const colonIdx = rest.indexOf(":");
38
+ if (colonIdx <= 0)
39
+ return null;
40
+ const provider = rest.slice(0, colonIdx);
41
+ const email = rest.slice(colonIdx + 1);
42
+ if (!provider || !email)
43
+ return null;
44
+ return { provider, email };
45
+ }
46
+ // user-anthropic-api-key:<email> (legacy alias)
47
+ if (settingsKey.startsWith("user-anthropic-api-key:")) {
48
+ const email = settingsKey.slice("user-anthropic-api-key:".length);
49
+ if (!email)
50
+ return null;
51
+ return { provider: "anthropic", email };
52
+ }
53
+ return null;
54
+ }
55
+ function secretKeyForProvider(provider) {
56
+ return PROVIDER_TO_ENV[provider] ?? `${provider.toUpperCase()}_API_KEY`;
57
+ }
58
+ function maskApiKey(value) {
59
+ if (!value)
60
+ return "(empty)";
61
+ if (value.length <= 8)
62
+ return "***";
63
+ return `${value.slice(0, 4)}…${value.slice(-4)} (len=${value.length})`;
64
+ }
65
+ export default async function dbMigrateUserApiKeys(args) {
66
+ const parsed = parseArgs(args);
67
+ if (parsed.help === "true") {
68
+ console.log(`Usage: pnpm action db-migrate-user-api-keys [options]
69
+
70
+ Copies legacy user-api-key:* + user-anthropic-api-key:* settings rows
71
+ into app_secrets (encrypted, scope=user) and deletes the originals.
72
+
73
+ Options:
74
+ --db <path> Path to SQLite database (default: data/app.db)
75
+ --dry-run Print what would be migrated without writing
76
+ --help Show this help message`);
77
+ return;
78
+ }
79
+ const dryRun = parsed["dry-run"] === "true";
80
+ let url;
81
+ if (parsed.db) {
82
+ url = "file:" + path.resolve(parsed.db);
83
+ }
84
+ else if (getDatabaseUrl()) {
85
+ url = getDatabaseUrl();
86
+ }
87
+ else {
88
+ url = "file:" + path.resolve(process.cwd(), "data", "app.db");
89
+ }
90
+ const dbLabel = url.startsWith("file:")
91
+ ? url.slice("file:".length)
92
+ : new URL(url).host || url;
93
+ console.log(`[migrate-user-api-keys] target: ${dbLabel}${dryRun ? " (dry-run)" : ""}`);
94
+ const legacy = await fetchLegacyRows(url);
95
+ if (legacy.length === 0) {
96
+ console.log("[migrate-user-api-keys] nothing to migrate.");
97
+ return;
98
+ }
99
+ console.log(`[migrate-user-api-keys] found ${legacy.length} legacy row(s):`);
100
+ for (const row of legacy) {
101
+ const target = secretKeyForProvider(row.provider);
102
+ console.log(` - ${row.email} ${row.provider} → app_secrets[${target}] ${maskApiKey(row.apiKey)}`);
103
+ }
104
+ if (dryRun)
105
+ return;
106
+ const { writeAppSecret } = await import("../../secrets/storage.js");
107
+ let migrated = 0;
108
+ let skipped = 0;
109
+ for (const row of legacy) {
110
+ try {
111
+ await writeAppSecret({
112
+ key: secretKeyForProvider(row.provider),
113
+ value: row.apiKey,
114
+ scope: "user",
115
+ scopeId: row.email,
116
+ });
117
+ await deleteLegacyRow(url, row.settingsKey);
118
+ migrated++;
119
+ }
120
+ catch (err) {
121
+ console.error(` ! failed to migrate ${row.settingsKey}:`, err instanceof Error ? err.message : err);
122
+ skipped++;
123
+ }
124
+ }
125
+ console.log(`[migrate-user-api-keys] done. migrated=${migrated} skipped=${skipped}`);
126
+ }
127
+ async function fetchLegacyRows(url) {
128
+ const out = [];
129
+ if (isPostgresUrl(url)) {
130
+ const { default: pg } = await import("postgres");
131
+ const sql = pg(url);
132
+ try {
133
+ const rows = (await sql.unsafe(`SELECT key, value FROM settings WHERE key LIKE 'user-api-key:%' OR key LIKE 'user-anthropic-api-key:%'`));
134
+ for (const row of rows) {
135
+ const parsed = parseLegacyKey(row.key);
136
+ if (!parsed)
137
+ continue;
138
+ const apiKey = extractKeyFromValue(row.value);
139
+ if (!apiKey)
140
+ continue;
141
+ out.push({
142
+ settingsKey: row.key,
143
+ provider: parsed.provider,
144
+ email: parsed.email,
145
+ apiKey,
146
+ });
147
+ }
148
+ }
149
+ finally {
150
+ await sql.end();
151
+ }
152
+ return out;
153
+ }
154
+ const client = createClient({ url, authToken: getDatabaseAuthToken() });
155
+ try {
156
+ const result = await client.execute({
157
+ sql: `SELECT key, value FROM settings WHERE key LIKE 'user-api-key:%' OR key LIKE 'user-anthropic-api-key:%'`,
158
+ args: [],
159
+ });
160
+ for (const row of result.rows) {
161
+ const settingsKey = row.key;
162
+ const value = row.value;
163
+ const parsed = parseLegacyKey(settingsKey);
164
+ if (!parsed)
165
+ continue;
166
+ const apiKey = extractKeyFromValue(value);
167
+ if (!apiKey)
168
+ continue;
169
+ out.push({
170
+ settingsKey,
171
+ provider: parsed.provider,
172
+ email: parsed.email,
173
+ apiKey,
174
+ });
175
+ }
176
+ }
177
+ finally {
178
+ client.close();
179
+ }
180
+ return out;
181
+ }
182
+ function extractKeyFromValue(value) {
183
+ // Settings rows store JSON. The save-key endpoint historically wrote
184
+ // `{ key: "sk-..." }`. Tolerate raw strings just in case.
185
+ if (!value)
186
+ return null;
187
+ try {
188
+ const parsed = JSON.parse(value);
189
+ if (typeof parsed === "string" && parsed.trim())
190
+ return parsed.trim();
191
+ if (parsed && typeof parsed.key === "string" && parsed.key.trim()) {
192
+ return parsed.key.trim();
193
+ }
194
+ return null;
195
+ }
196
+ catch {
197
+ const trimmed = value.trim();
198
+ return trimmed || null;
199
+ }
200
+ }
201
+ async function deleteLegacyRow(url, key) {
202
+ if (isPostgresUrl(url)) {
203
+ const { default: pg } = await import("postgres");
204
+ const sql = pg(url);
205
+ try {
206
+ await sql.unsafe(`DELETE FROM settings WHERE key = $1`, [key]);
207
+ }
208
+ finally {
209
+ await sql.end();
210
+ }
211
+ return;
212
+ }
213
+ const client = createClient({ url, authToken: getDatabaseAuthToken() });
214
+ try {
215
+ await client.execute({
216
+ sql: `DELETE FROM settings WHERE key = ?`,
217
+ args: [key],
218
+ });
219
+ }
220
+ finally {
221
+ client.close();
222
+ }
223
+ }
224
+ //# sourceMappingURL=migrate-user-api-keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate-user-api-keys.js","sourceRoot":"","sources":["../../../src/scripts/db/migrate-user-api-keys.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Core script: db-wipe-leaked-builder-keys
3
+ *
4
+ * One-shot cleanup for the legacy cross-tenant Builder credential leak.
5
+ *
6
+ * Pre-migration, the Builder OAuth callback wrote BUILDER_PRIVATE_KEY,
7
+ * BUILDER_PUBLIC_KEY, BUILDER_USER_ID, BUILDER_ORG_NAME, BUILDER_ORG_KIND
8
+ * into the unscoped `persisted-env-vars` settings row. On shared-DB
9
+ * hosted templates that row was global, so the first user to connect
10
+ * left their Builder identity sitting in `process.env` for every
11
+ * subsequent tenant on the same serverless instance — anyone without
12
+ * their own per-user app_secrets record fell back to the leaked key.
13
+ *
14
+ * Per-user Builder credentials now live in `app_secrets` (scope=user,
15
+ * scopeId=email). The plugin init scrubs BUILDER_* on every boot, but
16
+ * this script lets you wipe the row immediately, before redeploying.
17
+ *
18
+ * Idempotent. Re-running on a clean row is a no-op.
19
+ *
20
+ * Usage:
21
+ * DATABASE_URL=postgres://... pnpm action db-wipe-leaked-builder-keys
22
+ * DATABASE_URL=file:./data/app.db pnpm action db-wipe-leaked-builder-keys
23
+ * pnpm action db-wipe-leaked-builder-keys --db ./data/app.db
24
+ * pnpm action db-wipe-leaked-builder-keys --dry-run
25
+ */
26
+ export default function dbWipeLeakedBuilderKeys(args: string[]): Promise<void>;
27
+ //# sourceMappingURL=wipe-leaked-builder-keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wipe-leaked-builder-keys.d.ts","sourceRoot":"","sources":["../../../src/scripts/db/wipe-leaked-builder-keys.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAyBH,wBAA8B,uBAAuB,CACnD,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,IAAI,CAAC,CA4Gf"}
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Core script: db-wipe-leaked-builder-keys
3
+ *
4
+ * One-shot cleanup for the legacy cross-tenant Builder credential leak.
5
+ *
6
+ * Pre-migration, the Builder OAuth callback wrote BUILDER_PRIVATE_KEY,
7
+ * BUILDER_PUBLIC_KEY, BUILDER_USER_ID, BUILDER_ORG_NAME, BUILDER_ORG_KIND
8
+ * into the unscoped `persisted-env-vars` settings row. On shared-DB
9
+ * hosted templates that row was global, so the first user to connect
10
+ * left their Builder identity sitting in `process.env` for every
11
+ * subsequent tenant on the same serverless instance — anyone without
12
+ * their own per-user app_secrets record fell back to the leaked key.
13
+ *
14
+ * Per-user Builder credentials now live in `app_secrets` (scope=user,
15
+ * scopeId=email). The plugin init scrubs BUILDER_* on every boot, but
16
+ * this script lets you wipe the row immediately, before redeploying.
17
+ *
18
+ * Idempotent. Re-running on a clean row is a no-op.
19
+ *
20
+ * Usage:
21
+ * DATABASE_URL=postgres://... pnpm action db-wipe-leaked-builder-keys
22
+ * DATABASE_URL=file:./data/app.db pnpm action db-wipe-leaked-builder-keys
23
+ * pnpm action db-wipe-leaked-builder-keys --db ./data/app.db
24
+ * pnpm action db-wipe-leaked-builder-keys --dry-run
25
+ */
26
+ import path from "path";
27
+ import { createClient } from "@libsql/client";
28
+ import { getDatabaseUrl, getDatabaseAuthToken } from "../../db/client.js";
29
+ import { parseArgs } from "../utils.js";
30
+ const BUILDER_KEYS = [
31
+ "BUILDER_PRIVATE_KEY",
32
+ "BUILDER_PUBLIC_KEY",
33
+ "BUILDER_USER_ID",
34
+ "BUILDER_ORG_NAME",
35
+ "BUILDER_ORG_KIND",
36
+ ];
37
+ function isPostgresUrl(url) {
38
+ return url.startsWith("postgres://") || url.startsWith("postgresql://");
39
+ }
40
+ function maskValue(v) {
41
+ if (typeof v !== "string")
42
+ return String(v);
43
+ if (v.length <= 8)
44
+ return "***";
45
+ return `${v.slice(0, 4)}…${v.slice(-4)} (len=${v.length})`;
46
+ }
47
+ export default async function dbWipeLeakedBuilderKeys(args) {
48
+ const parsed = parseArgs(args);
49
+ if (parsed.help === "true") {
50
+ console.log(`Usage: pnpm action db-wipe-leaked-builder-keys [options]
51
+
52
+ Removes BUILDER_* keys from the persisted-env-vars row in the settings
53
+ table. Run this once per hosted template database.
54
+
55
+ Options:
56
+ --db <path> Path to SQLite database (default: data/app.db when no DATABASE_URL set)
57
+ --dry-run Print what would be removed without writing
58
+ --help Show this help message
59
+
60
+ Database resolution:
61
+ --db flag → DATABASE_URL env → ./data/app.db`);
62
+ return;
63
+ }
64
+ const dryRun = parsed["dry-run"] === "true";
65
+ let url;
66
+ if (parsed.db) {
67
+ url = "file:" + path.resolve(parsed.db);
68
+ }
69
+ else if (getDatabaseUrl()) {
70
+ url = getDatabaseUrl();
71
+ }
72
+ else {
73
+ url = "file:" + path.resolve(process.cwd(), "data", "app.db");
74
+ }
75
+ const dbLabel = url.startsWith("file:")
76
+ ? url.slice("file:".length)
77
+ : new URL(url).host || url;
78
+ console.log(`[wipe-leaked-builder-keys] target: ${dbLabel}${dryRun ? " (dry-run)" : ""}`);
79
+ let row = null;
80
+ if (isPostgresUrl(url)) {
81
+ const { default: pg } = await import("postgres");
82
+ const pgSql = pg(url);
83
+ try {
84
+ const result = await pgSql.unsafe(`SELECT value FROM settings WHERE key = 'persisted-env-vars'`);
85
+ const rows = Array.from(result);
86
+ if (rows.length === 0) {
87
+ console.log("[wipe-leaked-builder-keys] no persisted-env-vars row.");
88
+ return;
89
+ }
90
+ row = JSON.parse(rows[0].value);
91
+ const { cleaned, removed } = stripBuilderKeys(row ?? {});
92
+ if (removed.length === 0) {
93
+ console.log("[wipe-leaked-builder-keys] row already clean — nothing to do.");
94
+ return;
95
+ }
96
+ logRemoved(removed, row ?? {});
97
+ if (dryRun)
98
+ return;
99
+ await pgSql.unsafe(`UPDATE settings SET value = $1, updated_at = $2 WHERE key = 'persisted-env-vars'`, [JSON.stringify(cleaned), Date.now()]);
100
+ console.log(`[wipe-leaked-builder-keys] removed ${removed.length} key(s) from persisted-env-vars.`);
101
+ }
102
+ finally {
103
+ await pgSql.end();
104
+ }
105
+ return;
106
+ }
107
+ // libsql / SQLite
108
+ const client = createClient({
109
+ url,
110
+ authToken: getDatabaseAuthToken(),
111
+ });
112
+ try {
113
+ const result = await client.execute({
114
+ sql: `SELECT value FROM settings WHERE key = ?`,
115
+ args: ["persisted-env-vars"],
116
+ });
117
+ if (result.rows.length === 0) {
118
+ console.log("[wipe-leaked-builder-keys] no persisted-env-vars row.");
119
+ return;
120
+ }
121
+ row = JSON.parse(result.rows[0].value);
122
+ const { cleaned, removed } = stripBuilderKeys(row ?? {});
123
+ if (removed.length === 0) {
124
+ console.log("[wipe-leaked-builder-keys] row already clean — nothing to do.");
125
+ return;
126
+ }
127
+ logRemoved(removed, row ?? {});
128
+ if (dryRun)
129
+ return;
130
+ await client.execute({
131
+ sql: `UPDATE settings SET value = ?, updated_at = ? WHERE key = ?`,
132
+ args: [JSON.stringify(cleaned), Date.now(), "persisted-env-vars"],
133
+ });
134
+ console.log(`[wipe-leaked-builder-keys] removed ${removed.length} key(s) from persisted-env-vars.`);
135
+ }
136
+ finally {
137
+ client.close();
138
+ }
139
+ }
140
+ function stripBuilderKeys(row) {
141
+ const builderSet = new Set(BUILDER_KEYS);
142
+ const cleaned = {};
143
+ const removed = [];
144
+ for (const [k, v] of Object.entries(row)) {
145
+ if (builderSet.has(k)) {
146
+ removed.push(k);
147
+ }
148
+ else {
149
+ cleaned[k] = v;
150
+ }
151
+ }
152
+ return { cleaned, removed };
153
+ }
154
+ function logRemoved(removed, row) {
155
+ console.log(`[wipe-leaked-builder-keys] BUILDER_* keys present:`);
156
+ for (const k of removed) {
157
+ const masked = k === "BUILDER_ORG_NAME" || k === "BUILDER_ORG_KIND"
158
+ ? String(row[k])
159
+ : maskValue(row[k]);
160
+ console.log(` - ${k}: ${masked}`);
161
+ }
162
+ }
163
+ //# sourceMappingURL=wipe-leaked-builder-keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wipe-leaked-builder-keys.js","sourceRoot":"","sources":["../../../src/scripts/db/wipe-leaked-builder-keys.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,11 @@
8
8
  * Each call uses a `getRequiredSecret` guard so a template that has already
9
9
  * registered the same key (often with stricter settings like `required: true`)
10
10
  * wins — the framework registration is a fallback, not an override.
11
+ *
12
+ * NOTE: The framework previously registered OPENAI_API_KEY here for Whisper
13
+ * voice transcription. Voice transcription now routes through the Builder.io
14
+ * gateway (or Groq as a BYOK fallback), so the framework no longer registers
15
+ * the OpenAI key. Templates that need it (e.g. Clips) register it themselves.
11
16
  */
12
17
  export declare function registerFrameworkSecrets(): void;
13
18
  //# sourceMappingURL=register-framework-secrets.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"register-framework-secrets.d.ts","sourceRoot":"","sources":["../../src/secrets/register-framework-secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA8CH,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C"}
1
+ {"version":3,"file":"register-framework-secrets.d.ts","sourceRoot":"","sources":["../../src/secrets/register-framework-secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,wBAAgB,wBAAwB,IAAI,IAAI,CAI/C"}
@@ -8,52 +8,15 @@
8
8
  * Each call uses a `getRequiredSecret` guard so a template that has already
9
9
  * registered the same key (often with stricter settings like `required: true`)
10
10
  * wins — the framework registration is a fallback, not an override.
11
- */
12
- import { getRequiredSecret, registerRequiredSecret } from "./register.js";
13
- /**
14
- * OpenAI API key.
15
11
  *
16
- * The framework uses this for voice transcription in the agent sidebar
17
- * composer (Whisper). Templates like Clips register it as `required: true`
18
- * in their own `register-secrets.ts`; the framework keeps it optional here
19
- * so every other template still surfaces the input without forcing the
20
- * onboarding checklist step.
12
+ * NOTE: The framework previously registered OPENAI_API_KEY here for Whisper
13
+ * voice transcription. Voice transcription now routes through the Builder.io
14
+ * gateway (or Groq as a BYOK fallback), so the framework no longer registers
15
+ * the OpenAI key. Templates that need it (e.g. Clips) register it themselves.
21
16
  */
22
- function registerOpenAiKey() {
23
- if (getRequiredSecret("OPENAI_API_KEY"))
24
- return;
25
- registerRequiredSecret({
26
- key: "OPENAI_API_KEY",
27
- label: "OpenAI API Key",
28
- description: "Used for voice transcription (Whisper) in the agent composer. Without this, voice input falls back to your browser's built-in speech recognition.",
29
- docsUrl: "https://platform.openai.com/api-keys",
30
- scope: "user",
31
- kind: "api-key",
32
- required: false,
33
- validator: async (value) => {
34
- if (!value || typeof value !== "string" || value.length < 20) {
35
- return { ok: false, error: "Key looks too short." };
36
- }
37
- try {
38
- const res = await fetch("https://api.openai.com/v1/models", {
39
- headers: { Authorization: `Bearer ${value}` },
40
- });
41
- if (res.ok)
42
- return true;
43
- if (res.status === 401)
44
- return { ok: false, error: "OpenAI rejected this key (401)." };
45
- return { ok: false, error: `OpenAI returned ${res.status}.` };
46
- }
47
- catch (err) {
48
- return {
49
- ok: false,
50
- error: `Could not reach OpenAI: ${err?.message ?? err}`,
51
- };
52
- }
53
- },
54
- });
55
- }
56
17
  export function registerFrameworkSecrets() {
57
- registerOpenAiKey();
18
+ // No framework-level secrets at this time.
19
+ // Templates register their own keys via `registerRequiredSecret` in
20
+ // their own `register-secrets.ts`.
58
21
  }
59
22
  //# sourceMappingURL=register-framework-secrets.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"register-framework-secrets.js","sourceRoot":"","sources":["../../src/secrets/register-framework-secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAE1E;;;;;;;;GAQG;AACH,SAAS,iBAAiB;IACxB,IAAI,iBAAiB,CAAC,gBAAgB,CAAC;QAAE,OAAO;IAChD,sBAAsB,CAAC;QACrB,GAAG,EAAE,gBAAgB;QACrB,KAAK,EAAE,gBAAgB;QACvB,WAAW,EACT,mJAAmJ;QACrJ,OAAO,EAAE,sCAAsC;QAC/C,KAAK,EAAE,MAAM;QACb,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE,KAAK;QACf,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;YACzB,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;gBAC7D,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC;YACtD,CAAC;YACD,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,kCAAkC,EAAE;oBAC1D,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;iBAC9C,CAAC,CAAC;gBACH,IAAI,GAAG,CAAC,EAAE;oBAAE,OAAO,IAAI,CAAC;gBACxB,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;oBACpB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,iCAAiC,EAAE,CAAC;gBACjE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC;YAChE,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,OAAO;oBACL,EAAE,EAAE,KAAK;oBACT,KAAK,EAAE,2BAA2B,GAAG,EAAE,OAAO,IAAI,GAAG,EAAE;iBACxD,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,wBAAwB;IACtC,iBAAiB,EAAE,CAAC;AACtB,CAAC"}
1
+ {"version":3,"file":"register-framework-secrets.js","sourceRoot":"","sources":["../../src/secrets/register-framework-secrets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,UAAU,wBAAwB;IACtC,2CAA2C;IAC3C,oEAAoE;IACpE,mCAAmC;AACrC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"substitution.d.ts","sourceRoot":"","sources":["../../src/secrets/substitution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAIjD,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,0BAA0B,CAAC,CAkCrC;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,GACzB,OAAO,CAeT;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAU1B"}
1
+ {"version":3,"file":"substitution.d.ts","sourceRoot":"","sources":["../../src/secrets/substitution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAQjD,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,0BAA0B,CAAC,CAsCrC;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,GACzB,OAAO,CAeT;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAU1B"}
@@ -10,6 +10,7 @@
10
10
  * keys without breaking automations that reference workspace defaults.
11
11
  */
12
12
  import { readAppSecret, readAppSecretMeta } from "./storage.js";
13
+ import { getRequestOrgId, getRequestUserEmail, } from "../server/request-context.js";
13
14
  const KEY_REFERENCE_REGEX = /\$\{keys\.([A-Za-z0-9_-]+)\}/g;
14
15
  /**
15
16
  * Resolve `${keys.NAME}` references in `text`. For each reference, looks up
@@ -31,7 +32,11 @@ export async function resolveKeyReferences(text, scope, scopeId) {
31
32
  continue;
32
33
  let result = await readAppSecret({ key: name, scope, scopeId });
33
34
  if (!result && scope === "user") {
34
- result = await readAppSecret({ key: name, scope: "workspace", scopeId });
35
+ result = await readAppSecret({
36
+ key: name,
37
+ scope: "workspace",
38
+ scopeId: getWorkspaceScopeId(scopeId),
39
+ });
35
40
  }
36
41
  if (!result) {
37
42
  throw new Error(`Referenced key "${name}" is not defined for scope "${scope}". Create it in Settings or via the secrets API before using this automation.`);
@@ -85,9 +90,16 @@ export async function getKeyAllowlist(name, scope, scopeId) {
85
90
  meta = await readAppSecretMeta({
86
91
  key: name,
87
92
  scope: "workspace",
88
- scopeId,
93
+ scopeId: getWorkspaceScopeId(scopeId),
89
94
  });
90
95
  }
91
96
  return meta?.urlAllowlist ?? null;
92
97
  }
98
+ function getWorkspaceScopeId(userScopeId) {
99
+ const orgId = getRequestOrgId();
100
+ if (orgId)
101
+ return orgId;
102
+ const email = getRequestUserEmail() || userScopeId;
103
+ return `solo:${email}`;
104
+ }
93
105
  //# sourceMappingURL=substitution.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"substitution.js","sourceRoot":"","sources":["../../src/secrets/substitution.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"substitution.js","sourceRoot":"","sources":["../../src/secrets/substitution.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"action-discovery.d.ts","sourceRoot":"","sources":["../../src/server/action-discovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAkQhE;;;;;;;;GAQG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAqC7B;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAsCtC;AAED,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GACpC,OAAO,CAAC,IAAI,CAAC,CAiCf;AAED,oDAAoD;AACpD,eAAO,MAAM,mBAAmB,4BAAsB,CAAC"}
1
+ {"version":3,"file":"action-discovery.d.ts","sourceRoot":"","sources":["../../src/server/action-discovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAkQhE;;;;;;;;GAQG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAqC7B;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAuFtC;AAED,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GACpC,OAAO,CAAC,IAAI,CAAC,CAiCf;AAED,oDAAoD;AACpD,eAAO,MAAM,mBAAmB,4BAAsB,CAAC"}
@@ -321,6 +321,45 @@ export async function autoDiscoverActions(from) {
321
321
  catch (err) {
322
322
  console.warn(`[autoDiscoverActions] Could not read actions directory: ${actionsDir} — ${err?.message}`);
323
323
  }
324
+ // 1b. Fallback: if filesystem discovery found no template actions (common
325
+ // in bundled serverless environments like Netlify/Vercel where the
326
+ // actions/ directory doesn't exist on disk), try importing the
327
+ // generated static registry at .generated/actions-registry.
328
+ //
329
+ // This prevents the silent-empty-tools footgun where the agent has no
330
+ // template actions and falls back to generic tools like web-request.
331
+ // Prefer `loadActionsFromStaticRegistry` over `autoDiscoverActions` for
332
+ // production reliability — this fallback is a safety net, not the
333
+ // primary path.
334
+ if (Object.keys(registry).length === 0 && from) {
335
+ try {
336
+ let registryPath;
337
+ if (from.startsWith("file://") || from.startsWith("file:///")) {
338
+ const callerDir = nodePath.dirname(fileURLToPath(from));
339
+ registryPath = nodePath.resolve(callerDir, "../../.generated/actions-registry.js");
340
+ }
341
+ else {
342
+ registryPath = nodePath.resolve(from, "../.generated/actions-registry.js");
343
+ }
344
+ const mod = await import(/* @vite-ignore */ registryPath);
345
+ const staticEntries = loadActionsFromStaticRegistry(mod.default || mod);
346
+ Object.assign(registry, staticEntries);
347
+ if (Object.keys(staticEntries).length > 0) {
348
+ console.log(`[autoDiscoverActions] Filesystem scan found 0 actions — loaded ${Object.keys(staticEntries).length} from .generated/actions-registry.ts instead. ` +
349
+ `Consider switching to loadActionsFromStaticRegistry(actionsRegistry) for production reliability.`);
350
+ }
351
+ }
352
+ catch {
353
+ // No generated registry available — registry stays empty.
354
+ }
355
+ }
356
+ // If still empty after all fallbacks, warn loudly.
357
+ if (Object.keys(registry).length === 0) {
358
+ console.warn(`[autoDiscoverActions] WARNING: No template actions found! ` +
359
+ `The agent will have no template-specific tools. ` +
360
+ `If in production, switch from autoDiscoverActions to loadActionsFromStaticRegistry. ` +
361
+ `See: https://docs.agent-native.com/actions#static-registry`);
362
+ }
324
363
  // 2. Workspace-core actions — merged in with skipExisting so they can't
325
364
  // overwrite template entries.
326
365
  try {