@agent-native/core 0.7.12 → 0.7.13

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 (302) hide show
  1. package/README.md +1 -1
  2. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  3. package/dist/agent/engine/ai-sdk-engine.js +26 -8
  4. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  5. package/dist/agent/engine/builder-engine.d.ts +19 -0
  6. package/dist/agent/engine/builder-engine.d.ts.map +1 -0
  7. package/dist/agent/engine/builder-engine.js +430 -0
  8. package/dist/agent/engine/builder-engine.js.map +1 -0
  9. package/dist/agent/engine/builtin.d.ts.map +1 -1
  10. package/dist/agent/engine/builtin.js +26 -10
  11. package/dist/agent/engine/builtin.js.map +1 -1
  12. package/dist/agent/engine/index.d.ts +1 -1
  13. package/dist/agent/engine/index.d.ts.map +1 -1
  14. package/dist/agent/engine/index.js +1 -1
  15. package/dist/agent/engine/index.js.map +1 -1
  16. package/dist/agent/engine/registry.d.ts +20 -1
  17. package/dist/agent/engine/registry.d.ts.map +1 -1
  18. package/dist/agent/engine/registry.js +49 -1
  19. package/dist/agent/engine/registry.js.map +1 -1
  20. package/dist/agent/engine/types.d.ts +30 -0
  21. package/dist/agent/engine/types.d.ts.map +1 -1
  22. package/dist/agent/engine/types.js +19 -1
  23. package/dist/agent/engine/types.js.map +1 -1
  24. package/dist/agent/production-agent.d.ts.map +1 -1
  25. package/dist/agent/production-agent.js +65 -7
  26. package/dist/agent/production-agent.js.map +1 -1
  27. package/dist/agent/run-manager.d.ts.map +1 -1
  28. package/dist/agent/run-manager.js +11 -1
  29. package/dist/agent/run-manager.js.map +1 -1
  30. package/dist/agent/thread-data-builder.d.ts +4 -0
  31. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  32. package/dist/agent/thread-data-builder.js +1 -0
  33. package/dist/agent/thread-data-builder.js.map +1 -1
  34. package/dist/agent/types.d.ts +8 -0
  35. package/dist/agent/types.d.ts.map +1 -1
  36. package/dist/checkpoints/service.d.ts +1 -0
  37. package/dist/checkpoints/service.d.ts.map +1 -1
  38. package/dist/checkpoints/service.js +26 -2
  39. package/dist/checkpoints/service.js.map +1 -1
  40. package/dist/cli/create.d.ts +30 -0
  41. package/dist/cli/create.d.ts.map +1 -1
  42. package/dist/cli/create.js +25 -13
  43. package/dist/cli/create.js.map +1 -1
  44. package/dist/client/AgentPanel.js +1 -1
  45. package/dist/client/AgentPanel.js.map +1 -1
  46. package/dist/client/AssistantChat.d.ts.map +1 -1
  47. package/dist/client/AssistantChat.js +49 -10
  48. package/dist/client/AssistantChat.js.map +1 -1
  49. package/dist/client/ConnectBuilderCard.d.ts +1 -7
  50. package/dist/client/ConnectBuilderCard.d.ts.map +1 -1
  51. package/dist/client/ConnectBuilderCard.js +30 -132
  52. package/dist/client/ConnectBuilderCard.js.map +1 -1
  53. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  54. package/dist/client/MultiTabAssistantChat.js +30 -9
  55. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  56. package/dist/client/analytics.d.ts +5 -8
  57. package/dist/client/analytics.d.ts.map +1 -1
  58. package/dist/client/analytics.js +53 -11
  59. package/dist/client/analytics.js.map +1 -1
  60. package/dist/client/builder-mark.d.ts +9 -0
  61. package/dist/client/builder-mark.d.ts.map +1 -0
  62. package/dist/client/builder-mark.js +10 -0
  63. package/dist/client/builder-mark.js.map +1 -0
  64. package/dist/client/components/ui/popover.d.ts +8 -0
  65. package/dist/client/components/ui/popover.d.ts.map +1 -0
  66. package/dist/client/components/ui/popover.js +11 -0
  67. package/dist/client/components/ui/popover.js.map +1 -0
  68. package/dist/client/composer/ComposerPlusMenu.d.ts +2 -0
  69. package/dist/client/composer/ComposerPlusMenu.d.ts.map +1 -0
  70. package/dist/client/composer/ComposerPlusMenu.js +244 -0
  71. package/dist/client/composer/ComposerPlusMenu.js.map +1 -0
  72. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  73. package/dist/client/composer/TiptapComposer.js +9 -5
  74. package/dist/client/composer/TiptapComposer.js.map +1 -1
  75. package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
  76. package/dist/client/composer/useVoiceDictation.js +4 -2
  77. package/dist/client/composer/useVoiceDictation.js.map +1 -1
  78. package/dist/client/error-format.d.ts +2 -0
  79. package/dist/client/error-format.d.ts.map +1 -0
  80. package/dist/client/error-format.js +31 -0
  81. package/dist/client/error-format.js.map +1 -0
  82. package/dist/client/index.d.ts +3 -1
  83. package/dist/client/index.d.ts.map +1 -1
  84. package/dist/client/index.js +3 -1
  85. package/dist/client/index.js.map +1 -1
  86. package/dist/client/observability/ObservabilityDashboard.d.ts +5 -0
  87. package/dist/client/observability/ObservabilityDashboard.d.ts.map +1 -0
  88. package/dist/client/observability/ObservabilityDashboard.js +169 -0
  89. package/dist/client/observability/ObservabilityDashboard.js.map +1 -0
  90. package/dist/client/observability/ThumbsFeedback.d.ts +8 -0
  91. package/dist/client/observability/ThumbsFeedback.d.ts.map +1 -0
  92. package/dist/client/observability/ThumbsFeedback.js +64 -0
  93. package/dist/client/observability/ThumbsFeedback.js.map +1 -0
  94. package/dist/client/observability/index.d.ts +4 -0
  95. package/dist/client/observability/index.d.ts.map +1 -0
  96. package/dist/client/observability/index.js +4 -0
  97. package/dist/client/observability/index.js.map +1 -0
  98. package/dist/client/observability/useObservability.d.ts +128 -0
  99. package/dist/client/observability/useObservability.d.ts.map +1 -0
  100. package/dist/client/observability/useObservability.js +109 -0
  101. package/dist/client/observability/useObservability.js.map +1 -0
  102. package/dist/client/onboarding/OnboardingPanel.d.ts.map +1 -1
  103. package/dist/client/onboarding/OnboardingPanel.js +34 -92
  104. package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
  105. package/dist/client/org/RequireActiveOrg.d.ts +33 -0
  106. package/dist/client/org/RequireActiveOrg.d.ts.map +1 -0
  107. package/dist/client/org/RequireActiveOrg.js +63 -0
  108. package/dist/client/org/RequireActiveOrg.js.map +1 -0
  109. package/dist/client/org/hooks.d.ts.map +1 -1
  110. package/dist/client/org/hooks.js +50 -15
  111. package/dist/client/org/hooks.js.map +1 -1
  112. package/dist/client/org/index.d.ts +1 -0
  113. package/dist/client/org/index.d.ts.map +1 -1
  114. package/dist/client/org/index.js +1 -0
  115. package/dist/client/org/index.js.map +1 -1
  116. package/dist/client/resources/ResourcesPanel.js +3 -3
  117. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  118. package/dist/client/settings/AutomationsSection.js +1 -1
  119. package/dist/client/settings/AutomationsSection.js.map +1 -1
  120. package/dist/client/settings/BrowserSection.js +1 -1
  121. package/dist/client/settings/BrowserSection.js.map +1 -1
  122. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  123. package/dist/client/settings/SettingsPanel.js +112 -12
  124. package/dist/client/settings/SettingsPanel.js.map +1 -1
  125. package/dist/client/settings/VoiceTranscriptionSection.d.ts.map +1 -1
  126. package/dist/client/settings/VoiceTranscriptionSection.js +10 -4
  127. package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -1
  128. package/dist/client/settings/useBuilderStatus.d.ts +26 -0
  129. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  130. package/dist/client/settings/useBuilderStatus.js +128 -4
  131. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  132. package/dist/client/sse-event-processor.d.ts +2 -0
  133. package/dist/client/sse-event-processor.d.ts.map +1 -1
  134. package/dist/client/sse-event-processor.js +6 -2
  135. package/dist/client/sse-event-processor.js.map +1 -1
  136. package/dist/client/transcription/BuilderTranscriptionCta.d.ts +9 -0
  137. package/dist/client/transcription/BuilderTranscriptionCta.d.ts.map +1 -0
  138. package/dist/client/transcription/BuilderTranscriptionCta.js +18 -0
  139. package/dist/client/transcription/BuilderTranscriptionCta.js.map +1 -0
  140. package/dist/client/transcription/use-live-transcription.d.ts +29 -0
  141. package/dist/client/transcription/use-live-transcription.d.ts.map +1 -0
  142. package/dist/client/transcription/use-live-transcription.js +156 -0
  143. package/dist/client/transcription/use-live-transcription.js.map +1 -0
  144. package/dist/client/use-builder-enabled.d.ts +17 -0
  145. package/dist/client/use-builder-enabled.d.ts.map +1 -0
  146. package/dist/client/use-builder-enabled.js +36 -0
  147. package/dist/client/use-builder-enabled.js.map +1 -0
  148. package/dist/client/use-db-sync.d.ts.map +1 -1
  149. package/dist/client/use-db-sync.js +4 -2
  150. package/dist/client/use-db-sync.js.map +1 -1
  151. package/dist/client/useProductionAgent.d.ts.map +1 -1
  152. package/dist/client/useProductionAgent.js +3 -1
  153. package/dist/client/useProductionAgent.js.map +1 -1
  154. package/dist/db/migrations.d.ts +9 -0
  155. package/dist/db/migrations.d.ts.map +1 -1
  156. package/dist/db/migrations.js +75 -10
  157. package/dist/db/migrations.js.map +1 -1
  158. package/dist/file-upload/builder.d.ts.map +1 -1
  159. package/dist/file-upload/builder.js +11 -4
  160. package/dist/file-upload/builder.js.map +1 -1
  161. package/dist/jobs/tools.d.ts.map +1 -1
  162. package/dist/jobs/tools.js +137 -161
  163. package/dist/jobs/tools.js.map +1 -1
  164. package/dist/notifications/actions.d.ts +2 -2
  165. package/dist/notifications/actions.d.ts.map +1 -1
  166. package/dist/notifications/actions.js +77 -69
  167. package/dist/notifications/actions.js.map +1 -1
  168. package/dist/observability/evals.d.ts +22 -0
  169. package/dist/observability/evals.d.ts.map +1 -0
  170. package/dist/observability/evals.js +371 -0
  171. package/dist/observability/evals.js.map +1 -0
  172. package/dist/observability/experiments.d.ts +24 -0
  173. package/dist/observability/experiments.d.ts.map +1 -0
  174. package/dist/observability/experiments.js +274 -0
  175. package/dist/observability/experiments.js.map +1 -0
  176. package/dist/observability/feedback.d.ts +14 -0
  177. package/dist/observability/feedback.d.ts.map +1 -0
  178. package/dist/observability/feedback.js +256 -0
  179. package/dist/observability/feedback.js.map +1 -0
  180. package/dist/observability/index.d.ts +6 -0
  181. package/dist/observability/index.d.ts.map +1 -0
  182. package/dist/observability/index.js +5 -0
  183. package/dist/observability/index.js.map +1 -0
  184. package/dist/observability/plugin.d.ts +2 -0
  185. package/dist/observability/plugin.d.ts.map +1 -0
  186. package/dist/observability/plugin.js +12 -0
  187. package/dist/observability/plugin.js.map +1 -0
  188. package/dist/observability/routes.d.ts +68 -0
  189. package/dist/observability/routes.d.ts.map +1 -0
  190. package/dist/observability/routes.js +301 -0
  191. package/dist/observability/routes.js.map +1 -0
  192. package/dist/observability/store.d.ts +77 -0
  193. package/dist/observability/store.d.ts.map +1 -0
  194. package/dist/observability/store.js +976 -0
  195. package/dist/observability/store.js.map +1 -0
  196. package/dist/observability/traces.d.ts +37 -0
  197. package/dist/observability/traces.d.ts.map +1 -0
  198. package/dist/observability/traces.js +182 -0
  199. package/dist/observability/traces.js.map +1 -0
  200. package/dist/observability/types.d.ts +159 -0
  201. package/dist/observability/types.d.ts.map +1 -0
  202. package/dist/observability/types.js +16 -0
  203. package/dist/observability/types.js.map +1 -0
  204. package/dist/onboarding/default-steps.d.ts.map +1 -1
  205. package/dist/onboarding/default-steps.js +6 -5
  206. package/dist/onboarding/default-steps.js.map +1 -1
  207. package/dist/onboarding/types.d.ts +10 -1
  208. package/dist/onboarding/types.d.ts.map +1 -1
  209. package/dist/org/context.d.ts +8 -1
  210. package/dist/org/context.d.ts.map +1 -1
  211. package/dist/org/context.js +163 -6
  212. package/dist/org/context.js.map +1 -1
  213. package/dist/org/handlers.d.ts.map +1 -1
  214. package/dist/org/handlers.js +49 -30
  215. package/dist/org/handlers.js.map +1 -1
  216. package/dist/progress/actions.d.ts +3 -0
  217. package/dist/progress/actions.d.ts.map +1 -1
  218. package/dist/progress/actions.js +86 -110
  219. package/dist/progress/actions.js.map +1 -1
  220. package/dist/progress/routes.d.ts +1 -1
  221. package/dist/progress/routes.js +1 -1
  222. package/dist/scripts/agent-engines/list-agent-engines.js +1 -1
  223. package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -1
  224. package/dist/scripts/agent-engines/manage-agent-engine.d.ts +10 -0
  225. package/dist/scripts/agent-engines/manage-agent-engine.d.ts.map +1 -0
  226. package/dist/scripts/agent-engines/manage-agent-engine.js +47 -0
  227. package/dist/scripts/agent-engines/manage-agent-engine.js.map +1 -0
  228. package/dist/scripts/agent-engines/set-agent-engine.js +2 -2
  229. package/dist/scripts/agent-engines/set-agent-engine.js.map +1 -1
  230. package/dist/server/agent-chat-plugin.d.ts +39 -0
  231. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  232. package/dist/server/agent-chat-plugin.js +707 -443
  233. package/dist/server/agent-chat-plugin.js.map +1 -1
  234. package/dist/server/agent-teams.js +1 -1
  235. package/dist/server/agent-teams.js.map +1 -1
  236. package/dist/server/analytics.d.ts +5 -6
  237. package/dist/server/analytics.d.ts.map +1 -1
  238. package/dist/server/analytics.js +6 -14
  239. package/dist/server/analytics.js.map +1 -1
  240. package/dist/server/app-name.d.ts +5 -2
  241. package/dist/server/app-name.d.ts.map +1 -1
  242. package/dist/server/app-name.js +14 -3
  243. package/dist/server/app-name.js.map +1 -1
  244. package/dist/server/app-url.d.ts.map +1 -1
  245. package/dist/server/app-url.js +10 -1
  246. package/dist/server/app-url.js.map +1 -1
  247. package/dist/server/auth.d.ts +2 -0
  248. package/dist/server/auth.d.ts.map +1 -1
  249. package/dist/server/auth.js +153 -2
  250. package/dist/server/auth.js.map +1 -1
  251. package/dist/server/better-auth-instance.d.ts +2 -0
  252. package/dist/server/better-auth-instance.d.ts.map +1 -1
  253. package/dist/server/better-auth-instance.js +4 -0
  254. package/dist/server/better-auth-instance.js.map +1 -1
  255. package/dist/server/builder-browser.d.ts +59 -1
  256. package/dist/server/builder-browser.d.ts.map +1 -1
  257. package/dist/server/builder-browser.js +127 -11
  258. package/dist/server/builder-browser.js.map +1 -1
  259. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  260. package/dist/server/core-routes-plugin.js +208 -6
  261. package/dist/server/core-routes-plugin.js.map +1 -1
  262. package/dist/server/credential-provider.d.ts +7 -0
  263. package/dist/server/credential-provider.d.ts.map +1 -1
  264. package/dist/server/credential-provider.js +10 -0
  265. package/dist/server/credential-provider.js.map +1 -1
  266. package/dist/server/onboarding-html.d.ts.map +1 -1
  267. package/dist/server/onboarding-html.js +29 -4
  268. package/dist/server/onboarding-html.js.map +1 -1
  269. package/dist/server/poll.d.ts.map +1 -1
  270. package/dist/server/poll.js +46 -5
  271. package/dist/server/poll.js.map +1 -1
  272. package/dist/server/ssr-handler.d.ts.map +1 -1
  273. package/dist/server/ssr-handler.js +2 -1
  274. package/dist/server/ssr-handler.js.map +1 -1
  275. package/dist/server/transcribe-voice.d.ts.map +1 -1
  276. package/dist/server/transcribe-voice.js +44 -5
  277. package/dist/server/transcribe-voice.js.map +1 -1
  278. package/dist/styles/agent-native.css +11 -2
  279. package/dist/templates/default/.agents/skills/progress/SKILL.md +14 -12
  280. package/dist/templates/default/app/root.tsx +7 -0
  281. package/dist/transcription/builder-transcription.d.ts +27 -0
  282. package/dist/transcription/builder-transcription.d.ts.map +1 -0
  283. package/dist/transcription/builder-transcription.js +41 -0
  284. package/dist/transcription/builder-transcription.js.map +1 -0
  285. package/dist/triggers/actions.d.ts +3 -0
  286. package/dist/triggers/actions.d.ts.map +1 -1
  287. package/dist/triggers/actions.js +189 -213
  288. package/dist/triggers/actions.js.map +1 -1
  289. package/docs/content/agent-mentions.md +1 -1
  290. package/docs/content/automations.md +22 -19
  291. package/docs/content/cloneable-saas.md +2 -2
  292. package/docs/content/deployment.md +21 -61
  293. package/docs/content/getting-started.md +1 -1
  294. package/docs/content/key-concepts.md +1 -1
  295. package/docs/content/{enterprise-workspace.md → multi-app-workspace.md} +3 -3
  296. package/docs/content/multi-tenancy.md +1 -1
  297. package/docs/content/progress.md +11 -11
  298. package/docs/content/template-dispatch.md +3 -3
  299. package/docs/content/workspace-management.md +1 -1
  300. package/package.json +9 -2
  301. package/src/templates/default/.agents/skills/progress/SKILL.md +14 -12
  302. package/src/templates/default/app/root.tsx +7 -0
@@ -1,4 +1,14 @@
1
1
  import type { H3Event } from "h3";
2
+ export declare const BUILDER_CALLBACK_PATH = "/_agent-native/builder/callback";
3
+ /**
4
+ * Query-param name carrying the signed CSRF state on the connect→callback
5
+ * round-trip. Prefixed with `_an_` to avoid collisions if Builder ever
6
+ * adds standard OAuth `state` support to cli-auth. Builder preserves
7
+ * the path/query of `redirect_url` verbatim when redirecting back, so
8
+ * we embed `_an_state=…` inside the redirect_url query string at
9
+ * connect time and read it back on the callback.
10
+ */
11
+ export declare const BUILDER_STATE_PARAM = "_an_state";
2
12
  export interface BuilderBrowserStatus {
3
13
  configured: boolean;
4
14
  builderEnabled: boolean;
@@ -19,11 +29,59 @@ export interface BrowserConnectionArgs {
19
29
  proxyDefaultOrigin?: string;
20
30
  proxyDestination?: string;
21
31
  }
32
+ /**
33
+ * Mint a signed CSRF state token bound to the current session's email
34
+ * and a fresh nonce. Round-trips through Builder's cli-auth flow inside
35
+ * the redirect_url query string and is verified on the callback before
36
+ * any keys are written.
37
+ *
38
+ * Why bind to email: it's the only stable, universally-available
39
+ * identity field across all auth modes (Better Auth, BYOA, AUTH_MODE=local).
40
+ * Binding to the session token instead would put the cookie value in a
41
+ * URL that may end up in server logs / browser history.
42
+ */
43
+ export declare function signBuilderCallbackState(sessionEmail: string): string;
44
+ /**
45
+ * Verify a state token produced by `signBuilderCallbackState`. Returns
46
+ * false on any malformed, forged, expired, or cross-session token.
47
+ */
48
+ export declare function verifyBuilderCallbackState(token: string | null | undefined, sessionEmail: string): boolean;
22
49
  export declare function getBuilderAppHost(): string;
23
50
  export declare function getBuilderApiHost(): string;
51
+ /**
52
+ * Build the Builder cli-auth URL for the connect popup. When a signed
53
+ * `state` token is supplied it is embedded inside the `redirect_url`
54
+ * query string so it survives Builder's redirect verbatim — Builder
55
+ * preserves the redirect_url's existing query when appending p-key /
56
+ * api-key / etc., so we don't depend on Builder echoing a top-level
57
+ * `state` parameter (it doesn't).
58
+ *
59
+ * The user-facing connect entry point is `/_agent-native/builder/connect`
60
+ * (a server-side 302). Status / chat-card responses surface that path
61
+ * rather than the cli-auth URL directly, so the 302 handler can mint a
62
+ * fresh state bound to the current session on every click.
63
+ */
64
+ export declare function buildBuilderCliAuthUrl(origin: string, state?: string | null): string;
65
+ /**
66
+ * The URL surfaced to clients (chat card, settings panels, status
67
+ * endpoint) as `connectUrl`. Pointing every entry point at our local 302
68
+ * means the cli-auth URL — and the CSRF state token bound to the current
69
+ * session — are minted server-side at click time, instead of being baked
70
+ * into a status response that may be cached or rendered for a different
71
+ * session.
72
+ */
24
73
  export declare function getBuilderBrowserConnectUrl(origin: string): string;
25
74
  export declare function getBuilderBrowserStatus(origin: string): BuilderBrowserStatus;
26
75
  export declare function getBuilderBrowserStatusForEvent(event: H3Event): BuilderBrowserStatus;
76
+ /**
77
+ * Env vars written by the Builder CLI-auth callback. Single source of truth
78
+ * for the connect/disconnect key set — `getBuilderCallbackEnvVars` and the
79
+ * disconnect handler's scrub loop both derive from this list, so drift
80
+ * (e.g. disconnect silently leaving `BUILDER_USER_ID` behind because
81
+ * someone added a key to one site but not the other) is impossible.
82
+ */
83
+ export declare const BUILDER_ENV_KEYS: readonly ["BUILDER_PRIVATE_KEY", "BUILDER_PUBLIC_KEY", "BUILDER_USER_ID", "BUILDER_ORG_NAME", "BUILDER_ORG_KIND"];
84
+ export type BuilderEnvKey = (typeof BUILDER_ENV_KEYS)[number];
27
85
  export declare function getBuilderCallbackEnvVars(params: {
28
86
  privateKey?: string | null;
29
87
  publicKey?: string | null;
@@ -31,7 +89,7 @@ export declare function getBuilderCallbackEnvVars(params: {
31
89
  orgName?: string | null;
32
90
  orgKind?: string | null;
33
91
  }): {
34
- key: string;
92
+ key: "BUILDER_PRIVATE_KEY" | "BUILDER_ORG_NAME" | "BUILDER_PUBLIC_KEY" | "BUILDER_USER_ID" | "BUILDER_ORG_KIND";
35
93
  value: string;
36
94
  }[];
37
95
  export declare function resolveSafePreviewUrl(previewUrl: string | null | undefined, event: H3Event): string;
@@ -1 +1 @@
1
- {"version":3,"file":"builder-browser.d.ts","sourceRoot":"","sources":["../../src/server/builder-browser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAQlC,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAwBD,wBAAgB,iBAAiB,IAAI,MAAM,CAM1C;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAO1C;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAWlE;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,oBAAoB,CAe5E;AAED,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,OAAO,GACb,oBAAoB,CAEtB;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE;IAChD,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;;;IAQA;AAED,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACrC,KAAK,EAAE,OAAO,GACb,MAAM,CAKR;AAED,wBAAgB,gCAAgC,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAwD3E;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,qBAAqB,CAAC,CAmDhC;AAED,wBAAsB,+BAA+B,CACnD,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CA+ClC"}
1
+ {"version":3,"file":"builder-browser.d.ts","sourceRoot":"","sources":["../../src/server/builder-browser.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,80 @@
1
+ import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
2
+ import { getAuthSecret } from "./better-auth-instance.js";
1
3
  import { getOrigin } from "./google-oauth.js";
2
4
  const DEFAULT_BUILDER_APP_HOST = "https://builder.io";
3
5
  const DEFAULT_BUILDER_API_HOST = "https://api.builder.io";
4
6
  const BUILDER_BROWSER_HOST = "agent-native-browser";
5
7
  const BUILDER_BROWSER_CLIENT_ID = "Agent Native Browser";
8
+ export const BUILDER_CALLBACK_PATH = "/_agent-native/builder/callback";
9
+ /**
10
+ * Query-param name carrying the signed CSRF state on the connect→callback
11
+ * round-trip. Prefixed with `_an_` to avoid collisions if Builder ever
12
+ * adds standard OAuth `state` support to cli-auth. Builder preserves
13
+ * the path/query of `redirect_url` verbatim when redirecting back, so
14
+ * we embed `_an_state=…` inside the redirect_url query string at
15
+ * connect time and read it back on the callback.
16
+ */
17
+ export const BUILDER_STATE_PARAM = "_an_state";
18
+ const BUILDER_STATE_TTL_MS = 10 * 60 * 1000;
19
+ function macForParts(nonce, emailEncoded, ts) {
20
+ return createHmac("sha256", `builder-csrf:${getAuthSecret()}`)
21
+ .update(`${nonce}.${emailEncoded}.${ts}`)
22
+ .digest("base64url");
23
+ }
24
+ /**
25
+ * Mint a signed CSRF state token bound to the current session's email
26
+ * and a fresh nonce. Round-trips through Builder's cli-auth flow inside
27
+ * the redirect_url query string and is verified on the callback before
28
+ * any keys are written.
29
+ *
30
+ * Why bind to email: it's the only stable, universally-available
31
+ * identity field across all auth modes (Better Auth, BYOA, AUTH_MODE=local).
32
+ * Binding to the session token instead would put the cookie value in a
33
+ * URL that may end up in server logs / browser history.
34
+ */
35
+ export function signBuilderCallbackState(sessionEmail) {
36
+ const nonce = randomBytes(16).toString("base64url");
37
+ const ts = Date.now();
38
+ const emailEncoded = Buffer.from(sessionEmail, "utf8").toString("base64url");
39
+ const mac = macForParts(nonce, emailEncoded, ts);
40
+ return `${nonce}.${emailEncoded}.${ts}.${mac}`;
41
+ }
42
+ /**
43
+ * Verify a state token produced by `signBuilderCallbackState`. Returns
44
+ * false on any malformed, forged, expired, or cross-session token.
45
+ */
46
+ export function verifyBuilderCallbackState(token, sessionEmail) {
47
+ if (typeof token !== "string" || token.length === 0)
48
+ return false;
49
+ const parts = token.split(".");
50
+ if (parts.length !== 4)
51
+ return false;
52
+ const [nonce, emailEncoded, tsStr, mac] = parts;
53
+ if (!nonce || !emailEncoded || !tsStr || !mac)
54
+ return false;
55
+ let boundEmail;
56
+ try {
57
+ boundEmail = Buffer.from(emailEncoded, "base64url").toString("utf8");
58
+ }
59
+ catch {
60
+ return false;
61
+ }
62
+ if (boundEmail !== sessionEmail)
63
+ return false;
64
+ const ts = Number(tsStr);
65
+ if (!Number.isFinite(ts))
66
+ return false;
67
+ // Reject expired AND far-future timestamps — a clock-skew attacker
68
+ // (or a bug that mints states with `ts` in the future) shouldn't get
69
+ // an arbitrarily-long-lived token.
70
+ if (Math.abs(Date.now() - ts) > BUILDER_STATE_TTL_MS)
71
+ return false;
72
+ const expected = Buffer.from(macForParts(nonce, emailEncoded, ts));
73
+ const candidate = Buffer.from(mac);
74
+ if (expected.length !== candidate.length)
75
+ return false;
76
+ return timingSafeEqual(expected, candidate);
77
+ }
6
78
  function isAllowedBrowserReturnUrl(urlString) {
7
79
  try {
8
80
  const parsed = new URL(urlString);
@@ -12,7 +84,9 @@ function isAllowedBrowserReturnUrl(urlString) {
12
84
  hostname === "127.0.0.1" ||
13
85
  hostname === "[::1]";
14
86
  const isBuilderDomain = hostname === "builder.io" || hostname.endsWith(".builder.io");
15
- return isAllowedProtocol && (isLocalhost || isBuilderDomain);
87
+ const isAgentNativeDomain = hostname === "agent-native.com" || hostname.endsWith(".agent-native.com");
88
+ return (isAllowedProtocol &&
89
+ (isLocalhost || isBuilderDomain || isAgentNativeDomain));
16
90
  }
17
91
  catch {
18
92
  return false;
@@ -32,18 +106,45 @@ export function getBuilderApiHost() {
32
106
  process.env.BUILDER_API_HOST ||
33
107
  DEFAULT_BUILDER_API_HOST);
34
108
  }
35
- export function getBuilderBrowserConnectUrl(origin) {
109
+ /**
110
+ * Build the Builder cli-auth URL for the connect popup. When a signed
111
+ * `state` token is supplied it is embedded inside the `redirect_url`
112
+ * query string so it survives Builder's redirect verbatim — Builder
113
+ * preserves the redirect_url's existing query when appending p-key /
114
+ * api-key / etc., so we don't depend on Builder echoing a top-level
115
+ * `state` parameter (it doesn't).
116
+ *
117
+ * The user-facing connect entry point is `/_agent-native/builder/connect`
118
+ * (a server-side 302). Status / chat-card responses surface that path
119
+ * rather than the cli-auth URL directly, so the 302 handler can mint a
120
+ * fresh state bound to the current session on every click.
121
+ */
122
+ export function buildBuilderCliAuthUrl(origin, state = null) {
36
123
  const normalizedOrigin = normalizeOrigin(origin);
37
- const callbackUrl = `${normalizedOrigin}/_agent-native/builder/callback`;
124
+ const callbackUrl = new URL(BUILDER_CALLBACK_PATH, normalizedOrigin);
125
+ if (state) {
126
+ callbackUrl.searchParams.set(BUILDER_STATE_PARAM, state);
127
+ }
38
128
  const url = new URL("/cli-auth", getBuilderAppHost());
39
129
  url.searchParams.set("response_type", "code");
40
130
  url.searchParams.set("host", BUILDER_BROWSER_HOST);
41
131
  url.searchParams.set("client_id", BUILDER_BROWSER_CLIENT_ID);
42
- url.searchParams.set("redirect_url", callbackUrl);
132
+ url.searchParams.set("redirect_url", callbackUrl.toString());
43
133
  url.searchParams.set("preview_url", normalizedOrigin);
44
134
  url.searchParams.set("framework", "agent-native");
45
135
  return url.toString();
46
136
  }
137
+ /**
138
+ * The URL surfaced to clients (chat card, settings panels, status
139
+ * endpoint) as `connectUrl`. Pointing every entry point at our local 302
140
+ * means the cli-auth URL — and the CSRF state token bound to the current
141
+ * session — are minted server-side at click time, instead of being baked
142
+ * into a status response that may be cached or rendered for a different
143
+ * session.
144
+ */
145
+ export function getBuilderBrowserConnectUrl(origin) {
146
+ return `${normalizeOrigin(origin)}/_agent-native/builder/connect`;
147
+ }
47
148
  export function getBuilderBrowserStatus(origin) {
48
149
  return {
49
150
  configured: !!(process.env.BUILDER_PRIVATE_KEY && process.env.BUILDER_PUBLIC_KEY),
@@ -61,14 +162,29 @@ export function getBuilderBrowserStatus(origin) {
61
162
  export function getBuilderBrowserStatusForEvent(event) {
62
163
  return getBuilderBrowserStatus(getOrigin(event));
63
164
  }
165
+ /**
166
+ * Env vars written by the Builder CLI-auth callback. Single source of truth
167
+ * for the connect/disconnect key set — `getBuilderCallbackEnvVars` and the
168
+ * disconnect handler's scrub loop both derive from this list, so drift
169
+ * (e.g. disconnect silently leaving `BUILDER_USER_ID` behind because
170
+ * someone added a key to one site but not the other) is impossible.
171
+ */
172
+ export const BUILDER_ENV_KEYS = [
173
+ "BUILDER_PRIVATE_KEY",
174
+ "BUILDER_PUBLIC_KEY",
175
+ "BUILDER_USER_ID",
176
+ "BUILDER_ORG_NAME",
177
+ "BUILDER_ORG_KIND",
178
+ ];
64
179
  export function getBuilderCallbackEnvVars(params) {
65
- return [
66
- { key: "BUILDER_PRIVATE_KEY", value: params.privateKey?.trim() || "" },
67
- { key: "BUILDER_PUBLIC_KEY", value: params.publicKey?.trim() || "" },
68
- { key: "BUILDER_USER_ID", value: params.userId?.trim() || "" },
69
- { key: "BUILDER_ORG_NAME", value: params.orgName?.trim() || "" },
70
- { key: "BUILDER_ORG_KIND", value: params.orgKind?.trim() || "" },
71
- ];
180
+ const values = {
181
+ BUILDER_PRIVATE_KEY: params.privateKey?.trim() || "",
182
+ BUILDER_PUBLIC_KEY: params.publicKey?.trim() || "",
183
+ BUILDER_USER_ID: params.userId?.trim() || "",
184
+ BUILDER_ORG_NAME: params.orgName?.trim() || "",
185
+ BUILDER_ORG_KIND: params.orgKind?.trim() || "",
186
+ };
187
+ return BUILDER_ENV_KEYS.map((key) => ({ key, value: values[key] }));
72
188
  }
73
189
  export function resolveSafePreviewUrl(previewUrl, event) {
74
190
  if (previewUrl && isAllowedBrowserReturnUrl(previewUrl)) {
@@ -1 +1 @@
1
- {"version":3,"file":"builder-browser.js","sourceRoot":"","sources":["../../src/server/builder-browser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"builder-browser.js","sourceRoot":"","sources":["../../src/server/builder-browser.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"core-routes-plugin.d.ts","sourceRoot":"","sources":["../../src/server/core-routes-plugin.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAkDvD;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,mBAAmB,CAAC;AAEvD,KAAK,cAAc,GAAG,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE9D,MAAM,WAAW,uBAAuB;IACtC,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oDAAoD;IACpD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2DAA2D;IAC3D,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qEAAqE;IACrE,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,GAAE,uBAA4B,GACpC,cAAc,CAkyBhB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,EAAE,cAAyC,CAAC"}
1
+ {"version":3,"file":"core-routes-plugin.d.ts","sourceRoot":"","sources":["../../src/server/core-routes-plugin.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAuDvD;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,mBAAmB,CAAC;AAEvD,KAAK,cAAc,GAAG,CAAC,QAAQ,EAAE,GAAG,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE9D,MAAM,WAAW,uBAAuB;IACtC,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oDAAoD;IACpD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2DAA2D;IAC3D,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qEAAqE;IACrE,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,GAAE,uBAA4B,GACpC,cAAc,CA4gChB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,EAAE,cAAyC,CAAC"}
@@ -5,7 +5,7 @@ import { createPollHandler } from "./poll.js";
5
5
  import { createSSEHandler } from "./sse.js";
6
6
  import { upsertEnvFile } from "./create-server.js";
7
7
  import { readBody } from "./h3-helpers.js";
8
- import { createBuilderBrowserCallbackPage, getBuilderBrowserStatusForEvent, getBuilderCallbackEnvVars, resolveSafePreviewUrl, runBuilderAgent, } from "./builder-browser.js";
8
+ import { BUILDER_ENV_KEYS, BUILDER_STATE_PARAM, buildBuilderCliAuthUrl, createBuilderBrowserCallbackPage, getBuilderBrowserStatusForEvent, getBuilderCallbackEnvVars, resolveSafePreviewUrl, runBuilderAgent, signBuilderCallbackState, verifyBuilderCallbackState, } from "./builder-browser.js";
9
9
  import { getState, putState, deleteState, listComposeDrafts, getComposeDraft, putComposeDraft, deleteComposeDraft, deleteAllComposeDrafts, } from "../application-state/handlers.js";
10
10
  import { getSetting, putSetting, deleteSetting } from "../settings/store.js";
11
11
  import { getSession } from "./auth.js";
@@ -55,12 +55,57 @@ export function createCoreRoutesPlugin(options = {}) {
55
55
  // No-op when called from inside the bootstrap (auto-mount path).
56
56
  // Otherwise wait so other default plugins finish mounting first.
57
57
  await awaitBootstrap(nitroApp);
58
+ // Restore env vars from the settings table. On serverless, .env
59
+ // writes don't persist across invocations — the DB is the durable
60
+ // store. Only set keys that are currently empty so explicit env
61
+ // vars (Netlify dashboard, process-level) always win.
62
+ try {
63
+ const persisted = (await getSetting("persisted-env-vars"));
64
+ if (persisted) {
65
+ for (const [k, v] of Object.entries(persisted)) {
66
+ if (typeof v === "string" && !process.env[k]) {
67
+ process.env[k] = v;
68
+ }
69
+ }
70
+ }
71
+ }
72
+ catch {
73
+ // DB not ready yet — skip
74
+ }
75
+ // Honor Builder disconnect. Nitro's dev env-runner preserves
76
+ // `process.env` across `.env` file reloads inside the same worker, so
77
+ // deleting BUILDER_PRIVATE_KEY in the disconnect handler can bleed
78
+ // back through an env-runner restart. We persist a
79
+ // `builder-disconnected` flag in SQL and scrub BUILDER_* on every
80
+ // plugin init while the flag is set. The flag is cleared by the
81
+ // Builder cli-auth callback when the user re-connects.
82
+ try {
83
+ const disconnected = (await getSetting("builder-disconnected"));
84
+ if (disconnected) {
85
+ for (const key of BUILDER_ENV_KEYS) {
86
+ delete process.env[key];
87
+ }
88
+ }
89
+ }
90
+ catch {
91
+ // DB not ready — skip; the disconnect flag will be enforced on the
92
+ // next plugin boot once the settings table is reachable.
93
+ }
58
94
  // Register framework-level secrets (OPENAI_API_KEY for composer voice
59
95
  // transcription, etc.). Each registration is guarded so templates that
60
96
  // already registered the same key win.
61
97
  registerFrameworkSecrets();
62
98
  registerBuiltinProviders();
63
99
  registerBuiltinNotificationChannels();
100
+ try {
101
+ const { createObservabilityHandler } = await import("../observability/routes.js");
102
+ const { ensureObservabilityTables } = await import("../observability/store.js");
103
+ ensureObservabilityTables().catch(() => { });
104
+ getH3App(nitroApp).use(`${FRAMEWORK_ROUTE_PREFIX}/observability`, createObservabilityHandler());
105
+ }
106
+ catch {
107
+ // Observability module not available — skip
108
+ }
64
109
  const P = FRAMEWORK_ROUTE_PREFIX;
65
110
  // CORS for framework routes. Desktop tray apps (Tauri/Electron) run on
66
111
  // their own dev origin (e.g. localhost:1420) and make credentialed
@@ -110,15 +155,46 @@ export function createCoreRoutesPlugin(options = {}) {
110
155
  message: process.env.PING_MESSAGE ?? "pong",
111
156
  })));
112
157
  }
113
- getH3App(nitroApp).use(`${P}/builder/status`, defineEventHandler((event) => getBuilderBrowserStatusForEvent(event)));
158
+ getH3App(nitroApp).use(`${P}/builder/status`, defineEventHandler(async (event) => {
159
+ const status = getBuilderBrowserStatusForEvent(event);
160
+ // Honor the SQL disconnect flag even when process.env still has
161
+ // BUILDER_* (dev env-runner weirdness — see plugin init above).
162
+ try {
163
+ const disconnected = await getSetting("builder-disconnected");
164
+ if (disconnected) {
165
+ return {
166
+ ...status,
167
+ configured: false,
168
+ privateKeyConfigured: false,
169
+ publicKeyConfigured: false,
170
+ userId: undefined,
171
+ orgName: undefined,
172
+ orgKind: undefined,
173
+ };
174
+ }
175
+ }
176
+ catch {
177
+ // DB not reachable — fall back to env-only status.
178
+ }
179
+ return status;
180
+ }));
114
181
  // Lightweight 302 to the Builder CLI-auth URL. Lets clients do
115
182
  // `window.open('/_agent-native/builder/connect', '_blank')` synchronously
116
183
  // inside a click handler, avoiding the popup-blocker downgrade that
117
- // happens when an await sits before window.open.
118
- getH3App(nitroApp).use(`${P}/builder/connect`, defineEventHandler((event) => {
119
- const status = getBuilderBrowserStatusForEvent(event);
184
+ // happens when an await sits before window.open. We mint a signed
185
+ // CSRF state here and embed it in the callback URL we hand to
186
+ // Builder; the callback handler verifies it before accepting any
187
+ // keys. See `signBuilderCallbackState` for the threat model.
188
+ getH3App(nitroApp).use(`${P}/builder/connect`, defineEventHandler(async (event) => {
189
+ const session = await getSession(event).catch(() => null);
190
+ if (!session?.email) {
191
+ setResponseStatus(event, 401);
192
+ return { error: "Authentication required" };
193
+ }
194
+ const state = signBuilderCallbackState(session.email);
195
+ const cliAuthUrl = buildBuilderCliAuthUrl(getOrigin(event), state);
120
196
  setResponseStatus(event, 302);
121
- setResponseHeader(event, "Location", status.connectUrl);
197
+ setResponseHeader(event, "Location", cliAuthUrl);
122
198
  return "";
123
199
  }));
124
200
  // Hardcoded for the early preview — later this will come from workspace/org
@@ -182,7 +258,22 @@ export function createCoreRoutesPlugin(options = {}) {
182
258
  setResponseStatus(event, 405);
183
259
  return { error: "Method not allowed" };
184
260
  }
261
+ // Session blocks anonymous callers; the signed state below blocks
262
+ // CSRF (session cookies are SameSite=None;Secure for the iframe
263
+ // editor, so they ride along on attacker-crafted top-level links).
264
+ const session = await getSession(event).catch(() => null);
265
+ if (!session?.email) {
266
+ setResponseStatus(event, 401);
267
+ return { error: "Authentication required" };
268
+ }
185
269
  const requestUrl = new URL(`${event.url?.pathname || "/"}${event.url?.search || ""}`, getOrigin(event));
270
+ const state = requestUrl.searchParams.get(BUILDER_STATE_PARAM);
271
+ if (!verifyBuilderCallbackState(state, session.email)) {
272
+ setResponseStatus(event, 403);
273
+ return {
274
+ error: "Invalid or expired connect token. Restart the Builder connect flow from Settings.",
275
+ };
276
+ }
186
277
  const privateKey = requestUrl.searchParams.get("p-key");
187
278
  const publicKey = requestUrl.searchParams.get("api-key");
188
279
  if (!privateKey || !publicKey) {
@@ -196,6 +287,16 @@ export function createCoreRoutesPlugin(options = {}) {
196
287
  orgName: requestUrl.searchParams.get("org-name"),
197
288
  orgKind: requestUrl.searchParams.get("kind"),
198
289
  });
290
+ // Clear the disconnect flag first — a prior disconnect would
291
+ // otherwise cause the plugin init to scrub these keys right back
292
+ // out on the next env-runner reload.
293
+ try {
294
+ await deleteSetting("builder-disconnected");
295
+ }
296
+ catch {
297
+ // DB not ready — proceed; the worst case is a stale disconnect
298
+ // flag that gets cleared on the next reconnect attempt.
299
+ }
199
300
  // Prefer the workspace root .env when in an enterprise workspace so
200
301
  // Builder credentials are shared across every app automatically.
201
302
  try {
@@ -211,10 +312,96 @@ export function createCoreRoutesPlugin(options = {}) {
211
312
  for (const { key, value } of vars) {
212
313
  process.env[key] = value;
213
314
  }
315
+ // Persist to settings table so serverless cold starts can
316
+ // restore credentials (.env writes don't survive on Netlify).
317
+ try {
318
+ const envMap = {};
319
+ for (const { key, value } of vars)
320
+ envMap[key] = value;
321
+ const existing = (await getSetting("persisted-env-vars")) ?? {};
322
+ await putSetting("persisted-env-vars", { ...existing, ...envMap });
323
+ }
324
+ catch {
325
+ // DB not ready yet — skip
326
+ }
214
327
  const previewUrl = resolveSafePreviewUrl(requestUrl.searchParams.get("preview-url"), event);
215
328
  setResponseHeader(event, "Content-Type", "text/html; charset=utf-8");
216
329
  return createBuilderBrowserCallbackPage(previewUrl);
217
330
  }));
331
+ // POST /_agent-native/builder/disconnect — revoke the stored Builder
332
+ // credentials so the next turn falls back to BYO / env detection. Mirrors
333
+ // the callback handler's three write locations: the template `.env` file,
334
+ // the in-process `process.env`, and the `persisted-env-vars` settings row
335
+ // (rehydrated on serverless cold starts). All three must be cleared to
336
+ // avoid a "still connected after disconnect" state on restart.
337
+ getH3App(nitroApp).use(`${P}/builder/disconnect`, defineEventHandler(async (event) => {
338
+ if (getMethod(event) !== "POST") {
339
+ setResponseStatus(event, 405);
340
+ return { error: "Method not allowed" };
341
+ }
342
+ const session = await getSession(event).catch(() => null);
343
+ if (!session?.email) {
344
+ setResponseStatus(event, 401);
345
+ return { error: "unauthorized" };
346
+ }
347
+ // We intentionally do NOT rewrite the `.env` file on disconnect.
348
+ // A `.env` write triggers nitro's file watcher → env-runner
349
+ // restart, which tears down in-flight SSE / HMR connections and
350
+ // surfaces as `read ECONNRESET` in the vite overlay. The
351
+ // authoritative disconnect signal is the SQL `builder-disconnected`
352
+ // flag (checked in plugin init, the status endpoint, and the
353
+ // Builder engine before any gateway call). `.env` keys, if any
354
+ // survive, are neutered by the flag-driven scrub in plugin init.
355
+ // 1. Write the disconnect flag. This is load-bearing — every
356
+ // subsequent check (plugin init scrub, /builder/status override,
357
+ // BuilderEngine.stream short-circuit) reads this flag. If the
358
+ // write fails, we FAIL HARD: clearing process.env without
359
+ // persisting the flag means the next env-runner reload would
360
+ // silently restore BUILDER_* from whatever inherited env the
361
+ // worker was spawned with, and the user would see "Disconnected"
362
+ // in the UI that flips back to "Connected" moments later.
363
+ try {
364
+ await putSetting("builder-disconnected", { at: Date.now() });
365
+ }
366
+ catch (err) {
367
+ setResponseStatus(event, 500);
368
+ return {
369
+ ok: false,
370
+ error: "Could not persist disconnect flag — your Builder connection is unchanged. Please retry.",
371
+ cause: err instanceof Error ? err.message : String(err),
372
+ };
373
+ }
374
+ // 2. Scrub the persisted-env-vars row so serverless cold starts
375
+ // don't rehydrate BUILDER_* from SQL. Best-effort: the disconnect
376
+ // flag above already prevents Builder from being used; this is
377
+ // cleanup.
378
+ let warnPersisted;
379
+ try {
380
+ const existing = (await getSetting("persisted-env-vars")) ?? {};
381
+ const cleaned = {};
382
+ for (const [k, v] of Object.entries(existing)) {
383
+ if (!BUILDER_ENV_KEYS.includes(k))
384
+ cleaned[k] = v;
385
+ }
386
+ await putSetting("persisted-env-vars", cleaned);
387
+ }
388
+ catch (err) {
389
+ warnPersisted = err instanceof Error ? err.message : String(err);
390
+ }
391
+ // 3. Clear in-process env vars so the current worker stops routing
392
+ // through Builder immediately. Nitro's env-runner may re-populate
393
+ // these across a module reload, but by then the `builder-disconnected`
394
+ // flag will be enforced at the plugin-init scrub.
395
+ for (const key of BUILDER_ENV_KEYS) {
396
+ delete process.env[key];
397
+ }
398
+ return {
399
+ ok: true,
400
+ ...(warnPersisted
401
+ ? { warnings: { persistedEnvVars: warnPersisted } }
402
+ : {}),
403
+ };
404
+ }));
218
405
  // Proxy to Builder's agents-run API for background code changes.
219
406
  getH3App(nitroApp).use(`${P}/builder/agents-run`, defineEventHandler(async (event) => {
220
407
  if (getMethod(event) !== "POST") {
@@ -266,6 +453,10 @@ export function createCoreRoutesPlugin(options = {}) {
266
453
  // Env key management — framework keys are always included
267
454
  const frameworkEnvKeys = [
268
455
  { key: "ENABLE_BUILDER", label: "Enable Builder.io features" },
456
+ {
457
+ key: "AGENT_ENGINE_PREFER_BYO_KEY",
458
+ label: "Prefer BYO LLM key over Builder gateway (default: false — gateway wins)",
459
+ },
269
460
  ...Object.values(PROVIDER_ENV_META).map(({ envVar, label }) => ({
270
461
  key: envVar,
271
462
  label,
@@ -349,6 +540,17 @@ export function createCoreRoutesPlugin(options = {}) {
349
540
  for (const { key, value } of filtered) {
350
541
  process.env[key] = value;
351
542
  }
543
+ // Persist to settings table for serverless cold-start recovery.
544
+ try {
545
+ const envMap = {};
546
+ for (const { key, value } of filtered)
547
+ envMap[key] = value;
548
+ const existing = (await getSetting("persisted-env-vars")) ?? {};
549
+ await putSetting("persisted-env-vars", { ...existing, ...envMap });
550
+ }
551
+ catch {
552
+ // DB not ready yet — skip
553
+ }
352
554
  return { saved: filtered.map((v) => v.key) };
353
555
  }));
354
556
  }