@agent-native/core 0.15.7 → 0.15.10

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 (28) hide show
  1. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  2. package/dist/agent/engine/builder-engine.js +19 -1
  3. package/dist/agent/engine/builder-engine.js.map +1 -1
  4. package/dist/client/settings/SettingsPanel.js.map +1 -1
  5. package/dist/client/settings/useBuilderStatus.d.ts +10 -1
  6. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  7. package/dist/client/settings/useBuilderStatus.js +39 -3
  8. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  9. package/dist/client/settings/useBuilderStatus.spec.js +76 -0
  10. package/dist/client/settings/useBuilderStatus.spec.js.map +1 -1
  11. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  12. package/dist/server/agent-chat-plugin.js +5 -2
  13. package/dist/server/agent-chat-plugin.js.map +1 -1
  14. package/dist/server/builder-browser.d.ts +52 -15
  15. package/dist/server/builder-browser.d.ts.map +1 -1
  16. package/dist/server/builder-browser.js +126 -15
  17. package/dist/server/builder-browser.js.map +1 -1
  18. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  19. package/dist/server/core-routes-plugin.js +105 -19
  20. package/dist/server/core-routes-plugin.js.map +1 -1
  21. package/dist/server/credential-provider.d.ts +25 -4
  22. package/dist/server/credential-provider.d.ts.map +1 -1
  23. package/dist/server/credential-provider.js +112 -15
  24. package/dist/server/credential-provider.js.map +1 -1
  25. package/dist/server/google-realtime-session.d.ts.map +1 -1
  26. package/dist/server/google-realtime-session.js +1 -1
  27. package/dist/server/google-realtime-session.js.map +1 -1
  28. package/package.json +1 -1
@@ -22,14 +22,27 @@ export interface BuilderBrowserStatus {
22
22
  * account, which takes precedence for their request.
23
23
  */
24
24
  envManaged: boolean;
25
- credentialSource?: "user" | "org" | "env";
25
+ credentialSource?: "user" | "org" | "workspace" | "env";
26
+ /**
27
+ * The currently effective Builder credential was rejected by Builder's API.
28
+ * This is durable status about the credential pair, not a failure of an
29
+ * in-progress cli-auth callback.
30
+ */
31
+ authError?: {
32
+ message: string;
33
+ at: number;
34
+ };
35
+ connectError?: {
36
+ message: string;
37
+ at: number;
38
+ };
26
39
  appHost: string;
27
40
  apiHost: string;
28
41
  /**
29
- * Ready-to-open Builder CLI auth URL for this request owner. This points
30
- * directly at builder.io/cli-auth and carries signed callback state in the
31
- * nested redirect_url so the popup never has to visit the app's connect
32
- * trampoline first.
42
+ * Ready-to-open Builder CLI auth URL for this request owner, when the
43
+ * callback can return to the same deployment that minted the state. Preview
44
+ * deployments that must callback through a gateway omit this and use
45
+ * connectUrl so the server can write a pending-connect row first.
33
46
  */
34
47
  cliAuthUrl?: string;
35
48
  connectUrl: string;
@@ -75,6 +88,18 @@ export declare function getBuilderBranchProjectId(): string;
75
88
  export declare function isBuilderBranchingEnabled(): boolean;
76
89
  export declare function resolveBuilderBranchProjectId(): Promise<string>;
77
90
  export declare function resolveIsBuilderBranchingEnabled(): Promise<boolean>;
91
+ /**
92
+ * Query param on the callback URL that carries the original preview opener
93
+ * origin when cli-auth's allow-list forces `preview_url` to the gateway.
94
+ * Read on the callback to derive the correct postMessage targetOrigin.
95
+ *
96
+ * Not signed: the receive-side trust check in `useBuilderStatus` still
97
+ * gates messages by allow-listed origin. The worst an attacker could do by
98
+ * crafting a different `_an_opener` value is target a postMessage to an
99
+ * origin that doesn't match the actual opener — postMessage drops the
100
+ * message in that case, identical to the legacy wildcard-fallback path.
101
+ */
102
+ export declare const BUILDER_OPENER_PARAM = "_an_opener";
78
103
  /**
79
104
  * Build the Builder cli-auth URL for the connect popup. When a signed
80
105
  * `state` token is supplied it is embedded inside the `redirect_url`
@@ -83,12 +108,13 @@ export declare function resolveIsBuilderBranchingEnabled(): Promise<boolean>;
83
108
  * api-key / etc., so we don't depend on Builder echoing a top-level
84
109
  * `state` parameter (it doesn't).
85
110
  *
86
- * The user-facing connect entry point is `/_agent-native/builder/connect`
87
- * (a server-side 302). Status / chat-card responses surface that path
88
- * rather than the cli-auth URL directly, so the 302 handler can mint a
89
- * fresh state bound to the current session on every click.
111
+ * Status responses can surface this URL directly; the legacy
112
+ * `/_agent-native/builder/connect` trampoline still calls this helper for
113
+ * clients that only know the app-local connect URL.
90
114
  */
91
- export declare function buildBuilderCliAuthUrl(origin: string, state?: string | null): string;
115
+ export declare function buildBuilderCliAuthUrl(callbackOrigin: string, state?: string | null, options?: {
116
+ previewOrigin?: string;
117
+ }): string;
92
118
  /**
93
119
  * The bare URL surfaced to clients as `connectUrl`. The status route appends
94
120
  * a short-lived signed connect token when it knows the current owner; this
@@ -97,12 +123,20 @@ export declare function buildBuilderCliAuthUrl(origin: string, state?: string |
97
123
  */
98
124
  export declare function getBuilderBrowserConnectUrl(origin: string): string;
99
125
  /**
100
- * Builder CLI-auth does not need the workspace OAuth relay that Google uses.
101
- * In Builder/Fusion previews, keep connect + callback URLs on the actual app
102
- * preview origin so the signed connect token and pending row are verified by
103
- * the same deployment that minted them.
126
+ * User-visible Builder connect origin. In Builder/Fusion previews, keep the
127
+ * connect URL on the actual app preview origin so clicking Connect happens in
128
+ * the same deployment that minted the signed connect token.
104
129
  */
105
130
  export declare function getBuilderBrowserOriginForEvent(event: H3Event): string;
131
+ /**
132
+ * Builder's /cli-auth page currently only accepts localhost, *.builder.io,
133
+ * *.agent-native.com, or builder: redirect_url destinations. Preview hosts
134
+ * such as *.builderio.xyz and *.builder.codes are valid app origins for us,
135
+ * but Builder rejects them and falls back to http://localhost:10110/auth.
136
+ * Use a configured public gateway for the callback in those cases while
137
+ * leaving the surfaced connect URL on the user's active preview.
138
+ */
139
+ export declare function getBuilderCliAuthCallbackOriginForEvent(event: H3Event): string;
106
140
  export declare function getBuilderBrowserStatus(origin: string): BuilderBrowserStatus;
107
141
  export declare function getBuilderBrowserStatusForEvent(event: H3Event): BuilderBrowserStatus;
108
142
  /**
@@ -125,7 +159,9 @@ export declare function getBuilderCallbackEnvVars(params: {
125
159
  value: string;
126
160
  }[];
127
161
  export declare function resolveSafePreviewUrl(previewUrl: string | null | undefined, event: H3Event): string;
128
- export declare function createBuilderBrowserCallbackPage(previewUrl: string): string;
162
+ export declare function createBuilderBrowserCallbackPage(previewUrl: string, opts?: {
163
+ parentOrigin?: string;
164
+ }): string;
129
165
  /**
130
166
  * HTML page rendered inside the OAuth popup when the callback handler caught
131
167
  * an error persisting the per-user Builder credentials. Without this, the
@@ -144,6 +180,7 @@ export declare function createBuilderBrowserCallbackErrorPage(message: string, o
144
180
  title?: string;
145
181
  body?: string;
146
182
  closeHint?: string;
183
+ parentOrigin?: string;
147
184
  }): string;
148
185
  export interface RunBuilderAgentArgs {
149
186
  prompt: string;
@@ -1 +1 @@
1
- {"version":3,"file":"builder-browser.d.ts","sourceRoot":"","sources":["../../src/server/builder-browser.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"builder-browser.d.ts","sourceRoot":"","sources":["../../src/server/builder-browser.ts"],"names":[],"mappings":"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"}
@@ -233,6 +233,72 @@ export async function resolveBuilderBranchProjectId() {
233
233
  export async function resolveIsBuilderBranchingEnabled() {
234
234
  return !!(await resolveBuilderBranchProjectId());
235
235
  }
236
+ function isBuilderCliAuthAllowedOrigin(origin) {
237
+ if (!origin)
238
+ return false;
239
+ try {
240
+ const parsed = new URL(origin);
241
+ const hostname = parsed.hostname.toLowerCase();
242
+ const isAllowedProtocol = parsed.protocol === "http:" || parsed.protocol === "https:";
243
+ const isLocalhost = hostname === "localhost" ||
244
+ hostname === "127.0.0.1" ||
245
+ hostname === "::1" ||
246
+ hostname === "[::1]";
247
+ const isBuilderDomain = hostname === "builder.io" || hostname.endsWith(".builder.io");
248
+ const isAgentNativeDomain = hostname === "agent-native.com" || hostname.endsWith(".agent-native.com");
249
+ return (isAllowedProtocol &&
250
+ (isLocalhost || isBuilderDomain || isAgentNativeDomain));
251
+ }
252
+ catch {
253
+ return false;
254
+ }
255
+ }
256
+ function firstBuilderCliAuthCallbackOriginFromEnv() {
257
+ for (const key of [
258
+ "APP_URL",
259
+ "VITE_APP_URL",
260
+ "BETTER_AUTH_URL",
261
+ "VITE_BETTER_AUTH_URL",
262
+ "WORKSPACE_GATEWAY_URL",
263
+ "VITE_WORKSPACE_GATEWAY_URL",
264
+ ]) {
265
+ const raw = process.env[key];
266
+ if (!raw)
267
+ continue;
268
+ try {
269
+ const origin = new URL(raw).origin;
270
+ if (isBuilderCliAuthAllowedOrigin(origin))
271
+ return origin;
272
+ }
273
+ catch {
274
+ // Ignore malformed environment values.
275
+ }
276
+ }
277
+ return null;
278
+ }
279
+ /**
280
+ * Query param on the callback URL that carries the original preview opener
281
+ * origin when cli-auth's allow-list forces `preview_url` to the gateway.
282
+ * Read on the callback to derive the correct postMessage targetOrigin.
283
+ *
284
+ * Not signed: the receive-side trust check in `useBuilderStatus` still
285
+ * gates messages by allow-listed origin. The worst an attacker could do by
286
+ * crafting a different `_an_opener` value is target a postMessage to an
287
+ * origin that doesn't match the actual opener — postMessage drops the
288
+ * message in that case, identical to the legacy wildcard-fallback path.
289
+ */
290
+ export const BUILDER_OPENER_PARAM = "_an_opener";
291
+ function isBuilderOpenerOriginSafe(value) {
292
+ if (!value)
293
+ return false;
294
+ try {
295
+ const parsed = new URL(value);
296
+ return parsed.protocol === "http:" || parsed.protocol === "https:";
297
+ }
298
+ catch {
299
+ return false;
300
+ }
301
+ }
236
302
  /**
237
303
  * Build the Builder cli-auth URL for the connect popup. When a signed
238
304
  * `state` token is supplied it is embedded inside the `redirect_url`
@@ -241,24 +307,38 @@ export async function resolveIsBuilderBranchingEnabled() {
241
307
  * api-key / etc., so we don't depend on Builder echoing a top-level
242
308
  * `state` parameter (it doesn't).
243
309
  *
244
- * The user-facing connect entry point is `/_agent-native/builder/connect`
245
- * (a server-side 302). Status / chat-card responses surface that path
246
- * rather than the cli-auth URL directly, so the 302 handler can mint a
247
- * fresh state bound to the current session on every click.
310
+ * Status responses can surface this URL directly; the legacy
311
+ * `/_agent-native/builder/connect` trampoline still calls this helper for
312
+ * clients that only know the app-local connect URL.
248
313
  */
249
- export function buildBuilderCliAuthUrl(origin, state = null) {
250
- const normalizedOrigin = normalizeOrigin(origin);
314
+ export function buildBuilderCliAuthUrl(callbackOrigin, state = null, options = {}) {
315
+ const normalizedCallbackOrigin = normalizeOrigin(callbackOrigin);
316
+ const requestedPreviewOrigin = normalizeOrigin(options.previewOrigin || callbackOrigin);
317
+ const normalizedPreviewOrigin = isBuilderCliAuthAllowedOrigin(requestedPreviewOrigin)
318
+ ? requestedPreviewOrigin
319
+ : normalizedCallbackOrigin;
251
320
  const appBasePath = getAppBasePath();
252
- const callbackUrl = new URL(`${appBasePath}${BUILDER_CALLBACK_PATH}`, normalizedOrigin);
321
+ const callbackUrl = new URL(`${appBasePath}${BUILDER_CALLBACK_PATH}`, normalizedCallbackOrigin);
253
322
  if (state) {
254
323
  callbackUrl.searchParams.set(BUILDER_STATE_PARAM, state);
255
324
  }
325
+ // When the cli-auth allow-list forces preview_url onto the gateway origin,
326
+ // the callback would otherwise lose the real opener origin and post its
327
+ // success message to the gateway instead of the preview tab. Embed the
328
+ // original preview origin in the callback's own query string so the
329
+ // callback handler can recover it for parentOrigin / postMessage. Builder
330
+ // preserves the redirect_url's query verbatim, so this round-trips.
331
+ if (requestedPreviewOrigin &&
332
+ requestedPreviewOrigin !== normalizedPreviewOrigin &&
333
+ isBuilderOpenerOriginSafe(requestedPreviewOrigin)) {
334
+ callbackUrl.searchParams.set(BUILDER_OPENER_PARAM, requestedPreviewOrigin);
335
+ }
256
336
  const url = new URL("/cli-auth", getBuilderAppHost());
257
337
  url.searchParams.set("response_type", "code");
258
338
  url.searchParams.set("host", BUILDER_BROWSER_HOST);
259
339
  url.searchParams.set("client_id", BUILDER_BROWSER_CLIENT_ID);
260
340
  url.searchParams.set("redirect_url", callbackUrl.toString());
261
- url.searchParams.set("preview_url", `${normalizedOrigin}${appBasePath}`);
341
+ url.searchParams.set("preview_url", `${normalizedPreviewOrigin}${appBasePath}`);
262
342
  url.searchParams.set("framework", "agent-native");
263
343
  return url.toString();
264
344
  }
@@ -351,10 +431,9 @@ function firstPublicBuilderPreviewOriginFromEnv() {
351
431
  return null;
352
432
  }
353
433
  /**
354
- * Builder CLI-auth does not need the workspace OAuth relay that Google uses.
355
- * In Builder/Fusion previews, keep connect + callback URLs on the actual app
356
- * preview origin so the signed connect token and pending row are verified by
357
- * the same deployment that minted them.
434
+ * User-visible Builder connect origin. In Builder/Fusion previews, keep the
435
+ * connect URL on the actual app preview origin so clicking Connect happens in
436
+ * the same deployment that minted the signed connect token.
358
437
  */
359
438
  export function getBuilderBrowserOriginForEvent(event) {
360
439
  const headerHost = firstHeaderValue(readEventHeader(event, "x-forwarded-host") ||
@@ -374,6 +453,20 @@ export function getBuilderBrowserOriginForEvent(event) {
374
453
  : "http";
375
454
  return `${proto}://${headerHost}`;
376
455
  }
456
+ /**
457
+ * Builder's /cli-auth page currently only accepts localhost, *.builder.io,
458
+ * *.agent-native.com, or builder: redirect_url destinations. Preview hosts
459
+ * such as *.builderio.xyz and *.builder.codes are valid app origins for us,
460
+ * but Builder rejects them and falls back to http://localhost:10110/auth.
461
+ * Use a configured public gateway for the callback in those cases while
462
+ * leaving the surfaced connect URL on the user's active preview.
463
+ */
464
+ export function getBuilderCliAuthCallbackOriginForEvent(event) {
465
+ const previewOrigin = getBuilderBrowserOriginForEvent(event);
466
+ if (isBuilderCliAuthAllowedOrigin(previewOrigin))
467
+ return previewOrigin;
468
+ return firstBuilderCliAuthCallbackOriginFromEnv() ?? previewOrigin;
469
+ }
377
470
  export function getBuilderBrowserStatus(origin) {
378
471
  const branchProjectId = getConfiguredBuilderBranchProjectId();
379
472
  const envManaged = !!process.env.BUILDER_PRIVATE_KEY;
@@ -571,8 +664,24 @@ const BUILDER_CALLBACK_BASE_CSS = `
571
664
  word-break: break-word;
572
665
  }
573
666
  `;
574
- export function createBuilderBrowserCallbackPage(previewUrl) {
667
+ function safeOriginFromUrl(value) {
668
+ if (!value)
669
+ return null;
670
+ try {
671
+ return new URL(value).origin;
672
+ }
673
+ catch {
674
+ return null;
675
+ }
676
+ }
677
+ export function createBuilderBrowserCallbackPage(previewUrl, opts = {}) {
575
678
  const escapedUrl = JSON.stringify(previewUrl);
679
+ const parentOrigin = safeOriginFromUrl(opts.parentOrigin) ?? safeOriginFromUrl(previewUrl);
680
+ // postMessage requires a specific target origin for cross-origin opener
681
+ // delivery; only fall back to "*" when we have no usable origin (the
682
+ // BroadcastChannel path on the success page still works for same-origin
683
+ // openers in that case).
684
+ const escapedTargetOrigin = JSON.stringify(parentOrigin ?? "*");
576
685
  return `<!doctype html>
577
686
  <html lang="en">
578
687
  <head>
@@ -615,7 +724,7 @@ export function createBuilderBrowserCallbackPage(previewUrl) {
615
724
  if (window.opener && !window.opener.closed) {
616
725
  window.opener.postMessage(
617
726
  { type: "builder-connect-success" },
618
- "*",
727
+ ${escapedTargetOrigin},
619
728
  );
620
729
  }
621
730
  } catch (e) {}
@@ -651,6 +760,8 @@ export function createBuilderBrowserCallbackPage(previewUrl) {
651
760
  */
652
761
  export function createBuilderBrowserCallbackErrorPage(message, opts = {}) {
653
762
  const escapedMessage = JSON.stringify(message);
763
+ const parentOrigin = safeOriginFromUrl(opts.parentOrigin);
764
+ const escapedTargetOrigin = JSON.stringify(parentOrigin ?? "*");
654
765
  const title = opts.title ?? "Couldn't save Builder connection";
655
766
  const body = opts.body ??
656
767
  "Builder authorized your account but the server couldn't persist the credentials.";
@@ -699,7 +810,7 @@ export function createBuilderBrowserCallbackErrorPage(message, opts = {}) {
699
810
  try {
700
811
  window.opener.postMessage(
701
812
  { type: "builder-connect-error", message: msg },
702
- "*",
813
+ ${escapedTargetOrigin},
703
814
  );
704
815
  } catch (e) {}
705
816
  }