@agent-native/core 0.7.14 → 0.7.15

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 (737) hide show
  1. package/README.md +56 -6
  2. package/dist/a2a/handlers.d.ts.map +1 -1
  3. package/dist/a2a/handlers.js +149 -24
  4. package/dist/a2a/handlers.js.map +1 -1
  5. package/dist/a2a/server.d.ts.map +1 -1
  6. package/dist/a2a/server.js +166 -51
  7. package/dist/a2a/server.js.map +1 -1
  8. package/dist/a2a/task-store.d.ts +10 -1
  9. package/dist/a2a/task-store.d.ts.map +1 -1
  10. package/dist/a2a/task-store.js +36 -2
  11. package/dist/a2a/task-store.js.map +1 -1
  12. package/dist/agent/default-model.d.ts +21 -0
  13. package/dist/agent/default-model.d.ts.map +1 -0
  14. package/dist/agent/default-model.js +21 -0
  15. package/dist/agent/default-model.js.map +1 -0
  16. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  17. package/dist/agent/engine/ai-sdk-engine.js +7 -4
  18. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  19. package/dist/agent/engine/anthropic-engine.d.ts +1 -1
  20. package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
  21. package/dist/agent/engine/anthropic-engine.js +10 -4
  22. package/dist/agent/engine/anthropic-engine.js.map +1 -1
  23. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  24. package/dist/agent/engine/builder-engine.js +4 -1
  25. package/dist/agent/engine/builder-engine.js.map +1 -1
  26. package/dist/agent/engine/builtin.js +1 -1
  27. package/dist/agent/engine/builtin.js.map +1 -1
  28. package/dist/agent/engine/registry.d.ts +27 -7
  29. package/dist/agent/engine/registry.d.ts.map +1 -1
  30. package/dist/agent/engine/registry.js +101 -20
  31. package/dist/agent/engine/registry.js.map +1 -1
  32. package/dist/agent/index.d.ts +1 -0
  33. package/dist/agent/index.d.ts.map +1 -1
  34. package/dist/agent/index.js +1 -0
  35. package/dist/agent/index.js.map +1 -1
  36. package/dist/agent/production-agent.d.ts +25 -3
  37. package/dist/agent/production-agent.d.ts.map +1 -1
  38. package/dist/agent/production-agent.js +227 -36
  39. package/dist/agent/production-agent.js.map +1 -1
  40. package/dist/application-state/handlers.d.ts.map +1 -1
  41. package/dist/application-state/handlers.js +10 -6
  42. package/dist/application-state/handlers.js.map +1 -1
  43. package/dist/application-state/script-helpers.d.ts +1 -1
  44. package/dist/application-state/script-helpers.d.ts.map +1 -1
  45. package/dist/application-state/script-helpers.js +12 -8
  46. package/dist/application-state/script-helpers.js.map +1 -1
  47. package/dist/application-state/store.d.ts.map +1 -1
  48. package/dist/application-state/store.js +19 -10
  49. package/dist/application-state/store.js.map +1 -1
  50. package/dist/chat-threads/store.d.ts.map +1 -1
  51. package/dist/chat-threads/store.js +4 -1
  52. package/dist/chat-threads/store.js.map +1 -1
  53. package/dist/cli/create.d.ts.map +1 -1
  54. package/dist/cli/create.js +79 -13
  55. package/dist/cli/create.js.map +1 -1
  56. package/dist/cli/index.js +97 -39
  57. package/dist/cli/index.js.map +1 -1
  58. package/dist/cli/templates-meta.d.ts +4 -0
  59. package/dist/cli/templates-meta.d.ts.map +1 -1
  60. package/dist/cli/templates-meta.js +56 -12
  61. package/dist/cli/templates-meta.js.map +1 -1
  62. package/dist/cli/workspacify.d.ts +2 -0
  63. package/dist/cli/workspacify.d.ts.map +1 -1
  64. package/dist/cli/workspacify.js +5 -4
  65. package/dist/cli/workspacify.js.map +1 -1
  66. package/dist/client/AgentPanel.d.ts +5 -2
  67. package/dist/client/AgentPanel.d.ts.map +1 -1
  68. package/dist/client/AgentPanel.js +61 -23
  69. package/dist/client/AgentPanel.js.map +1 -1
  70. package/dist/client/AgentTaskCard.d.ts.map +1 -1
  71. package/dist/client/AgentTaskCard.js +3 -2
  72. package/dist/client/AgentTaskCard.js.map +1 -1
  73. package/dist/client/AssistantChat.d.ts.map +1 -1
  74. package/dist/client/AssistantChat.js +79 -16
  75. package/dist/client/AssistantChat.js.map +1 -1
  76. package/dist/client/ConnectBuilderCard.d.ts.map +1 -1
  77. package/dist/client/ConnectBuilderCard.js +2 -1
  78. package/dist/client/ConnectBuilderCard.js.map +1 -1
  79. package/dist/client/DefaultSpinner.d.ts +1 -1
  80. package/dist/client/DefaultSpinner.d.ts.map +1 -1
  81. package/dist/client/DefaultSpinner.js +2 -9
  82. package/dist/client/DefaultSpinner.js.map +1 -1
  83. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  84. package/dist/client/MultiTabAssistantChat.js +20 -19
  85. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  86. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  87. package/dist/client/agent-chat-adapter.js +2 -1
  88. package/dist/client/agent-chat-adapter.js.map +1 -1
  89. package/dist/client/agent-chat.d.ts.map +1 -1
  90. package/dist/client/agent-chat.js +3 -1
  91. package/dist/client/agent-chat.js.map +1 -1
  92. package/dist/client/analytics.d.ts.map +1 -1
  93. package/dist/client/analytics.js +70 -1
  94. package/dist/client/analytics.js.map +1 -1
  95. package/dist/client/api-path.d.ts +5 -0
  96. package/dist/client/api-path.d.ts.map +1 -0
  97. package/dist/client/api-path.js +48 -0
  98. package/dist/client/api-path.js.map +1 -0
  99. package/dist/client/components/ApiKeySettings.d.ts.map +1 -1
  100. package/dist/client/components/ApiKeySettings.js +3 -2
  101. package/dist/client/components/ApiKeySettings.js.map +1 -1
  102. package/dist/client/components/CodeRequiredDialog.d.ts.map +1 -1
  103. package/dist/client/components/CodeRequiredDialog.js +3 -2
  104. package/dist/client/components/CodeRequiredDialog.js.map +1 -1
  105. package/dist/client/composer/TiptapComposer.d.ts +3 -1
  106. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  107. package/dist/client/composer/TiptapComposer.js +9 -8
  108. package/dist/client/composer/TiptapComposer.js.map +1 -1
  109. package/dist/client/composer/draft-key.d.ts +2 -0
  110. package/dist/client/composer/draft-key.d.ts.map +1 -0
  111. package/dist/client/composer/draft-key.js +8 -0
  112. package/dist/client/composer/draft-key.js.map +1 -0
  113. package/dist/client/composer/use-file-search.d.ts.map +1 -1
  114. package/dist/client/composer/use-file-search.js +2 -1
  115. package/dist/client/composer/use-file-search.js.map +1 -1
  116. package/dist/client/composer/use-mention-search.d.ts.map +1 -1
  117. package/dist/client/composer/use-mention-search.js +2 -1
  118. package/dist/client/composer/use-mention-search.js.map +1 -1
  119. package/dist/client/composer/use-skills.d.ts.map +1 -1
  120. package/dist/client/composer/use-skills.js +2 -1
  121. package/dist/client/composer/use-skills.js.map +1 -1
  122. package/dist/client/composer/useVoiceDictation.d.ts +1 -1
  123. package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
  124. package/dist/client/composer/useVoiceDictation.js +16 -8
  125. package/dist/client/composer/useVoiceDictation.js.map +1 -1
  126. package/dist/client/dev-mode.d.ts +14 -0
  127. package/dist/client/dev-mode.d.ts.map +1 -0
  128. package/dist/client/dev-mode.js +14 -0
  129. package/dist/client/dev-mode.js.map +1 -0
  130. package/dist/client/dev-overlay/DevOverlay.d.ts +26 -0
  131. package/dist/client/dev-overlay/DevOverlay.d.ts.map +1 -0
  132. package/dist/client/dev-overlay/DevOverlay.js +315 -0
  133. package/dist/client/dev-overlay/DevOverlay.js.map +1 -0
  134. package/dist/client/dev-overlay/builtins.d.ts +6 -0
  135. package/dist/client/dev-overlay/builtins.d.ts.map +1 -0
  136. package/dist/client/dev-overlay/builtins.js +35 -0
  137. package/dist/client/dev-overlay/builtins.js.map +1 -0
  138. package/dist/client/dev-overlay/index.d.ts +6 -0
  139. package/dist/client/dev-overlay/index.d.ts.map +1 -0
  140. package/dist/client/dev-overlay/index.js +5 -0
  141. package/dist/client/dev-overlay/index.js.map +1 -0
  142. package/dist/client/dev-overlay/registry.d.ts +13 -0
  143. package/dist/client/dev-overlay/registry.d.ts.map +1 -0
  144. package/dist/client/dev-overlay/registry.js +63 -0
  145. package/dist/client/dev-overlay/registry.js.map +1 -0
  146. package/dist/client/dev-overlay/types.d.ts +56 -0
  147. package/dist/client/dev-overlay/types.d.ts.map +1 -0
  148. package/dist/client/dev-overlay/types.js +9 -0
  149. package/dist/client/dev-overlay/types.js.map +1 -0
  150. package/dist/client/dev-overlay/use-dev-option.d.ts +12 -0
  151. package/dist/client/dev-overlay/use-dev-option.d.ts.map +1 -0
  152. package/dist/client/dev-overlay/use-dev-option.js +73 -0
  153. package/dist/client/dev-overlay/use-dev-option.js.map +1 -0
  154. package/dist/client/dev-overlay/use-dev-overlay-shortcut.d.ts +6 -0
  155. package/dist/client/dev-overlay/use-dev-overlay-shortcut.d.ts.map +1 -0
  156. package/dist/client/dev-overlay/use-dev-overlay-shortcut.js +29 -0
  157. package/dist/client/dev-overlay/use-dev-overlay-shortcut.js.map +1 -0
  158. package/dist/client/frame.d.ts +1 -0
  159. package/dist/client/frame.d.ts.map +1 -1
  160. package/dist/client/frame.js +32 -11
  161. package/dist/client/frame.js.map +1 -1
  162. package/dist/client/index.d.ts +4 -0
  163. package/dist/client/index.d.ts.map +1 -1
  164. package/dist/client/index.js +4 -0
  165. package/dist/client/index.js.map +1 -1
  166. package/dist/client/integrations/IntegrationCard.d.ts.map +1 -1
  167. package/dist/client/integrations/IntegrationCard.js +3 -2
  168. package/dist/client/integrations/IntegrationCard.js.map +1 -1
  169. package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -1
  170. package/dist/client/integrations/IntegrationsPanel.js +3 -2
  171. package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
  172. package/dist/client/integrations/useIntegrationStatus.d.ts.map +1 -1
  173. package/dist/client/integrations/useIntegrationStatus.js +2 -1
  174. package/dist/client/integrations/useIntegrationStatus.js.map +1 -1
  175. package/dist/client/notifications/NotificationsBell.d.ts.map +1 -1
  176. package/dist/client/notifications/NotificationsBell.js +26 -8
  177. package/dist/client/notifications/NotificationsBell.js.map +1 -1
  178. package/dist/client/observability/ThumbsFeedback.d.ts.map +1 -1
  179. package/dist/client/observability/ThumbsFeedback.js +2 -1
  180. package/dist/client/observability/ThumbsFeedback.js.map +1 -1
  181. package/dist/client/observability/useObservability.d.ts.map +1 -1
  182. package/dist/client/observability/useObservability.js +2 -1
  183. package/dist/client/observability/useObservability.js.map +1 -1
  184. package/dist/client/onboarding/OnboardingPanel.d.ts +0 -7
  185. package/dist/client/onboarding/OnboardingPanel.d.ts.map +1 -1
  186. package/dist/client/onboarding/OnboardingPanel.js +20 -10
  187. package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
  188. package/dist/client/onboarding/index.d.ts +1 -0
  189. package/dist/client/onboarding/index.d.ts.map +1 -1
  190. package/dist/client/onboarding/index.js +1 -0
  191. package/dist/client/onboarding/index.js.map +1 -1
  192. package/dist/client/onboarding/use-onboarding.d.ts +1 -7
  193. package/dist/client/onboarding/use-onboarding.d.ts.map +1 -1
  194. package/dist/client/onboarding/use-onboarding.js +27 -13
  195. package/dist/client/onboarding/use-onboarding.js.map +1 -1
  196. package/dist/client/onboarding/use-preview-mode.d.ts +10 -0
  197. package/dist/client/onboarding/use-preview-mode.d.ts.map +1 -0
  198. package/dist/client/onboarding/use-preview-mode.js +35 -0
  199. package/dist/client/onboarding/use-preview-mode.js.map +1 -0
  200. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  201. package/dist/client/org/OrgSwitcher.js +2 -1
  202. package/dist/client/org/OrgSwitcher.js.map +1 -1
  203. package/dist/client/org/TeamPage.d.ts.map +1 -1
  204. package/dist/client/org/TeamPage.js +7 -5
  205. package/dist/client/org/TeamPage.js.map +1 -1
  206. package/dist/client/org/hooks.d.ts.map +1 -1
  207. package/dist/client/org/hooks.js +2 -1
  208. package/dist/client/org/hooks.js.map +1 -1
  209. package/dist/client/progress/RunsTray.d.ts.map +1 -1
  210. package/dist/client/progress/RunsTray.js +2 -1
  211. package/dist/client/progress/RunsTray.js.map +1 -1
  212. package/dist/client/resources/McpServerDetail.d.ts +0 -8
  213. package/dist/client/resources/McpServerDetail.d.ts.map +1 -1
  214. package/dist/client/resources/McpServerDetail.js +6 -1
  215. package/dist/client/resources/McpServerDetail.js.map +1 -1
  216. package/dist/client/resources/ResourceEditor.d.ts.map +1 -1
  217. package/dist/client/resources/ResourceEditor.js +2 -1
  218. package/dist/client/resources/ResourceEditor.js.map +1 -1
  219. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  220. package/dist/client/resources/ResourcesPanel.js +2 -1
  221. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  222. package/dist/client/resources/use-mcp-servers.d.ts.map +1 -1
  223. package/dist/client/resources/use-mcp-servers.js +7 -2
  224. package/dist/client/resources/use-mcp-servers.js.map +1 -1
  225. package/dist/client/resources/use-resources.d.ts.map +1 -1
  226. package/dist/client/resources/use-resources.js +9 -7
  227. package/dist/client/resources/use-resources.js.map +1 -1
  228. package/dist/client/settings/AgentsSection.d.ts.map +1 -1
  229. package/dist/client/settings/AgentsSection.js +7 -5
  230. package/dist/client/settings/AgentsSection.js.map +1 -1
  231. package/dist/client/settings/AutomationsSection.d.ts.map +1 -1
  232. package/dist/client/settings/AutomationsSection.js +9 -5
  233. package/dist/client/settings/AutomationsSection.js.map +1 -1
  234. package/dist/client/settings/BackgroundAgentSection.d.ts.map +1 -1
  235. package/dist/client/settings/BackgroundAgentSection.js +2 -1
  236. package/dist/client/settings/BackgroundAgentSection.js.map +1 -1
  237. package/dist/client/settings/SecretsSection.d.ts.map +1 -1
  238. package/dist/client/settings/SecretsSection.js +12 -4
  239. package/dist/client/settings/SecretsSection.js.map +1 -1
  240. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  241. package/dist/client/settings/SettingsPanel.js +15 -23
  242. package/dist/client/settings/SettingsPanel.js.map +1 -1
  243. package/dist/client/settings/UsageSection.d.ts.map +1 -1
  244. package/dist/client/settings/UsageSection.js +2 -1
  245. package/dist/client/settings/UsageSection.js.map +1 -1
  246. package/dist/client/settings/VoiceTranscriptionSection.d.ts +2 -4
  247. package/dist/client/settings/VoiceTranscriptionSection.d.ts.map +1 -1
  248. package/dist/client/settings/VoiceTranscriptionSection.js +66 -23
  249. package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -1
  250. package/dist/client/settings/useBuilderStatus.d.ts +9 -0
  251. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  252. package/dist/client/settings/useBuilderStatus.js +31 -3
  253. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  254. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  255. package/dist/client/sharing/ShareButton.js +7 -2
  256. package/dist/client/sharing/ShareButton.js.map +1 -1
  257. package/dist/client/sharing/ShareDialog.d.ts.map +1 -1
  258. package/dist/client/sharing/ShareDialog.js +4 -3
  259. package/dist/client/sharing/ShareDialog.js.map +1 -1
  260. package/dist/client/terminal/AgentTerminal.d.ts +1 -0
  261. package/dist/client/terminal/AgentTerminal.d.ts.map +1 -1
  262. package/dist/client/terminal/AgentTerminal.js +12 -8
  263. package/dist/client/terminal/AgentTerminal.js.map +1 -1
  264. package/dist/client/tools/EmbeddedTool.d.ts +20 -0
  265. package/dist/client/tools/EmbeddedTool.d.ts.map +1 -0
  266. package/dist/client/tools/EmbeddedTool.js +113 -0
  267. package/dist/client/tools/EmbeddedTool.js.map +1 -0
  268. package/dist/client/tools/ExtensionSlot.d.ts +27 -0
  269. package/dist/client/tools/ExtensionSlot.d.ts.map +1 -0
  270. package/dist/client/tools/ExtensionSlot.js +96 -0
  271. package/dist/client/tools/ExtensionSlot.js.map +1 -0
  272. package/dist/client/tools/ToolEditor.d.ts.map +1 -1
  273. package/dist/client/tools/ToolEditor.js +5 -4
  274. package/dist/client/tools/ToolEditor.js.map +1 -1
  275. package/dist/client/tools/ToolViewer.d.ts.map +1 -1
  276. package/dist/client/tools/ToolViewer.js +10 -44
  277. package/dist/client/tools/ToolViewer.js.map +1 -1
  278. package/dist/client/tools/ToolViewerPage.d.ts.map +1 -1
  279. package/dist/client/tools/ToolViewerPage.js +2 -1
  280. package/dist/client/tools/ToolViewerPage.js.map +1 -1
  281. package/dist/client/tools/ToolsListPage.d.ts.map +1 -1
  282. package/dist/client/tools/ToolsListPage.js +3 -2
  283. package/dist/client/tools/ToolsListPage.js.map +1 -1
  284. package/dist/client/tools/ToolsSidebarSection.d.ts.map +1 -1
  285. package/dist/client/tools/ToolsSidebarSection.js +4 -3
  286. package/dist/client/tools/ToolsSidebarSection.js.map +1 -1
  287. package/dist/client/tools/iframe-bridge.d.ts +16 -0
  288. package/dist/client/tools/iframe-bridge.d.ts.map +1 -0
  289. package/dist/client/tools/iframe-bridge.js +118 -0
  290. package/dist/client/tools/iframe-bridge.js.map +1 -0
  291. package/dist/client/tools/index.d.ts +2 -0
  292. package/dist/client/tools/index.d.ts.map +1 -1
  293. package/dist/client/tools/index.js +2 -0
  294. package/dist/client/tools/index.js.map +1 -1
  295. package/dist/client/use-action.d.ts.map +1 -1
  296. package/dist/client/use-action.js +2 -1
  297. package/dist/client/use-action.js.map +1 -1
  298. package/dist/client/use-avatar.d.ts.map +1 -1
  299. package/dist/client/use-avatar.js +3 -2
  300. package/dist/client/use-avatar.js.map +1 -1
  301. package/dist/client/use-builder-enabled.d.ts.map +1 -1
  302. package/dist/client/use-builder-enabled.js +2 -1
  303. package/dist/client/use-builder-enabled.js.map +1 -1
  304. package/dist/client/use-chat-threads.d.ts.map +1 -1
  305. package/dist/client/use-chat-threads.js +2 -1
  306. package/dist/client/use-chat-threads.js.map +1 -1
  307. package/dist/client/use-db-sync.d.ts.map +1 -1
  308. package/dist/client/use-db-sync.js +3 -2
  309. package/dist/client/use-db-sync.js.map +1 -1
  310. package/dist/client/use-dev-mode.d.ts.map +1 -1
  311. package/dist/client/use-dev-mode.js +2 -1
  312. package/dist/client/use-dev-mode.js.map +1 -1
  313. package/dist/client/use-send-to-agent-chat.d.ts.map +1 -1
  314. package/dist/client/use-send-to-agent-chat.js +3 -1
  315. package/dist/client/use-send-to-agent-chat.js.map +1 -1
  316. package/dist/client/use-session.d.ts.map +1 -1
  317. package/dist/client/use-session.js +2 -1
  318. package/dist/client/use-session.js.map +1 -1
  319. package/dist/client/useProductionAgent.d.ts.map +1 -1
  320. package/dist/client/useProductionAgent.js +2 -1
  321. package/dist/client/useProductionAgent.js.map +1 -1
  322. package/dist/collab/client.d.ts.map +1 -1
  323. package/dist/collab/client.js +3 -2
  324. package/dist/collab/client.js.map +1 -1
  325. package/dist/credentials/index.d.ts +27 -10
  326. package/dist/credentials/index.d.ts.map +1 -1
  327. package/dist/credentials/index.js +61 -19
  328. package/dist/credentials/index.js.map +1 -1
  329. package/dist/db/client.d.ts.map +1 -1
  330. package/dist/db/client.js +10 -1
  331. package/dist/db/client.js.map +1 -1
  332. package/dist/db/migrations.d.ts +13 -5
  333. package/dist/db/migrations.d.ts.map +1 -1
  334. package/dist/db/migrations.js +9 -2
  335. package/dist/db/migrations.js.map +1 -1
  336. package/dist/deploy/build.d.ts +12 -1
  337. package/dist/deploy/build.d.ts.map +1 -1
  338. package/dist/deploy/build.js +195 -23
  339. package/dist/deploy/build.js.map +1 -1
  340. package/dist/file-upload/registry.d.ts.map +1 -1
  341. package/dist/file-upload/registry.js +25 -1
  342. package/dist/file-upload/registry.js.map +1 -1
  343. package/dist/index.d.ts +1 -1
  344. package/dist/index.d.ts.map +1 -1
  345. package/dist/index.js +1 -1
  346. package/dist/index.js.map +1 -1
  347. package/dist/integrations/adapters/email.d.ts.map +1 -1
  348. package/dist/integrations/adapters/email.js +152 -32
  349. package/dist/integrations/adapters/email.js.map +1 -1
  350. package/dist/integrations/adapters/slack.d.ts.map +1 -1
  351. package/dist/integrations/adapters/slack.js +190 -32
  352. package/dist/integrations/adapters/slack.js.map +1 -1
  353. package/dist/integrations/adapters/telegram.d.ts.map +1 -1
  354. package/dist/integrations/adapters/telegram.js +37 -2
  355. package/dist/integrations/adapters/telegram.js.map +1 -1
  356. package/dist/integrations/adapters/whatsapp.d.ts.map +1 -1
  357. package/dist/integrations/adapters/whatsapp.js +91 -12
  358. package/dist/integrations/adapters/whatsapp.js.map +1 -1
  359. package/dist/integrations/google-docs-poller.d.ts.map +1 -1
  360. package/dist/integrations/google-docs-poller.js +5 -2
  361. package/dist/integrations/google-docs-poller.js.map +1 -1
  362. package/dist/integrations/internal-token.d.ts.map +1 -1
  363. package/dist/integrations/internal-token.js +17 -1
  364. package/dist/integrations/internal-token.js.map +1 -1
  365. package/dist/integrations/pending-tasks-retry-job.d.ts.map +1 -1
  366. package/dist/integrations/pending-tasks-retry-job.js +18 -7
  367. package/dist/integrations/pending-tasks-retry-job.js.map +1 -1
  368. package/dist/integrations/pending-tasks-store.d.ts +16 -0
  369. package/dist/integrations/pending-tasks-store.d.ts.map +1 -1
  370. package/dist/integrations/pending-tasks-store.js +58 -5
  371. package/dist/integrations/pending-tasks-store.js.map +1 -1
  372. package/dist/integrations/plugin.d.ts.map +1 -1
  373. package/dist/integrations/plugin.js +198 -15
  374. package/dist/integrations/plugin.js.map +1 -1
  375. package/dist/integrations/types.d.ts +33 -2
  376. package/dist/integrations/types.d.ts.map +1 -1
  377. package/dist/integrations/webhook-handler.d.ts +6 -0
  378. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  379. package/dist/integrations/webhook-handler.js +141 -61
  380. package/dist/integrations/webhook-handler.js.map +1 -1
  381. package/dist/jobs/cron.d.ts.map +1 -1
  382. package/dist/jobs/cron.js +12 -4
  383. package/dist/jobs/cron.js.map +1 -1
  384. package/dist/jobs/scheduler.d.ts.map +1 -1
  385. package/dist/jobs/scheduler.js +141 -16
  386. package/dist/jobs/scheduler.js.map +1 -1
  387. package/dist/jobs/tools.d.ts.map +1 -1
  388. package/dist/jobs/tools.js +94 -3
  389. package/dist/jobs/tools.js.map +1 -1
  390. package/dist/mcp/server.d.ts.map +1 -1
  391. package/dist/mcp/server.js +128 -62
  392. package/dist/mcp/server.js.map +1 -1
  393. package/dist/mcp-client/hub-routes.d.ts +14 -0
  394. package/dist/mcp-client/hub-routes.d.ts.map +1 -1
  395. package/dist/mcp-client/hub-routes.js +42 -2
  396. package/dist/mcp-client/hub-routes.js.map +1 -1
  397. package/dist/mcp-client/index.d.ts +1 -1
  398. package/dist/mcp-client/index.d.ts.map +1 -1
  399. package/dist/mcp-client/index.js +1 -1
  400. package/dist/mcp-client/index.js.map +1 -1
  401. package/dist/mcp-client/manager.d.ts.map +1 -1
  402. package/dist/mcp-client/manager.js +28 -3
  403. package/dist/mcp-client/manager.js.map +1 -1
  404. package/dist/mcp-client/remote-store.d.ts +49 -1
  405. package/dist/mcp-client/remote-store.d.ts.map +1 -1
  406. package/dist/mcp-client/remote-store.js +253 -6
  407. package/dist/mcp-client/remote-store.js.map +1 -1
  408. package/dist/mcp-client/routes.d.ts.map +1 -1
  409. package/dist/mcp-client/routes.js +11 -9
  410. package/dist/mcp-client/routes.js.map +1 -1
  411. package/dist/mcp-client/visibility.d.ts +7 -3
  412. package/dist/mcp-client/visibility.d.ts.map +1 -1
  413. package/dist/mcp-client/visibility.js +16 -7
  414. package/dist/mcp-client/visibility.js.map +1 -1
  415. package/dist/notifications/actions.d.ts.map +1 -1
  416. package/dist/notifications/actions.js +7 -1
  417. package/dist/notifications/actions.js.map +1 -1
  418. package/dist/notifications/routes.d.ts +1 -1
  419. package/dist/notifications/routes.d.ts.map +1 -1
  420. package/dist/notifications/routes.js +20 -3
  421. package/dist/notifications/routes.js.map +1 -1
  422. package/dist/notifications/store.d.ts.map +1 -1
  423. package/dist/notifications/store.js +6 -1
  424. package/dist/notifications/store.js.map +1 -1
  425. package/dist/oauth-tokens/store.d.ts +43 -2
  426. package/dist/oauth-tokens/store.d.ts.map +1 -1
  427. package/dist/oauth-tokens/store.js +83 -14
  428. package/dist/oauth-tokens/store.js.map +1 -1
  429. package/dist/observability/experiments.js +5 -5
  430. package/dist/observability/experiments.js.map +1 -1
  431. package/dist/observability/routes.d.ts.map +1 -1
  432. package/dist/observability/routes.js +37 -8
  433. package/dist/observability/routes.js.map +1 -1
  434. package/dist/observability/store.d.ts.map +1 -1
  435. package/dist/observability/store.js +19 -3
  436. package/dist/observability/store.js.map +1 -1
  437. package/dist/observability/types.d.ts +7 -0
  438. package/dist/observability/types.d.ts.map +1 -1
  439. package/dist/observability/types.js.map +1 -1
  440. package/dist/onboarding/default-steps.d.ts.map +1 -1
  441. package/dist/onboarding/default-steps.js +1 -2
  442. package/dist/onboarding/default-steps.js.map +1 -1
  443. package/dist/onboarding/plugin.d.ts.map +1 -1
  444. package/dist/onboarding/plugin.js +63 -32
  445. package/dist/onboarding/plugin.js.map +1 -1
  446. package/dist/onboarding/types.d.ts +6 -1
  447. package/dist/onboarding/types.d.ts.map +1 -1
  448. package/dist/org/accept-pending.d.ts.map +1 -1
  449. package/dist/org/accept-pending.js +2 -1
  450. package/dist/org/accept-pending.js.map +1 -1
  451. package/dist/progress/actions.d.ts.map +1 -1
  452. package/dist/progress/actions.js +10 -1
  453. package/dist/progress/actions.js.map +1 -1
  454. package/dist/progress/routes.d.ts +1 -1
  455. package/dist/progress/routes.d.ts.map +1 -1
  456. package/dist/progress/routes.js +20 -3
  457. package/dist/progress/routes.js.map +1 -1
  458. package/dist/progress/store.d.ts.map +1 -1
  459. package/dist/progress/store.js +6 -1
  460. package/dist/progress/store.js.map +1 -1
  461. package/dist/resources/handlers.d.ts.map +1 -1
  462. package/dist/resources/handlers.js +35 -7
  463. package/dist/resources/handlers.js.map +1 -1
  464. package/dist/resources/script-helpers.d.ts.map +1 -1
  465. package/dist/resources/script-helpers.js +15 -3
  466. package/dist/resources/script-helpers.js.map +1 -1
  467. package/dist/resources/store.d.ts.map +1 -1
  468. package/dist/resources/store.js +12 -4
  469. package/dist/resources/store.js.map +1 -1
  470. package/dist/scripts/call-agent.d.ts +1 -0
  471. package/dist/scripts/call-agent.d.ts.map +1 -1
  472. package/dist/scripts/call-agent.js +78 -40
  473. package/dist/scripts/call-agent.js.map +1 -1
  474. package/dist/scripts/chat/search-chats.d.ts.map +1 -1
  475. package/dist/scripts/chat/search-chats.js +3 -2
  476. package/dist/scripts/chat/search-chats.js.map +1 -1
  477. package/dist/scripts/db/exec.d.ts +1 -1
  478. package/dist/scripts/db/exec.d.ts.map +1 -1
  479. package/dist/scripts/db/exec.js +22 -3
  480. package/dist/scripts/db/exec.js.map +1 -1
  481. package/dist/scripts/db/migrate-user-api-keys.d.ts.map +1 -1
  482. package/dist/scripts/db/migrate-user-api-keys.js +10 -0
  483. package/dist/scripts/db/migrate-user-api-keys.js.map +1 -1
  484. package/dist/scripts/db/query.d.ts +1 -1
  485. package/dist/scripts/db/query.d.ts.map +1 -1
  486. package/dist/scripts/db/query.js +22 -3
  487. package/dist/scripts/db/query.js.map +1 -1
  488. package/dist/scripts/db/scoping.d.ts.map +1 -1
  489. package/dist/scripts/db/scoping.js +15 -9
  490. package/dist/scripts/db/scoping.js.map +1 -1
  491. package/dist/scripts/dev/shell.d.ts.map +1 -1
  492. package/dist/scripts/dev/shell.js +3 -1
  493. package/dist/scripts/dev/shell.js.map +1 -1
  494. package/dist/scripts/resources/delete-memory.d.ts.map +1 -1
  495. package/dist/scripts/resources/delete-memory.js +2 -1
  496. package/dist/scripts/resources/delete-memory.js.map +1 -1
  497. package/dist/scripts/resources/delete.d.ts.map +1 -1
  498. package/dist/scripts/resources/delete.js +2 -1
  499. package/dist/scripts/resources/delete.js.map +1 -1
  500. package/dist/scripts/resources/list.d.ts.map +1 -1
  501. package/dist/scripts/resources/list.js +2 -1
  502. package/dist/scripts/resources/list.js.map +1 -1
  503. package/dist/scripts/resources/migrate-learnings.d.ts.map +1 -1
  504. package/dist/scripts/resources/migrate-learnings.js +2 -1
  505. package/dist/scripts/resources/migrate-learnings.js.map +1 -1
  506. package/dist/scripts/resources/read.d.ts.map +1 -1
  507. package/dist/scripts/resources/read.js +2 -1
  508. package/dist/scripts/resources/read.js.map +1 -1
  509. package/dist/scripts/resources/save-memory.d.ts.map +1 -1
  510. package/dist/scripts/resources/save-memory.js +2 -1
  511. package/dist/scripts/resources/save-memory.js.map +1 -1
  512. package/dist/scripts/resources/write.d.ts.map +1 -1
  513. package/dist/scripts/resources/write.js +2 -1
  514. package/dist/scripts/resources/write.js.map +1 -1
  515. package/dist/secrets/onboarding.d.ts.map +1 -1
  516. package/dist/secrets/onboarding.js +24 -16
  517. package/dist/secrets/onboarding.js.map +1 -1
  518. package/dist/secrets/routes.d.ts.map +1 -1
  519. package/dist/secrets/routes.js +139 -37
  520. package/dist/secrets/routes.js.map +1 -1
  521. package/dist/secrets/storage.d.ts.map +1 -1
  522. package/dist/secrets/storage.js +23 -12
  523. package/dist/secrets/storage.js.map +1 -1
  524. package/dist/secrets/substitution.d.ts +24 -2
  525. package/dist/secrets/substitution.d.ts.map +1 -1
  526. package/dist/secrets/substitution.js +44 -6
  527. package/dist/secrets/substitution.js.map +1 -1
  528. package/dist/server/action-discovery.d.ts.map +1 -1
  529. package/dist/server/action-discovery.js +15 -51
  530. package/dist/server/action-discovery.js.map +1 -1
  531. package/dist/server/action-routes.d.ts.map +1 -1
  532. package/dist/server/action-routes.js +42 -15
  533. package/dist/server/action-routes.js.map +1 -1
  534. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  535. package/dist/server/agent-chat-plugin.js +447 -335
  536. package/dist/server/agent-chat-plugin.js.map +1 -1
  537. package/dist/server/agent-discovery.d.ts +8 -0
  538. package/dist/server/agent-discovery.d.ts.map +1 -1
  539. package/dist/server/agent-discovery.js +39 -12
  540. package/dist/server/agent-discovery.js.map +1 -1
  541. package/dist/server/agent-teams.d.ts.map +1 -1
  542. package/dist/server/agent-teams.js +4 -1
  543. package/dist/server/agent-teams.js.map +1 -1
  544. package/dist/server/analytics.d.ts +0 -1
  545. package/dist/server/analytics.d.ts.map +1 -1
  546. package/dist/server/analytics.js +0 -1
  547. package/dist/server/analytics.js.map +1 -1
  548. package/dist/server/app-base-path.d.ts +4 -0
  549. package/dist/server/app-base-path.d.ts.map +1 -0
  550. package/dist/server/app-base-path.js +33 -0
  551. package/dist/server/app-base-path.js.map +1 -0
  552. package/dist/server/auth.d.ts +15 -0
  553. package/dist/server/auth.d.ts.map +1 -1
  554. package/dist/server/auth.js +400 -68
  555. package/dist/server/auth.js.map +1 -1
  556. package/dist/server/better-auth-instance.d.ts +1 -0
  557. package/dist/server/better-auth-instance.d.ts.map +1 -1
  558. package/dist/server/better-auth-instance.js +67 -15
  559. package/dist/server/better-auth-instance.js.map +1 -1
  560. package/dist/server/builder-browser.d.ts +15 -0
  561. package/dist/server/builder-browser.d.ts.map +1 -1
  562. package/dist/server/builder-browser.js +90 -4
  563. package/dist/server/builder-browser.js.map +1 -1
  564. package/dist/server/cli-capture.d.ts +31 -0
  565. package/dist/server/cli-capture.d.ts.map +1 -0
  566. package/dist/server/cli-capture.js +120 -0
  567. package/dist/server/cli-capture.js.map +1 -0
  568. package/dist/server/collab-plugin.d.ts +12 -0
  569. package/dist/server/collab-plugin.d.ts.map +1 -1
  570. package/dist/server/collab-plugin.js +63 -21
  571. package/dist/server/collab-plugin.js.map +1 -1
  572. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  573. package/dist/server/core-routes-plugin.js +435 -106
  574. package/dist/server/core-routes-plugin.js.map +1 -1
  575. package/dist/server/create-server.d.ts +2 -0
  576. package/dist/server/create-server.d.ts.map +1 -1
  577. package/dist/server/create-server.js +82 -11
  578. package/dist/server/create-server.js.map +1 -1
  579. package/dist/server/credential-provider.d.ts +11 -0
  580. package/dist/server/credential-provider.d.ts.map +1 -1
  581. package/dist/server/credential-provider.js +51 -2
  582. package/dist/server/credential-provider.js.map +1 -1
  583. package/dist/server/csrf.d.ts +58 -0
  584. package/dist/server/csrf.d.ts.map +1 -0
  585. package/dist/server/csrf.js +165 -0
  586. package/dist/server/csrf.js.map +1 -0
  587. package/dist/server/framework-request-handler.d.ts +20 -0
  588. package/dist/server/framework-request-handler.d.ts.map +1 -1
  589. package/dist/server/framework-request-handler.js +115 -34
  590. package/dist/server/framework-request-handler.js.map +1 -1
  591. package/dist/server/google-auth-plugin.d.ts.map +1 -1
  592. package/dist/server/google-auth-plugin.js +10 -2
  593. package/dist/server/google-auth-plugin.js.map +1 -1
  594. package/dist/server/google-oauth.d.ts +84 -2
  595. package/dist/server/google-oauth.d.ts.map +1 -1
  596. package/dist/server/google-oauth.js +248 -45
  597. package/dist/server/google-oauth.js.map +1 -1
  598. package/dist/server/index.d.ts +4 -4
  599. package/dist/server/index.d.ts.map +1 -1
  600. package/dist/server/index.js +4 -4
  601. package/dist/server/index.js.map +1 -1
  602. package/dist/server/oauth-helpers.d.ts +8 -3
  603. package/dist/server/oauth-helpers.d.ts.map +1 -1
  604. package/dist/server/oauth-helpers.js +12 -8
  605. package/dist/server/oauth-helpers.js.map +1 -1
  606. package/dist/server/onboarding-html.d.ts.map +1 -1
  607. package/dist/server/onboarding-html.js +37 -9
  608. package/dist/server/onboarding-html.js.map +1 -1
  609. package/dist/server/poll.d.ts +33 -0
  610. package/dist/server/poll.d.ts.map +1 -1
  611. package/dist/server/poll.js +43 -2
  612. package/dist/server/poll.js.map +1 -1
  613. package/dist/server/request-context.d.ts +102 -3
  614. package/dist/server/request-context.d.ts.map +1 -1
  615. package/dist/server/request-context.js +100 -7
  616. package/dist/server/request-context.js.map +1 -1
  617. package/dist/server/security-headers.d.ts +51 -0
  618. package/dist/server/security-headers.d.ts.map +1 -0
  619. package/dist/server/security-headers.js +90 -0
  620. package/dist/server/security-headers.js.map +1 -0
  621. package/dist/server/ssr-handler.d.ts.map +1 -1
  622. package/dist/server/ssr-handler.js +96 -2
  623. package/dist/server/ssr-handler.js.map +1 -1
  624. package/dist/server/transcribe-voice.d.ts.map +1 -1
  625. package/dist/server/transcribe-voice.js +307 -56
  626. package/dist/server/transcribe-voice.js.map +1 -1
  627. package/dist/server/voice-providers-status.d.ts +12 -0
  628. package/dist/server/voice-providers-status.d.ts.map +1 -0
  629. package/dist/server/voice-providers-status.js +71 -0
  630. package/dist/server/voice-providers-status.js.map +1 -0
  631. package/dist/sharing/access.d.ts.map +1 -1
  632. package/dist/sharing/access.js +16 -13
  633. package/dist/sharing/access.js.map +1 -1
  634. package/dist/sharing/actions/share-resource.d.ts +1 -0
  635. package/dist/sharing/actions/share-resource.d.ts.map +1 -1
  636. package/dist/sharing/actions/share-resource.js +45 -0
  637. package/dist/sharing/actions/share-resource.js.map +1 -1
  638. package/dist/templates/default/.agents/skills/delegate-to-agent/SKILL.md +54 -0
  639. package/dist/templates/default/app/root.tsx +1 -1
  640. package/dist/templates/default/app/routes/_index.tsx +6 -1
  641. package/dist/templates/default/public/favicon.svg +13 -0
  642. package/dist/templates/default/public/icon-180.svg +12 -3
  643. package/dist/templates/default/public/icon-192.svg +12 -3
  644. package/dist/templates/default/public/icon-512.svg +12 -3
  645. package/dist/templates/workspace-core/package.json +22 -4
  646. package/dist/templates/workspace-core/src/credentials.ts +32 -5
  647. package/dist/templates/workspace-core/tsconfig.json +4 -1
  648. package/dist/terminal/pty-server.d.ts.map +1 -1
  649. package/dist/terminal/pty-server.js +7 -1
  650. package/dist/terminal/pty-server.js.map +1 -1
  651. package/dist/terminal/terminal-plugin.js +3 -3
  652. package/dist/terminal/terminal-plugin.js.map +1 -1
  653. package/dist/tools/actions.d.ts.map +1 -1
  654. package/dist/tools/actions.js +130 -0
  655. package/dist/tools/actions.js.map +1 -1
  656. package/dist/tools/fetch-tool.d.ts +1 -0
  657. package/dist/tools/fetch-tool.d.ts.map +1 -1
  658. package/dist/tools/fetch-tool.js +38 -16
  659. package/dist/tools/fetch-tool.js.map +1 -1
  660. package/dist/tools/html-shell.d.ts +43 -1
  661. package/dist/tools/html-shell.d.ts.map +1 -1
  662. package/dist/tools/html-shell.js +102 -4
  663. package/dist/tools/html-shell.js.map +1 -1
  664. package/dist/tools/proxy-security.d.ts +12 -0
  665. package/dist/tools/proxy-security.d.ts.map +1 -0
  666. package/dist/tools/proxy-security.js +158 -0
  667. package/dist/tools/proxy-security.js.map +1 -0
  668. package/dist/tools/routes.d.ts.map +1 -1
  669. package/dist/tools/routes.js +158 -105
  670. package/dist/tools/routes.js.map +1 -1
  671. package/dist/tools/schema.d.ts +3 -0
  672. package/dist/tools/schema.d.ts.map +1 -1
  673. package/dist/tools/schema.js +3 -0
  674. package/dist/tools/schema.js.map +1 -1
  675. package/dist/tools/slots/routes.d.ts +15 -0
  676. package/dist/tools/slots/routes.d.ts.map +1 -0
  677. package/dist/tools/slots/routes.js +94 -0
  678. package/dist/tools/slots/routes.js.map +1 -0
  679. package/dist/tools/slots/schema.d.ts +303 -0
  680. package/dist/tools/slots/schema.d.ts.map +1 -0
  681. package/dist/tools/slots/schema.js +76 -0
  682. package/dist/tools/slots/schema.js.map +1 -0
  683. package/dist/tools/slots/store.d.ts +66 -0
  684. package/dist/tools/slots/store.d.ts.map +1 -0
  685. package/dist/tools/slots/store.js +227 -0
  686. package/dist/tools/slots/store.js.map +1 -0
  687. package/dist/tools/store.d.ts.map +1 -1
  688. package/dist/tools/store.js +28 -37
  689. package/dist/tools/store.js.map +1 -1
  690. package/dist/tools/url-safety.d.ts +24 -0
  691. package/dist/tools/url-safety.d.ts.map +1 -0
  692. package/dist/tools/url-safety.js +224 -0
  693. package/dist/tools/url-safety.js.map +1 -0
  694. package/dist/tracking/providers.d.ts.map +1 -1
  695. package/dist/tracking/providers.js +28 -11
  696. package/dist/tracking/providers.js.map +1 -1
  697. package/dist/tracking/registry.d.ts.map +1 -1
  698. package/dist/tracking/registry.js +7 -3
  699. package/dist/tracking/registry.js.map +1 -1
  700. package/dist/triggers/actions.d.ts.map +1 -1
  701. package/dist/triggers/actions.js +11 -6
  702. package/dist/triggers/actions.js.map +1 -1
  703. package/dist/triggers/condition-evaluator.d.ts +8 -0
  704. package/dist/triggers/condition-evaluator.d.ts.map +1 -1
  705. package/dist/triggers/condition-evaluator.js +39 -4
  706. package/dist/triggers/condition-evaluator.js.map +1 -1
  707. package/dist/triggers/dispatcher.d.ts.map +1 -1
  708. package/dist/triggers/dispatcher.js +67 -4
  709. package/dist/triggers/dispatcher.js.map +1 -1
  710. package/dist/vite/action-types-plugin.d.ts.map +1 -1
  711. package/dist/vite/action-types-plugin.js +8 -5
  712. package/dist/vite/action-types-plugin.js.map +1 -1
  713. package/dist/vite/client.d.ts +2 -0
  714. package/dist/vite/client.d.ts.map +1 -1
  715. package/dist/vite/client.js +216 -4
  716. package/dist/vite/client.js.map +1 -1
  717. package/docs/content/authentication.md +27 -12
  718. package/docs/content/drop-in-agent.md +2 -2
  719. package/docs/content/messaging.md +195 -155
  720. package/docs/content/onboarding.md +82 -12
  721. package/docs/content/template-analytics.md +65 -59
  722. package/docs/content/template-clips.md +7 -9
  723. package/docs/content/template-design.md +55 -0
  724. package/docs/content/template-dispatch.md +13 -0
  725. package/docs/content/template-forms.md +7 -6
  726. package/docs/content/template-mail.md +78 -80
  727. package/package.json +2 -1
  728. package/src/templates/default/.agents/skills/delegate-to-agent/SKILL.md +54 -0
  729. package/src/templates/default/app/root.tsx +1 -1
  730. package/src/templates/default/app/routes/_index.tsx +6 -1
  731. package/src/templates/default/public/favicon.svg +13 -0
  732. package/src/templates/default/public/icon-180.svg +12 -3
  733. package/src/templates/default/public/icon-192.svg +12 -3
  734. package/src/templates/default/public/icon-512.svg +12 -3
  735. package/src/templates/workspace-core/package.json +22 -4
  736. package/src/templates/workspace-core/src/credentials.ts +32 -5
  737. package/src/templates/workspace-core/tsconfig.json +4 -1
@@ -1,20 +1,22 @@
1
- import { runWithRequestContext, getRequestOrgId } from "./request-context.js";
1
+ import { runWithRequestContext, getRequestOrgId, getRequestUserEmail, getRequestRunContext, ensureRequestRunContext, } from "./request-context.js";
2
2
  import { getSetting, putSetting } from "../settings/store.js";
3
3
  import { getH3App, trackPluginInit } from "./framework-request-handler.js";
4
4
  import { createProductionAgentHandler, runAgentLoop, actionsToEngineTools, getActiveRunForThreadAsync, abortRun, subscribeToRun, } from "../agent/production-agent.js";
5
5
  import { resolveEngine, createAnthropicEngine } from "../agent/engine/index.js";
6
+ import { DEFAULT_MODEL } from "../agent/default-model.js";
6
7
  import { McpClientManager, loadMcpConfig, autoDetectMcpConfig, mcpToolsToActionEntries, syncMcpActionEntries, mountMcpServersRoutes, mountMcpHubRoutes, buildMergedConfig, getHubStatus, isHubServeEnabled, } from "../mcp-client/index.js";
7
8
  import { discoverAgents } from "./agent-discovery.js";
8
9
  import { loadSchemaPromptBlock } from "./schema-prompt.js";
9
10
  import { buildAssistantMessage, extractThreadMeta, } from "../agent/thread-data-builder.js";
10
11
  import { defineEventHandler, setResponseStatus, setResponseHeader, getMethod, getQuery, getHeader, } from "h3";
11
- import { getSession } from "./auth.js";
12
+ import { getSession, DEV_MODE_USER_EMAIL } from "./auth.js";
12
13
  import { getOrigin } from "./google-oauth.js";
13
14
  import { createThread, forkThread, getThread, listThreads, searchThreads, updateThreadData, withThreadDataLock, deleteThread, setThreadQueuedMessages, } from "../chat-threads/store.js";
14
15
  import { resourceListAccessible, resourceList, resourceGet, resourceGetByPath, ensurePersonalDefaults, SHARED_OWNER, } from "../resources/store.js";
15
16
  import nodePath from "node:path";
16
17
  import { readBody } from "./h3-helpers.js";
17
18
  import { getBuilderBrowserConnectUrl } from "./builder-browser.js";
19
+ import { captureCliOutput } from "./cli-capture.js";
18
20
  // Lazy fs — loaded via dynamic import() on first use.
19
21
  // This avoids require() which bundlers convert to createRequire(import.meta.url)
20
22
  // that crashes on CF Workers where import.meta.url is undefined.
@@ -27,7 +29,9 @@ async function lazyFs() {
27
29
  }
28
30
  /**
29
31
  * Wraps a core CLI script (that writes to console.log) as a ActionEntry
30
- * by capturing stdout.
32
+ * by capturing stdout. Uses an AsyncLocalStorage-backed capture so
33
+ * concurrent tool calls do not corrupt the global console/stdout pointers
34
+ * (see `cli-capture.ts`).
31
35
  */
32
36
  function wrapCliScript(tool, cliDefault, opts) {
33
37
  return {
@@ -38,39 +42,7 @@ function wrapCliScript(tool, cliDefault, opts) {
38
42
  for (const [k, v] of Object.entries(args)) {
39
43
  cliArgs.push(`--${k}`, v);
40
44
  }
41
- const logs = [];
42
- const origLog = console.log;
43
- const origError = console.error;
44
- const origStdoutWrite = process.stdout.write;
45
- console.log = (...a) => {
46
- logs.push(a.map(String).join(" "));
47
- };
48
- console.error = (...a) => {
49
- logs.push(a.map(String).join(" "));
50
- };
51
- // Intercept process.stdout.write so scripts that write directly
52
- // (e.g. resource-read) have their output captured
53
- process.stdout.write = ((chunk, ...rest) => {
54
- if (typeof chunk === "string") {
55
- logs.push(chunk);
56
- }
57
- else if (Buffer.isBuffer(chunk)) {
58
- logs.push(chunk.toString());
59
- }
60
- return true;
61
- });
62
- try {
63
- await cliDefault(cliArgs);
64
- }
65
- catch (err) {
66
- logs.push(`Error: ${err?.message ?? String(err)}`);
67
- }
68
- finally {
69
- console.log = origLog;
70
- console.error = origError;
71
- process.stdout.write = origStdoutWrite;
72
- }
73
- return logs.join("\n") || "(no output)";
45
+ return captureCliOutput(() => cliDefault(cliArgs));
74
46
  },
75
47
  };
76
48
  }
@@ -156,6 +128,12 @@ function createRefreshScreenEntry() {
156
128
  }
157
129
  /** Well-known application-state key used by the refresh-screen tool. */
158
130
  const SCREEN_REFRESH_KEY = "__screen_refresh__";
131
+ /**
132
+ * In-memory rate-limit tracker for `/generate-title`. Keyed by user email,
133
+ * value is recent invocation timestamps within the rolling window. Stale
134
+ * entries are pruned on read.
135
+ */
136
+ const generateTitleRateLimit = new Map();
159
137
  /**
160
138
  * Creates the `set-search-params` / `set-url-path` tools. Writes a one-shot
161
139
  * URL command to application_state; the client's URLSync component applies
@@ -953,6 +931,8 @@ const FRAMEWORK_CORE_COMPACT = `
953
931
  6. **Memory** — Use \`save-memory\` proactively when you learn preferences, corrections, or project context.
954
932
  7. **Security** — Always use parameterized queries. Never \`dangerouslySetInnerHTML\`, \`innerHTML\`, or \`eval()\`.
955
933
  8. **\`db-*\` tools are internal only** — \`db-query\`, \`db-exec\`, \`db-patch\` ONLY access the app's own SQL database (settings, application_state, template tables). They CANNOT reach BigQuery, HubSpot, GA4, Jira, or any external data source. If the user asks about a table that is NOT in the app schema (e.g. \`dbt_analytics.*\`, \`dbt_mart.*\`, or any fully-qualified \`project.dataset.table\`), use the appropriate template action instead — \`bigquery\` for warehouse tables, \`ga4-report\` for Google Analytics, \`hubspot-deals\` for HubSpot, etc. **Never use \`db-query\` for external data — it will fail.**
934
+ 9. **Never fabricate data** — Do NOT invent numbers, metrics, records, or query results. Do NOT present estimated or example data as if it were real. If a data source is unavailable (missing credentials, connection error, tool failure), say so clearly, note the gap, and work with whatever data you do have. If no data can be retrieved at all, say "I can't retrieve this data right now" and explain why. Presenting made-up data as real is a critical failure — it is worse than admitting the limitation.
935
+ 10. **Never fabricate success from tool errors** — When any tool call returns an error (marked \`isError: true\`, contains "Command failed", "Error:", or non-zero exit output), the operation FAILED. Do NOT synthesize a success narrative or describe what the action "would have" produced. Report the failure verbatim from the tool output. This applies especially to \`shell(command="pnpm action ...")\` calls: if the action threw, it did NOT succeed.
956
936
 
957
937
  ### Resources
958
938
 
@@ -1117,6 +1097,8 @@ const FRAMEWORK_CORE = `
1117
1097
  6. **Memory** — Use the structured memory system to persist knowledge across sessions. Use \`save-memory\` proactively when you learn preferences, corrections, or project context. Update shared AGENTS.md for instructions that should apply to all users.
1118
1098
  7. **Security** — Always use \`defineAction\` with a Zod \`schema:\` for input validation. Never construct SQL with string concatenation — use parameterized queries via db-query/db-exec. Never use \`dangerouslySetInnerHTML\`, \`innerHTML\`, or \`eval()\`. Never expose secrets in responses or source code. Every table with user data must have \`owner_email\`.
1119
1099
  8. **\`db-*\` tools are internal only** — \`db-query\`, \`db-exec\`, \`db-patch\` ONLY access the app's own SQL database (settings, application_state, template tables). They CANNOT reach BigQuery, HubSpot, GA4, Jira, or any external data source. If the user asks about a table that is NOT in the app schema (e.g. \`dbt_analytics.*\`, \`dbt_mart.*\`, or any fully-qualified \`project.dataset.table\`), use the appropriate template action instead — \`bigquery\` for warehouse tables, \`ga4-report\` for Google Analytics, \`hubspot-deals\` for HubSpot, etc. **Never use \`db-query\` for external data — it will fail.**
1100
+ 9. **Never fabricate data** — Do NOT invent numbers, metrics, records, or query results. Do NOT present estimated or example data as if it were real. If a data source is unavailable (missing credentials, connection error, tool failure), say so clearly, note the gap, and work with whatever data you do have. If no data can be retrieved at all, say "I can't retrieve this data right now" and explain why. Presenting made-up data as real is a critical failure — it is worse than admitting the limitation.
1101
+ 10. **Never fabricate success from tool errors** — When any tool call returns an error (marked \`isError: true\`, contains "Command failed", "Error:", or non-zero exit output), the operation FAILED. Do NOT synthesize a success narrative, format a result table, or describe what the action "would have" produced. Report the failure verbatim from the tool output. This applies especially to \`shell(command="pnpm action ...")\` calls: if the underlying action threw (visible in the error text), the action did NOT succeed — report the error, do not describe a successful outcome.
1120
1102
 
1121
1103
  ### Resources
1122
1104
 
@@ -1274,8 +1256,16 @@ The agent and the UI are equal partners — everything the UI can do, you can do
1274
1256
 
1275
1257
  **In production mode, you operate through registered actions exposed as tools.** These are your capabilities — use them to read data, take actions, and help the user. You cannot edit source code or access the filesystem directly. Your tools are the app's API.
1276
1258
 
1259
+ ### Tools (Mini-Apps) — Use \`create-tool\` for tools / widgets / dashboards
1260
+
1261
+ If the user asks you to create, build, or make a **tool**, **widget**, **dashboard**, **calculator**, **mini-app**, or any small self-contained interactive utility — call \`create-tool\` immediately with a self-contained Alpine.js HTML body. This is **NOT** a code change and does **NOT** go through \`connect-builder\`. Tools are sandboxed mini-apps stored in the database — no source files are touched, no PR is opened, no build is required. The tool appears in the Tools view and can be edited later via \`update-tool\`.
1262
+
1263
+ When in doubt — if the request mentions "tool", "widget", "dashboard", "calculator", or asks for a small interactive utility — choose \`create-tool\`. Do **not** preface the call with planning text like "let me build the dashboard…" — just call \`create-tool\` directly. One tool call, one response.
1264
+
1277
1265
  ### Code Changes Not Available — Call \`connect-builder\` Immediately
1278
1266
 
1267
+ If the request matches the Tools section above (tool / widget / dashboard / calculator / mini-app), use \`create-tool\` instead — do NOT route it to \`connect-builder\`.
1268
+
1279
1269
  When the user asks you to change the UI, modify code, add a feature, fix a bug in the app itself, change styles, add a hook, create a component, add a route, add an integration, or anything else that requires editing source files — you MUST take exactly these steps, in order:
1280
1270
 
1281
1271
  1. Call the \`connect-builder\` tool, passing the user's full request verbatim as the \`prompt\` argument. This renders an inline card. If Builder is connected, the card hands the prompt off to Builder's cloud agent on one click and returns a branch URL; otherwise it shows a connect / waitlist flow. Either way, Builder writes the code — no local setup, no clone, no install.
@@ -1323,9 +1313,13 @@ The agent and the UI are equal partners — everything the UI can do, you can do
1323
1313
 
1324
1314
  **In production mode, you operate through registered actions exposed as tools.** These are your capabilities — use them to read data, take actions, and help the user. You cannot edit source code or access the filesystem directly. Your tools are the app's API.
1325
1315
 
1316
+ ### Tools (Mini-Apps) — Use \`create-tool\`
1317
+
1318
+ If the user asks for a **tool**, **widget**, **dashboard**, **calculator**, or **mini-app**, call \`create-tool\` immediately with a self-contained Alpine.js HTML body. This is NOT a code change — tools are sandboxed mini-apps stored in the database. Do not preface with "let me build…" — just call \`create-tool\`.
1319
+
1326
1320
  ### Code Changes — Call \`connect-builder\`
1327
1321
 
1328
- When the user asks to change the UI, modify code, add a feature, or fix a bug in the app itself — call \`connect-builder\` immediately, passing the user's request as the \`prompt\`. Do NOT write code, list files, make plans, or spawn sub-agents for code changes. Builder handles it in the cloud. Mention \`npx agent-native create <app-name>\` as an offline fallback.
1322
+ When the user asks to change the UI, modify code, add a feature, or fix a bug in the app itself — call \`connect-builder\` immediately, passing the user's request as the \`prompt\`. (Tool / widget / dashboard requests use \`create-tool\` instead — see above.) Do NOT write code, list files, make plans, or spawn sub-agents for code changes. Builder handles it in the cloud. Mention \`npx agent-native create <app-name>\` as an offline fallback.
1329
1323
  ${FRAMEWORK_CORE_COMPACT}`;
1330
1324
  const DEV_FRAMEWORK_PROMPT_COMPACT = `## Agent-Native Framework — Development Mode
1331
1325
 
@@ -1760,9 +1754,8 @@ export function createAgentChatPlugin(options) {
1760
1754
  ...engineScripts,
1761
1755
  };
1762
1756
  const callAgentScript = await createCallAgentScriptEntry(options?.appId);
1763
- let _currentRequestOrigin = "http://localhost:3000";
1764
1757
  const browserTools = createBuilderBrowserTool({
1765
- getOrigin: () => _currentRequestOrigin,
1758
+ getOrigin: () => getRequestRunContext()?.requestOrigin ?? "http://localhost:3000",
1766
1759
  });
1767
1760
  // Auto-mount A2A protocol endpoints so every app is discoverable
1768
1761
  // and callable by other agents via the standard protocol.
@@ -1893,27 +1886,57 @@ export function createAgentChatPlugin(options) {
1893
1886
  }
1894
1887
  catch { }
1895
1888
  }
1896
- // Mutable owner set per-request by the production handler, read by
1897
- // automation tools and fetch tool via closure. Declared here (before
1898
- // allScripts) so the tools are in scope when allScripts is built.
1899
- let _currentRunOwner = "local@localhost";
1900
- // Automation tools + fetch tool depend on _currentRunOwner via callback
1889
+ // Per-request owner is read from the AsyncLocalStorage run context
1890
+ // (populated by prepareRun). Module-scope `let` would race across
1891
+ // concurrent requests on a long-lived Node process overlapping
1892
+ // tool calls would observe whichever request wrote last. ALS gives
1893
+ // each async call-chain its own view of the owner.
1894
+ //
1895
+ // Falls back to `getRequestUserEmail()` so callers that wrap work
1896
+ // in `runWithRequestContext({ userEmail }, …)` without going through
1897
+ // `prepareRun` (recurring jobs, trigger dispatcher) still see the
1898
+ // correct owner.
1899
+ //
1900
+ // SECURITY: returns `null` when neither the run context nor the
1901
+ // request user-email is populated. Consumers MUST short-circuit
1902
+ // with an explicit error rather than fall back to a sentinel
1903
+ // identity (e.g. DEV_MODE_USER_EMAIL). The previous fallback to
1904
+ // `local@localhost` slipped past `guard-no-localhost-fallback`
1905
+ // because the literal was hidden behind a symbolic alias —
1906
+ // any agent loop that reached this code without a populated
1907
+ // session would resolve `${keys.NAME}` against the dev-shim's
1908
+ // `app_secrets WHERE scope_id='local@localhost'` rows. See
1909
+ // audit 02 (HIGH: getCurrentRunOwner) and the
1910
+ // 2026-04-29 credentials-leak incident for the prior shape.
1911
+ const getCurrentRunOwner = () => getRequestRunContext()?.owner ?? getRequestUserEmail() ?? null;
1912
+ const requireCurrentRunOwner = (operation) => {
1913
+ const owner = getCurrentRunOwner();
1914
+ if (!owner) {
1915
+ throw new Error(`[agent-chat] No authenticated owner in run context — ` +
1916
+ `refusing to ${operation}. Ensure the request goes through ` +
1917
+ `prepareRun() or is wrapped in runWithRequestContext({ userEmail, ... }).`);
1918
+ }
1919
+ return owner;
1920
+ };
1921
+ // Automation tools + fetch tool — depend on owner via callback.
1922
+ // Each callback short-circuits with a clear error when the run context
1923
+ // has no authenticated owner (see SECURITY note on getCurrentRunOwner).
1901
1924
  let automationTools = {};
1902
1925
  try {
1903
1926
  const { createAutomationToolEntries } = await import("../triggers/actions.js");
1904
- automationTools = createAutomationToolEntries(() => _currentRunOwner);
1927
+ automationTools = createAutomationToolEntries(() => requireCurrentRunOwner("manage automations"));
1905
1928
  }
1906
1929
  catch { }
1907
1930
  let notificationTools = {};
1908
1931
  try {
1909
1932
  const { createNotificationToolEntries } = await import("../notifications/actions.js");
1910
- notificationTools = createNotificationToolEntries(() => _currentRunOwner);
1933
+ notificationTools = createNotificationToolEntries(() => requireCurrentRunOwner("manage notifications"));
1911
1934
  }
1912
1935
  catch { }
1913
1936
  let progressTools = {};
1914
1937
  try {
1915
1938
  const { createProgressToolEntries } = await import("../progress/actions.js");
1916
- progressTools = createProgressToolEntries(() => _currentRunOwner);
1939
+ progressTools = createProgressToolEntries(() => requireCurrentRunOwner("manage progress"));
1917
1940
  }
1918
1941
  catch { }
1919
1942
  let fetchTool = {};
@@ -1921,10 +1944,10 @@ export function createAgentChatPlugin(options) {
1921
1944
  const { createFetchToolEntry } = await import("../tools/fetch-tool.js");
1922
1945
  const { resolveKeyReferences, validateUrlAllowlist, getKeyAllowlist } = await import("../secrets/substitution.js");
1923
1946
  fetchTool = createFetchToolEntry({
1924
- resolveKeys: async (text) => resolveKeyReferences(text, "user", _currentRunOwner),
1947
+ resolveKeys: async (text) => resolveKeyReferences(text, "user", requireCurrentRunOwner("resolve key references")),
1925
1948
  validateUrl: async (url, usedKeys) => {
1926
1949
  for (const keyName of usedKeys) {
1927
- const allowlist = await getKeyAllowlist(keyName, "user", _currentRunOwner);
1950
+ const allowlist = await getKeyAllowlist(keyName, "user", requireCurrentRunOwner("validate URL allowlist"));
1928
1951
  if (allowlist && !validateUrlAllowlist(url, allowlist)) {
1929
1952
  return false;
1930
1953
  }
@@ -1994,11 +2017,80 @@ export function createAgentChatPlugin(options) {
1994
2017
  streaming: true,
1995
2018
  handler: async function* (message, context) {
1996
2019
  // Resolve the caller's identity for user-scoped data access.
2020
+ // Priority: A2A-JWT verified email (set by the A2A handler in
2021
+ // request-context) > dev session DB (dev only) > Google OAuth
2022
+ // tokeninfo (prod only). Without the JWT-verified-email path,
2023
+ // cross-app A2A calls landed owned by `local@localhost` (dev) or
2024
+ // `dispatch@shared`, which made resources invisible to the actual
2025
+ // signed-in user.
2026
+ //
2027
+ // SECURITY: we deliberately do NOT trust `context.metadata.userEmail`
2028
+ // as a fallback. The A2A endpoint runs in three modes — JWT-signed
2029
+ // (verified email lands in request context), API-key (caller is
2030
+ // app-authenticated but NOT user-authenticated), and unsigned
2031
+ // (no auth at all). Trusting caller-supplied metadata on the latter
2032
+ // two paths would let any reachable caller forge `metadata.userEmail`
2033
+ // and impersonate an arbitrary user. The JWT path already populates
2034
+ // the request context, so the metadata fallback was only ever used
2035
+ // on the unauthenticated paths — exactly where it's unsafe.
1997
2036
  const isDev = process.env.NODE_ENV !== "production";
1998
2037
  let userEmail;
1999
- if (isDev) {
2000
- userEmail = context.metadata?.userEmail || undefined;
2001
- if (!userEmail) {
2038
+ // 1. JWT-verified email from A2A receiver (auth boundary already
2039
+ // enforced upstream). Works in dev AND prod.
2040
+ try {
2041
+ const { getRequestUserEmail } = await import("./request-context.js");
2042
+ userEmail = getRequestUserEmail();
2043
+ }
2044
+ catch { }
2045
+ // Dev-mode-only: when no JWT-verified email is present, fall back
2046
+ // to the most recently logged-in session. This is convenient for a
2047
+ // single-developer dev box but is a silent-impersonation hole if
2048
+ // it ever fires in production or on an exposed dev environment
2049
+ // (preview deploys, ngrok tunnels, etc.).
2050
+ //
2051
+ // SECURITY: gate this fallback narrowly:
2052
+ // - NODE_ENV strictly === "development" (not "test", not unset).
2053
+ // - AUTH_MODE === "local" (the dev-only auth shim).
2054
+ // - Request host is localhost / 127.0.0.1 (best-effort: when the
2055
+ // A2A handler doesn't have direct H3 event access, we rely on
2056
+ // env-based shape checks).
2057
+ //
2058
+ // In production this MUST never fire — the runtime assertion
2059
+ // below crashes loud if NODE_ENV === "production" somehow reaches
2060
+ // this block.
2061
+ if (!userEmail && isDev) {
2062
+ if (process.env.NODE_ENV === "production") {
2063
+ throw new Error("[agent-chat] Dev-mode 'latest session' fallback reached in production — refusing.");
2064
+ }
2065
+ const strictlyDev = process.env.NODE_ENV === "development";
2066
+ const localAuthMode = process.env.AUTH_MODE === "local";
2067
+ // Request host check: rely on the request-context request origin
2068
+ // which prepareRun() / mountActionRoutes populate. The A2A
2069
+ // handler doesn't have direct H3 event access, but on a
2070
+ // misconfigured non-localhost dev box we still want to refuse.
2071
+ let isLocalHost = false;
2072
+ try {
2073
+ const origin = getRequestRunContext()?.requestOrigin;
2074
+ if (origin) {
2075
+ const url = new URL(origin);
2076
+ isLocalHost =
2077
+ url.hostname === "localhost" ||
2078
+ url.hostname === "127.0.0.1" ||
2079
+ url.hostname === "::1";
2080
+ }
2081
+ else {
2082
+ // No origin in context — the A2A handler runs without an
2083
+ // explicit request origin. Treat absence as permissive only
2084
+ // when we're confident the process is dev-only (NODE_ENV
2085
+ // strictly "development" + AUTH_MODE=local). Otherwise
2086
+ // refuse.
2087
+ isLocalHost = strictlyDev && localAuthMode;
2088
+ }
2089
+ }
2090
+ catch {
2091
+ isLocalHost = false;
2092
+ }
2093
+ if (strictlyDev && localAuthMode && isLocalHost) {
2002
2094
  try {
2003
2095
  const { getDbExec } = await import("../db/client.js");
2004
2096
  const db = getDbExec();
@@ -2012,7 +2104,7 @@ export function createAgentChatPlugin(options) {
2012
2104
  catch { }
2013
2105
  }
2014
2106
  }
2015
- else {
2107
+ if (!userEmail && !isDev) {
2016
2108
  const googleToken = context.metadata?.googleToken;
2017
2109
  if (googleToken) {
2018
2110
  try {
@@ -2027,9 +2119,6 @@ export function createAgentChatPlugin(options) {
2027
2119
  catch { }
2028
2120
  }
2029
2121
  }
2030
- if (userEmail) {
2031
- process.env.AGENT_USER_EMAIL = userEmail;
2032
- }
2033
2122
  const text = message.parts
2034
2123
  .filter((p) => p.type === "text")
2035
2124
  .map((p) => p.text)
@@ -2053,7 +2142,9 @@ export function createAgentChatPlugin(options) {
2053
2142
  const devActive = isDevMode();
2054
2143
  const handler = devActive && devHandler ? devHandler : prodHandler;
2055
2144
  // Build the same system prompt the interactive agent uses
2056
- const owner = userEmail || "local@localhost";
2145
+ if (!userEmail)
2146
+ throw new Error("no authenticated user");
2147
+ const owner = userEmail;
2057
2148
  const resources = await loadResourcesForPrompt(owner, lazyContext);
2058
2149
  const schemaBlock = lazyContext
2059
2150
  ? ""
@@ -2061,7 +2152,7 @@ export function createAgentChatPlugin(options) {
2061
2152
  const systemPrompt = devActive
2062
2153
  ? devPrompt + resources + schemaBlock
2063
2154
  : basePrompt + resources + schemaBlock;
2064
- const model = options?.model ?? "claude-sonnet-4-6";
2155
+ const model = options?.model ?? DEFAULT_MODEL;
2065
2156
  // Build tools — same as interactive handler but WITHOUT call-agent
2066
2157
  // to prevent infinite recursive A2A loops (agent calling itself).
2067
2158
  // In dev mode, template actions are invoked via shell (not native tools),
@@ -2181,7 +2272,7 @@ export function createAgentChatPlugin(options) {
2181
2272
  engineOption: options?.engine,
2182
2273
  apiKey: options?.apiKey,
2183
2274
  });
2184
- const model = options?.model ?? "claude-sonnet-4-6";
2275
+ const model = options?.model ?? DEFAULT_MODEL;
2185
2276
  // Same actions as A2A — without call-agent to prevent loops.
2186
2277
  // In dev mode, template actions go through shell, not native tools.
2187
2278
  const devActiveMcp = isDevMode();
@@ -2207,10 +2298,10 @@ export function createAgentChatPlugin(options) {
2207
2298
  ...toolActions,
2208
2299
  };
2209
2300
  const mcpTools = actionsToEngineTools(mcpActions);
2210
- const resources = await loadResourcesForPrompt("local@localhost", lazyContext);
2301
+ const resources = await loadResourcesForPrompt(DEV_MODE_USER_EMAIL, lazyContext);
2211
2302
  const schemaBlock = lazyContext
2212
2303
  ? ""
2213
- : await buildSchemaBlock("local@localhost", devActiveMcp);
2304
+ : await buildSchemaBlock(DEV_MODE_USER_EMAIL, devActiveMcp);
2214
2305
  // Build the MCP handler's own prompt — always use the shell-based
2215
2306
  // dev prompt in dev mode because mcpActions routes template actions
2216
2307
  // through shell (`devScriptsForA2A`), regardless of `nativeActionsInDev`.
@@ -2248,13 +2339,15 @@ export function createAgentChatPlugin(options) {
2248
2339
  });
2249
2340
  // Resolve owner from the H3 event's session — matches how resources are created
2250
2341
  const getOwnerFromEvent = async (event) => {
2251
- try {
2252
- const session = await getSession(event);
2253
- return session?.email || "local@localhost";
2254
- }
2255
- catch {
2256
- return "local@localhost";
2342
+ const session = await getSession(event);
2343
+ if (!session?.email) {
2344
+ const { createError } = await import("h3");
2345
+ throw createError({
2346
+ statusCode: 401,
2347
+ statusMessage: "Unauthenticated",
2348
+ });
2257
2349
  }
2350
+ return session.email;
2258
2351
  };
2259
2352
  // Auto-mount template actions as HTTP endpoints under /_agent-native/actions/
2260
2353
  // Include engine management script so the UI can call manage-agent-engine.
@@ -2348,10 +2441,11 @@ export function createAgentChatPlugin(options) {
2348
2441
  }
2349
2442
  // Store debug metadata so we can inspect what the LLM actually
2350
2443
  // received (system prompt, model, engine) when diagnosing issues.
2444
+ const runCtx = getRequestRunContext();
2351
2445
  repo._debug = {
2352
- systemPrompt: _currentRunSystemPrompt,
2353
- model: _currentRunModel ?? resolvedModel,
2354
- engine: _currentRunEngine?.name ?? "unknown",
2446
+ systemPrompt: runCtx?.systemPrompt,
2447
+ model: runCtx?.model ?? resolvedModel,
2448
+ engine: runCtx?.engine?.name ?? "unknown",
2355
2449
  timestamp: Date.now(),
2356
2450
  };
2357
2451
  const meta = extractThreadMeta(repo);
@@ -2361,13 +2455,32 @@ export function createAgentChatPlugin(options) {
2361
2455
  // Best-effort — don't break cleanup
2362
2456
  }
2363
2457
  });
2364
- // Emit agent.turn.completed for automation triggers
2458
+ // Emit agent.turn.completed for automation triggers.
2459
+ //
2460
+ // SECURITY: include `owner` so the trigger dispatcher's tenant-scope
2461
+ // check engages (see triggers/dispatcher.ts:212-218). Without an
2462
+ // owner, every user's matching `agent.turn.completed` trigger
2463
+ // would fire when ANY user's chat turn completes — cross-tenant
2464
+ // fan-out (audit 12 #9). Owner comes from the thread row when
2465
+ // available (most reliable; persisted at thread create time),
2466
+ // falling back to the current run context's owner. If neither
2467
+ // resolves we skip emission entirely rather than emit unowned.
2365
2468
  try {
2366
- const { emit } = await import("../event-bus/index.js");
2367
- emit("agent.turn.completed", {
2368
- threadId,
2369
- model: resolvedModel,
2370
- });
2469
+ let ownerEmail;
2470
+ try {
2471
+ const ownerThread = await getThread(threadId);
2472
+ ownerEmail = ownerThread?.ownerEmail;
2473
+ }
2474
+ catch {
2475
+ // ignore — fall through to run-context owner
2476
+ }
2477
+ if (!ownerEmail) {
2478
+ ownerEmail = getRequestRunContext()?.owner;
2479
+ }
2480
+ if (ownerEmail) {
2481
+ const { emit } = await import("../event-bus/index.js");
2482
+ emit("agent.turn.completed", { threadId, model: resolvedModel }, { owner: ownerEmail });
2483
+ }
2371
2484
  }
2372
2485
  catch {
2373
2486
  // Event bus not available — skip
@@ -2428,18 +2541,10 @@ export function createAgentChatPlugin(options) {
2428
2541
  // Each run gets its own send function, keyed by threadId so concurrent
2429
2542
  // requests for different threads don't clobber each other.
2430
2543
  const _runSendByThread = new Map();
2431
- let _currentRunUserApiKey;
2432
- let _currentRunThreadId = "";
2433
- let _currentRunSystemPrompt = basePrompt;
2434
- // Populated by onEngineResolved per request so sub-agents inherit
2435
- // whichever provider + model the user configured (OpenRouter, Groq, …)
2436
- // instead of silently falling back to Anthropic + Claude.
2437
- let _currentRunEngine;
2438
- let _currentRunModel;
2439
- const resolvedModel = options?.model ?? "claude-sonnet-4-6";
2544
+ const resolvedModel = options?.model ?? DEFAULT_MODEL;
2440
2545
  const teamTools = createTeamTools({
2441
- getOwner: () => _currentRunOwner,
2442
- getSystemPrompt: () => _currentRunSystemPrompt,
2546
+ getOwner: () => requireCurrentRunOwner("spawn or manage sub-agents"),
2547
+ getSystemPrompt: () => getRequestRunContext()?.systemPrompt ?? basePrompt,
2443
2548
  getActions: () => isDevMode()
2444
2549
  ? {
2445
2550
  // Sub-agents spawned in dev mode also invoke template actions
@@ -2460,20 +2565,24 @@ export function createAgentChatPlugin(options) {
2460
2565
  ...urlTools,
2461
2566
  ...chatScripts,
2462
2567
  },
2463
- getEngine: () => _currentRunEngine ??
2464
- createAnthropicEngine({
2465
- // Sub-agents must inherit the parent run's resolved key so a
2466
- // BYO-key user can't bypass the free-tier check on the parent
2467
- // run and then have agent-teams spawn delegations bill the platform key.
2468
- apiKey: _currentRunUserApiKey ??
2469
- options?.apiKey ??
2470
- process.env.ANTHROPIC_API_KEY,
2471
- }),
2472
- getModel: () => _currentRunModel ?? resolvedModel,
2473
- getParentThreadId: () => _currentRunThreadId,
2568
+ getEngine: () => {
2569
+ const runCtx = getRequestRunContext();
2570
+ return (runCtx?.engine ??
2571
+ createAnthropicEngine({
2572
+ // Sub-agents must inherit the parent run's resolved key so a
2573
+ // BYO-key user can't bypass the free-tier check on the parent
2574
+ // run and then have agent-teams spawn delegations bill the platform key.
2575
+ apiKey: runCtx?.userApiKey ??
2576
+ options?.apiKey ??
2577
+ process.env.ANTHROPIC_API_KEY,
2578
+ }));
2579
+ },
2580
+ getModel: () => getRequestRunContext()?.model ?? resolvedModel,
2581
+ getParentThreadId: () => getRequestRunContext()?.threadId ?? "",
2474
2582
  getSend: () => {
2475
2583
  // Return the send for the current run's thread
2476
- const send = _runSendByThread.get(_currentRunThreadId);
2584
+ const threadId = getRequestRunContext()?.threadId ?? "";
2585
+ const send = _runSendByThread.get(threadId);
2477
2586
  return send ?? null;
2478
2587
  },
2479
2588
  });
@@ -2545,27 +2654,37 @@ export function createAgentChatPlugin(options) {
2545
2654
  // and tokens that minimal/voice apps don't need.
2546
2655
  const leanBasePrompt = (options?.systemPrompt ?? "") + prodActionsPrompt;
2547
2656
  // Per-request preamble shared by both prod and dev handlers. Resolves
2548
- // owner + user API key (stashed on the closure so downstream tools can
2549
- // reach them) and the template-authored `extraContext`. `extraContext`
2550
- // runs in every prompt variant (lean, lazy, full) — if a template
2551
- // defined it, they opted in; framework-provided content is what the
2552
- // token-saving modes strip.
2657
+ // owner + user API key onto the AsyncLocalStorage run context so
2658
+ // downstream tool closures (automation, fetch, team) read the
2659
+ // current request's identity without racing against concurrent
2660
+ // requests. `extraContext` runs in every prompt variant (lean, lazy,
2661
+ // full) if a template defined it, they opted in; framework-provided
2662
+ // content is what the token-saving modes strip.
2553
2663
  const prepareRun = async (event) => {
2554
- _currentRequestOrigin = getOrigin(event);
2555
2664
  const owner = await getOwnerFromEvent(event);
2556
- _currentRunOwner = owner;
2557
2665
  const { getOwnerActiveApiKey } = await import("../agent/production-agent.js");
2558
- _currentRunUserApiKey = await getOwnerActiveApiKey(owner);
2666
+ const userApiKey = await getOwnerActiveApiKey(owner);
2667
+ const runCtx = ensureRequestRunContext();
2668
+ if (runCtx) {
2669
+ runCtx.requestOrigin = getOrigin(event);
2670
+ runCtx.owner = owner;
2671
+ runCtx.userApiKey = userApiKey;
2672
+ }
2559
2673
  const extra = await resolveExtraContext(event, owner);
2560
2674
  return { owner, extra };
2561
2675
  };
2676
+ const setSystemPromptOnContext = (prompt) => {
2677
+ const runCtx = ensureRequestRunContext();
2678
+ if (runCtx)
2679
+ runCtx.systemPrompt = prompt;
2680
+ return prompt;
2681
+ };
2562
2682
  const prodHandler = createProductionAgentHandler({
2563
2683
  actions: leanPrompt ? leanActions : prodActions,
2564
2684
  systemPrompt: async (event) => {
2565
2685
  const { owner, extra } = await prepareRun(event);
2566
2686
  if (leanPrompt) {
2567
- _currentRunSystemPrompt = leanBasePrompt + extra;
2568
- return _currentRunSystemPrompt;
2687
+ return setSystemPromptOnContext(leanBasePrompt + extra);
2569
2688
  }
2570
2689
  const resources = await loadResourcesForPrompt(owner, lazyContext);
2571
2690
  // In lazy context mode, skip embedding the full schema — the agent
@@ -2573,20 +2692,23 @@ export function createAgentChatPlugin(options) {
2573
2692
  const schemaBlock = lazyContext
2574
2693
  ? ""
2575
2694
  : await buildSchemaBlock(owner, false);
2576
- _currentRunSystemPrompt =
2577
- basePrompt + resources + schemaBlock + extra;
2578
- return _currentRunSystemPrompt;
2695
+ return setSystemPromptOnContext(basePrompt + resources + schemaBlock + extra);
2579
2696
  },
2580
- model: options?.model ?? "claude-sonnet-4-6",
2697
+ model: options?.model ?? DEFAULT_MODEL,
2581
2698
  apiKey: options?.apiKey,
2582
2699
  skipFilesContext: leanPrompt,
2583
2700
  onEngineResolved: (engine, model) => {
2584
- _currentRunEngine = engine;
2585
- _currentRunModel = model;
2701
+ const runCtx = ensureRequestRunContext();
2702
+ if (runCtx) {
2703
+ runCtx.engine = engine;
2704
+ runCtx.model = model;
2705
+ }
2586
2706
  },
2587
2707
  onRunStart: (send, threadId) => {
2588
2708
  _runSendByThread.set(threadId, send);
2589
- _currentRunThreadId = threadId;
2709
+ const runCtx = ensureRequestRunContext();
2710
+ if (runCtx)
2711
+ runCtx.threadId = threadId;
2590
2712
  },
2591
2713
  onRunComplete: async (run, threadId) => {
2592
2714
  if (threadId)
@@ -2645,27 +2767,29 @@ export function createAgentChatPlugin(options) {
2645
2767
  systemPrompt: async (event) => {
2646
2768
  const { owner, extra } = await prepareRun(event);
2647
2769
  if (leanPrompt) {
2648
- _currentRunSystemPrompt = leanBasePrompt + extra;
2649
- return _currentRunSystemPrompt;
2770
+ return setSystemPromptOnContext(leanBasePrompt + extra);
2650
2771
  }
2651
2772
  const resources = await loadResourcesForPrompt(owner, lazyContext);
2652
2773
  const schemaBlock = lazyContext
2653
2774
  ? ""
2654
2775
  : await buildSchemaBlock(owner, true);
2655
- _currentRunSystemPrompt =
2656
- devPrompt + resources + schemaBlock + extra;
2657
- return _currentRunSystemPrompt;
2776
+ return setSystemPromptOnContext(devPrompt + resources + schemaBlock + extra);
2658
2777
  },
2659
2778
  model: options?.model,
2660
2779
  apiKey: options?.apiKey,
2661
2780
  skipFilesContext: leanPrompt,
2662
2781
  onEngineResolved: (engine, model) => {
2663
- _currentRunEngine = engine;
2664
- _currentRunModel = model;
2782
+ const runCtx = ensureRequestRunContext();
2783
+ if (runCtx) {
2784
+ runCtx.engine = engine;
2785
+ runCtx.model = model;
2786
+ }
2665
2787
  },
2666
2788
  onRunStart: (send, threadId) => {
2667
2789
  _runSendByThread.set(threadId, send);
2668
- _currentRunThreadId = threadId;
2790
+ const runCtx = ensureRequestRunContext();
2791
+ if (runCtx)
2792
+ runCtx.threadId = threadId;
2669
2793
  },
2670
2794
  onRunComplete: async (run, threadId) => {
2671
2795
  if (threadId)
@@ -2713,10 +2837,11 @@ export function createAgentChatPlugin(options) {
2713
2837
  return { devMode: currentDevMode, canToggle };
2714
2838
  }));
2715
2839
  // Mount save-key BEFORE the prefix handler so it isn't shadowed.
2716
- // Persists the user's key per-owner in the SQL settings table so it
2717
- // survives across serverless invocations (where mutating process.env
2718
- // and writing .env are both no-ops). Also updates process.env and
2719
- // .env when running locally for fast pickup by other handlers.
2840
+ // Persists the user's API key in `app_secrets` (encrypted, scope=user,
2841
+ // scopeId=email). Hard rule: never mutates process.env, never writes
2842
+ // .env. User-pasted secrets must not become deploy-level identity —
2843
+ // that's the cross-tenant leak class (KVesta Space, 2026-04).
2844
+ // Consumers read these values per-request via `resolveSecret(key)`.
2720
2845
  getH3App(nitroApp).use(`${routePath}/save-key`, defineEventHandler(async (event) => {
2721
2846
  if (getMethod(event) !== "POST") {
2722
2847
  setResponseStatus(event, 405);
@@ -2730,75 +2855,35 @@ export function createAgentChatPlugin(options) {
2730
2855
  return { error: "API key is required" };
2731
2856
  }
2732
2857
  const trimmedKey = key.trim();
2733
- // Persist per-owner so the key survives cold starts in serverless
2734
- // and so the user's key isn't shared across users on multi-tenant
2735
- // hosted deployments. We require a real authenticated owner here —
2736
- // `local@localhost` is the unauthenticated fallback and must never
2737
- // become the shared key bucket on hosted deployments.
2738
2858
  const ownerEmail = await getOwnerFromEvent(event);
2739
- if (isHostedProd &&
2740
- (!ownerEmail || ownerEmail === "local@localhost")) {
2859
+ if (!ownerEmail || ownerEmail === DEV_MODE_USER_EMAIL) {
2741
2860
  setResponseStatus(event, 401);
2742
2861
  return { error: "Authentication required" };
2743
2862
  }
2744
- if (ownerEmail && ownerEmail !== "local@localhost") {
2745
- try {
2746
- await putSetting(`user-api-key:${provider}:${ownerEmail}`, {
2747
- key: trimmedKey,
2748
- });
2749
- // Verify the write actually landed — some managed DB drivers
2750
- // swallow errors on degraded connections. Without this the
2751
- // client sees "saved", reloads, and the usage-limit card
2752
- // re-appears on the next message because the key isn't
2753
- // really persisted.
2754
- const check = await getSetting(`user-api-key:${provider}:${ownerEmail}`);
2755
- if (!check ||
2756
- typeof check.key !== "string" ||
2757
- check.key !== trimmedKey) {
2758
- throw new Error("settings write did not persist");
2759
- }
2760
- }
2761
- catch (err) {
2762
- if (isHostedProd) {
2763
- console.error("[agent-chat] save-key persistence failed:", err instanceof Error ? err.message : err);
2764
- setResponseStatus(event, 500);
2765
- return {
2766
- error: "Failed to persist API key. Please try again or contact support.",
2767
- };
2768
- }
2769
- // Local dev falls through to the env-file path below.
2770
- }
2771
- }
2772
- // In hosted/multi-tenant mode we deliberately do NOT touch
2773
- // process.env or .env: the per-owner SQL lookup above is the
2774
- // single source of truth, and overwriting the shared env key
2775
- // would leak one tenant's credentials into every subsequent
2776
- // request that hit the same warm instance without its own key.
2777
- if (!isHostedProd) {
2778
- const providerToEnv = {
2779
- anthropic: "ANTHROPIC_API_KEY",
2780
- openai: "OPENAI_API_KEY",
2781
- google: "GOOGLE_GENERATIVE_AI_API_KEY",
2782
- groq: "GROQ_API_KEY",
2783
- mistral: "MISTRAL_API_KEY",
2784
- cohere: "COHERE_API_KEY",
2863
+ const providerToEnv = {
2864
+ anthropic: "ANTHROPIC_API_KEY",
2865
+ openai: "OPENAI_API_KEY",
2866
+ google: "GOOGLE_GENERATIVE_AI_API_KEY",
2867
+ groq: "GROQ_API_KEY",
2868
+ mistral: "MISTRAL_API_KEY",
2869
+ cohere: "COHERE_API_KEY",
2870
+ };
2871
+ const secretKey = providerToEnv[provider] ?? `${provider.toUpperCase()}_API_KEY`;
2872
+ try {
2873
+ const { writeAppSecret } = await import("../secrets/storage.js");
2874
+ await writeAppSecret({
2875
+ key: secretKey,
2876
+ value: trimmedKey,
2877
+ scope: "user",
2878
+ scopeId: ownerEmail,
2879
+ });
2880
+ }
2881
+ catch (err) {
2882
+ console.error("[agent-chat] save-key persistence failed:", err instanceof Error ? err.message : err);
2883
+ setResponseStatus(event, 500);
2884
+ return {
2885
+ error: "Failed to persist API key. Please try again or contact support.",
2785
2886
  };
2786
- const envVar = providerToEnv[provider] ?? `${provider.toUpperCase()}_API_KEY`;
2787
- try {
2788
- const path = await import("path");
2789
- const { upsertEnvFile } = await import("./create-server.js");
2790
- const envPath = path.join(process.cwd(), ".env");
2791
- await upsertEnvFile(envPath, [
2792
- { key: envVar, value: trimmedKey },
2793
- ]);
2794
- }
2795
- catch {
2796
- // Edge runtime — can't write .env, but can still update process.env
2797
- }
2798
- // Update process.env so the agent works immediately in the
2799
- // current local-dev invocation; the SQL persist above covers
2800
- // future invocations.
2801
- process.env[envVar] = trimmedKey;
2802
2887
  }
2803
2888
  return { ok: true };
2804
2889
  }));
@@ -2836,7 +2921,7 @@ export function createAgentChatPlugin(options) {
2836
2921
  // Query resources
2837
2922
  try {
2838
2923
  const resources = currentDevMode
2839
- ? await resourceListAccessible("local@localhost")
2924
+ ? await resourceListAccessible(DEV_MODE_USER_EMAIL)
2840
2925
  : await resourceList(SHARED_OWNER);
2841
2926
  for (const r of resources) {
2842
2927
  if (!seen.has(r.path)) {
@@ -2921,7 +3006,7 @@ export function createAgentChatPlugin(options) {
2921
3006
  // Query resources with skills/ prefix
2922
3007
  try {
2923
3008
  const resourceSkills = currentDevMode
2924
- ? await resourceListAccessible("local@localhost", "skills/")
3009
+ ? await resourceListAccessible(DEV_MODE_USER_EMAIL, "skills/")
2925
3010
  : await resourceList(SHARED_OWNER, "skills/");
2926
3011
  for (const r of resourceSkills) {
2927
3012
  // Try to get content to parse frontmatter
@@ -2966,6 +3051,22 @@ export function createAgentChatPlugin(options) {
2966
3051
  setResponseStatus(event, 405);
2967
3052
  return { error: "Method not allowed" };
2968
3053
  }
3054
+ // Resolve the caller and run the entire stream inside a request
3055
+ // context so custom mention providers can use `accessFilter` /
3056
+ // `resolveAccess` when querying ownable tables. Without this,
3057
+ // a provider that searches `decks` (or any sharable resource)
3058
+ // would see every row regardless of ownership.
3059
+ const mentionsOwner = await getOwnerFromEvent(event).catch(() => undefined);
3060
+ let mentionsOrgId;
3061
+ if (options?.resolveOrgId) {
3062
+ try {
3063
+ const resolved = await options.resolveOrgId(event);
3064
+ mentionsOrgId = resolved ?? undefined;
3065
+ }
3066
+ catch {
3067
+ mentionsOrgId = undefined;
3068
+ }
3069
+ }
2969
3070
  const query = getQuery(event);
2970
3071
  const q = typeof query.q === "string" ? query.q.toLowerCase() : "";
2971
3072
  const matchesQuery = (item) => !q ||
@@ -2976,148 +3077,154 @@ export function createAgentChatPlugin(options) {
2976
3077
  setResponseHeader(event, "Content-Type", "application/x-ndjson");
2977
3078
  setResponseHeader(event, "Cache-Control", "no-cache");
2978
3079
  const stream = new ReadableStream({
2979
- async start(controller) {
2980
- const MAX_RESULTS = 50;
2981
- let totalSent = 0;
2982
- let cancelled = false;
2983
- const flush = (batch) => {
2984
- if (cancelled)
2985
- return;
2986
- const filtered = batch.filter(matchesQuery);
2987
- if (filtered.length === 0)
2988
- return;
2989
- const remaining = MAX_RESULTS - totalSent;
2990
- const toSend = filtered.slice(0, remaining);
2991
- if (toSend.length > 0) {
2992
- totalSent += toSend.length;
2993
- try {
2994
- controller.enqueue(enc.encode(JSON.stringify({ items: toSend }) + "\n"));
2995
- }
2996
- catch {
2997
- // Stream was closed by client
2998
- cancelled = true;
2999
- }
3000
- }
3001
- };
3002
- // All sources run in parallel; each flushes independently.
3003
- const sources = [];
3004
- // 1. Resources from SQL (fast — flush first)
3005
- sources.push((async () => {
3080
+ start(controller) {
3081
+ return runWithRequestContext({
3082
+ userEmail: mentionsOwner,
3083
+ orgId: mentionsOrgId,
3084
+ }, () => mentionsStreamWork(controller));
3085
+ },
3086
+ cancel() {
3087
+ // Client disconnected — stop enqueuing
3088
+ },
3089
+ });
3090
+ return stream;
3091
+ async function mentionsStreamWork(controller) {
3092
+ const MAX_RESULTS = 50;
3093
+ let totalSent = 0;
3094
+ let cancelled = false;
3095
+ const flush = (batch) => {
3096
+ if (cancelled)
3097
+ return;
3098
+ const filtered = batch.filter(matchesQuery);
3099
+ if (filtered.length === 0)
3100
+ return;
3101
+ const remaining = MAX_RESULTS - totalSent;
3102
+ const toSend = filtered.slice(0, remaining);
3103
+ if (toSend.length > 0) {
3104
+ totalSent += toSend.length;
3006
3105
  try {
3007
- const resources = currentDevMode
3008
- ? await resourceListAccessible("local@localhost")
3009
- : await resourceList(SHARED_OWNER);
3010
- flush(resources.map((r) => {
3011
- const isShared = r.owner === SHARED_OWNER;
3012
- return {
3013
- id: `resource:${r.path}`,
3014
- label: r.path.split("/").pop() || r.path,
3015
- description: r.path,
3016
- icon: "file",
3017
- source: isShared
3018
- ? "resource:shared"
3019
- : "resource:private",
3020
- refType: "file",
3021
- refPath: r.path,
3022
- section: "Files",
3023
- };
3024
- }));
3106
+ controller.enqueue(enc.encode(JSON.stringify({ items: toSend }) + "\n"));
3025
3107
  }
3026
- catch { }
3027
- })());
3028
- // 2. Codebase files (dev mode only — can be slow on large repos)
3029
- if (currentDevMode) {
3030
- sources.push((async () => {
3031
- const codebaseFiles = [];
3032
- try {
3033
- await collectFiles(process.cwd(), "", 0, codebaseFiles);
3034
- }
3035
- catch { }
3036
- flush(codebaseFiles.map((f) => ({
3037
- id: `codebase:${f.path}`,
3038
- label: f.name,
3039
- description: f.path !== f.name ? f.path : undefined,
3040
- icon: f.type,
3041
- source: "codebase",
3108
+ catch {
3109
+ // Stream was closed by client
3110
+ cancelled = true;
3111
+ }
3112
+ }
3113
+ };
3114
+ // All sources run in parallel; each flushes independently.
3115
+ const sources = [];
3116
+ // 1. Resources from SQL (fast — flush first)
3117
+ sources.push((async () => {
3118
+ try {
3119
+ const resources = currentDevMode
3120
+ ? await resourceListAccessible(DEV_MODE_USER_EMAIL)
3121
+ : await resourceList(SHARED_OWNER);
3122
+ flush(resources.map((r) => {
3123
+ const isShared = r.owner === SHARED_OWNER;
3124
+ return {
3125
+ id: `resource:${r.path}`,
3126
+ label: r.path.split("/").pop() || r.path,
3127
+ description: r.path,
3128
+ icon: "file",
3129
+ source: isShared
3130
+ ? "resource:shared"
3131
+ : "resource:private",
3042
3132
  refType: "file",
3043
- refPath: f.path,
3133
+ refPath: r.path,
3044
3134
  section: "Files",
3045
- })));
3046
- })());
3047
- }
3048
- // 3. Custom mention providers (each flushes independently)
3049
- for (const [key, provider] of Object.entries(mentionProviders)) {
3050
- sources.push((async () => {
3051
- try {
3052
- const providerItems = await provider.search(q, event);
3053
- flush(providerItems.map((item) => ({
3054
- id: item.id,
3055
- label: item.label,
3056
- description: item.description,
3057
- icon: item.icon || provider.icon || "file",
3058
- source: key,
3059
- refType: item.refType,
3060
- refPath: item.refPath,
3061
- refId: item.refId,
3062
- section: provider.label,
3063
- })));
3064
- }
3065
- catch (e) {
3066
- console.error(`[agent-native] Mention provider "${key}" failed:`, e);
3067
- }
3068
- })());
3135
+ };
3136
+ }));
3069
3137
  }
3070
- // 4. Custom workspace agents
3138
+ catch { }
3139
+ })());
3140
+ // 2. Codebase files (dev mode only — can be slow on large repos)
3141
+ if (currentDevMode) {
3071
3142
  sources.push((async () => {
3143
+ const codebaseFiles = [];
3072
3144
  try {
3073
- const owner = await getOwnerFromEvent(event);
3074
- const { listAccessibleCustomAgents } = await import("../resources/agents.js");
3075
- const agents = await listAccessibleCustomAgents(owner);
3076
- flush(agents.map((agent) => ({
3077
- id: `custom-agent:${agent.id}`,
3078
- label: agent.name,
3079
- description: agent.description || agent.path,
3080
- icon: "agent",
3081
- source: "agent:custom",
3082
- refType: "custom-agent",
3083
- refPath: agent.path,
3084
- refId: agent.id,
3085
- section: "Agents",
3086
- })));
3087
- }
3088
- catch (e) {
3089
- console.error("[agent-native] Custom agent discovery failed:", e);
3145
+ await collectFiles(process.cwd(), "", 0, codebaseFiles);
3090
3146
  }
3147
+ catch { }
3148
+ flush(codebaseFiles.map((f) => ({
3149
+ id: `codebase:${f.path}`,
3150
+ label: f.name,
3151
+ description: f.path !== f.name ? f.path : undefined,
3152
+ icon: f.type,
3153
+ source: "codebase",
3154
+ refType: "file",
3155
+ refPath: f.path,
3156
+ section: "Files",
3157
+ })));
3091
3158
  })());
3092
- // 5. Peer agent discovery (network call — often slowest)
3159
+ }
3160
+ // 3. Custom mention providers (each flushes independently)
3161
+ for (const [key, provider] of Object.entries(mentionProviders)) {
3093
3162
  sources.push((async () => {
3094
3163
  try {
3095
- const agents = await discoverAgents(options?.appId);
3096
- flush(agents.map((agent) => ({
3097
- id: `agent:${agent.id}`,
3098
- label: agent.name,
3099
- description: agent.description,
3100
- icon: "agent",
3101
- source: "agent",
3102
- refType: "agent",
3103
- refPath: agent.url,
3104
- refId: agent.id,
3105
- section: "Connected Agents",
3164
+ const providerItems = await provider.search(q, event);
3165
+ flush(providerItems.map((item) => ({
3166
+ id: item.id,
3167
+ label: item.label,
3168
+ description: item.description,
3169
+ icon: item.icon || provider.icon || "file",
3170
+ source: key,
3171
+ refType: item.refType,
3172
+ refPath: item.refPath,
3173
+ refId: item.refId,
3174
+ section: provider.label,
3106
3175
  })));
3107
3176
  }
3108
3177
  catch (e) {
3109
- console.error("[agent-native] Agent discovery failed:", e);
3178
+ console.error(`[agent-native] Mention provider "${key}" failed:`, e);
3110
3179
  }
3111
3180
  })());
3112
- await Promise.all(sources);
3113
- if (!cancelled)
3114
- controller.close();
3115
- },
3116
- cancel() {
3117
- // Client disconnected stop enqueuing
3118
- },
3119
- });
3120
- return stream;
3181
+ }
3182
+ // 4. Custom workspace agents
3183
+ sources.push((async () => {
3184
+ try {
3185
+ const owner = await getOwnerFromEvent(event);
3186
+ const { listAccessibleCustomAgents } = await import("../resources/agents.js");
3187
+ const agents = await listAccessibleCustomAgents(owner);
3188
+ flush(agents.map((agent) => ({
3189
+ id: `custom-agent:${agent.id}`,
3190
+ label: agent.name,
3191
+ description: agent.description || agent.path,
3192
+ icon: "agent",
3193
+ source: "agent:custom",
3194
+ refType: "custom-agent",
3195
+ refPath: agent.path,
3196
+ refId: agent.id,
3197
+ section: "Agents",
3198
+ })));
3199
+ }
3200
+ catch (e) {
3201
+ console.error("[agent-native] Custom agent discovery failed:", e);
3202
+ }
3203
+ })());
3204
+ // 5. Peer agent discovery (network call — often slowest)
3205
+ sources.push((async () => {
3206
+ try {
3207
+ const agents = await discoverAgents(options?.appId);
3208
+ flush(agents.map((agent) => ({
3209
+ id: `agent:${agent.id}`,
3210
+ label: agent.name,
3211
+ description: agent.description,
3212
+ icon: "agent",
3213
+ source: "agent",
3214
+ refType: "agent",
3215
+ refPath: agent.url,
3216
+ refId: agent.id,
3217
+ section: "Connected Agents",
3218
+ })));
3219
+ }
3220
+ catch (e) {
3221
+ console.error("[agent-native] Agent discovery failed:", e);
3222
+ }
3223
+ })());
3224
+ await Promise.all(sources);
3225
+ if (!cancelled)
3226
+ controller.close();
3227
+ }
3121
3228
  }));
3122
3229
  // ─── Generate thread title ──────────────────────────────────────────
3123
3230
  getH3App(nitroApp).use(`${routePath}/generate-title`, defineEventHandler(async (event) => {
@@ -3126,6 +3233,19 @@ export function createAgentChatPlugin(options) {
3126
3233
  return { error: "Method not allowed" };
3127
3234
  }
3128
3235
  const ownerEmail = await getOwnerFromEvent(event);
3236
+ // Per-user rate limit: 10 calls / 60s. Prevents an authenticated
3237
+ // user from spamming the endpoint to exhaust shared Anthropic
3238
+ // credits on platform-key deployments.
3239
+ const now = Date.now();
3240
+ const limitWindowMs = 60_000;
3241
+ const limitMax = 10;
3242
+ const recent = (generateTitleRateLimit.get(ownerEmail) ?? []).filter((t) => now - t < limitWindowMs);
3243
+ if (recent.length >= limitMax) {
3244
+ setResponseStatus(event, 429);
3245
+ return { error: "Rate limit exceeded" };
3246
+ }
3247
+ recent.push(now);
3248
+ generateTitleRateLimit.set(ownerEmail, recent);
3129
3249
  const body = await readBody(event);
3130
3250
  const message = body?.message;
3131
3251
  if (!message || typeof message !== "string") {
@@ -3498,14 +3618,6 @@ export function createAgentChatPlugin(options) {
3498
3618
  // Session not available
3499
3619
  }
3500
3620
  }
3501
- // Also set process.env for backwards compat (CLI scripts, legacy readers)
3502
- process.env.AGENT_USER_EMAIL = owner;
3503
- if (resolvedOrgId) {
3504
- process.env.AGENT_ORG_ID = resolvedOrgId;
3505
- }
3506
- else {
3507
- delete process.env.AGENT_ORG_ID;
3508
- }
3509
3621
  // Propagate the caller's IANA timezone from `x-user-timezone` so that
3510
3622
  // tool calls made by the agent (e.g. log-meal with no explicit date)
3511
3623
  // resolve "today" in the user's local timezone instead of server UTC.
@@ -3515,8 +3627,6 @@ export function createAgentChatPlugin(options) {
3515
3627
  tzRaw.trim().length < 64
3516
3628
  ? tzRaw.trim()
3517
3629
  : undefined;
3518
- if (timezone)
3519
- process.env.AGENT_USER_TIMEZONE = timezone;
3520
3630
  return runWithRequestContext({ userEmail: owner, orgId: resolvedOrgId, timezone }, () => {
3521
3631
  const handler = currentDevMode && devHandler ? devHandler : prodHandler;
3522
3632
  return handler(event);
@@ -3635,9 +3745,10 @@ export function getGlobalMcpManager() {
3635
3745
  return _globalMcpManager;
3636
3746
  }
3637
3747
  function mountMcpHubStatusRoute(nitroApp) {
3638
- if (globalThis.__agentNativeMcpHubStatusMounted)
3748
+ const mountedApps = (globalThis.__agentNativeMcpHubStatusMountedApps ??= new WeakSet());
3749
+ if (mountedApps.has(nitroApp))
3639
3750
  return;
3640
- globalThis.__agentNativeMcpHubStatusMounted = true;
3751
+ mountedApps.add(nitroApp);
3641
3752
  try {
3642
3753
  getH3App(nitroApp).use("/_agent-native/mcp/hub/status", defineEventHandler(async (event) => {
3643
3754
  if (getMethod(event) !== "GET") {
@@ -3653,10 +3764,11 @@ function mountMcpHubStatusRoute(nitroApp) {
3653
3764
  }
3654
3765
  }
3655
3766
  function mountMcpStatusRoute(nitroApp, manager) {
3656
- // Idempotent agent-chat-plugin can be invoked once per process; guard anyway.
3657
- if (globalThis.__agentNativeMcpStatusMounted)
3767
+ // Idempotent per Nitro app; dev-all may host multiple templates in one process.
3768
+ const mountedApps = (globalThis.__agentNativeMcpStatusMountedApps ??= new WeakSet());
3769
+ if (mountedApps.has(nitroApp))
3658
3770
  return;
3659
- globalThis.__agentNativeMcpStatusMounted = true;
3771
+ mountedApps.add(nitroApp);
3660
3772
  try {
3661
3773
  getH3App(nitroApp).use("/_agent-native/mcp/status", defineEventHandler(async (event) => {
3662
3774
  if (getMethod(event) !== "GET") {