@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.
Files changed (115) hide show
  1. package/dist/agent/actions/get-agentkit-capabilities.d.ts +12 -1
  2. package/dist/agent/actions/get-agentkit-capabilities.js +13 -5
  3. package/dist/agent/production-agent.js +14 -4
  4. package/dist/agentkit/capabilities.d.ts +4 -2
  5. package/dist/agentkit/capabilities.js +71 -18
  6. package/dist/app-config/experience-profiles.d.ts +4 -0
  7. package/dist/app-config/experience-profiles.js +7 -0
  8. package/dist/app-config/onboarding.d.ts +2 -0
  9. package/dist/app-config/onboarding.js +5 -0
  10. package/dist/app-config/schema.d.ts +5 -0
  11. package/dist/app-config/schema.js +2 -0
  12. package/dist/application-state/handlers.d.ts +2 -2
  13. package/dist/client/agent-chat.d.ts +3 -1
  14. package/dist/client/agent-chat.js +8 -0
  15. package/dist/client/agentkit-chat/transport.d.ts +2 -1
  16. package/dist/client/agentkit-chat/transport.js +2 -1
  17. package/dist/client/auth/builder-signup.d.ts +14 -0
  18. package/dist/client/auth/builder-signup.js +75 -0
  19. package/dist/client/chat/agentkit-agent-native.d.ts +4 -0
  20. package/dist/client/chat/agentkit-agent-native.js +25 -0
  21. package/dist/client/chat/composer-draft.d.ts +1 -7
  22. package/dist/client/chat/composer-draft.js +5 -1
  23. package/dist/client/chat/native-uploads.d.ts +11 -0
  24. package/dist/client/chat/native-uploads.js +97 -0
  25. package/dist/client/experience-profiles.d.ts +182 -0
  26. package/dist/client/experience-profiles.js +19 -0
  27. package/dist/client/uploads/index.d.ts +1 -1
  28. package/dist/client/uploads/index.js +1 -1
  29. package/dist/client/use-action.js +3 -0
  30. package/dist/collab/routes.d.ts +1 -1
  31. package/dist/experience-profiles/index.d.ts +13 -0
  32. package/dist/experience-profiles/index.js +10 -0
  33. package/dist/experience-profiles/server.d.ts +38 -0
  34. package/dist/experience-profiles/server.js +76 -0
  35. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  36. package/dist/framework-package-versions.json +11 -11
  37. package/dist/localization/workspace-integration-messages.d.ts +11 -0
  38. package/dist/localization/workspace-integration-messages.js +132 -0
  39. package/dist/mcp/screen-memory-stdio.d.ts +3 -3
  40. package/dist/notifications/routes.d.ts +3 -3
  41. package/dist/org/index.d.ts +1 -1
  42. package/dist/provider-api/actions/custom-provider-registration.d.ts +5 -5
  43. package/dist/provider-api/actions/provider-api.d.ts +3 -3
  44. package/dist/provider-api/actions/provider-api.js +2 -0
  45. package/dist/provider-api/index.d.ts +7 -1
  46. package/dist/provider-api/index.js +42 -2
  47. package/dist/scripts/resources/read.d.ts +6 -1
  48. package/dist/scripts/resources/read.js +85 -8
  49. package/dist/secrets/routes.d.ts +2 -2
  50. package/dist/server/agent-chat/script-entries.js +27 -6
  51. package/dist/server/agent-chat-plugin.js +102 -33
  52. package/dist/server/agent-engine-api-key-route.d.ts +4 -4
  53. package/dist/server/agent-engine-ollama-models-route.d.ts +1 -1
  54. package/dist/server/auth.js +25 -1
  55. package/dist/server/better-auth-instance.d.ts +1 -0
  56. package/dist/server/builder-browser.d.ts +2 -0
  57. package/dist/server/builder-browser.js +8 -4
  58. package/dist/server/builder-signup-experiment.d.ts +67 -0
  59. package/dist/server/builder-signup-experiment.js +345 -0
  60. package/dist/server/core-routes-plugin.d.ts +2 -0
  61. package/dist/server/core-routes-plugin.js +77 -25
  62. package/dist/server/first-touch-route.d.ts +1 -1
  63. package/dist/server/google-oauth.d.ts +2 -0
  64. package/dist/server/google-oauth.js +5 -0
  65. package/dist/server/index.d.ts +1 -1
  66. package/dist/server/index.js +1 -1
  67. package/dist/server/transcribe-voice.d.ts +1 -1
  68. package/dist/shared/agent-chat-references.d.ts +2 -0
  69. package/dist/shared/agent-chat-references.js +8 -0
  70. package/dist/shared/auth-copy.d.ts +1 -0
  71. package/dist/shared/auth-copy.js +11 -0
  72. package/dist/shared/index.d.ts +1 -0
  73. package/dist/shared/index.js +1 -0
  74. package/dist/templates/builder-code-starter/server/lib/composer-reference-messages.ts.patch +44 -0
  75. package/dist/templates/builder-code-starter/server/plugins/agent-chat.ts.patch +10 -1
  76. package/dist/templates/chat/app/components/ChatComposerContext.tsx +31 -0
  77. package/dist/templates/chat/app/components/chat/ChatRouteContent.tsx +3 -0
  78. package/dist/templates/chat/app/components/home/HomePage.tsx +4 -2
  79. package/dist/templates/chat/app/components/layout/AgentInspector.tsx +2 -0
  80. package/dist/templates/chat/app/i18n/ar-SA.ts +7 -0
  81. package/dist/templates/chat/app/i18n/de-DE.ts +8 -0
  82. package/dist/templates/chat/app/i18n/en-US.ts +8 -0
  83. package/dist/templates/chat/app/i18n/es-ES.ts +8 -0
  84. package/dist/templates/chat/app/i18n/fr-FR.ts +8 -0
  85. package/dist/templates/chat/app/i18n/hi-IN.ts +7 -0
  86. package/dist/templates/chat/app/i18n/ja-JP.ts +8 -0
  87. package/dist/templates/chat/app/i18n/ko-KR.ts +8 -0
  88. package/dist/templates/chat/app/i18n/pt-BR.ts +8 -0
  89. package/dist/templates/chat/app/i18n/zh-CN.ts +7 -0
  90. package/dist/templates/chat/app/i18n/zh-TW.ts +7 -0
  91. package/dist/templates/chat/server/lib/composer-reference-messages.ts +34 -0
  92. package/dist/templates/chat/server/lib/composer-references.ts +60 -0
  93. package/dist/templates/chat/server/plugins/agent-chat.ts +13 -0
  94. package/docs/content/components.mdx +7 -2
  95. package/package.json +9 -4
  96. package/src/templates/builder-code-starter/server/lib/composer-reference-messages.ts.patch +44 -0
  97. package/src/templates/builder-code-starter/server/plugins/agent-chat.ts.patch +10 -1
  98. package/src/templates/chat/app/components/ChatComposerContext.tsx +31 -0
  99. package/src/templates/chat/app/components/chat/ChatRouteContent.tsx +3 -0
  100. package/src/templates/chat/app/components/home/HomePage.tsx +4 -2
  101. package/src/templates/chat/app/components/layout/AgentInspector.tsx +2 -0
  102. package/src/templates/chat/app/i18n/ar-SA.ts +7 -0
  103. package/src/templates/chat/app/i18n/de-DE.ts +8 -0
  104. package/src/templates/chat/app/i18n/en-US.ts +8 -0
  105. package/src/templates/chat/app/i18n/es-ES.ts +8 -0
  106. package/src/templates/chat/app/i18n/fr-FR.ts +8 -0
  107. package/src/templates/chat/app/i18n/hi-IN.ts +7 -0
  108. package/src/templates/chat/app/i18n/ja-JP.ts +8 -0
  109. package/src/templates/chat/app/i18n/ko-KR.ts +8 -0
  110. package/src/templates/chat/app/i18n/pt-BR.ts +8 -0
  111. package/src/templates/chat/app/i18n/zh-CN.ts +7 -0
  112. package/src/templates/chat/app/i18n/zh-TW.ts +7 -0
  113. package/src/templates/chat/server/lib/composer-reference-messages.ts +34 -0
  114. package/src/templates/chat/server/lib/composer-references.ts +60 -0
  115. 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(() => undefined);
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
- const inheritedPersonalScope = mentionsOrgId === undefined &&
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
- sources.push((async () => {
5300
- try {
5301
- const owner = await getOwnerFromEvent(event);
5302
- const { listAccessibleCustomAgents } = await import("../resources/agents.js");
5303
- const agents = await listAccessibleCustomAgents(owner);
5304
- flush(agents.map((agent) => ({
5305
- id: `custom-agent:${agent.id}`,
5306
- label: agent.name,
5307
- description: agent.description || agent.path,
5308
- icon: "agent",
5309
- source: "agent:custom",
5310
- refType: "custom-agent",
5311
- refPath: agent.path,
5312
- refId: agent.id,
5313
- section: "Agents",
5314
- })));
5315
- }
5316
- catch (e) {
5317
- console.error("[agent-native] Custom agent discovery failed:", e);
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;
@@ -1,6 +1,6 @@
1
1
  export declare function createAgentEngineOllamaModelsHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
2
- ok?: undefined;
3
2
  error: string;
3
+ ok?: undefined;
4
4
  models?: undefined;
5
5
  } | {
6
6
  error?: undefined;
@@ -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
  }
@@ -212,6 +212,7 @@ export interface BetterAuthInternalAdapter {
212
212
  image?: string | null;
213
213
  emailVerified?: boolean;
214
214
  onboardingRole?: string | null;
215
+ createdAt?: Date | string;
215
216
  };
216
217
  accounts: Array<{
217
218
  id: string;
@@ -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 = agentNativeApp || agentNativeTemplate
1884
- ? "agent-native-account-v2"
1885
- : "agent-native-account-v1";
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 === "agent-native-account-v2"
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 {};