@agent-native/core 0.225.2-nightly-20261106152255 → 0.226.0
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/actions/get-agentkit-capabilities.d.ts +12 -1
- package/dist/agent/actions/get-agentkit-capabilities.js +13 -5
- package/dist/agent/production-agent.js +14 -4
- package/dist/agentkit/capabilities.d.ts +4 -2
- package/dist/agentkit/capabilities.js +71 -18
- package/dist/app-config/experience-profiles.d.ts +4 -0
- package/dist/app-config/experience-profiles.js +7 -0
- package/dist/app-config/onboarding.d.ts +2 -0
- package/dist/app-config/onboarding.js +5 -0
- package/dist/app-config/schema.d.ts +5 -0
- package/dist/app-config/schema.js +2 -0
- package/dist/application-state/handlers.d.ts +2 -2
- package/dist/client/agent-chat.d.ts +3 -1
- package/dist/client/agent-chat.js +8 -0
- package/dist/client/agentkit-chat/transport.d.ts +2 -1
- package/dist/client/agentkit-chat/transport.js +2 -1
- package/dist/client/auth/builder-signup.d.ts +14 -0
- package/dist/client/auth/builder-signup.js +75 -0
- package/dist/client/chat/agentkit-agent-native.d.ts +4 -0
- package/dist/client/chat/agentkit-agent-native.js +25 -0
- package/dist/client/chat/composer-draft.d.ts +1 -7
- package/dist/client/chat/composer-draft.js +5 -1
- package/dist/client/chat/native-uploads.d.ts +11 -0
- package/dist/client/chat/native-uploads.js +97 -0
- package/dist/client/experience-profiles.d.ts +182 -0
- package/dist/client/experience-profiles.js +19 -0
- package/dist/client/uploads/index.d.ts +1 -1
- package/dist/client/uploads/index.js +1 -1
- package/dist/client/use-action.js +3 -0
- package/dist/collab/routes.d.ts +1 -1
- package/dist/experience-profiles/index.d.ts +13 -0
- package/dist/experience-profiles/index.js +10 -0
- package/dist/experience-profiles/server.d.ts +38 -0
- package/dist/experience-profiles/server.js +76 -0
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/framework-package-versions.json +11 -11
- package/dist/localization/workspace-integration-messages.d.ts +11 -0
- package/dist/localization/workspace-integration-messages.js +132 -0
- package/dist/mcp/screen-memory-stdio.d.ts +3 -3
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/org/index.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +5 -5
- package/dist/provider-api/actions/provider-api.d.ts +3 -3
- package/dist/provider-api/actions/provider-api.js +2 -0
- package/dist/provider-api/index.d.ts +7 -1
- package/dist/provider-api/index.js +42 -2
- package/dist/scripts/resources/read.d.ts +6 -1
- package/dist/scripts/resources/read.js +85 -8
- package/dist/secrets/routes.d.ts +2 -2
- package/dist/server/agent-chat/script-entries.js +27 -6
- package/dist/server/agent-chat-plugin.js +102 -33
- package/dist/server/agent-engine-api-key-route.d.ts +4 -4
- package/dist/server/agent-engine-ollama-models-route.d.ts +1 -1
- package/dist/server/auth.js +25 -1
- package/dist/server/better-auth-instance.d.ts +1 -0
- package/dist/server/builder-browser.d.ts +2 -0
- package/dist/server/builder-browser.js +8 -4
- package/dist/server/builder-signup-experiment.d.ts +67 -0
- package/dist/server/builder-signup-experiment.js +345 -0
- package/dist/server/core-routes-plugin.d.ts +2 -0
- package/dist/server/core-routes-plugin.js +77 -25
- package/dist/server/first-touch-route.d.ts +1 -1
- package/dist/server/google-oauth.d.ts +2 -0
- package/dist/server/google-oauth.js +5 -0
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/shared/agent-chat-references.d.ts +2 -0
- package/dist/shared/agent-chat-references.js +8 -0
- package/dist/shared/auth-copy.d.ts +1 -0
- package/dist/shared/auth-copy.js +11 -0
- package/dist/shared/index.d.ts +1 -0
- package/dist/shared/index.js +1 -0
- package/dist/templates/builder-code-starter/server/lib/composer-reference-messages.ts.patch +44 -0
- package/dist/templates/builder-code-starter/server/plugins/agent-chat.ts.patch +10 -1
- package/dist/templates/chat/app/components/ChatComposerContext.tsx +31 -0
- package/dist/templates/chat/app/components/chat/ChatRouteContent.tsx +3 -0
- package/dist/templates/chat/app/components/home/HomePage.tsx +4 -2
- package/dist/templates/chat/app/components/layout/AgentInspector.tsx +2 -0
- package/dist/templates/chat/app/i18n/ar-SA.ts +7 -0
- package/dist/templates/chat/app/i18n/de-DE.ts +8 -0
- package/dist/templates/chat/app/i18n/en-US.ts +8 -0
- package/dist/templates/chat/app/i18n/es-ES.ts +8 -0
- package/dist/templates/chat/app/i18n/fr-FR.ts +8 -0
- package/dist/templates/chat/app/i18n/hi-IN.ts +7 -0
- package/dist/templates/chat/app/i18n/ja-JP.ts +8 -0
- package/dist/templates/chat/app/i18n/ko-KR.ts +8 -0
- package/dist/templates/chat/app/i18n/pt-BR.ts +8 -0
- package/dist/templates/chat/app/i18n/zh-CN.ts +7 -0
- package/dist/templates/chat/app/i18n/zh-TW.ts +7 -0
- package/dist/templates/chat/server/lib/composer-reference-messages.ts +34 -0
- package/dist/templates/chat/server/lib/composer-references.ts +60 -0
- package/dist/templates/chat/server/plugins/agent-chat.ts +13 -0
- package/docs/content/components.mdx +7 -2
- package/package.json +9 -4
- package/src/templates/builder-code-starter/server/lib/composer-reference-messages.ts.patch +44 -0
- package/src/templates/builder-code-starter/server/plugins/agent-chat.ts.patch +10 -1
- package/src/templates/chat/app/components/ChatComposerContext.tsx +31 -0
- package/src/templates/chat/app/components/chat/ChatRouteContent.tsx +3 -0
- package/src/templates/chat/app/components/home/HomePage.tsx +4 -2
- package/src/templates/chat/app/components/layout/AgentInspector.tsx +2 -0
- package/src/templates/chat/app/i18n/ar-SA.ts +7 -0
- package/src/templates/chat/app/i18n/de-DE.ts +8 -0
- package/src/templates/chat/app/i18n/en-US.ts +8 -0
- package/src/templates/chat/app/i18n/es-ES.ts +8 -0
- package/src/templates/chat/app/i18n/fr-FR.ts +8 -0
- package/src/templates/chat/app/i18n/hi-IN.ts +7 -0
- package/src/templates/chat/app/i18n/ja-JP.ts +8 -0
- package/src/templates/chat/app/i18n/ko-KR.ts +8 -0
- package/src/templates/chat/app/i18n/pt-BR.ts +8 -0
- package/src/templates/chat/app/i18n/zh-CN.ts +7 -0
- package/src/templates/chat/app/i18n/zh-TW.ts +7 -0
- package/src/templates/chat/server/lib/composer-reference-messages.ts +34 -0
- package/src/templates/chat/server/lib/composer-references.ts +60 -0
- package/src/templates/chat/server/plugins/agent-chat.ts +13 -0
|
@@ -50,6 +50,7 @@ import { RECURRING_JOBS_SWEEP_PATH } from "../jobs/scheduler-dispatch.js";
|
|
|
50
50
|
import { RECURRING_SWEEP_BUDGET_MS } from "../jobs/sweep-hooks.js";
|
|
51
51
|
import { CHATGPT_SUBSCRIPTION_LAB } from "../labs/core-labs.js";
|
|
52
52
|
import { getUserLabEnabled } from "../labs/store.js";
|
|
53
|
+
import { workspaceIntegrationMessagesForUser } from "../localization/workspace-integration-messages.js";
|
|
53
54
|
import { mcpToolsToActionEntries, mountMcpServersRoutes, mountMcpHubRoutes, getHubStatus, isHubServeEnabled, } from "../mcp-client/index.js";
|
|
54
55
|
import { normalizeMcpPrincipal, principalFromRequestContext, } from "../mcp-client/principal.js";
|
|
55
56
|
import { declaredMcpToolNames, getMcpDirectoryWidgetResourceUri, } from "../mcp/build-server.js";
|
|
@@ -5149,13 +5150,64 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
5149
5150
|
// `resolveAccess` when querying ownable tables. Without this,
|
|
5150
5151
|
// a provider that searches `decks` (or any sharable resource)
|
|
5151
5152
|
// would see every row regardless of ownership.
|
|
5152
|
-
const mentionsOwner = await getOwnerFromEvent(event).catch(() =>
|
|
5153
|
+
const mentionsOwner = await getOwnerFromEvent(event).catch((error) => {
|
|
5154
|
+
if (error &&
|
|
5155
|
+
typeof error === "object" &&
|
|
5156
|
+
(("statusCode" in error && error.statusCode === 401) ||
|
|
5157
|
+
("status" in error && error.status === 401)))
|
|
5158
|
+
return undefined;
|
|
5159
|
+
throw error;
|
|
5160
|
+
});
|
|
5161
|
+
const referenceMessages = await workspaceIntegrationMessagesForUser(mentionsOwner ?? "");
|
|
5153
5162
|
const mentionsOrgId = await resolveResourceOrgId(event, options?.resolveOrgId);
|
|
5163
|
+
const mentionContext = {
|
|
5164
|
+
...(mentionsOwner ? { userEmail: mentionsOwner } : {}),
|
|
5165
|
+
...(mentionsOrgId ? { orgId: mentionsOrgId } : {}),
|
|
5166
|
+
...((mentionsOrgId === null ||
|
|
5167
|
+
(mentionsOrgId === undefined &&
|
|
5168
|
+
getRequestContext()?.orgScope === "personal")) && {
|
|
5169
|
+
orgScope: "personal",
|
|
5170
|
+
}),
|
|
5171
|
+
};
|
|
5154
5172
|
const query = getQuery(event);
|
|
5155
5173
|
const q = typeof query.q === "string" ? query.q.toLowerCase() : "";
|
|
5156
5174
|
const matchesQuery = (item) => !q ||
|
|
5157
5175
|
item.label.toLowerCase().includes(q) ||
|
|
5158
5176
|
(item.description?.toLowerCase().includes(q) ?? false);
|
|
5177
|
+
if (query.source !== undefined) {
|
|
5178
|
+
const source = typeof query.source === "string" ? query.source : "";
|
|
5179
|
+
const mentionErrorResponse = (status, code, message) => new Response(JSON.stringify({ error: { code, message, source } }), {
|
|
5180
|
+
status,
|
|
5181
|
+
headers: {
|
|
5182
|
+
"Content-Type": "application/json",
|
|
5183
|
+
"Cache-Control": "no-cache",
|
|
5184
|
+
},
|
|
5185
|
+
});
|
|
5186
|
+
const provider = Object.prototype.hasOwnProperty.call(mentionProviders, source)
|
|
5187
|
+
? mentionProviders[source]
|
|
5188
|
+
: undefined;
|
|
5189
|
+
if (!provider)
|
|
5190
|
+
return mentionErrorResponse(404, "mention_source_not_found", referenceMessages.referenceUnknown);
|
|
5191
|
+
if (!mentionsOwner)
|
|
5192
|
+
return mentionErrorResponse(401, "unauthorized", referenceMessages.referenceSignIn);
|
|
5193
|
+
let items;
|
|
5194
|
+
try {
|
|
5195
|
+
items = await runWithRequestContext(mentionContext, () => provider.search(q, event));
|
|
5196
|
+
}
|
|
5197
|
+
catch {
|
|
5198
|
+
return mentionErrorResponse(503, "mention_source_unavailable", referenceMessages.referenceUnavailable);
|
|
5199
|
+
}
|
|
5200
|
+
setResponseHeader(event, "Content-Type", "application/x-ndjson");
|
|
5201
|
+
setResponseHeader(event, "Cache-Control", "no-cache");
|
|
5202
|
+
return (JSON.stringify({
|
|
5203
|
+
items: items.slice(0, 50).map((item) => ({
|
|
5204
|
+
...item,
|
|
5205
|
+
source,
|
|
5206
|
+
section: provider.label,
|
|
5207
|
+
icon: item.icon || provider.icon || "file",
|
|
5208
|
+
})),
|
|
5209
|
+
}) + "\n");
|
|
5210
|
+
}
|
|
5159
5211
|
const enc = new TextEncoder();
|
|
5160
5212
|
// Stream NDJSON — each source flushes its batch as soon as it's ready.
|
|
5161
5213
|
setResponseHeader(event, "Content-Type", "application/x-ndjson");
|
|
@@ -5166,15 +5218,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
5166
5218
|
const mentionsAbort = new AbortController();
|
|
5167
5219
|
const stream = new ReadableStream({
|
|
5168
5220
|
start(controller) {
|
|
5169
|
-
|
|
5170
|
-
getRequestContext()?.orgScope === "personal";
|
|
5171
|
-
return runWithRequestContext({
|
|
5172
|
-
userEmail: mentionsOwner,
|
|
5173
|
-
orgId: mentionsOrgId ?? undefined,
|
|
5174
|
-
...((mentionsOrgId === null || inheritedPersonalScope) && {
|
|
5175
|
-
orgScope: "personal",
|
|
5176
|
-
}),
|
|
5177
|
-
}, () => mentionsStreamWork(controller));
|
|
5221
|
+
return runWithRequestContext(mentionContext, () => mentionsStreamWork(controller));
|
|
5178
5222
|
},
|
|
5179
5223
|
cancel() {
|
|
5180
5224
|
// Client disconnected — stop enqueuing and let in-flight source
|
|
@@ -5210,6 +5254,22 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
5210
5254
|
}
|
|
5211
5255
|
}
|
|
5212
5256
|
};
|
|
5257
|
+
const reportSourceFailure = (source) => {
|
|
5258
|
+
if (cancelled || mentionsAbort.signal.aborted)
|
|
5259
|
+
return;
|
|
5260
|
+
try {
|
|
5261
|
+
controller.enqueue(enc.encode(JSON.stringify({
|
|
5262
|
+
error: {
|
|
5263
|
+
code: "mention_source_unavailable",
|
|
5264
|
+
message: referenceMessages.referenceUnavailable,
|
|
5265
|
+
source,
|
|
5266
|
+
},
|
|
5267
|
+
}) + "\n"));
|
|
5268
|
+
}
|
|
5269
|
+
catch {
|
|
5270
|
+
cancelled = true;
|
|
5271
|
+
}
|
|
5272
|
+
};
|
|
5213
5273
|
// All sources run in parallel; each flushes independently.
|
|
5214
5274
|
const sources = [];
|
|
5215
5275
|
// 1. Resources from SQL (fast — flush first)
|
|
@@ -5242,7 +5302,9 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
5242
5302
|
};
|
|
5243
5303
|
}));
|
|
5244
5304
|
}
|
|
5245
|
-
catch {
|
|
5305
|
+
catch {
|
|
5306
|
+
reportSourceFailure("resources");
|
|
5307
|
+
}
|
|
5246
5308
|
})());
|
|
5247
5309
|
// 2. Codebase files (dev mode only — can be slow on large repos)
|
|
5248
5310
|
if (currentDevMode) {
|
|
@@ -5251,7 +5313,10 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
5251
5313
|
try {
|
|
5252
5314
|
await collectFiles(process.cwd(), "", 0, codebaseFiles);
|
|
5253
5315
|
}
|
|
5254
|
-
catch {
|
|
5316
|
+
catch {
|
|
5317
|
+
reportSourceFailure("codebase");
|
|
5318
|
+
return;
|
|
5319
|
+
}
|
|
5255
5320
|
flush(codebaseFiles.map((f) => ({
|
|
5256
5321
|
id: `codebase:${f.path}`,
|
|
5257
5322
|
label: f.name,
|
|
@@ -5291,32 +5356,35 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
5291
5356
|
})));
|
|
5292
5357
|
}
|
|
5293
5358
|
catch (e) {
|
|
5359
|
+
reportSourceFailure(key);
|
|
5294
5360
|
console.error(`[agent-native] Mention provider "${key}" failed:`, e);
|
|
5295
5361
|
}
|
|
5296
5362
|
})());
|
|
5297
5363
|
}
|
|
5298
5364
|
// 4. Custom workspace agents
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
5310
|
-
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5365
|
+
if (mentionsOwner)
|
|
5366
|
+
sources.push((async () => {
|
|
5367
|
+
try {
|
|
5368
|
+
const owner = await getOwnerFromEvent(event);
|
|
5369
|
+
const { listAccessibleCustomAgents } = await import("../resources/agents.js");
|
|
5370
|
+
const agents = await listAccessibleCustomAgents(owner);
|
|
5371
|
+
flush(agents.map((agent) => ({
|
|
5372
|
+
id: `custom-agent:${agent.id}`,
|
|
5373
|
+
label: agent.name,
|
|
5374
|
+
description: agent.description || agent.path,
|
|
5375
|
+
icon: "agent",
|
|
5376
|
+
source: "agent:custom",
|
|
5377
|
+
refType: "custom-agent",
|
|
5378
|
+
refPath: agent.path,
|
|
5379
|
+
refId: agent.id,
|
|
5380
|
+
section: "Agents",
|
|
5381
|
+
})));
|
|
5382
|
+
}
|
|
5383
|
+
catch (e) {
|
|
5384
|
+
reportSourceFailure("custom-agents");
|
|
5385
|
+
console.error("[agent-native] Custom agent discovery failed:", e);
|
|
5386
|
+
}
|
|
5387
|
+
})());
|
|
5320
5388
|
// 5. Peer agent discovery (network call — often slowest)
|
|
5321
5389
|
sources.push((async () => {
|
|
5322
5390
|
try {
|
|
@@ -5334,6 +5402,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
|
|
|
5334
5402
|
})));
|
|
5335
5403
|
}
|
|
5336
5404
|
catch (e) {
|
|
5405
|
+
reportSourceFailure("connected-agents");
|
|
5337
5406
|
console.error("[agent-native] Agent discovery failed:", e);
|
|
5338
5407
|
}
|
|
5339
5408
|
})());
|
|
@@ -54,21 +54,21 @@ export declare function resolveAgentEngineApiKeyWriteTarget(event: H3Event, scop
|
|
|
54
54
|
error: string;
|
|
55
55
|
}>;
|
|
56
56
|
export declare function createAgentEngineApiKeyHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
57
|
-
error: string;
|
|
58
|
-
errorCode?: undefined;
|
|
59
57
|
code?: undefined;
|
|
58
|
+
errorCode?: undefined;
|
|
59
|
+
error: string;
|
|
60
60
|
} | {
|
|
61
|
+
code?: undefined;
|
|
61
62
|
error: string;
|
|
62
63
|
errorCode: string;
|
|
63
|
-
code?: undefined;
|
|
64
64
|
} | {
|
|
65
65
|
errorCode?: undefined;
|
|
66
66
|
error: string;
|
|
67
67
|
code: ProviderKeyCheckCode;
|
|
68
68
|
} | {
|
|
69
69
|
error?: undefined;
|
|
70
|
-
errorCode?: undefined;
|
|
71
70
|
code?: undefined;
|
|
71
|
+
errorCode?: undefined;
|
|
72
72
|
ok: boolean;
|
|
73
73
|
key: string;
|
|
74
74
|
baseUrlKey?: string | undefined;
|
package/dist/server/auth.js
CHANGED
|
@@ -12,6 +12,7 @@ import { FIRST_RUN_ONBOARDING_COOKIE, FIRST_RUN_ONBOARDING_MAX_AGE, } from "../s
|
|
|
12
12
|
import { FIRST_TOUCH_SERVER_PATH } from "../shared/first-touch-persistence.js";
|
|
13
13
|
import { isGoogleProfileImageUrl } from "../shared/google-profile-image.js";
|
|
14
14
|
import { corsAllowHeadersFor, EMBED_TRANSPLANT_HEADER, isExplicitCorsAllowedOrigin, isMcpEmbedCorsOrigin, MCP_EMBED_CORS_ALLOW_HEADERS, shouldAllowMcpEmbedCredentials, } from "../shared/mcp-embed-headers.js";
|
|
15
|
+
import { bindBuilderSignupAttempt, BUILDER_SIGNUP_COOKIE, } from "./builder-signup-experiment.js";
|
|
15
16
|
import { createConsentHandler, createConsentRegionHandler, requestAllowsConsentCategory, } from "./consent-route.js";
|
|
16
17
|
import { readDevActionDiscoveryFile } from "./dev-action-discovery.js";
|
|
17
18
|
import { devLoopbackAuthHint } from "./dev-origin-hint.js";
|
|
@@ -153,6 +154,16 @@ function requestWithSignupAttribution(request, signupAttribution) {
|
|
|
153
154
|
function headersWithSignupAttribution(headers, cookieHeader) {
|
|
154
155
|
return addSignupAttributionHeader(headers, signupAttributionContextFromCookieHeader(cookieHeader));
|
|
155
156
|
}
|
|
157
|
+
async function recordBuilderSignupBinding(event, attemptId, method, email) {
|
|
158
|
+
if (typeof attemptId !== "string" && !getCookie(event, BUILDER_SIGNUP_COOKIE))
|
|
159
|
+
return;
|
|
160
|
+
try {
|
|
161
|
+
await bindBuilderSignupAttempt(event, attemptId, method, email);
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
captureAuthError(error, { route: "signup", email });
|
|
165
|
+
}
|
|
166
|
+
}
|
|
156
167
|
// ---------------------------------------------------------------------------
|
|
157
168
|
// Constants
|
|
158
169
|
// ---------------------------------------------------------------------------
|
|
@@ -4223,6 +4234,10 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
4223
4234
|
flowId: flowId ?? undefined,
|
|
4224
4235
|
desktopVerifierHash,
|
|
4225
4236
|
desktopBrowserBindingHash,
|
|
4237
|
+
builderSignupAttemptId: typeof q.builder_signup_attempt === "string" &&
|
|
4238
|
+
q.builder_signup_attempt.length <= 128
|
|
4239
|
+
? q.builder_signup_attempt
|
|
4240
|
+
: undefined,
|
|
4226
4241
|
signupAttribution,
|
|
4227
4242
|
signupAnonymousId,
|
|
4228
4243
|
signupSessionId,
|
|
@@ -4304,7 +4319,7 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
4304
4319
|
});
|
|
4305
4320
|
return oauthErrorPage(AUTH_GOOGLE_START_FALLBACK);
|
|
4306
4321
|
}
|
|
4307
|
-
const { redirectUri, desktop, mobile, returnUrl, flowId, desktopVerifierHash, desktopBrowserBindingHash, signupAttribution, signupAnonymousId, signupSessionId, mcpSignupAttribution, } = state;
|
|
4322
|
+
const { redirectUri, desktop, mobile, returnUrl, flowId, desktopVerifierHash, desktopBrowserBindingHash, builderSignupAttemptId, signupAttribution, signupAnonymousId, signupSessionId, mcpSignupAttribution, } = state;
|
|
4308
4323
|
callbackFlowId = flowId;
|
|
4309
4324
|
callbackDesktop = desktop ?? false;
|
|
4310
4325
|
callbackMobile = mobile ?? false;
|
|
@@ -4435,6 +4450,8 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
4435
4450
|
isNewUser: isNewGoogleUser,
|
|
4436
4451
|
},
|
|
4437
4452
|
});
|
|
4453
|
+
if (isNewGoogleUser)
|
|
4454
|
+
await recordBuilderSignupBinding(event, builderSignupAttemptId, "google", email);
|
|
4438
4455
|
logGoogleOAuthDebug(event, "callback-session-created", {
|
|
4439
4456
|
flowId,
|
|
4440
4457
|
desktop,
|
|
@@ -5412,6 +5429,9 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
5412
5429
|
const rawReturn = Array.isArray(query.return)
|
|
5413
5430
|
? query.return[0]
|
|
5414
5431
|
: query.return;
|
|
5432
|
+
const signupSession = await getSession(event);
|
|
5433
|
+
if (signupSession?.emailVerified)
|
|
5434
|
+
await recordBuilderSignupBinding(event, query.builder_signup_attempt, "magic-link", signupSession.email);
|
|
5415
5435
|
setFirstRunOnboardingCookie(event);
|
|
5416
5436
|
return queryEchoSafeRedirect(event, redirectWithStagedCookies(event, safeReturnPath(rawReturn), 302));
|
|
5417
5437
|
}));
|
|
@@ -5501,6 +5521,8 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
5501
5521
|
}, getAuthSecret())
|
|
5502
5522
|
: undefined;
|
|
5503
5523
|
const newUserCallbackUrl = new URL(`${getAppBasePath()}${publicFrameworkPath("/_agent-native/auth/magic-link/new-user")}?return=${encodeURIComponent(callbackPath)}`, getOrigin(event));
|
|
5524
|
+
if (typeof body?.builderSignupAttemptId === "string")
|
|
5525
|
+
newUserCallbackUrl.searchParams.set("builder_signup_attempt", body.builderSignupAttemptId);
|
|
5504
5526
|
if (attributionToken) {
|
|
5505
5527
|
newUserCallbackUrl.searchParams.set(MAGIC_LINK_ATTRIBUTION_PARAM, attributionToken);
|
|
5506
5528
|
}
|
|
@@ -5577,6 +5599,7 @@ async function mountBetterAuthRoutes(app, options) {
|
|
|
5577
5599
|
},
|
|
5578
5600
|
headers: headersWithSignupAttribution(event.headers, getHeader(event, "cookie") ?? null),
|
|
5579
5601
|
}));
|
|
5602
|
+
await recordBuilderSignupBinding(event, body?.builderSignupAttemptId, "password", email);
|
|
5580
5603
|
setFirstRunOnboardingCookie(event);
|
|
5581
5604
|
return { ok: true };
|
|
5582
5605
|
}
|
|
@@ -5785,6 +5808,7 @@ function mountAuthFallbackRoutes(app) {
|
|
|
5785
5808
|
body: { email, password, name: email.split("@")[0] },
|
|
5786
5809
|
headers: headersWithSignupAttribution(event.headers, getHeader(event, "cookie") ?? null),
|
|
5787
5810
|
}));
|
|
5811
|
+
await recordBuilderSignupBinding(event, body?.builderSignupAttemptId, "password", email);
|
|
5788
5812
|
setFirstRunOnboardingCookie(event);
|
|
5789
5813
|
return { ok: true };
|
|
5790
5814
|
}
|
|
@@ -323,6 +323,8 @@ export interface BuilderProjectResult {
|
|
|
323
323
|
}
|
|
324
324
|
export declare function isBuilderAccountProvisioningEnabled(): boolean;
|
|
325
325
|
export declare function provisionBuilderAccount(input: {
|
|
326
|
+
/** Version 3 is rejected by older servers rather than connecting an existing account. */
|
|
327
|
+
newAccountOnly?: boolean;
|
|
326
328
|
email: string;
|
|
327
329
|
name?: string;
|
|
328
330
|
agentNativeApp?: string;
|
|
@@ -1880,9 +1880,11 @@ export async function provisionBuilderAccount(input) {
|
|
|
1880
1880
|
const name = input.name?.trim().slice(0, 120) || email.slice(0, email.indexOf("@"));
|
|
1881
1881
|
const agentNativeApp = cleanTrackingParam(input.agentNativeApp);
|
|
1882
1882
|
const agentNativeTemplate = cleanTrackingParam(input.agentNativeTemplate);
|
|
1883
|
-
const version =
|
|
1884
|
-
? "agent-native-account-
|
|
1885
|
-
:
|
|
1883
|
+
const version = input.newAccountOnly
|
|
1884
|
+
? "agent-native-account-v3"
|
|
1885
|
+
: agentNativeApp || agentNativeTemplate
|
|
1886
|
+
? "agent-native-account-v2"
|
|
1887
|
+
: "agent-native-account-v1";
|
|
1886
1888
|
const timestamp = String(Date.now());
|
|
1887
1889
|
const requestId = randomBytes(32).toString("base64url");
|
|
1888
1890
|
const signaturePayload = [
|
|
@@ -1891,9 +1893,10 @@ export async function provisionBuilderAccount(input) {
|
|
|
1891
1893
|
requestId,
|
|
1892
1894
|
email,
|
|
1893
1895
|
name,
|
|
1894
|
-
...(version
|
|
1896
|
+
...(version !== "agent-native-account-v1"
|
|
1895
1897
|
? [agentNativeApp ?? "", agentNativeTemplate ?? ""]
|
|
1896
1898
|
: []),
|
|
1899
|
+
...(input.newAccountOnly ? ["new-account-only"] : []),
|
|
1897
1900
|
].join("\n");
|
|
1898
1901
|
const signature = createHmac("sha256", builderAccountProvisioningSecret())
|
|
1899
1902
|
.update(signaturePayload)
|
|
@@ -1910,6 +1913,7 @@ export async function provisionBuilderAccount(input) {
|
|
|
1910
1913
|
body: JSON.stringify({
|
|
1911
1914
|
email,
|
|
1912
1915
|
name,
|
|
1916
|
+
...(input.newAccountOnly ? { newAccountOnly: true } : {}),
|
|
1913
1917
|
...(agentNativeApp ? { agentNativeApp } : {}),
|
|
1914
1918
|
...(agentNativeTemplate ? { agentNativeTemplate } : {}),
|
|
1915
1919
|
}),
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { type H3Event } from "h3";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import type { AuthSession } from "./auth.js";
|
|
4
|
+
export declare const BUILDER_SIGNUP_EXPERIMENT = "design_builder_signup_v1";
|
|
5
|
+
export declare const BUILDER_SIGNUP_POLICY = "builder-signup-2026-11-06";
|
|
6
|
+
export declare const BUILDER_SIGNUP_COOKIE = "an_builder_signup";
|
|
7
|
+
declare const assignmentSchema: z.ZodObject<{
|
|
8
|
+
id: z.ZodString;
|
|
9
|
+
variant: z.ZodEnum<{
|
|
10
|
+
automatic: "automatic";
|
|
11
|
+
control: "control";
|
|
12
|
+
}>;
|
|
13
|
+
issuedAt: z.ZodNumber;
|
|
14
|
+
acceptedAt: z.ZodOptional<z.ZodNumber>;
|
|
15
|
+
attemptId: z.ZodOptional<z.ZodString>;
|
|
16
|
+
method: z.ZodOptional<z.ZodEnum<{
|
|
17
|
+
google: "google";
|
|
18
|
+
"magic-link": "magic-link";
|
|
19
|
+
password: "password";
|
|
20
|
+
}>>;
|
|
21
|
+
email: z.ZodOptional<z.ZodString>;
|
|
22
|
+
policy: z.ZodLiteral<"builder-signup-2026-11-06">;
|
|
23
|
+
}, z.core.$strip>;
|
|
24
|
+
type Assignment = z.infer<typeof assignmentSchema>;
|
|
25
|
+
export declare function encodeBuilderSignupAssignment(assignment: Assignment): string;
|
|
26
|
+
export declare function decodeBuilderSignupAssignment(value: string | undefined): Assignment | null;
|
|
27
|
+
export declare function isBuilderSignupExperimentEnabled(): boolean;
|
|
28
|
+
export declare function bindBuilderSignupAttempt(event: H3Event, attemptId: unknown, method: "password" | "magic-link" | "google", email: string): Promise<boolean>;
|
|
29
|
+
export declare function getBuilderSignupConnectError(userId: string | undefined): Promise<{
|
|
30
|
+
code: "account_exists";
|
|
31
|
+
message: string;
|
|
32
|
+
at: number;
|
|
33
|
+
} | undefined>;
|
|
34
|
+
export declare function createBuilderSignupExperimentHandler(dependencies: {
|
|
35
|
+
getSession: (event: H3Event) => Promise<AuthSession | null>;
|
|
36
|
+
sameOrigin: (event: H3Event) => boolean;
|
|
37
|
+
activate: (event: H3Event, session: AuthSession) => Promise<{
|
|
38
|
+
ok: boolean;
|
|
39
|
+
code?: string;
|
|
40
|
+
message?: string;
|
|
41
|
+
}>;
|
|
42
|
+
}): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
|
|
43
|
+
status: "unavailable";
|
|
44
|
+
code: string;
|
|
45
|
+
} | {
|
|
46
|
+
status: "disabled";
|
|
47
|
+
} | {
|
|
48
|
+
id: string;
|
|
49
|
+
variant: "automatic" | "control";
|
|
50
|
+
issuedAt: number;
|
|
51
|
+
acceptedAt?: number | undefined;
|
|
52
|
+
attemptId?: string | undefined;
|
|
53
|
+
method?: "google" | "magic-link" | "password" | undefined;
|
|
54
|
+
email?: string | undefined;
|
|
55
|
+
policy: "builder-signup-2026-11-06";
|
|
56
|
+
status: "assigned";
|
|
57
|
+
} | {
|
|
58
|
+
status: "not_required";
|
|
59
|
+
} | {
|
|
60
|
+
status: "accepted";
|
|
61
|
+
} | {
|
|
62
|
+
status: "connected" | "fallback";
|
|
63
|
+
code?: string | undefined;
|
|
64
|
+
} | {
|
|
65
|
+
status: "pending";
|
|
66
|
+
}>>;
|
|
67
|
+
export {};
|