@agent-native/toolkit 0.200.0 → 0.200.1-nightly-20261002213029

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 (133) hide show
  1. package/dist/app/chat/AgentKitAssistantChat.js +2 -0
  2. package/dist/app/chat/AgentKitAssistantChat.js.map +1 -1
  3. package/dist/app/chat/AgentPanel.d.ts.map +1 -1
  4. package/dist/app/chat/AgentPanel.js +12 -99
  5. package/dist/app/chat/AgentPanel.js.map +1 -1
  6. package/dist/app/chat/ConnectBuilderCard.js +2 -2
  7. package/dist/app/chat/ConnectBuilderCard.js.map +1 -1
  8. package/dist/app/i18n/catalogs/ar-SA.d.ts.map +1 -1
  9. package/dist/app/i18n/catalogs/ar-SA.js +36 -26
  10. package/dist/app/i18n/catalogs/ar-SA.js.map +1 -1
  11. package/dist/app/i18n/catalogs/de-DE.d.ts.map +1 -1
  12. package/dist/app/i18n/catalogs/de-DE.js +36 -26
  13. package/dist/app/i18n/catalogs/de-DE.js.map +1 -1
  14. package/dist/app/i18n/catalogs/en-US.d.ts +36 -26
  15. package/dist/app/i18n/catalogs/en-US.d.ts.map +1 -1
  16. package/dist/app/i18n/catalogs/en-US.js +36 -26
  17. package/dist/app/i18n/catalogs/en-US.js.map +1 -1
  18. package/dist/app/i18n/catalogs/es-ES.d.ts.map +1 -1
  19. package/dist/app/i18n/catalogs/es-ES.js +36 -26
  20. package/dist/app/i18n/catalogs/es-ES.js.map +1 -1
  21. package/dist/app/i18n/catalogs/fr-FR.d.ts.map +1 -1
  22. package/dist/app/i18n/catalogs/fr-FR.js +36 -26
  23. package/dist/app/i18n/catalogs/fr-FR.js.map +1 -1
  24. package/dist/app/i18n/catalogs/hi-IN.d.ts.map +1 -1
  25. package/dist/app/i18n/catalogs/hi-IN.js +36 -26
  26. package/dist/app/i18n/catalogs/hi-IN.js.map +1 -1
  27. package/dist/app/i18n/catalogs/ja-JP.d.ts.map +1 -1
  28. package/dist/app/i18n/catalogs/ja-JP.js +36 -26
  29. package/dist/app/i18n/catalogs/ja-JP.js.map +1 -1
  30. package/dist/app/i18n/catalogs/ko-KR.d.ts.map +1 -1
  31. package/dist/app/i18n/catalogs/ko-KR.js +36 -26
  32. package/dist/app/i18n/catalogs/ko-KR.js.map +1 -1
  33. package/dist/app/i18n/catalogs/pt-BR.d.ts.map +1 -1
  34. package/dist/app/i18n/catalogs/pt-BR.js +36 -26
  35. package/dist/app/i18n/catalogs/pt-BR.js.map +1 -1
  36. package/dist/app/i18n/catalogs/zh-CN.d.ts.map +1 -1
  37. package/dist/app/i18n/catalogs/zh-CN.js +36 -26
  38. package/dist/app/i18n/catalogs/zh-CN.js.map +1 -1
  39. package/dist/app/i18n/catalogs/zh-TW.d.ts.map +1 -1
  40. package/dist/app/i18n/catalogs/zh-TW.js +36 -26
  41. package/dist/app/i18n/catalogs/zh-TW.js.map +1 -1
  42. package/dist/app/onboarding/FirstRunOnboarding.d.ts.map +1 -1
  43. package/dist/app/onboarding/FirstRunOnboarding.js +3 -5
  44. package/dist/app/onboarding/FirstRunOnboarding.js.map +1 -1
  45. package/dist/app/onboarding/NewWorkspaceAppFlow.d.ts.map +1 -1
  46. package/dist/app/onboarding/NewWorkspaceAppFlow.js +4 -2
  47. package/dist/app/onboarding/NewWorkspaceAppFlow.js.map +1 -1
  48. package/dist/app/onboarding/OnboardingPanel.d.ts.map +1 -1
  49. package/dist/app/onboarding/OnboardingPanel.js +3 -1
  50. package/dist/app/onboarding/OnboardingPanel.js.map +1 -1
  51. package/dist/app/settings/BuilderConnectPopover.d.ts +1 -0
  52. package/dist/app/settings/BuilderConnectPopover.d.ts.map +1 -1
  53. package/dist/app/settings/BuilderConnectPopover.js +11 -4
  54. package/dist/app/settings/BuilderConnectPopover.js.map +1 -1
  55. package/dist/app/settings/SettingsPanel.d.ts.map +1 -1
  56. package/dist/app/settings/SettingsPanel.js +16 -8
  57. package/dist/app/settings/SettingsPanel.js.map +1 -1
  58. package/dist/app/settings/VoiceTranscriptionSection.d.ts.map +1 -1
  59. package/dist/app/settings/VoiceTranscriptionSection.js +7 -6
  60. package/dist/app/settings/VoiceTranscriptionSection.js.map +1 -1
  61. package/dist/app/settings/infra/InfrastructureSettingsPage.js +2 -2
  62. package/dist/app/settings/infra/InfrastructureSettingsPage.js.map +1 -1
  63. package/dist/app/settings/model/ModelSettingsPage.js +4 -2
  64. package/dist/app/settings/model/ModelSettingsPage.js.map +1 -1
  65. package/dist/app/settings/useBuilderStatus.d.ts +1 -0
  66. package/dist/app/settings/useBuilderStatus.d.ts.map +1 -1
  67. package/dist/app/settings/useBuilderStatus.js +43 -29
  68. package/dist/app/settings/useBuilderStatus.js.map +1 -1
  69. package/dist/app/setup-connections/SetupConnectionsPage.d.ts.map +1 -1
  70. package/dist/app/setup-connections/SetupConnectionsPage.js +4 -2
  71. package/dist/app/setup-connections/SetupConnectionsPage.js.map +1 -1
  72. package/dist/app/setup-connections/useBuilderConnectCardController.d.ts +1 -1
  73. package/dist/app/setup-connections/useBuilderConnectCardController.d.ts.map +1 -1
  74. package/dist/app/setup-connections/useBuilderConnectCardController.js +7 -6
  75. package/dist/app/setup-connections/useBuilderConnectCardController.js.map +1 -1
  76. package/dist/app/transcription/BuilderTranscriptionCta.d.ts.map +1 -1
  77. package/dist/app/transcription/BuilderTranscriptionCta.js +3 -1
  78. package/dist/app/transcription/BuilderTranscriptionCta.js.map +1 -1
  79. package/dist/composer/MessageQueueDrawer.d.ts +1 -1
  80. package/dist/composer/MessageQueueDrawer.d.ts.map +1 -1
  81. package/dist/composer/MessageQueueDrawer.js +10 -1
  82. package/dist/composer/MessageQueueDrawer.js.map +1 -1
  83. package/dist/composer/PromptComposer.d.ts +1 -1
  84. package/dist/composer/TiptapComposer.d.ts +1 -1
  85. package/dist/composer/TiptapComposer.js +4 -4
  86. package/dist/composer/TiptapComposer.js.map +1 -1
  87. package/dist/composer/useRealtimeVoiceMode.js +2 -2
  88. package/dist/composer/useRealtimeVoiceMode.js.map +1 -1
  89. package/package.json +4 -4
  90. package/src/app/chat/AgentKitAssistantChat.spec.tsx +30 -5
  91. package/src/app/chat/AgentKitAssistantChat.tsx +1 -0
  92. package/src/app/chat/AgentPanel.tsx +33 -112
  93. package/src/app/chat/ConnectBuilderCard.tsx +2 -2
  94. package/src/app/chat/chat/run-recovery.spec.tsx +8 -8
  95. package/src/app/i18n/catalogs/ar-SA.ts +46 -26
  96. package/src/app/i18n/catalogs/de-DE.ts +47 -26
  97. package/src/app/i18n/catalogs/en-US.ts +47 -26
  98. package/src/app/i18n/catalogs/es-ES.ts +47 -26
  99. package/src/app/i18n/catalogs/fr-FR.ts +48 -26
  100. package/src/app/i18n/catalogs/hi-IN.ts +47 -26
  101. package/src/app/i18n/catalogs/ja-JP.ts +47 -26
  102. package/src/app/i18n/catalogs/ko-KR.ts +47 -26
  103. package/src/app/i18n/catalogs/pt-BR.ts +48 -26
  104. package/src/app/i18n/catalogs/zh-CN.ts +47 -26
  105. package/src/app/i18n/catalogs/zh-TW.ts +47 -26
  106. package/src/app/integrations/BuilderIntegrationPage.spec.tsx +11 -7
  107. package/src/app/onboarding/FirstRunOnboarding.spec.tsx +24 -12
  108. package/src/app/onboarding/FirstRunOnboarding.tsx +14 -16
  109. package/src/app/onboarding/NewWorkspaceAppFlow.spec.ts +23 -7
  110. package/src/app/onboarding/NewWorkspaceAppFlow.tsx +4 -2
  111. package/src/app/onboarding/OnboardingPanel.tsx +4 -8
  112. package/src/app/settings/BuilderConnectPopover.spec.tsx +41 -1
  113. package/src/app/settings/BuilderConnectPopover.tsx +21 -4
  114. package/src/app/settings/SettingsPanel.connections.spec.tsx +2 -2
  115. package/src/app/settings/SettingsPanel.tsx +16 -8
  116. package/src/app/settings/VoiceTranscriptionSection.tsx +8 -7
  117. package/src/app/settings/infra/InfrastructureSettingsPage.spec.tsx +4 -4
  118. package/src/app/settings/infra/InfrastructureSettingsPage.tsx +5 -2
  119. package/src/app/settings/model/ModelSettingsPage.spec.tsx +7 -5
  120. package/src/app/settings/model/ModelSettingsPage.tsx +4 -2
  121. package/src/app/settings/useBuilderStatus.spec.tsx +82 -52
  122. package/src/app/settings/useBuilderStatus.ts +44 -54
  123. package/src/app/setup-connections/BuilderConnectCard.spec.tsx +11 -11
  124. package/src/app/setup-connections/SetupConnectionsPage.tsx +4 -2
  125. package/src/app/setup-connections/useBuilderConnectCardController.spec.tsx +19 -6
  126. package/src/app/setup-connections/useBuilderConnectCardController.ts +10 -9
  127. package/src/app/transcription/BuilderTranscriptionCta.tsx +4 -2
  128. package/src/composer/MessageQueueDrawer.spec.tsx +108 -0
  129. package/src/composer/MessageQueueDrawer.tsx +22 -2
  130. package/src/composer/PromptComposer.tsx +1 -1
  131. package/src/composer/RealtimeVoiceMode.spec.tsx +4 -4
  132. package/src/composer/TiptapComposer.tsx +5 -5
  133. package/src/composer/useRealtimeVoiceMode.tsx +2 -2
@@ -1,9 +1,11 @@
1
- import { openMcpAppHostLink } from "@agent-native/core/client/mcp-app-host";
2
1
  // @vitest-environment happy-dom
2
+ import { AgentNativeI18nProvider } from "@agent-native/core/client/i18n";
3
+ import { openMcpAppHostLink } from "@agent-native/core/client/mcp-app-host";
3
4
  import React, { act } from "react";
4
5
  import { createRoot, type Root } from "react-dom/client";
5
6
  import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
6
7
 
8
+ import { createToolkitI18nCatalog } from "../i18n.js";
7
9
  import { BuilderConnectPopover } from "./BuilderConnectPopover.js";
8
10
  import {
9
11
  isBuilderConnectComplete,
@@ -13,6 +15,8 @@ import {
13
15
  type BuilderConnectionScope,
14
16
  } from "./useBuilderStatus.js";
15
17
 
18
+ const toolkitI18nCatalog = createToolkitI18nCatalog({ messages: {} });
19
+
16
20
  vi.mock("@agent-native/core/client/mcp-app-host", () => ({
17
21
  openMcpAppHostLink: vi.fn(() => false),
18
22
  }));
@@ -43,7 +47,7 @@ function setEmbeddedWindow(embedded: boolean) {
43
47
  });
44
48
  }
45
49
 
46
- function BuilderConnectProbe({
50
+ function BuilderConnectProbeContent({
47
51
  enabled = true,
48
52
  popupUrl,
49
53
  provisionAccount = false,
@@ -103,7 +107,20 @@ function BuilderConnectProbe({
103
107
  );
104
108
  }
105
109
 
106
- function BuilderConnectPopoverProbe() {
110
+ function BuilderConnectProbe(
111
+ props: React.ComponentProps<typeof BuilderConnectProbeContent>,
112
+ ) {
113
+ return (
114
+ <AgentNativeI18nProvider
115
+ catalog={toolkitI18nCatalog}
116
+ persistPreference={false}
117
+ >
118
+ <BuilderConnectProbeContent {...props} />
119
+ </AgentNativeI18nProvider>
120
+ );
121
+ }
122
+
123
+ function BuilderConnectPopoverProbeContent() {
107
124
  const flow = useBuilderConnectFlow();
108
125
  return (
109
126
  <BuilderConnectPopover flow={flow}>
@@ -112,6 +129,17 @@ function BuilderConnectPopoverProbe() {
112
129
  );
113
130
  }
114
131
 
132
+ function BuilderConnectPopoverProbe() {
133
+ return (
134
+ <AgentNativeI18nProvider
135
+ catalog={toolkitI18nCatalog}
136
+ persistPreference={false}
137
+ >
138
+ <BuilderConnectPopoverProbeContent />
139
+ </AgentNativeI18nProvider>
140
+ );
141
+ }
142
+
115
143
  function BuilderStatusProbe() {
116
144
  const { status, loading, stale, error } = useBuilderStatus();
117
145
  return (
@@ -816,7 +844,7 @@ describe("useBuilderConnectFlow", () => {
816
844
  expect(activationAttempts).toBe(1);
817
845
  expect(container.textContent).toContain("configured idle resolved");
818
846
  expect(container.textContent).not.toContain(
819
- "Couldn't start Builder connect.",
847
+ "Couldn't start Builder.io setup.",
820
848
  );
821
849
  expect(onConnected).toHaveBeenCalled();
822
850
  expect(openSpy).not.toHaveBeenCalled();
@@ -852,7 +880,7 @@ describe("useBuilderConnectFlow", () => {
852
880
 
853
881
  expect(container.textContent).toContain("configured idle");
854
882
  expect(container.textContent).toContain(
855
- "Couldn't start Builder connect. Refresh this page and try again.",
883
+ "Couldn't start Builder.io setup. Refresh this page and try again.",
856
884
  );
857
885
  expect(onConnected).not.toHaveBeenCalled();
858
886
  });
@@ -868,7 +896,7 @@ describe("useBuilderConnectFlow", () => {
868
896
 
869
897
  expect(container.textContent).toContain("not-configured idle");
870
898
  expect(container.textContent).toContain(
871
- "Couldn't start Builder connect. Refresh this page and try again.",
899
+ "Couldn't start Builder.io setup. Refresh this page and try again.",
872
900
  );
873
901
  });
874
902
 
@@ -918,7 +946,7 @@ describe("useBuilderConnectFlow", () => {
918
946
  expect(posts).toHaveLength(2);
919
947
  expect(container.textContent).toContain("not-configured idle");
920
948
  expect(container.textContent).toContain(
921
- "Couldn't start Builder connect. Refresh this page and try again.",
949
+ "Couldn't start Builder.io setup. Refresh this page and try again.",
922
950
  );
923
951
  });
924
952
 
@@ -1001,7 +1029,7 @@ describe("useBuilderConnectFlow", () => {
1001
1029
 
1002
1030
  expect(container.textContent).toContain("not-configured idle");
1003
1031
  expect(container.textContent).toContain(
1004
- "Couldn't start Builder connect. Refresh this page and try again.",
1032
+ "Couldn't start Builder.io setup. Refresh this page and try again.",
1005
1033
  );
1006
1034
  expect(onConnected).not.toHaveBeenCalled();
1007
1035
  expect(openSpy).not.toHaveBeenCalled();
@@ -1063,33 +1091,41 @@ describe("useBuilderConnectFlow", () => {
1063
1091
  });
1064
1092
  });
1065
1093
 
1066
- it("uses the click-time provisioning capability instead of a stale closure", async () => {
1067
- setUserAgent("Mozilla/5.0 Chrome/140.0");
1068
- const popup = createPopupStub();
1069
- openSpy.mockReturnValue(popup);
1094
+ it("refreshes stale provisioning capability and never opens OAuth to create", async () => {
1070
1095
  vi.mocked(fetch).mockReset();
1071
- vi.mocked(fetch)
1072
- .mockResolvedValueOnce(
1073
- jsonResponse({
1096
+ let statusReads = 0;
1097
+ let activationPosts = 0;
1098
+ vi.mocked(fetch).mockImplementation(async (input) => {
1099
+ const url = new URL(String(input));
1100
+ if (url.pathname === "/_agent-native/builder/provision") {
1101
+ activationPosts += 1;
1102
+ return jsonResponse({ ok: true, scope: "personal" });
1103
+ }
1104
+ statusReads += 1;
1105
+ if (statusReads === 1) {
1106
+ return jsonResponse({
1074
1107
  configured: false,
1075
1108
  agentNativeProvisioningEnabled: false,
1076
1109
  envManaged: false,
1077
1110
  builderEnabled: true,
1078
1111
  orgName: null,
1079
1112
  connectUrl: signedConnectUrl,
1080
- }),
1081
- )
1082
- .mockResolvedValueOnce(
1083
- jsonResponse({
1084
- configured: false,
1085
- agentNativeProvisioningEnabled: true,
1086
- agentNativeProvisioningToken: provisioningToken,
1087
- envManaged: false,
1088
- builderEnabled: true,
1089
- orgName: null,
1090
- connectUrl: signedConnectUrl,
1091
- }),
1113
+ });
1114
+ }
1115
+ return jsonResponse(
1116
+ activationPosts
1117
+ ? connectedBuilderStatus
1118
+ : {
1119
+ configured: false,
1120
+ agentNativeProvisioningEnabled: true,
1121
+ agentNativeProvisioningToken: provisioningToken,
1122
+ envManaged: false,
1123
+ builderEnabled: true,
1124
+ orgName: null,
1125
+ connectUrl: signedConnectUrl,
1126
+ },
1092
1127
  );
1128
+ });
1093
1129
 
1094
1130
  await act(async () => {
1095
1131
  root.render(<BuilderConnectProbe provisionAccount />);
@@ -1105,19 +1141,12 @@ describe("useBuilderConnectFlow", () => {
1105
1141
  await Promise.resolve();
1106
1142
  });
1107
1143
 
1108
- expect(withoutConnectAttempt(popup.location.href)).toBe(
1109
- expectedProvisionedConnectUrl(signedConnectUrl),
1110
- );
1111
- expect(
1112
- new URL(popup.location.href).searchParams.get("_an_connect_attempt"),
1113
- ).toMatch(/^[0-9a-f-]{36}$/);
1144
+ expect(activationPosts).toBe(1);
1145
+ expect(openSpy).not.toHaveBeenCalled();
1146
+ expect(container.textContent).toContain("configured idle resolved");
1114
1147
  });
1115
1148
 
1116
- it("keeps account provisioning dormant when the server does not advertise it", async () => {
1117
- setUserAgent("Mozilla/5.0 Chrome/140.0");
1118
- const popup = createPopupStub();
1119
- openSpy.mockReturnValue(popup);
1120
-
1149
+ it("does not open OAuth when one-click provisioning is unavailable", async () => {
1121
1150
  await act(async () => {
1122
1151
  root.render(<BuilderConnectProbe provisionAccount />);
1123
1152
  await Promise.resolve();
@@ -1132,8 +1161,9 @@ describe("useBuilderConnectFlow", () => {
1132
1161
  await Promise.resolve();
1133
1162
  });
1134
1163
 
1135
- expect(withoutConnectAttempt(popup.location.href)).toBe(
1136
- expectedConnectUrl(signedConnectUrl),
1164
+ expect(openSpy).not.toHaveBeenCalled();
1165
+ expect(container.textContent).toContain(
1166
+ "Couldn't start Builder.io setup. Refresh this page and try again.",
1137
1167
  );
1138
1168
  });
1139
1169
 
@@ -1286,7 +1316,7 @@ describe("useBuilderConnectFlow", () => {
1286
1316
  expectedConnectUrl(signedConnectUrl),
1287
1317
  );
1288
1318
  expect(container.textContent).not.toContain(
1289
- "Couldn't start Builder connect",
1319
+ "Couldn't start Builder.io setup",
1290
1320
  );
1291
1321
  });
1292
1322
 
@@ -1807,7 +1837,7 @@ describe("useBuilderConnectFlow", () => {
1807
1837
  expectedConnectUrl(signedConnectUrl),
1808
1838
  );
1809
1839
  expect(container.textContent).not.toContain(
1810
- "Couldn't start Builder connect",
1840
+ "Couldn't start Builder.io setup",
1811
1841
  );
1812
1842
 
1813
1843
  resolveInitialFetch(jsonResponse({ configured: false }));
@@ -1969,7 +1999,7 @@ describe("useBuilderConnectFlow", () => {
1969
1999
 
1970
2000
  expect(container.textContent).toContain("not-configured connecting");
1971
2001
  expect(container.textContent).not.toContain(
1972
- "Couldn't start Builder connect",
2002
+ "Couldn't start Builder.io setup",
1973
2003
  );
1974
2004
  });
1975
2005
 
@@ -2055,7 +2085,7 @@ describe("useBuilderConnectFlow", () => {
2055
2085
 
2056
2086
  expect(container.textContent).toContain("configured idle resolved");
2057
2087
  expect(container.textContent).not.toContain(
2058
- "Couldn't start Builder connect",
2088
+ "Couldn't start Builder.io setup",
2059
2089
  );
2060
2090
  });
2061
2091
 
@@ -2110,7 +2140,7 @@ describe("useBuilderConnectFlow", () => {
2110
2140
 
2111
2141
  expect(container.textContent).toContain("not-configured connecting");
2112
2142
  expect(container.textContent).not.toContain(
2113
- "Couldn't start Builder connect",
2143
+ "Couldn't start Builder.io setup",
2114
2144
  );
2115
2145
 
2116
2146
  await act(async () => {
@@ -2272,7 +2302,7 @@ describe("useBuilderConnectFlow", () => {
2272
2302
 
2273
2303
  expect(container.textContent).toContain("not-configured idle");
2274
2304
  expect(container.textContent).toContain(
2275
- "Didn't finish connecting to Builder.io",
2305
+ "Builder.io setup didn't finish. Try again, or use your own keys.",
2276
2306
  );
2277
2307
 
2278
2308
  const button = container.querySelector("button");
@@ -2339,7 +2369,7 @@ describe("useBuilderConnectFlow", () => {
2339
2369
 
2340
2370
  expect(container.textContent).toContain("not-configured idle");
2341
2371
  expect(container.textContent).toContain(
2342
- "Didn't finish connecting to Builder.io",
2372
+ "Builder.io setup didn't finish. Try again, or use your own keys.",
2343
2373
  );
2344
2374
  });
2345
2375
 
@@ -2416,7 +2446,7 @@ describe("useBuilderConnectFlow", () => {
2416
2446
 
2417
2447
  expect(container.textContent).toContain("configured idle resolved");
2418
2448
  expect(container.textContent).not.toContain(
2419
- "Didn't finish connecting to Builder.io",
2449
+ "Builder.io setup didn't finish. Try again, or use your own keys.",
2420
2450
  );
2421
2451
  });
2422
2452
 
@@ -2488,7 +2518,7 @@ describe("useBuilderConnectFlow", () => {
2488
2518
 
2489
2519
  expect(container.textContent).toContain("not-configured idle");
2490
2520
  expect(container.textContent).toContain(
2491
- "Didn't finish connecting to Builder.io",
2521
+ "Builder.io setup didn't finish. Try again, or use your own keys.",
2492
2522
  );
2493
2523
  });
2494
2524
 
@@ -2592,7 +2622,7 @@ describe("useBuilderConnectFlow", () => {
2592
2622
 
2593
2623
  expect(container.textContent).toContain("not-configured idle");
2594
2624
  expect(container.textContent).toContain(
2595
- "Didn't finish connecting to Builder.io",
2625
+ "Builder.io setup didn't finish. Try again, or use your own keys.",
2596
2626
  );
2597
2627
  });
2598
2628
 
@@ -2716,7 +2746,7 @@ describe("useBuilderConnectFlow", () => {
2716
2746
 
2717
2747
  expect(container.textContent).toContain("not-configured idle");
2718
2748
  expect(container.textContent).toContain(
2719
- "Didn't finish connecting to Builder.io",
2749
+ "Builder.io setup didn't finish. Try again, or use your own keys.",
2720
2750
  );
2721
2751
  });
2722
2752
 
@@ -2802,7 +2832,7 @@ describe("useBuilderConnectFlow", () => {
2802
2832
  });
2803
2833
  expect(container.textContent).toContain("not-configured idle");
2804
2834
  expect(container.textContent).toContain(
2805
- "Didn't finish connecting to Builder.io",
2835
+ "Builder.io setup didn't finish. Try again, or use your own keys.",
2806
2836
  );
2807
2837
  releaseStalledStatus?.();
2808
2838
  });
@@ -3,6 +3,7 @@ import { agentNativePath } from "@agent-native/core/client/api-path";
3
3
  import { getCallbackOrigin } from "@agent-native/core/client/frame";
4
4
  import { scheduleAfterPaint } from "@agent-native/core/client/hooks";
5
5
  import { usePollLoop } from "@agent-native/core/client/hooks";
6
+ import { useT } from "@agent-native/core/client/i18n";
6
7
  import { openMcpAppHostLink } from "@agent-native/core/client/mcp-app-host";
7
8
  import { oauthPopupWaitingUrl } from "@agent-native/core/client/oauth-popup";
8
9
  import { applyBuilderUtmTrackingParams } from "@agent-native/core/shared/builder-link-tracking";
@@ -216,6 +217,7 @@ export interface BuilderConnectStartOptions {
216
217
 
217
218
  export interface BuilderConnectFlow {
218
219
  configured: boolean;
220
+ provisionAccount?: boolean;
219
221
  statusResolved: boolean;
220
222
  statusReadSettledCount: number;
221
223
  envManaged: boolean;
@@ -253,14 +255,9 @@ const POPUP_LOAD_TIMEOUT_MS = 20_000;
253
255
  const STATUS_FETCH_ABORT_MS = 10_000;
254
256
  const BUILDER_STATUS_UNAVAILABLE_MESSAGE =
255
257
  "Couldn't reach Builder to check your account. Retrying.";
256
- const BUILDER_CONNECT_START_FAILED_MESSAGE =
257
- "Couldn't start Builder connect. Refresh this page and try again.";
258
258
  const CALLBACK_SUCCESS_STATUS_RETRY_MS = 500;
259
259
  const CALLBACK_SUCCESS_STATUS_RETRIES = 10;
260
260
  const BUILDER_CONNECT_PARAM = "_an_connect";
261
- const BUILDER_CONNECT_MODE_PARAM = "_an_mode";
262
- const BUILDER_AGENT_NATIVE_PROVISION_MODE = "agent-native";
263
- const BUILDER_PROVISIONING_TOKEN_PARAM = "_an_provision";
264
261
  const BUILDER_CONNECT_ATTEMPT_PARAM = "_an_connect_attempt";
265
262
  const BUILDER_SIGNUP_SOURCE_PARAM = "signupSource";
266
263
  const BUILDER_AGENT_NATIVE_FLOW_PARAM = "agentNativeFlow";
@@ -778,6 +775,7 @@ export function isBuilderConnectComplete(
778
775
  export function useBuilderConnectFlow(
779
776
  opts: BuilderConnectFlowOptions = {},
780
777
  ): BuilderConnectFlow {
778
+ const t = useT();
781
779
  const {
782
780
  enabled = true,
783
781
  popupUrl,
@@ -1164,7 +1162,7 @@ export function useBuilderConnectFlow(
1164
1162
  ? statusConnectUrl
1165
1163
  : null;
1166
1164
 
1167
- if (provisionAccountForStart && agentNativeProvisioningEnabled) {
1165
+ if (provisionAccountForStart) {
1168
1166
  const trackedFlow =
1169
1167
  cleanTrackingParam(clickTrackingFlow) ??
1170
1168
  inferBuilderConnectTrackingFlow(clickTrackingSource);
@@ -1201,29 +1199,39 @@ export function useBuilderConnectFlow(
1201
1199
  const freshProvisioningCredentials = async () => {
1202
1200
  // coercion-ok: no fresh token is sent as none and refused as provision_token_invalid
1203
1201
  const status = await fetchStatus();
1202
+ if (!status?.agentNativeProvisioningEnabled) return null;
1204
1203
  const freshUrl = status?.connectUrl ?? null;
1205
- return {
1206
- provisioningToken: status?.agentNativeProvisioningToken ?? null,
1207
- connectToken: freshUrl
1208
- ? new URL(freshUrl, origin).searchParams.get(
1209
- BUILDER_CONNECT_PARAM,
1210
- )
1211
- : null,
1212
- };
1204
+ const freshConnectToken = freshUrl
1205
+ ? new URL(freshUrl, origin).searchParams.get(BUILDER_CONNECT_PARAM)
1206
+ : null;
1207
+ return status.agentNativeProvisioningToken && freshConnectToken
1208
+ ? {
1209
+ provisioningToken: status.agentNativeProvisioningToken,
1210
+ connectToken: freshConnectToken,
1211
+ }
1212
+ : null;
1213
1213
  };
1214
1214
  void (async () => {
1215
1215
  // The provisioning token outlives the signed connect URL by a
1216
1216
  // minute, so cached credentials count only when both are usable.
1217
1217
  const cachedCredentials =
1218
- agentNativeProvisioningToken && connectToken
1218
+ agentNativeProvisioningEnabled &&
1219
+ agentNativeProvisioningToken &&
1220
+ connectToken
1219
1221
  ? {
1220
1222
  provisioningToken: agentNativeProvisioningToken,
1221
1223
  connectToken,
1222
1224
  }
1223
1225
  : null;
1224
- let result = await activate(
1225
- cachedCredentials ?? (await freshProvisioningCredentials()),
1226
- );
1226
+ const credentials =
1227
+ cachedCredentials ?? (await freshProvisioningCredentials());
1228
+ if (!credentials) {
1229
+ connectStartedAtRef.current = null;
1230
+ setConnecting(false);
1231
+ setError(t("agentChat.settingsShell.builder.setupStartFailed"));
1232
+ return;
1233
+ }
1234
+ let result = await activate(credentials);
1227
1235
  if (
1228
1236
  !result.ok &&
1229
1237
  cachedCredentials &&
@@ -1231,7 +1239,14 @@ export function useBuilderConnectFlow(
1231
1239
  result.code === "cross_origin") &&
1232
1240
  isCurrentAttempt()
1233
1241
  ) {
1234
- result = await activate(await freshProvisioningCredentials());
1242
+ const freshCredentials = await freshProvisioningCredentials();
1243
+ result = freshCredentials
1244
+ ? await activate(freshCredentials)
1245
+ : {
1246
+ ok: false,
1247
+ code: "provisioning_unavailable",
1248
+ message: null,
1249
+ };
1235
1250
  }
1236
1251
  if (!isCurrentAttempt()) {
1237
1252
  notifyAgentEngineConfiguredChanged("builder-connect");
@@ -1273,7 +1288,7 @@ export function useBuilderConnectFlow(
1273
1288
  setError(
1274
1289
  result.message && result.code !== "provision_token_invalid"
1275
1290
  ? result.message
1276
- : BUILDER_CONNECT_START_FAILED_MESSAGE,
1291
+ : t("agentChat.settingsShell.builder.setupStartFailed"),
1277
1292
  );
1278
1293
  })();
1279
1294
  return;
@@ -1289,11 +1304,7 @@ export function useBuilderConnectFlow(
1289
1304
  agentNativePath("/_agent-native/builder/connect"),
1290
1305
  origin,
1291
1306
  ).href;
1292
- const withProvisionMode = (
1293
- url: string,
1294
- provisioningEnabled = agentNativeProvisioningEnabled,
1295
- provisioningToken = agentNativeProvisioningToken,
1296
- ): string => {
1307
+ const withConnectAttempt = (url: string): string => {
1297
1308
  const connectUrl = new URL(url, origin);
1298
1309
  connectUrl.searchParams.set(
1299
1310
  BUILDER_CONNECT_ATTEMPT_PARAM,
@@ -1305,24 +1316,9 @@ export function useBuilderConnectFlow(
1305
1316
  scopeForStart,
1306
1317
  );
1307
1318
  }
1308
- if (
1309
- !provisionAccountForStart ||
1310
- !provisioningEnabled ||
1311
- !provisioningToken
1312
- ) {
1313
- return connectUrl.toString();
1314
- }
1315
- connectUrl.searchParams.set(
1316
- BUILDER_CONNECT_MODE_PARAM,
1317
- BUILDER_AGENT_NATIVE_PROVISION_MODE,
1318
- );
1319
- connectUrl.searchParams.set(
1320
- BUILDER_PROVISIONING_TOKEN_PARAM,
1321
- provisioningToken,
1322
- );
1323
1319
  return connectUrl.toString();
1324
1320
  };
1325
- const directUrl = withProvisionMode(
1321
+ const directUrl = withConnectAttempt(
1326
1322
  cachedFreshUrl ?? signedPropUrl ?? fallbackUrl,
1327
1323
  );
1328
1324
 
@@ -1388,10 +1384,8 @@ export function useBuilderConnectFlow(
1388
1384
  setOrgName(s.orgName ?? null);
1389
1385
  }
1390
1386
 
1391
- const hostUrl = withProvisionMode(
1387
+ const hostUrl = withConnectAttempt(
1392
1388
  s?.connectUrl ?? cachedFreshUrl ?? directUrl,
1393
- !!s?.agentNativeProvisioningEnabled,
1394
- s?.agentNativeProvisioningToken ?? null,
1395
1389
  );
1396
1390
  const trackedHostUrl = withBuilderConnectTrackingParams(hostUrl, {
1397
1391
  source: clickTrackingSource,
@@ -1402,9 +1396,7 @@ export function useBuilderConnectFlow(
1402
1396
  if (!mountedRef.current || openedByHost) return;
1403
1397
  connectStartedAtRef.current = null;
1404
1398
  setConnecting(false);
1405
- setError(
1406
- "Couldn't open Builder from this chat host. Open this app in a browser tab and try Connect Builder (free tier available) again.",
1407
- );
1399
+ setError(t("agentChat.settingsShell.builder.setupHostFailed"));
1408
1400
  })();
1409
1401
  } else {
1410
1402
  const isCurrentConnectAttempt = () =>
@@ -1455,10 +1447,8 @@ export function useBuilderConnectFlow(
1455
1447
  setOrgName(s.orgName ?? null);
1456
1448
  }
1457
1449
 
1458
- const freshUrl = withProvisionMode(
1450
+ const freshUrl = withConnectAttempt(
1459
1451
  s?.connectUrl ?? cachedFreshUrl ?? signedPropUrl ?? fallbackUrl,
1460
- !!s?.agentNativeProvisioningEnabled,
1461
- s?.agentNativeProvisioningToken ?? null,
1462
1452
  );
1463
1453
  if (!freshUrl) {
1464
1454
  try {
@@ -1468,7 +1458,7 @@ export function useBuilderConnectFlow(
1468
1458
  }
1469
1459
  connectStartedAtRef.current = null;
1470
1460
  setConnecting(false);
1471
- setError(BUILDER_CONNECT_START_FAILED_MESSAGE);
1461
+ setError(t("agentChat.settingsShell.builder.setupStartFailed"));
1472
1462
  return;
1473
1463
  }
1474
1464
  const popupLoaded = await popupReady;
@@ -1512,6 +1502,7 @@ export function useBuilderConnectFlow(
1512
1502
  },
1513
1503
  [
1514
1504
  enabled,
1505
+ t,
1515
1506
  fetchStatus,
1516
1507
  agentNativeProvisioningEnabled,
1517
1508
  agentNativeProvisioningToken,
@@ -1608,9 +1599,7 @@ export function useBuilderConnectFlow(
1608
1599
  cleanTrackingParam(flow) ??
1609
1600
  inferBuilderConnectTrackingFlow(source),
1610
1601
  });
1611
- setError(
1612
- "Didn't finish connecting to Builder.io. Try again, or use your own keys.",
1613
- );
1602
+ setError(t("agentChat.settingsShell.builder.setupFailed"));
1614
1603
  }
1615
1604
  } else if (Date.now() - started > POLL_TIMEOUT_MS) {
1616
1605
  connectStartedAtRef.current = null;
@@ -1878,6 +1867,7 @@ export function useBuilderConnectFlow(
1878
1867
 
1879
1868
  return {
1880
1869
  configured,
1870
+ provisionAccount,
1881
1871
  codeChangeConfigured,
1882
1872
  statusResolved,
1883
1873
  statusReadSettledCount,
@@ -60,16 +60,16 @@ describe("BuilderConnectCard", () => {
60
60
  beforeEach(() => {
61
61
  vi.stubGlobal("IS_REACT_ACT_ENVIRONMENT", true);
62
62
  viewModel = {
63
- title: "Builder connect",
63
+ title: "Use Builder.io",
64
64
  description:
65
- "Connect Builder.io for managed model access, browser automation, and workspace identity. Free tier available.",
65
+ "Model access, browser automation, file storage, and workspace identity. Free tier available.",
66
66
  status: { kind: "ready", label: "Ready to connect" },
67
67
  configured: false,
68
68
  pending: false,
69
69
  error: null,
70
70
  orgName: null,
71
71
  action: {
72
- label: "Connect Builder.io",
72
+ label: "Use Builder.io",
73
73
  pending: false,
74
74
  disabled: false,
75
75
  onPress: vi.fn(),
@@ -111,7 +111,7 @@ describe("BuilderConnectCard", () => {
111
111
  expect(mocks.useBuilderConnectCardController).toHaveBeenCalledWith(
112
112
  expect.objectContaining({ trackingSource: "settings" }),
113
113
  );
114
- expect(container.textContent).toContain("Builder connect");
114
+ expect(container.textContent).toContain("Use Builder.io");
115
115
  expect(container.textContent).toContain("Ready to connect");
116
116
  expect(container.querySelector("[data-semantic-action]")).not.toBeNull();
117
117
  expect(container.querySelector("[data-semantic-status]")).not.toBeNull();
@@ -257,7 +257,7 @@ describe("BuilderConnectCard", () => {
257
257
  ).click();
258
258
  });
259
259
  const reconnect = Array.from(document.body.querySelectorAll("button")).find(
260
- (button) => button.textContent?.includes("Reconnect Builder.io"),
260
+ (button) => button.textContent?.includes("Use Builder.io"),
261
261
  );
262
262
  act(() => reconnect?.click());
263
263
 
@@ -312,7 +312,7 @@ describe("BuilderConnectCard", () => {
312
312
  ).click();
313
313
  });
314
314
 
315
- expect(document.body.textContent).toContain("Reconnect Builder.io");
315
+ expect(document.body.textContent).toContain("Use Builder.io");
316
316
  expect(document.body.textContent).not.toContain("Disconnect");
317
317
  });
318
318
 
@@ -403,7 +403,7 @@ describe("BuilderConnectCard", () => {
403
403
  renderManaged(flow);
404
404
 
405
405
  openMenu();
406
- act(() => menuButton("Reconnect Builder.io")?.click());
406
+ act(() => menuButton("Use Builder.io")?.click());
407
407
  expect(flow.start).toHaveBeenCalledWith(
408
408
  expect.objectContaining({ scope: "org", provisionAccount: false }),
409
409
  );
@@ -442,7 +442,7 @@ describe("BuilderConnectCard", () => {
442
442
  renderManaged(flow, "personal");
443
443
 
444
444
  openMenu();
445
- act(() => menuButton("Reconnect Builder.io")?.click());
445
+ act(() => menuButton("Use Builder.io")?.click());
446
446
  expect(flow.start).toHaveBeenCalledWith(
447
447
  expect.objectContaining({ scope: "personal" }),
448
448
  );
@@ -482,7 +482,7 @@ describe("BuilderConnectCard", () => {
482
482
  renderManaged(flow);
483
483
 
484
484
  openMenu();
485
- act(() => menuButton("Reconnect Builder.io")?.click());
485
+ act(() => menuButton("Use Builder.io")?.click());
486
486
  expect(flow.start).toHaveBeenCalledWith(
487
487
  expect.objectContaining({ scope: "org", provisionAccount: false }),
488
488
  );
@@ -517,7 +517,7 @@ describe("BuilderConnectCard", () => {
517
517
  renderManaged(flow);
518
518
 
519
519
  openMenu();
520
- act(() => menuButton("Reconnect Builder.io")?.click());
520
+ act(() => menuButton("Use Builder.io")?.click());
521
521
  expect(flow.start).toHaveBeenCalledWith(
522
522
  expect.not.objectContaining({ scope: expect.anything() }),
523
523
  );
@@ -547,7 +547,7 @@ describe("BuilderConnectCard", () => {
547
547
  ),
548
548
  );
549
549
 
550
- expect(container.textContent).toContain("Builder connect");
550
+ expect(container.textContent).toContain("Use Builder.io");
551
551
  expect(container.textContent).toContain("Ready to connect");
552
552
  });
553
553
  });
@@ -1,3 +1,4 @@
1
+ import { useT } from "@agent-native/core/client/i18n";
1
2
  import { cn } from "@agent-native/toolkit/utils";
2
3
  import type { ReactNode } from "react";
3
4
 
@@ -23,7 +24,7 @@ export interface SetupConnectionsPageProps {
23
24
 
24
25
  export function SetupConnectionsPage({
25
26
  title = "Setup & connections",
26
- description = "Manage setup status, Builder connect, app secrets, and workspace connections from one standard surface.",
27
+ description,
27
28
  onboardingTitle = "Setup checklist",
28
29
  focusSecretKey,
29
30
  providerReadiness,
@@ -35,6 +36,7 @@ export function SetupConnectionsPage({
35
36
  showIntegrations = false,
36
37
  className,
37
38
  }: SetupConnectionsPageProps) {
39
+ const t = useT();
38
40
  return (
39
41
  <div className={cn("min-h-full bg-background p-4 sm:p-6", className)}>
40
42
  <div className="mx-auto flex w-full max-w-6xl flex-col gap-5">
@@ -43,7 +45,7 @@ export function SetupConnectionsPage({
43
45
  {title}
44
46
  </h1>
45
47
  <p className="max-w-3xl text-sm leading-6 text-muted-foreground">
46
- {description}
48
+ {description ?? t("agentChat.setup.connectionsDescription")}
47
49
  </p>
48
50
  </header>
49
51