@agent-native/core 0.75.5 → 0.76.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 (427) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +7 -0
  3. package/corpus/core/docs/AGENTS.md +1 -0
  4. package/corpus/core/docs/content/client.md +15 -0
  5. package/corpus/core/docs/content/internationalization.md +145 -0
  6. package/corpus/core/docs/content/locales/ar-SA/internationalization.md +102 -0
  7. package/corpus/core/docs/content/locales/de-DE/internationalization.md +102 -0
  8. package/corpus/core/docs/content/locales/es-ES/internationalization.md +102 -0
  9. package/corpus/core/docs/content/locales/fr-FR/internationalization.md +102 -0
  10. package/corpus/core/docs/content/locales/hi-IN/internationalization.md +102 -0
  11. package/corpus/core/docs/content/locales/ja-JP/internationalization.md +114 -0
  12. package/corpus/core/docs/content/locales/ko-KR/internationalization.md +102 -0
  13. package/corpus/core/docs/content/locales/pt-BR/internationalization.md +102 -0
  14. package/corpus/core/docs/content/locales/zh-CN/internationalization.md +102 -0
  15. package/corpus/core/docs/content/skills-guide.md +19 -18
  16. package/corpus/core/package.json +7 -1
  17. package/corpus/core/src/client/CommandMenu.tsx +16 -0
  18. package/corpus/core/src/client/app-providers.tsx +26 -1
  19. package/corpus/core/src/client/i18n.tsx +605 -0
  20. package/corpus/core/src/client/index.ts +28 -0
  21. package/corpus/core/src/index.browser.ts +25 -0
  22. package/corpus/core/src/localization/actions/get-localization-preference.ts +23 -0
  23. package/corpus/core/src/localization/actions/set-localization-preference.ts +30 -0
  24. package/corpus/core/src/localization/index.ts +2 -0
  25. package/corpus/core/src/localization/server.ts +131 -0
  26. package/corpus/core/src/localization/shared.ts +163 -0
  27. package/corpus/core/src/server/action-discovery.ts +8 -0
  28. package/corpus/core/src/server/index.ts +8 -0
  29. package/corpus/core/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +5 -0
  30. package/corpus/core/src/templates/default/.agents/skills/internationalization/SKILL.md +77 -0
  31. package/corpus/core/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +6 -0
  32. package/corpus/core/src/templates/default/AGENTS.md +16 -15
  33. package/corpus/core/src/templates/default/app/i18n/en-US.ts +29 -0
  34. package/corpus/core/src/templates/default/app/i18n/index.ts +13 -0
  35. package/corpus/core/src/templates/default/app/root.tsx +20 -1
  36. package/corpus/core/src/templates/default/app/routes/_index.tsx +24 -9
  37. package/corpus/core/src/templates/default/app/routes/settings.tsx +67 -0
  38. package/corpus/core/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +5 -0
  39. package/corpus/core/src/templates/workspace-core/.agents/skills/internationalization/SKILL.md +77 -0
  40. package/corpus/core/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +6 -0
  41. package/corpus/core/src/vite/action-types-plugin.ts +10 -0
  42. package/corpus/templates/analytics/.agents/skills/self-modifying-code/SKILL.md +6 -0
  43. package/corpus/templates/analytics/app/components/layout/Header.tsx +18 -15
  44. package/corpus/templates/analytics/app/components/layout/Layout.tsx +7 -5
  45. package/corpus/templates/analytics/app/components/layout/MobileNav.tsx +9 -3
  46. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +5 -3
  47. package/corpus/templates/analytics/app/i18n/ar-SA.ts +3 -0
  48. package/corpus/templates/analytics/app/i18n/de-DE.ts +3 -0
  49. package/corpus/templates/analytics/app/i18n/en-US.ts +3 -0
  50. package/corpus/templates/analytics/app/i18n/es-ES.ts +3 -0
  51. package/corpus/templates/analytics/app/i18n/fr-FR.ts +3 -0
  52. package/corpus/templates/analytics/app/i18n/hi-IN.ts +3 -0
  53. package/corpus/templates/analytics/app/i18n/index.ts +31 -0
  54. package/corpus/templates/analytics/app/i18n/ja-JP.ts +3 -0
  55. package/corpus/templates/analytics/app/i18n/ko-KR.ts +3 -0
  56. package/corpus/templates/analytics/app/i18n/pt-BR.ts +3 -0
  57. package/corpus/templates/analytics/app/i18n/zh-CN.ts +3 -0
  58. package/corpus/templates/analytics/app/i18n-data.ts +433 -0
  59. package/corpus/templates/analytics/app/pages/Settings.tsx +50 -16
  60. package/corpus/templates/analytics/app/root.tsx +14 -1
  61. package/corpus/templates/analytics/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
  62. package/corpus/templates/analytics/changelog/2026-06-24-settings-now-link-directly-to-agent-settings-for-model-api-k.md +6 -0
  63. package/corpus/templates/assets/.agents/skills/self-modifying-code/SKILL.md +6 -0
  64. package/corpus/templates/assets/app/components/layout/Header.tsx +17 -8
  65. package/corpus/templates/assets/app/components/layout/Layout.tsx +10 -6
  66. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +40 -23
  67. package/corpus/templates/assets/app/i18n/ar-SA.ts +3 -0
  68. package/corpus/templates/assets/app/i18n/de-DE.ts +3 -0
  69. package/corpus/templates/assets/app/i18n/en-US.ts +3 -0
  70. package/corpus/templates/assets/app/i18n/es-ES.ts +3 -0
  71. package/corpus/templates/assets/app/i18n/fr-FR.ts +3 -0
  72. package/corpus/templates/assets/app/i18n/hi-IN.ts +3 -0
  73. package/corpus/templates/assets/app/i18n/index.ts +31 -0
  74. package/corpus/templates/assets/app/i18n/ja-JP.ts +3 -0
  75. package/corpus/templates/assets/app/i18n/ko-KR.ts +3 -0
  76. package/corpus/templates/assets/app/i18n/pt-BR.ts +3 -0
  77. package/corpus/templates/assets/app/i18n/zh-CN.ts +3 -0
  78. package/corpus/templates/assets/app/i18n-data.ts +668 -0
  79. package/corpus/templates/assets/app/root.tsx +40 -15
  80. package/corpus/templates/assets/app/routes/_index.tsx +9 -10
  81. package/corpus/templates/assets/app/routes/settings.tsx +37 -6
  82. package/corpus/templates/assets/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
  83. package/corpus/templates/assets/changelog/2026-06-24-settings-now-link-directly-to-agent-settings-for-model-api-k.md +6 -0
  84. package/corpus/templates/brain/.agents/skills/adding-a-feature/SKILL.md +5 -0
  85. package/corpus/templates/brain/.agents/skills/self-modifying-code/SKILL.md +6 -0
  86. package/corpus/templates/brain/app/components/layout/Layout.tsx +12 -8
  87. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +23 -12
  88. package/corpus/templates/brain/app/i18n/ar-SA.ts +3 -0
  89. package/corpus/templates/brain/app/i18n/de-DE.ts +3 -0
  90. package/corpus/templates/brain/app/i18n/en-US.ts +3 -0
  91. package/corpus/templates/brain/app/i18n/es-ES.ts +3 -0
  92. package/corpus/templates/brain/app/i18n/fr-FR.ts +3 -0
  93. package/corpus/templates/brain/app/i18n/hi-IN.ts +3 -0
  94. package/corpus/templates/brain/app/i18n/index.ts +31 -0
  95. package/corpus/templates/brain/app/i18n/ja-JP.ts +3 -0
  96. package/corpus/templates/brain/app/i18n/ko-KR.ts +3 -0
  97. package/corpus/templates/brain/app/i18n/pt-BR.ts +3 -0
  98. package/corpus/templates/brain/app/i18n/zh-CN.ts +3 -0
  99. package/corpus/templates/brain/app/i18n-data.ts +624 -0
  100. package/corpus/templates/brain/app/root.tsx +27 -12
  101. package/corpus/templates/brain/app/routes/settings.tsx +45 -8
  102. package/corpus/templates/brain/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
  103. package/corpus/templates/brain/changelog/2026-06-24-settings-now-link-directly-to-agent-settings-for-model-api-k.md +6 -0
  104. package/corpus/templates/calendar/.agents/skills/self-modifying-code/SKILL.md +6 -0
  105. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +2 -0
  106. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +16 -9
  107. package/corpus/templates/calendar/app/i18n/ar-SA.ts +57 -0
  108. package/corpus/templates/calendar/app/i18n/de-DE.ts +58 -0
  109. package/corpus/templates/calendar/app/i18n/en-US.ts +57 -0
  110. package/corpus/templates/calendar/app/i18n/es-ES.ts +58 -0
  111. package/corpus/templates/calendar/app/i18n/fr-FR.ts +58 -0
  112. package/corpus/templates/calendar/app/i18n/hi-IN.ts +57 -0
  113. package/corpus/templates/calendar/app/i18n/index.ts +31 -0
  114. package/corpus/templates/calendar/app/i18n/ja-JP.ts +58 -0
  115. package/corpus/templates/calendar/app/i18n/ko-KR.ts +57 -0
  116. package/corpus/templates/calendar/app/i18n/pt-BR.ts +57 -0
  117. package/corpus/templates/calendar/app/i18n/zh-CN.ts +57 -0
  118. package/corpus/templates/calendar/app/i18n-data.ts +516 -0
  119. package/corpus/templates/calendar/app/pages/CalendarView.tsx +2 -0
  120. package/corpus/templates/calendar/app/pages/Settings.tsx +63 -28
  121. package/corpus/templates/calendar/app/root.tsx +78 -7
  122. package/corpus/templates/calendar/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
  123. package/corpus/templates/calendar/changelog/2026-06-24-settings-now-link-directly-to-agent-settings-for-model-api-k.md +6 -0
  124. package/corpus/templates/chat/.agents/skills/adding-a-feature/SKILL.md +5 -0
  125. package/corpus/templates/chat/.agents/skills/self-modifying-code/SKILL.md +6 -0
  126. package/corpus/templates/chat/app/components/layout/Header.tsx +17 -11
  127. package/corpus/templates/chat/app/components/layout/Layout.tsx +12 -8
  128. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +47 -18
  129. package/corpus/templates/chat/app/i18n/ar-SA.ts +62 -0
  130. package/corpus/templates/chat/app/i18n/de-DE.ts +63 -0
  131. package/corpus/templates/chat/app/i18n/en-US.ts +63 -0
  132. package/corpus/templates/chat/app/i18n/es-ES.ts +63 -0
  133. package/corpus/templates/chat/app/i18n/fr-FR.ts +63 -0
  134. package/corpus/templates/chat/app/i18n/hi-IN.ts +63 -0
  135. package/corpus/templates/chat/app/i18n/index.ts +31 -0
  136. package/corpus/templates/chat/app/i18n/ja-JP.ts +63 -0
  137. package/corpus/templates/chat/app/i18n/ko-KR.ts +63 -0
  138. package/corpus/templates/chat/app/i18n/pt-BR.ts +63 -0
  139. package/corpus/templates/chat/app/i18n/zh-CN.ts +61 -0
  140. package/corpus/templates/chat/app/i18n-data.ts +475 -0
  141. package/corpus/templates/chat/app/root.tsx +18 -5
  142. package/corpus/templates/chat/app/routes/_index.tsx +9 -8
  143. package/corpus/templates/chat/app/routes/settings.tsx +86 -0
  144. package/corpus/templates/chat/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
  145. package/corpus/templates/chat/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
  146. package/corpus/templates/clips/.agents/skills/self-modifying-code/SKILL.md +6 -0
  147. package/corpus/templates/clips/app/components/layout/Header.tsx +23 -17
  148. package/corpus/templates/clips/app/components/library/empty-state.tsx +10 -34
  149. package/corpus/templates/clips/app/components/library/library-layout.tsx +45 -34
  150. package/corpus/templates/clips/app/i18n/ar-SA.ts +182 -0
  151. package/corpus/templates/clips/app/i18n/de-DE.ts +184 -0
  152. package/corpus/templates/clips/app/i18n/en-US.ts +179 -0
  153. package/corpus/templates/clips/app/i18n/es-ES.ts +183 -0
  154. package/corpus/templates/clips/app/i18n/fr-FR.ts +184 -0
  155. package/corpus/templates/clips/app/i18n/hi-IN.ts +180 -0
  156. package/corpus/templates/clips/app/i18n/index.ts +41 -0
  157. package/corpus/templates/clips/app/i18n/ja-JP.ts +180 -0
  158. package/corpus/templates/clips/app/i18n/ko-KR.ts +178 -0
  159. package/corpus/templates/clips/app/i18n/pt-BR.ts +183 -0
  160. package/corpus/templates/clips/app/i18n/zh-CN.ts +173 -0
  161. package/corpus/templates/clips/app/root.tsx +104 -10
  162. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +154 -95
  163. package/corpus/templates/clips/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
  164. package/corpus/templates/clips/changelog/2026-06-24-clips-now-includes-a-language-picker-and-simplified-chinese-ui.md +6 -0
  165. package/corpus/templates/clips/changelog/2026-06-24-settings-now-link-directly-to-agent-settings-for-model-api-k.md +6 -0
  166. package/corpus/templates/content/.agents/skills/self-modifying-code/SKILL.md +6 -0
  167. package/corpus/templates/content/app/components/EmptyState.tsx +7 -5
  168. package/corpus/templates/content/app/components/ThemeToggle.tsx +4 -2
  169. package/corpus/templates/content/app/components/layout/Header.tsx +2 -0
  170. package/corpus/templates/content/app/components/layout/Layout.tsx +8 -7
  171. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +41 -1
  172. package/corpus/templates/content/app/i18n/ar-SA.ts +3 -0
  173. package/corpus/templates/content/app/i18n/de-DE.ts +3 -0
  174. package/corpus/templates/content/app/i18n/en-US.ts +3 -0
  175. package/corpus/templates/content/app/i18n/es-ES.ts +3 -0
  176. package/corpus/templates/content/app/i18n/fr-FR.ts +3 -0
  177. package/corpus/templates/content/app/i18n/hi-IN.ts +3 -0
  178. package/corpus/templates/content/app/i18n/index.ts +31 -0
  179. package/corpus/templates/content/app/i18n/ja-JP.ts +3 -0
  180. package/corpus/templates/content/app/i18n/ko-KR.ts +3 -0
  181. package/corpus/templates/content/app/i18n/pt-BR.ts +3 -0
  182. package/corpus/templates/content/app/i18n/zh-CN.ts +3 -0
  183. package/corpus/templates/content/app/i18n-data.ts +490 -0
  184. package/corpus/templates/content/app/root.tsx +110 -23
  185. package/corpus/templates/content/app/routes/_app.settings.tsx +84 -0
  186. package/corpus/templates/content/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
  187. package/corpus/templates/content/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
  188. package/corpus/templates/design/.agents/skills/self-modifying-code/SKILL.md +6 -0
  189. package/corpus/templates/design/app/components/layout/Header.tsx +16 -8
  190. package/corpus/templates/design/app/components/layout/Layout.tsx +8 -6
  191. package/corpus/templates/design/app/components/layout/Sidebar.tsx +25 -9
  192. package/corpus/templates/design/app/i18n/ar-SA.ts +3 -0
  193. package/corpus/templates/design/app/i18n/de-DE.ts +3 -0
  194. package/corpus/templates/design/app/i18n/en-US.ts +3 -0
  195. package/corpus/templates/design/app/i18n/es-ES.ts +3 -0
  196. package/corpus/templates/design/app/i18n/fr-FR.ts +3 -0
  197. package/corpus/templates/design/app/i18n/hi-IN.ts +3 -0
  198. package/corpus/templates/design/app/i18n/index.ts +31 -0
  199. package/corpus/templates/design/app/i18n/ja-JP.ts +3 -0
  200. package/corpus/templates/design/app/i18n/ko-KR.ts +3 -0
  201. package/corpus/templates/design/app/i18n/pt-BR.ts +3 -0
  202. package/corpus/templates/design/app/i18n/zh-CN.ts +3 -0
  203. package/corpus/templates/design/app/i18n-data.ts +350 -0
  204. package/corpus/templates/design/app/root.tsx +40 -15
  205. package/corpus/templates/design/app/routes/settings.tsx +43 -0
  206. package/corpus/templates/design/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
  207. package/corpus/templates/design/changelog/2026-06-24-settings-now-link-directly-to-agent-settings-for-model-api-k.md +6 -0
  208. package/corpus/templates/dispatch/.agents/skills/self-modifying-code/SKILL.md +6 -0
  209. package/corpus/templates/dispatch/app/i18n/ar-SA.ts +3 -0
  210. package/corpus/templates/dispatch/app/i18n/de-DE.ts +3 -0
  211. package/corpus/templates/dispatch/app/i18n/en-US.ts +3 -0
  212. package/corpus/templates/dispatch/app/i18n/es-ES.ts +3 -0
  213. package/corpus/templates/dispatch/app/i18n/fr-FR.ts +3 -0
  214. package/corpus/templates/dispatch/app/i18n/hi-IN.ts +3 -0
  215. package/corpus/templates/dispatch/app/i18n/index.ts +31 -0
  216. package/corpus/templates/dispatch/app/i18n/ja-JP.ts +3 -0
  217. package/corpus/templates/dispatch/app/i18n/ko-KR.ts +3 -0
  218. package/corpus/templates/dispatch/app/i18n/pt-BR.ts +3 -0
  219. package/corpus/templates/dispatch/app/i18n/zh-CN.ts +3 -0
  220. package/corpus/templates/dispatch/app/i18n-data.ts +267 -0
  221. package/corpus/templates/dispatch/app/root.tsx +18 -4
  222. package/corpus/templates/dispatch/app/routes/settings.tsx +86 -0
  223. package/corpus/templates/dispatch/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
  224. package/corpus/templates/dispatch/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
  225. package/corpus/templates/forms/.agents/skills/self-modifying-code/SKILL.md +6 -0
  226. package/corpus/templates/forms/app/components/layout/Header.tsx +16 -9
  227. package/corpus/templates/forms/app/components/layout/Layout.tsx +6 -4
  228. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +34 -17
  229. package/corpus/templates/forms/app/i18n/ar-SA.ts +58 -0
  230. package/corpus/templates/forms/app/i18n/de-DE.ts +59 -0
  231. package/corpus/templates/forms/app/i18n/en-US.ts +59 -0
  232. package/corpus/templates/forms/app/i18n/es-ES.ts +59 -0
  233. package/corpus/templates/forms/app/i18n/fr-FR.ts +59 -0
  234. package/corpus/templates/forms/app/i18n/hi-IN.ts +59 -0
  235. package/corpus/templates/forms/app/i18n/index.ts +31 -0
  236. package/corpus/templates/forms/app/i18n/ja-JP.ts +59 -0
  237. package/corpus/templates/forms/app/i18n/ko-KR.ts +59 -0
  238. package/corpus/templates/forms/app/i18n/pt-BR.ts +59 -0
  239. package/corpus/templates/forms/app/i18n/zh-CN.ts +56 -0
  240. package/corpus/templates/forms/app/root.tsx +65 -16
  241. package/corpus/templates/forms/app/routes/_app.settings.tsx +85 -0
  242. package/corpus/templates/forms/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
  243. package/corpus/templates/forms/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
  244. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +29 -17
  245. package/corpus/templates/macros/app/components/layout/Header.tsx +16 -10
  246. package/corpus/templates/macros/app/i18n/ar-SA.ts +54 -0
  247. package/corpus/templates/macros/app/i18n/de-DE.ts +55 -0
  248. package/corpus/templates/macros/app/i18n/en-US.ts +55 -0
  249. package/corpus/templates/macros/app/i18n/es-ES.ts +55 -0
  250. package/corpus/templates/macros/app/i18n/fr-FR.ts +55 -0
  251. package/corpus/templates/macros/app/i18n/hi-IN.ts +55 -0
  252. package/corpus/templates/macros/app/i18n/index.ts +31 -0
  253. package/corpus/templates/macros/app/i18n/ja-JP.ts +55 -0
  254. package/corpus/templates/macros/app/i18n/ko-KR.ts +55 -0
  255. package/corpus/templates/macros/app/i18n/pt-BR.ts +55 -0
  256. package/corpus/templates/macros/app/i18n/zh-CN.ts +53 -0
  257. package/corpus/templates/macros/app/root.tsx +65 -15
  258. package/corpus/templates/macros/app/routes/settings.tsx +85 -0
  259. package/corpus/templates/macros/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
  260. package/corpus/templates/macros/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
  261. package/corpus/templates/mail/.agents/skills/self-modifying-code/SKILL.md +6 -0
  262. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +9 -4
  263. package/corpus/templates/mail/app/i18n/ar-SA.ts +33 -0
  264. package/corpus/templates/mail/app/i18n/de-DE.ts +33 -0
  265. package/corpus/templates/mail/app/i18n/en-US.ts +32 -0
  266. package/corpus/templates/mail/app/i18n/es-ES.ts +33 -0
  267. package/corpus/templates/mail/app/i18n/fr-FR.ts +33 -0
  268. package/corpus/templates/mail/app/i18n/hi-IN.ts +32 -0
  269. package/corpus/templates/mail/app/i18n/index.ts +31 -0
  270. package/corpus/templates/mail/app/i18n/ja-JP.ts +32 -0
  271. package/corpus/templates/mail/app/i18n/ko-KR.ts +33 -0
  272. package/corpus/templates/mail/app/i18n/pt-BR.ts +34 -0
  273. package/corpus/templates/mail/app/i18n/zh-CN.ts +32 -0
  274. package/corpus/templates/mail/app/pages/SettingsPage.tsx +67 -13
  275. package/corpus/templates/mail/app/root.tsx +20 -0
  276. package/corpus/templates/mail/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
  277. package/corpus/templates/mail/changelog/2026-06-24-settings-now-link-directly-to-agent-settings-for-model-api-k.md +6 -0
  278. package/corpus/templates/plan/.agents/skills/adding-a-feature/SKILL.md +5 -0
  279. package/corpus/templates/plan/.agents/skills/self-modifying-code/SKILL.md +6 -0
  280. package/corpus/templates/plan/app/components/layout/Header.tsx +19 -12
  281. package/corpus/templates/plan/app/components/layout/Layout.tsx +11 -7
  282. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +41 -28
  283. package/corpus/templates/plan/app/i18n/ar-SA.ts +77 -0
  284. package/corpus/templates/plan/app/i18n/de-DE.ts +78 -0
  285. package/corpus/templates/plan/app/i18n/en-US.ts +78 -0
  286. package/corpus/templates/plan/app/i18n/es-ES.ts +78 -0
  287. package/corpus/templates/plan/app/i18n/fr-FR.ts +78 -0
  288. package/corpus/templates/plan/app/i18n/hi-IN.ts +78 -0
  289. package/corpus/templates/plan/app/i18n/index.ts +31 -0
  290. package/corpus/templates/plan/app/i18n/ja-JP.ts +79 -0
  291. package/corpus/templates/plan/app/i18n/ko-KR.ts +77 -0
  292. package/corpus/templates/plan/app/i18n/pt-BR.ts +78 -0
  293. package/corpus/templates/plan/app/i18n/zh-CN.ts +74 -0
  294. package/corpus/templates/plan/app/root.tsx +45 -8
  295. package/corpus/templates/plan/app/routes/settings.tsx +86 -0
  296. package/corpus/templates/plan/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
  297. package/corpus/templates/plan/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
  298. package/corpus/templates/slides/.agents/skills/self-modifying-code/SKILL.md +6 -0
  299. package/corpus/templates/slides/app/components/layout/Header.tsx +23 -11
  300. package/corpus/templates/slides/app/components/layout/Layout.tsx +7 -6
  301. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +23 -11
  302. package/corpus/templates/slides/app/i18n/ar-SA.ts +54 -0
  303. package/corpus/templates/slides/app/i18n/de-DE.ts +56 -0
  304. package/corpus/templates/slides/app/i18n/en-US.ts +55 -0
  305. package/corpus/templates/slides/app/i18n/es-ES.ts +55 -0
  306. package/corpus/templates/slides/app/i18n/fr-FR.ts +55 -0
  307. package/corpus/templates/slides/app/i18n/hi-IN.ts +55 -0
  308. package/corpus/templates/slides/app/i18n/index.ts +31 -0
  309. package/corpus/templates/slides/app/i18n/ja-JP.ts +55 -0
  310. package/corpus/templates/slides/app/i18n/ko-KR.ts +55 -0
  311. package/corpus/templates/slides/app/i18n/pt-BR.ts +55 -0
  312. package/corpus/templates/slides/app/i18n/zh-CN.ts +53 -0
  313. package/corpus/templates/slides/app/root.tsx +50 -8
  314. package/corpus/templates/slides/app/routes/settings.tsx +85 -0
  315. package/corpus/templates/slides/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
  316. package/corpus/templates/slides/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
  317. package/corpus/templates/videos/.agents/skills/self-modifying-code/SKILL.md +6 -0
  318. package/corpus/templates/videos/app/components/NewCompositionPopover.tsx +14 -9
  319. package/corpus/templates/videos/app/components/Sidebar.tsx +16 -9
  320. package/corpus/templates/videos/app/components/StudioHeader.tsx +12 -8
  321. package/corpus/templates/videos/app/components/layout/Header.tsx +21 -15
  322. package/corpus/templates/videos/app/components/layout/Layout.tsx +10 -7
  323. package/corpus/templates/videos/app/components/layout/NavSidebar.tsx +21 -6
  324. package/corpus/templates/videos/app/i18n/ar-SA.ts +73 -0
  325. package/corpus/templates/videos/app/i18n/de-DE.ts +75 -0
  326. package/corpus/templates/videos/app/i18n/en-US.ts +74 -0
  327. package/corpus/templates/videos/app/i18n/es-ES.ts +75 -0
  328. package/corpus/templates/videos/app/i18n/fr-FR.ts +75 -0
  329. package/corpus/templates/videos/app/i18n/hi-IN.ts +74 -0
  330. package/corpus/templates/videos/app/i18n/index.ts +31 -0
  331. package/corpus/templates/videos/app/i18n/ja-JP.ts +74 -0
  332. package/corpus/templates/videos/app/i18n/ko-KR.ts +74 -0
  333. package/corpus/templates/videos/app/i18n/pt-BR.ts +75 -0
  334. package/corpus/templates/videos/app/i18n/zh-CN.ts +72 -0
  335. package/corpus/templates/videos/app/pages/Index.tsx +11 -9
  336. package/corpus/templates/videos/app/root.tsx +45 -7
  337. package/corpus/templates/videos/app/routes/settings.tsx +85 -0
  338. package/corpus/templates/videos/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
  339. package/corpus/templates/videos/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
  340. package/dist/client/CommandMenu.d.ts +3 -0
  341. package/dist/client/CommandMenu.d.ts.map +1 -1
  342. package/dist/client/CommandMenu.js +9 -0
  343. package/dist/client/CommandMenu.js.map +1 -1
  344. package/dist/client/app-providers.d.ts +8 -1
  345. package/dist/client/app-providers.d.ts.map +1 -1
  346. package/dist/client/app-providers.js +7 -5
  347. package/dist/client/app-providers.js.map +1 -1
  348. package/dist/client/i18n.d.ts +54 -0
  349. package/dist/client/i18n.d.ts.map +1 -0
  350. package/dist/client/i18n.js +354 -0
  351. package/dist/client/i18n.js.map +1 -0
  352. package/dist/client/index.d.ts +2 -1
  353. package/dist/client/index.d.ts.map +1 -1
  354. package/dist/client/index.js +2 -1
  355. package/dist/client/index.js.map +1 -1
  356. package/dist/index.browser.d.ts +1 -1
  357. package/dist/index.browser.d.ts.map +1 -1
  358. package/dist/index.browser.js +1 -1
  359. package/dist/index.browser.js.map +1 -1
  360. package/dist/localization/actions/get-localization-preference.d.ts +4 -0
  361. package/dist/localization/actions/get-localization-preference.d.ts.map +1 -0
  362. package/dist/localization/actions/get-localization-preference.js +16 -0
  363. package/dist/localization/actions/get-localization-preference.js.map +1 -0
  364. package/dist/localization/actions/set-localization-preference.d.ts +6 -0
  365. package/dist/localization/actions/set-localization-preference.d.ts.map +1 -0
  366. package/dist/localization/actions/set-localization-preference.js +24 -0
  367. package/dist/localization/actions/set-localization-preference.js.map +1 -0
  368. package/dist/localization/index.d.ts +3 -0
  369. package/dist/localization/index.d.ts.map +1 -0
  370. package/dist/localization/index.js +3 -0
  371. package/dist/localization/index.js.map +1 -0
  372. package/dist/localization/server.d.ts +25 -0
  373. package/dist/localization/server.d.ts.map +1 -0
  374. package/dist/localization/server.js +69 -0
  375. package/dist/localization/server.js.map +1 -0
  376. package/dist/localization/shared.d.ts +25 -0
  377. package/dist/localization/shared.d.ts.map +1 -0
  378. package/dist/localization/shared.js +134 -0
  379. package/dist/localization/shared.js.map +1 -0
  380. package/dist/server/action-discovery.d.ts.map +1 -1
  381. package/dist/server/action-discovery.js +8 -0
  382. package/dist/server/action-discovery.js.map +1 -1
  383. package/dist/server/index.d.ts +1 -0
  384. package/dist/server/index.d.ts.map +1 -1
  385. package/dist/server/index.js +1 -0
  386. package/dist/server/index.js.map +1 -1
  387. package/dist/templates/default/.agents/skills/adding-a-feature/SKILL.md +5 -0
  388. package/dist/templates/default/.agents/skills/internationalization/SKILL.md +77 -0
  389. package/dist/templates/default/.agents/skills/self-modifying-code/SKILL.md +6 -0
  390. package/dist/templates/default/AGENTS.md +16 -15
  391. package/dist/templates/default/app/i18n/en-US.ts +29 -0
  392. package/dist/templates/default/app/i18n/index.ts +13 -0
  393. package/dist/templates/default/app/root.tsx +20 -1
  394. package/dist/templates/default/app/routes/_index.tsx +24 -9
  395. package/dist/templates/default/app/routes/settings.tsx +67 -0
  396. package/dist/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +5 -0
  397. package/dist/templates/workspace-core/.agents/skills/internationalization/SKILL.md +77 -0
  398. package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +6 -0
  399. package/dist/vite/action-types-plugin.d.ts.map +1 -1
  400. package/dist/vite/action-types-plugin.js +8 -0
  401. package/dist/vite/action-types-plugin.js.map +1 -1
  402. package/docs/AGENTS.md +1 -0
  403. package/docs/content/client.md +15 -0
  404. package/docs/content/internationalization.md +145 -0
  405. package/docs/content/locales/ar-SA/internationalization.md +102 -0
  406. package/docs/content/locales/de-DE/internationalization.md +102 -0
  407. package/docs/content/locales/es-ES/internationalization.md +102 -0
  408. package/docs/content/locales/fr-FR/internationalization.md +102 -0
  409. package/docs/content/locales/hi-IN/internationalization.md +102 -0
  410. package/docs/content/locales/ja-JP/internationalization.md +114 -0
  411. package/docs/content/locales/ko-KR/internationalization.md +102 -0
  412. package/docs/content/locales/pt-BR/internationalization.md +102 -0
  413. package/docs/content/locales/zh-CN/internationalization.md +102 -0
  414. package/docs/content/skills-guide.md +19 -18
  415. package/package.json +7 -1
  416. package/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +5 -0
  417. package/src/templates/default/.agents/skills/internationalization/SKILL.md +77 -0
  418. package/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +6 -0
  419. package/src/templates/default/AGENTS.md +16 -15
  420. package/src/templates/default/app/i18n/en-US.ts +29 -0
  421. package/src/templates/default/app/i18n/index.ts +13 -0
  422. package/src/templates/default/app/root.tsx +20 -1
  423. package/src/templates/default/app/routes/_index.tsx +24 -9
  424. package/src/templates/default/app/routes/settings.tsx +67 -0
  425. package/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +5 -0
  426. package/src/templates/workspace-core/.agents/skills/internationalization/SKILL.md +77 -0
  427. package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +6 -0
@@ -5,7 +5,9 @@ import {
5
5
  Scripts,
6
6
  ScrollRestoration,
7
7
  isRouteErrorResponse,
8
+ useLoaderData,
8
9
  useLocation,
10
+ useRouteLoaderData,
9
11
  useRouteError,
10
12
  } from "react-router";
11
13
  import { useCallback, useEffect, useState } from "react";
@@ -21,15 +23,22 @@ import {
21
23
  appPath,
22
24
  CommandMenu,
23
25
  createAgentNativeQueryClient,
26
+ getLocaleInitScript,
24
27
  getThemeInitScript,
28
+ type LocaleCode,
29
+ type LocaleMessages,
30
+ type LocalizationPreference,
25
31
  useCommandMenuShortcut,
32
+ useT,
26
33
  } from "@agent-native/core/client";
34
+ import { resolveLocaleFromRequest } from "@agent-native/core/server";
27
35
  import { useDbSync } from "./hooks/use-db-sync";
28
36
  import { useNavigationState } from "./hooks/use-navigation-state";
29
37
  import changelog from "../CHANGELOG.md?raw";
30
- import type { LinksFunction } from "react-router";
38
+ import type { LinksFunction, LoaderFunctionArgs } from "react-router";
31
39
  import stylesheet from "./global.css?url";
32
40
  import { configureTracking } from "@agent-native/core/client";
41
+ import { i18nCatalog } from "./i18n";
33
42
  configureTracking({
34
43
  getDefaultProps: (_name, properties) => ({
35
44
  ...properties,
@@ -41,9 +50,40 @@ export const links: LinksFunction = () => [
41
50
  { rel: "stylesheet", href: stylesheet },
42
51
  ];
43
52
 
53
+ interface RootLoaderData {
54
+ locale: LocaleCode;
55
+ preference: LocalizationPreference;
56
+ dir: "ltr" | "rtl";
57
+ messages: LocaleMessages;
58
+ }
59
+
60
+ export async function loader({
61
+ request,
62
+ }: LoaderFunctionArgs): Promise<RootLoaderData> {
63
+ const resolved = resolveLocaleFromRequest({ request });
64
+ const messages =
65
+ ((await i18nCatalog.loadMessages?.(resolved.locale)) as
66
+ | LocaleMessages
67
+ | null
68
+ | undefined) ?? i18nCatalog.messages;
69
+ return {
70
+ locale: resolved.locale,
71
+ preference: resolved.preference,
72
+ dir: resolved.dir,
73
+ messages,
74
+ };
75
+ }
76
+
44
77
  // Pass args to match content's 3-way theme-cycle UX (no disableTransitionOnChange).
45
78
  const THEME_INIT_SCRIPT = getThemeInitScript("system", true);
46
79
 
80
+ const DEFAULT_LOADER_DATA: RootLoaderData = {
81
+ locale: "en-US",
82
+ preference: { locale: "system" },
83
+ dir: "ltr",
84
+ messages: i18nCatalog.messages,
85
+ };
86
+
47
87
  const themeOptions = [
48
88
  { value: "system", label: "System", icon: IconDeviceDesktop },
49
89
  { value: "light", label: "Light", icon: IconSun },
@@ -90,8 +130,21 @@ function nextTheme(theme: ThemeOption): ThemeOption {
90
130
  }
91
131
 
92
132
  export function Layout({ children }: { children: React.ReactNode }) {
133
+ const loaderData =
134
+ useRouteLoaderData<typeof loader>("root") ?? DEFAULT_LOADER_DATA;
135
+ const localeInitScript = getLocaleInitScript({
136
+ locale: loaderData.locale,
137
+ preference: loaderData.preference,
138
+ messages: loaderData.messages,
139
+ });
140
+
93
141
  return (
94
- <html lang="en" suppressHydrationWarning>
142
+ <html
143
+ lang={loaderData.locale}
144
+ dir={loaderData.dir}
145
+ data-locale={loaderData.locale}
146
+ suppressHydrationWarning
147
+ >
95
148
  <head>
96
149
  <meta charSet="utf-8" />
97
150
  <meta
@@ -102,6 +155,11 @@ export function Layout({ children }: { children: React.ReactNode }) {
102
155
  suppressHydrationWarning
103
156
  dangerouslySetInnerHTML={{ __html: THEME_INIT_SCRIPT }}
104
157
  />
158
+ <script
159
+ data-agent-native-locale-init
160
+ suppressHydrationWarning
161
+ dangerouslySetInnerHTML={{ __html: localeInitScript }}
162
+ />
105
163
  <link rel="manifest" href={appPath("/manifest.json")} />
106
164
  <meta name="theme-color" content="#10B981" />
107
165
  <meta name="mobile-web-app-capable" content="yes" />
@@ -132,6 +190,7 @@ function AppSetup() {
132
190
 
133
191
  function ThemeToggleItem() {
134
192
  const { theme, setTheme } = useTheme();
193
+ const t = useT();
135
194
  const [selectedTheme, setSelectedTheme] = useState<ThemeOption>("system");
136
195
 
137
196
  useEffect(() => {
@@ -156,9 +215,9 @@ function ThemeToggleItem() {
156
215
  keywords={["theme", "dark", "light", "system", "mode"]}
157
216
  >
158
217
  <ActiveIcon size={16} />
159
- Toggle theme
218
+ {t("root.toggleTheme")}
160
219
  <span className="ml-auto text-xs text-muted-foreground">
161
- {activeOption.label}
220
+ {t(`theme.${activeOption.value}`)}
162
221
  </span>
163
222
  </CommandMenu.Item>
164
223
  );
@@ -166,6 +225,7 @@ function ThemeToggleItem() {
166
225
 
167
226
  function PublicAgentShell({ children }: { children: React.ReactNode }) {
168
227
  const [mounted, setMounted] = useState(false);
228
+ const t = useT();
169
229
 
170
230
  useEffect(() => setMounted(true), []);
171
231
 
@@ -195,11 +255,11 @@ function PublicAgentShell({ children }: { children: React.ReactNode }) {
195
255
  position="right"
196
256
  defaultOpen
197
257
  defaultSidebarWidth={420}
198
- emptyStateText="Ask me anything about this document"
258
+ emptyStateText={t("chat.publicEmptyState")}
199
259
  suggestions={[
200
- "Summarize this document",
201
- "What are the key takeaways?",
202
- "Turn this into an action plan",
260
+ t("chat.publicSuggestionSummary"),
261
+ t("chat.publicSuggestionTakeaways"),
262
+ t("chat.publicSuggestionActionPlan"),
203
263
  ]}
204
264
  >
205
265
  {content}
@@ -207,10 +267,38 @@ function PublicAgentShell({ children }: { children: React.ReactNode }) {
207
267
  );
208
268
  }
209
269
 
270
+ function ContentCommandMenu({
271
+ open,
272
+ onOpenChange,
273
+ }: {
274
+ open: boolean;
275
+ onOpenChange: (open: boolean) => void;
276
+ }) {
277
+ const t = useT();
278
+ return (
279
+ <CommandMenu
280
+ open={open}
281
+ onOpenChange={onOpenChange}
282
+ changelog={changelog}
283
+ changelogKey="content"
284
+ >
285
+ <CommandMenu.Group heading={t("root.commandContent")}>
286
+ <CommandMenu.Item onSelect={() => {}}>
287
+ {t("root.commandSearchDocuments")}
288
+ </CommandMenu.Item>
289
+ </CommandMenu.Group>
290
+ <CommandMenu.Group heading={t("root.commandAppearance")}>
291
+ <ThemeToggleItem />
292
+ </CommandMenu.Group>
293
+ </CommandMenu>
294
+ );
295
+ }
296
+
210
297
  export default function Root() {
211
298
  const [queryClient] = useState(() => createAgentNativeQueryClient());
212
299
  const [cmdkOpen, setCmdkOpen] = useState(false);
213
300
  const location = useLocation();
301
+ const loaderData = useLoaderData<typeof loader>();
214
302
  useCommandMenuShortcut(useCallback(() => setCmdkOpen(true), []));
215
303
 
216
304
  // Public document paths (/p/*) SSR real content without the ClientOnly gate
@@ -231,6 +319,13 @@ export default function Root() {
231
319
  isPublicPath
232
320
  disableThemeTransitions={false}
233
321
  toaster={contentToaster}
322
+ i18n={{
323
+ catalog: i18nCatalog,
324
+ initialLocale: loaderData.locale,
325
+ initialPreference: loaderData.preference,
326
+ initialMessages: loaderData.messages,
327
+ persistPreference: false,
328
+ }}
234
329
  >
235
330
  <Toaster />
236
331
  <PublicAgentShell>
@@ -245,24 +340,16 @@ export default function Root() {
245
340
  queryClient={queryClient}
246
341
  disableThemeTransitions={false}
247
342
  toaster={contentToaster}
343
+ i18n={{
344
+ catalog: i18nCatalog,
345
+ initialLocale: loaderData.locale,
346
+ initialPreference: loaderData.preference,
347
+ initialMessages: loaderData.messages,
348
+ }}
248
349
  >
249
350
  <AppSetup />
250
351
  <Toaster />
251
- <CommandMenu
252
- open={cmdkOpen}
253
- onOpenChange={setCmdkOpen}
254
- changelog={changelog}
255
- changelogKey="content"
256
- >
257
- <CommandMenu.Group heading="Content">
258
- <CommandMenu.Item onSelect={() => {}}>
259
- Search documents
260
- </CommandMenu.Item>
261
- </CommandMenu.Group>
262
- <CommandMenu.Group heading="Appearance">
263
- <ThemeToggleItem />
264
- </CommandMenu.Group>
265
- </CommandMenu>
352
+ <ContentCommandMenu open={cmdkOpen} onOpenChange={setCmdkOpen} />
266
353
  <Outlet />
267
354
  </AppProviders>
268
355
  );
@@ -0,0 +1,84 @@
1
+ import { Link } from "react-router";
2
+ import {
3
+ ChangelogSettingsCard,
4
+ LanguagePicker,
5
+ openAgentSettings,
6
+ useT,
7
+ } from "@agent-native/core/client";
8
+ import { useSetPageTitle } from "@/components/layout/HeaderActions";
9
+ import { Button } from "@/components/ui/button";
10
+ import { Label } from "@/components/ui/label";
11
+ import changelog from "../../CHANGELOG.md?raw";
12
+
13
+ export function meta() {
14
+ return [{ title: "Settings - Content" }];
15
+ }
16
+
17
+ export default function SettingsRoute() {
18
+ const t = useT();
19
+ useSetPageTitle(t("settings.title"));
20
+
21
+ return (
22
+ <div className="flex-1 overflow-auto">
23
+ <main className="mx-auto w-full max-w-3xl space-y-6 px-4 py-6 sm:px-8 sm:py-10">
24
+ <div className="space-y-1">
25
+ <h1 className="text-2xl font-bold tracking-tight">
26
+ {t("settings.title")}
27
+ </h1>
28
+ <p className="text-sm leading-6 text-muted-foreground">
29
+ {t("settings.description")}
30
+ </p>
31
+ </div>
32
+
33
+ <section className="rounded-lg border border-border bg-card p-5">
34
+ <div className="space-y-1">
35
+ <h2 className="text-base font-semibold">
36
+ {t("settings.languageTitle")}
37
+ </h2>
38
+ <p className="text-sm leading-6 text-muted-foreground">
39
+ {t("settings.languageDescription")}
40
+ </p>
41
+ </div>
42
+ <div className="mt-4 max-w-xs space-y-1.5">
43
+ <Label>{t("settings.languageLabel")}</Label>
44
+ <LanguagePicker label={t("settings.languageLabel")} />
45
+ </div>
46
+ </section>
47
+
48
+ <section className="rounded-lg border border-border bg-card p-5">
49
+ <div className="space-y-1">
50
+ <h2 className="text-base font-semibold">
51
+ {t("settings.workspaceTitle")}
52
+ </h2>
53
+ <p className="text-sm leading-6 text-muted-foreground">
54
+ {t("settings.workspaceDescription")}
55
+ </p>
56
+ </div>
57
+ <Button className="mt-4" variant="outline" asChild>
58
+ <Link to="/team">{t("settings.openTeamSettings")}</Link>
59
+ </Button>
60
+ </section>
61
+
62
+ <section className="rounded-lg border border-border bg-card p-5">
63
+ <div className="space-y-1">
64
+ <h2 className="text-base font-semibold">
65
+ {t("settings.agentTitle")}
66
+ </h2>
67
+ <p className="text-sm leading-6 text-muted-foreground">
68
+ {t("settings.agentDescription")}
69
+ </p>
70
+ </div>
71
+ <Button
72
+ className="mt-4"
73
+ variant="outline"
74
+ onClick={() => openAgentSettings()}
75
+ >
76
+ {t("settings.openAgentSettings")}
77
+ </Button>
78
+ </section>
79
+
80
+ <ChangelogSettingsCard markdown={changelog} />
81
+ </main>
82
+ </div>
83
+ );
84
+ }
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-06-24
4
+ ---
5
+
6
+ A new Settings page gives quick access to language, workspace, and agent preferences.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-06-24
4
+ ---
5
+
6
+ Added a language picker and localized app chrome for supported languages.
@@ -66,6 +66,11 @@ el.dataset.selectedId = selectedItem?.id || "";
66
66
 
67
67
  **Use configuration-driven rendering** — Extract visual decisions (colors, layouts, sizes) into JSON config files in `data/`. The agent can modify the config (Tier 1) instead of the component source (Tier 2).
68
68
 
69
+ **Keep localized copy in catalogs** — When editing visible UI copy, labels,
70
+ toasts, empty states, prompts, or formatting, read `internationalization` and
71
+ update `app/i18n/en-US.ts` plus existing locale catalogs instead of leaving new
72
+ inline strings in components.
73
+
69
74
  ## Don't
70
75
 
71
76
  - Don't modify `.env` files or files containing secrets
@@ -80,3 +85,4 @@ el.dataset.selectedId = selectedItem?.id || "";
80
85
  - **actions** — The agent can create or modify actions to add new capabilities
81
86
  - **delegate-to-agent** — Self-modification requests come through the agent chat
82
87
  - **real-time-sync** — Database writes trigger change events to update the UI
88
+ - **internationalization** — UI copy, language catalogs, locale switching, and RTL-safe edits
@@ -1,15 +1,19 @@
1
1
  import { useLocation } from "react-router";
2
- import { useActionQuery } from "@agent-native/core/client";
2
+ import {
3
+ LanguagePicker,
4
+ useActionQuery,
5
+ useT,
6
+ } from "@agent-native/core/client";
3
7
  import { useHeaderTitle, useHeaderActions } from "./HeaderActions";
4
8
  import { AgentToggleButton } from "@agent-native/core/client";
5
9
  import { RunsTray } from "@agent-native/core/client/progress";
6
10
 
7
- const pageTitles: Record<string, string> = {
8
- "/": "Designs",
9
- "/templates": "Templates",
10
- "/design-systems": "Design Systems",
11
- "/design-systems/setup": "Set up design system",
12
- "/settings": "Settings",
11
+ const pageTitleKeys: Record<string, string> = {
12
+ "/": "navigation.designs",
13
+ "/templates": "navigation.templates",
14
+ "/design-systems": "navigation.designSystems",
15
+ "/design-systems/setup": "navigation.setupDesignSystem",
16
+ "/settings": "navigation.settings",
13
17
  };
14
18
 
15
19
  function DesignTitle({ id }: { id: string }) {
@@ -21,7 +25,10 @@ function DesignTitle({ id }: { id: string }) {
21
25
  }
22
26
 
23
27
  function StaticTitle({ pathname }: { pathname: string }) {
24
- const title = pageTitles[pathname] ?? "Design";
28
+ const t = useT();
29
+ const title = pageTitleKeys[pathname]
30
+ ? t(pageTitleKeys[pathname])
31
+ : t("navigation.brand");
25
32
  return (
26
33
  <h1 className="text-lg font-semibold tracking-tight truncate">{title}</h1>
27
34
  );
@@ -47,6 +54,7 @@ export function Header() {
47
54
  </div>
48
55
  <div className="flex items-center gap-2 shrink-0">
49
56
  {actions}
57
+ <LanguagePicker variant="icon" />
50
58
  <RunsTray pollMs={1500} />
51
59
  <AgentToggleButton />
52
60
  </div>
@@ -15,6 +15,7 @@ import {
15
15
  AgentSidebar,
16
16
  isEmbedAuthActive,
17
17
  getBrowserTabId,
18
+ useT,
18
19
  } from "@agent-native/core/client";
19
20
  import { useNavigationState } from "@/hooks/use-navigation-state";
20
21
  import { cn } from "@/lib/utils";
@@ -43,6 +44,7 @@ const EDITOR_PREFIXES = ["/design/", "/extensions"];
43
44
  export function Layout({ children }: LayoutProps) {
44
45
  useNavigationState();
45
46
  const location = useLocation();
47
+ const t = useT();
46
48
  const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false);
47
49
  const openMobileSidebar = useCallback(() => setMobileSidebarOpen(true), []);
48
50
 
@@ -98,11 +100,11 @@ export function Layout({ children }: LayoutProps) {
98
100
  <MobileSidebarContext.Provider value={openMobileSidebar}>
99
101
  <AgentSidebar
100
102
  position="right"
101
- emptyStateText="Describe a design to create"
103
+ emptyStateText={t("chat.emptyState")}
102
104
  suggestions={[
103
- "Design a landing page for my startup",
104
- "Make this match our brand",
105
- "Add a mobile version of this",
105
+ t("chat.suggestionLandingPage"),
106
+ t("chat.suggestionBrandMatch"),
107
+ t("chat.suggestionMobile"),
106
108
  ]}
107
109
  scope={designScope}
108
110
  browserTabId={getBrowserTabId()}
@@ -131,12 +133,12 @@ export function Layout({ children }: LayoutProps) {
131
133
  <button
132
134
  onClick={openMobileSidebar}
133
135
  className="-ml-1 mr-3 cursor-pointer rounded-md p-2.5 hover:bg-sidebar-accent/50"
134
- aria-label="Open navigation"
136
+ aria-label={t("navigation.openNavigation")}
135
137
  >
136
138
  <IconMenu2 className="h-5 w-5 text-foreground" />
137
139
  </button>
138
140
  <span className="text-base font-bold tracking-tight">
139
- Design
141
+ {t("navigation.brand")}
140
142
  </span>
141
143
  </div>
142
144
  )}
@@ -14,6 +14,7 @@ import {
14
14
  DevDatabaseLink,
15
15
  FeedbackButton,
16
16
  appPath,
17
+ useT,
17
18
  } from "@agent-native/core/client";
18
19
  import { OrgSwitcher } from "@agent-native/core/client/org";
19
20
  import { ThemeToggle } from "@/components/ThemeToggle";
@@ -24,16 +25,21 @@ import {
24
25
  } from "@/components/ui/tooltip";
25
26
 
26
27
  const navItems = [
27
- { icon: IconPencil, label: "Designs", href: "/" },
28
- { icon: IconTemplate, label: "Templates", href: "/templates" },
29
- { icon: IconPalette, label: "Design Systems", href: "/design-systems" },
30
- { icon: IconSettings, label: "Settings", href: "/settings" },
28
+ { icon: IconPencil, labelKey: "navigation.designs", href: "/" },
29
+ { icon: IconTemplate, labelKey: "navigation.templates", href: "/templates" },
30
+ {
31
+ icon: IconPalette,
32
+ labelKey: "navigation.designSystems",
33
+ href: "/design-systems",
34
+ },
35
+ { icon: IconSettings, labelKey: "navigation.settings", href: "/settings" },
31
36
  ];
32
37
 
33
38
  const COLLAPSE_KEY = "design.sidebar.collapsed";
34
39
 
35
40
  export function Sidebar() {
36
41
  const location = useLocation();
42
+ const t = useT();
37
43
  const [collapsed, setCollapsed] = useState<boolean>(() => {
38
44
  if (typeof window === "undefined") return false;
39
45
  try {
@@ -79,7 +85,9 @@ export function Sidebar() {
79
85
  aria-hidden="true"
80
86
  className="hidden h-4 w-auto dark:block"
81
87
  />
82
- <span className="text-sm font-semibold tracking-tight">Design</span>
88
+ <span className="text-sm font-semibold tracking-tight">
89
+ {t("navigation.brand")}
90
+ </span>
83
91
  </div>
84
92
  )}
85
93
  <Tooltip delayDuration={0}>
@@ -87,7 +95,11 @@ export function Sidebar() {
87
95
  <button
88
96
  onClick={() => setCollapsed((c) => !c)}
89
97
  className="flex h-7 w-7 cursor-pointer items-center justify-center rounded-md text-muted-foreground hover:bg-sidebar-accent/50 hover:text-foreground"
90
- aria-label={collapsed ? "Expand sidebar" : "Collapse sidebar"}
98
+ aria-label={
99
+ collapsed
100
+ ? t("navigation.expandSidebar")
101
+ : t("navigation.collapseSidebar")
102
+ }
91
103
  >
92
104
  {collapsed ? (
93
105
  <IconLayoutSidebarLeftExpand className="h-4 w-4" />
@@ -97,7 +109,9 @@ export function Sidebar() {
97
109
  </button>
98
110
  </TooltipTrigger>
99
111
  <TooltipContent side="right">
100
- {collapsed ? "Expand sidebar" : "Collapse sidebar"}
112
+ {collapsed
113
+ ? t("navigation.expandSidebar")
114
+ : t("navigation.collapseSidebar")}
101
115
  </TooltipContent>
102
116
  </Tooltip>
103
117
  </div>
@@ -124,14 +138,16 @@ export function Sidebar() {
124
138
  )}
125
139
  >
126
140
  <Icon className="h-4 w-4 shrink-0" />
127
- {!collapsed && item.label}
141
+ {!collapsed && t(item.labelKey)}
128
142
  </Link>
129
143
  );
130
144
  if (collapsed) {
131
145
  return (
132
146
  <Tooltip key={item.href} delayDuration={0}>
133
147
  <TooltipTrigger asChild>{link}</TooltipTrigger>
134
- <TooltipContent side="right">{item.label}</TooltipContent>
148
+ <TooltipContent side="right">
149
+ {t(item.labelKey)}
150
+ </TooltipContent>
135
151
  </Tooltip>
136
152
  );
137
153
  }
@@ -0,0 +1,3 @@
1
+ import { messagesByLocale } from "../i18n-data";
2
+
3
+ export default messagesByLocale["ar-SA"];
@@ -0,0 +1,3 @@
1
+ import { messagesByLocale } from "../i18n-data";
2
+
3
+ export default messagesByLocale["de-DE"];
@@ -0,0 +1,3 @@
1
+ import { messagesByLocale } from "../i18n-data";
2
+
3
+ export default messagesByLocale["en-US"];
@@ -0,0 +1,3 @@
1
+ import { messagesByLocale } from "../i18n-data";
2
+
3
+ export default messagesByLocale["es-ES"];
@@ -0,0 +1,3 @@
1
+ import { messagesByLocale } from "../i18n-data";
2
+
3
+ export default messagesByLocale["fr-FR"];
@@ -0,0 +1,3 @@
1
+ import { messagesByLocale } from "../i18n-data";
2
+
3
+ export default messagesByLocale["hi-IN"];
@@ -0,0 +1,31 @@
1
+ import enUS from "./en-US";
2
+ import type { AgentNativeI18nCatalog } from "@agent-native/core/client";
3
+
4
+ export const i18nCatalog = {
5
+ sourceLocale: "en-US",
6
+ messages: enUS,
7
+ loadMessages: async (locale) => {
8
+ switch (locale) {
9
+ case "zh-CN":
10
+ return (await import("./zh-CN")).default;
11
+ case "es-ES":
12
+ return (await import("./es-ES")).default;
13
+ case "fr-FR":
14
+ return (await import("./fr-FR")).default;
15
+ case "de-DE":
16
+ return (await import("./de-DE")).default;
17
+ case "ja-JP":
18
+ return (await import("./ja-JP")).default;
19
+ case "ko-KR":
20
+ return (await import("./ko-KR")).default;
21
+ case "pt-BR":
22
+ return (await import("./pt-BR")).default;
23
+ case "hi-IN":
24
+ return (await import("./hi-IN")).default;
25
+ case "ar-SA":
26
+ return (await import("./ar-SA")).default;
27
+ default:
28
+ return null;
29
+ }
30
+ },
31
+ } satisfies AgentNativeI18nCatalog;
@@ -0,0 +1,3 @@
1
+ import { messagesByLocale } from "../i18n-data";
2
+
3
+ export default messagesByLocale["ja-JP"];
@@ -0,0 +1,3 @@
1
+ import { messagesByLocale } from "../i18n-data";
2
+
3
+ export default messagesByLocale["ko-KR"];
@@ -0,0 +1,3 @@
1
+ import { messagesByLocale } from "../i18n-data";
2
+
3
+ export default messagesByLocale["pt-BR"];
@@ -0,0 +1,3 @@
1
+ import { messagesByLocale } from "../i18n-data";
2
+
3
+ export default messagesByLocale["zh-CN"];