@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.
- package/dist/agent/engine/builder-engine.d.ts.map +1 -1
- package/dist/agent/engine/builder-engine.js +19 -1
- package/dist/agent/engine/builder-engine.js.map +1 -1
- package/dist/client/settings/SettingsPanel.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.d.ts +10 -1
- package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
- package/dist/client/settings/useBuilderStatus.js +39 -3
- package/dist/client/settings/useBuilderStatus.js.map +1 -1
- package/dist/client/settings/useBuilderStatus.spec.js +76 -0
- package/dist/client/settings/useBuilderStatus.spec.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +5 -2
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/builder-browser.d.ts +52 -15
- package/dist/server/builder-browser.d.ts.map +1 -1
- package/dist/server/builder-browser.js +126 -15
- package/dist/server/builder-browser.js.map +1 -1
- package/dist/server/core-routes-plugin.d.ts.map +1 -1
- package/dist/server/core-routes-plugin.js +105 -19
- package/dist/server/core-routes-plugin.js.map +1 -1
- package/dist/server/credential-provider.d.ts +25 -4
- package/dist/server/credential-provider.d.ts.map +1 -1
- package/dist/server/credential-provider.js +112 -15
- package/dist/server/credential-provider.js.map +1 -1
- package/dist/server/google-realtime-session.d.ts.map +1 -1
- package/dist/server/google-realtime-session.js +1 -1
- package/dist/server/google-realtime-session.js.map +1 -1
- 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
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
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
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
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(
|
|
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
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
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
|
|
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":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAUlC,eAAO,MAAM,qBAAqB,oCAAoC,CAAC;AAmBvE;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,cAAc,CAAC;AAC/C,eAAO,MAAM,qBAAqB,gBAAgB,CAAC;AACnD,eAAO,MAAM,4BAA4B,6BAA6B,CAAC;AAIvE,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,yBAAyB,EAAE,OAAO,CAAC;IACnC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;
|
|
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
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
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(
|
|
250
|
-
const
|
|
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}`,
|
|
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", `${
|
|
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
|
-
*
|
|
355
|
-
*
|
|
356
|
-
*
|
|
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
|
-
|
|
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
|
}
|