@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
@@ -16,11 +16,14 @@ import {
16
16
  useSession,
17
17
  agentNativePath,
18
18
  appApiPath,
19
+ LanguagePicker,
19
20
  parseChangelog,
20
21
  useActionQuery,
21
22
  useBuilderConnectFlow,
22
23
  useBuilderStatus,
23
24
  ChangelogSettingsCard,
25
+ openAgentSettings,
26
+ useT,
24
27
  } from "@agent-native/core/client";
25
28
  import changelog from "../../CHANGELOG.md?raw";
26
29
  import { toast } from "sonner";
@@ -383,6 +386,7 @@ function CompactChangelogAside() {
383
386
 
384
387
  export default function SettingsIndexRoute() {
385
388
  const { session } = useSession();
389
+ const t = useT();
386
390
  const email = session?.email ?? "";
387
391
  const storageStatus = useVideoStorageStatus();
388
392
  const builderStatus = useBuilderStatus();
@@ -393,7 +397,7 @@ export default function SettingsIndexRoute() {
393
397
  trackingFlow: "clips_setup",
394
398
  onConnected: async () => {
395
399
  await Promise.all([storageStatus.refetch(), builderStatus.refetch()]);
396
- toast.success("Builder.io connected");
400
+ toast.success(t("settings.builderConnectedToast"));
397
401
  },
398
402
  });
399
403
  const slackStatus = useActionQuery<SlackInstallationsResponse>(
@@ -482,9 +486,11 @@ export default function SettingsIndexRoute() {
482
486
  displayName: displayName.trim() || undefined,
483
487
  transcriptCleanupEnabled,
484
488
  });
485
- toast.success("Settings saved");
489
+ toast.success(t("settings.saved"));
486
490
  } catch (err) {
487
- toast.error(err instanceof Error ? err.message : "Failed to save");
491
+ toast.error(
492
+ err instanceof Error ? err.message : t("settings.saveFailed"),
493
+ );
488
494
  } finally {
489
495
  setSaving(false);
490
496
  }
@@ -501,7 +507,7 @@ export default function SettingsIndexRoute() {
501
507
  !(s3Values[field.key] ?? "").trim(),
502
508
  );
503
509
  if (missing.length > 0) {
504
- toast.error("Endpoint, bucket, access key, and secret are required.");
510
+ toast.error(t("settings.storageRequired"));
505
511
  return;
506
512
  }
507
513
 
@@ -513,9 +519,11 @@ export default function SettingsIndexRoute() {
513
519
  S3_SECRET_ACCESS_KEY: "",
514
520
  }));
515
521
  await storageStatus.refetch();
516
- toast.success("Storage settings saved");
522
+ toast.success(t("settings.storageSaved"));
517
523
  } catch (err) {
518
- toast.error(err instanceof Error ? err.message : "Failed to save");
524
+ toast.error(
525
+ err instanceof Error ? err.message : t("settings.saveFailed"),
526
+ );
519
527
  } finally {
520
528
  setSavingStorage(false);
521
529
  }
@@ -524,7 +532,7 @@ export default function SettingsIndexRoute() {
524
532
  async function handleSaveApiKey(key: string) {
525
533
  const value = (apiKeyValues[key] ?? "").trim();
526
534
  if (!value) {
527
- toast.error("Paste a provider key first.");
535
+ toast.error(t("settings.pasteProviderKey"));
528
536
  return;
529
537
  }
530
538
 
@@ -540,9 +548,11 @@ export default function SettingsIndexRoute() {
540
548
  setApiKeyStatus((current) => ({ ...current, [key]: true }));
541
549
  window.dispatchEvent(new CustomEvent("agent-engine:configured-changed"));
542
550
  await refreshApiKeyStatus();
543
- toast.success("API key saved");
551
+ toast.success(t("settings.apiKeySaved"));
544
552
  } catch (err) {
545
- toast.error(err instanceof Error ? err.message : "Failed to save key");
553
+ toast.error(
554
+ err instanceof Error ? err.message : t("settings.apiKeyFailed"),
555
+ );
546
556
  } finally {
547
557
  setSavingApiKey(null);
548
558
  }
@@ -556,9 +566,9 @@ export default function SettingsIndexRoute() {
556
566
  const refreshed = await slackStatus.refetch();
557
567
  const afterCount = refreshed.data?.installations?.length ?? beforeCount;
558
568
  if (afterCount > beforeCount) {
559
- toast.success("Slack connected");
569
+ toast.success(t("settings.slackConnectedToast"));
560
570
  } else {
561
- toast.message("Slack connection checked");
571
+ toast.message(t("settings.slackCheckedToast"));
562
572
  }
563
573
  } catch (err) {
564
574
  toast.error(
@@ -577,7 +587,7 @@ export default function SettingsIndexRoute() {
577
587
  await requestDisconnectSlack(target.id);
578
588
  setDisconnectSlackTarget(null);
579
589
  await slackStatus.refetch();
580
- toast.success("Slack disconnected");
590
+ toast.success(t("settings.slackDisconnectedToast"));
581
591
  } catch (err) {
582
592
  toast.error(
583
593
  err instanceof Error ? err.message : "Failed to disconnect Slack",
@@ -616,25 +626,55 @@ export default function SettingsIndexRoute() {
616
626
  <>
617
627
  <PageHeader>
618
628
  <h1 className="text-base font-semibold tracking-tight truncate">
619
- Settings
629
+ {t("settings.title")}
620
630
  </h1>
621
631
  </PageHeader>
622
632
  <div className="mx-auto w-full max-w-6xl p-6">
623
633
  <div className="grid gap-6 2xl:grid-cols-[minmax(0,1fr)_360px]">
624
634
  <div className="min-w-0 space-y-6">
625
635
  <p className="text-sm text-muted-foreground">
626
- Preferences and connected services for this Clips workspace.
636
+ {t("settings.intro")}
627
637
  </p>
628
638
 
639
+ <Card>
640
+ <CardHeader>
641
+ <CardTitle className="text-base">
642
+ {t("settings.languageTitle")}
643
+ </CardTitle>
644
+ <CardDescription>
645
+ {t("settings.languageDescription")}
646
+ </CardDescription>
647
+ </CardHeader>
648
+ <CardContent className="max-w-xs space-y-1.5">
649
+ <Label>{t("settings.languageLabel")}</Label>
650
+ <LanguagePicker label={t("settings.languageLabel")} />
651
+ </CardContent>
652
+ </Card>
653
+
654
+ <Card>
655
+ <CardHeader>
656
+ <CardTitle className="text-base">
657
+ {t("settings.agentTitle")}
658
+ </CardTitle>
659
+ <CardDescription>
660
+ {t("settings.agentDescription")}
661
+ </CardDescription>
662
+ </CardHeader>
663
+ <CardContent>
664
+ <Button variant="outline" onClick={() => openAgentSettings()}>
665
+ {t("settings.openAgentSettings")}
666
+ </Button>
667
+ </CardContent>
668
+ </Card>
669
+
629
670
  <Card id="video-storage" className="scroll-mt-16">
630
671
  <CardHeader>
631
672
  <CardTitle className="text-base flex items-center gap-2">
632
673
  <IconCloud className="size-4 text-primary" />
633
- Video storage
674
+ {t("settings.videoStorage")}
634
675
  </CardTitle>
635
676
  <CardDescription>
636
- Builder.io is the primary storage path for Clips uploads. S3
637
- is available when you need to bring your own bucket.
677
+ {t("settings.videoStorageDescription")}
638
678
  </CardDescription>
639
679
  </CardHeader>
640
680
  <CardContent className="space-y-4">
@@ -654,22 +694,24 @@ export default function SettingsIndexRoute() {
654
694
  <IconKey className="h-4 w-4 text-muted-foreground" />
655
695
  )}
656
696
  {builderStatusLoading
657
- ? "Checking Builder.io"
697
+ ? t("settings.checkingBuilder")
658
698
  : builderConnected
659
- ? "Builder.io connected"
660
- : "Connect Builder.io"}
699
+ ? t("settings.builderConnected")
700
+ : t("settings.connectBuilder")}
661
701
  </div>
662
702
  <p className="mt-0.5 text-xs text-muted-foreground">
663
703
  {builderConnected
664
704
  ? builderOrgName
665
- ? `Using Builder.io for ${builderOrgName}.`
666
- : "New clips use the connected Builder.io provider."
667
- : "Includes object storage, uploads, and managed transcription for new clips."}
705
+ ? t("settings.builderConnectedFor", {
706
+ orgName: builderOrgName,
707
+ })
708
+ : t("settings.builderConnectedGeneric")
709
+ : t("settings.builderIncludes")}
668
710
  </p>
669
711
  </div>
670
712
  {builderConnected ? (
671
713
  <Badge variant="secondary" className="shrink-0">
672
- Connected
714
+ {t("common.connected")}
673
715
  </Badge>
674
716
  ) : (
675
717
  <Button
@@ -692,7 +734,7 @@ export default function SettingsIndexRoute() {
692
734
  ) : (
693
735
  <IconExternalLink className="h-4 w-4" />
694
736
  )}
695
- Connect Builder.io
737
+ {t("settings.connectBuilder")}
696
738
  </Button>
697
739
  )}
698
740
  </div>
@@ -706,22 +748,24 @@ export default function SettingsIndexRoute() {
706
748
  <div className="min-w-0">
707
749
  <div className="flex flex-wrap items-center gap-2 text-sm font-medium">
708
750
  <IconServer className="h-4 w-4 text-muted-foreground" />
709
- S3-compatible storage
751
+ {t("settings.s3Title")}
710
752
  <Badge variant="outline" className="text-[10px]">
711
- Secondary
753
+ {t("settings.secondary")}
712
754
  </Badge>
713
755
  {s3Configured ? (
714
756
  <Badge variant="secondary" className="text-[10px]">
715
- Active
757
+ {t("settings.active")}
716
758
  </Badge>
717
759
  ) : null}
718
760
  </div>
719
761
  <p className="mt-0.5 text-xs text-muted-foreground">
720
762
  {builderConnected
721
- ? "Use this only if this workspace should upload to your own bucket instead of Builder.io."
763
+ ? t("settings.s3BuilderConnectedDescription")
722
764
  : storageConfigured && activeProviderName
723
- ? `Currently using ${activeProviderName}.`
724
- : "Use your own bucket if you do not want Builder.io storage."}
765
+ ? t("settings.s3CurrentProvider", {
766
+ providerName: activeProviderName,
767
+ })
768
+ : t("settings.s3OwnBucketDescription")}
725
769
  </p>
726
770
  </div>
727
771
  {builderConnected ? (
@@ -732,7 +776,9 @@ export default function SettingsIndexRoute() {
732
776
  size="sm"
733
777
  className="shrink-0"
734
778
  >
735
- {s3Collapsed ? "Configure S3" : "Hide S3"}
779
+ {s3Collapsed
780
+ ? t("settings.configureS3")
781
+ : t("settings.hideS3")}
736
782
  <IconChevronDown
737
783
  className={cn(
738
784
  "h-4 w-4 transition-transform",
@@ -780,7 +826,7 @@ export default function SettingsIndexRoute() {
780
826
  {savingStorage && (
781
827
  <IconLoader2 className="h-4 w-4 animate-spin" />
782
828
  )}
783
- Save storage
829
+ {t("settings.saveStorage")}
784
830
  </Button>
785
831
  </div>
786
832
  </div>
@@ -794,12 +840,10 @@ export default function SettingsIndexRoute() {
794
840
  <CardHeader>
795
841
  <CardTitle className="text-base flex items-center gap-2">
796
842
  <IconBrandSlack className="size-4 text-primary" />
797
- Agent-Native Clips for Slack
843
+ {t("settings.slackTitle")}
798
844
  </CardTitle>
799
845
  <CardDescription>
800
- Share a public clip, paste the link in Slack, and it plays
801
- inline — no extra steps for viewers. Connect each workspace
802
- once.
846
+ {t("settings.slackDescription")}
803
847
  </CardDescription>
804
848
  </CardHeader>
805
849
  <CardContent className="space-y-4">
@@ -808,17 +852,17 @@ export default function SettingsIndexRoute() {
808
852
  <div className="flex items-center gap-2 text-sm font-medium">
809
853
  <IconBrandSlack className="h-4 w-4 text-muted-foreground" />
810
854
  {slackStatus.isLoading
811
- ? "Checking Slack"
855
+ ? t("settings.checkingSlack")
812
856
  : slackConnected
813
- ? `${slackInstallations.length} workspace${
814
- slackInstallations.length === 1 ? "" : "s"
815
- } connected`
857
+ ? t("settings.slackConnected", {
858
+ count: slackInstallations.length,
859
+ })
816
860
  : slackOauthConfigured
817
- ? "Not connected"
818
- : "OAuth credentials needed"}
861
+ ? t("common.notConnected")
862
+ : t("settings.slackOauthNeeded")}
819
863
  </div>
820
864
  <p className="mt-0.5 text-xs text-muted-foreground">
821
- Public Clips links can render as playable Slack previews.
865
+ {t("settings.slackPreviewDescription")}
822
866
  </p>
823
867
  </div>
824
868
  <Button
@@ -838,21 +882,19 @@ export default function SettingsIndexRoute() {
838
882
  ) : (
839
883
  <IconExternalLink className="h-4 w-4" />
840
884
  )}
841
- Connect Slack
885
+ {t("settings.connectSlack")}
842
886
  </Button>
843
887
  </div>
844
888
 
845
889
  {!slackOauthConfigured ? (
846
890
  <div className="rounded-md border border-border p-3 text-xs text-muted-foreground">
847
- Set SLACK_CLIENT_ID and SLACK_CLIENT_SECRET for this
848
- deployment before connecting workspaces.
891
+ {t("settings.slackClientMissing")}
849
892
  </div>
850
893
  ) : null}
851
894
 
852
895
  {!slackSigningConfigured ? (
853
896
  <div className="rounded-md border border-border p-3 text-xs text-muted-foreground">
854
- Set SLACK_SIGNING_SECRET so Slack event callbacks can be
855
- verified.
897
+ {t("settings.slackSigningMissing")}
856
898
  </div>
857
899
  ) : null}
858
900
 
@@ -872,7 +914,11 @@ export default function SettingsIndexRoute() {
872
914
  {installation.enterpriseName ? (
873
915
  <span>{installation.enterpriseName}</span>
874
916
  ) : null}
875
- <span>Connected by {installation.ownerEmail}</span>
917
+ <span>
918
+ {t("settings.connectedBy", {
919
+ email: installation.ownerEmail,
920
+ })}
921
+ </span>
876
922
  </div>
877
923
  </div>
878
924
  <Button
@@ -880,9 +926,9 @@ export default function SettingsIndexRoute() {
880
926
  variant="ghost"
881
927
  size="icon"
882
928
  className="shrink-0"
883
- aria-label={`Disconnect ${
884
- installation.teamName || installation.teamId
885
- }`}
929
+ aria-label={t("settings.disconnectSlackLabel", {
930
+ team: installation.teamName || installation.teamId,
931
+ })}
886
932
  onClick={() => setDisconnectSlackTarget(installation)}
887
933
  >
888
934
  <IconTrash className="h-4 w-4" />
@@ -898,11 +944,10 @@ export default function SettingsIndexRoute() {
898
944
  <CardHeader>
899
945
  <CardTitle className="text-base flex items-center gap-2">
900
946
  <IconBrain className="size-4 text-primary" />
901
- AI setup
947
+ {t("settings.apiSetup")}
902
948
  </CardTitle>
903
949
  <CardDescription>
904
- Builder.io is the default path for managed AI credits.
905
- Provider keys are optional and can be added here.
950
+ {t("settings.apiSetupDescription")}
906
951
  </CardDescription>
907
952
  </CardHeader>
908
953
  <CardContent className="space-y-4">
@@ -922,20 +967,20 @@ export default function SettingsIndexRoute() {
922
967
  <IconKey className="h-4 w-4 text-muted-foreground" />
923
968
  )}
924
969
  {builderStatusLoading
925
- ? "Checking Builder.io"
970
+ ? t("settings.checkingBuilder")
926
971
  : builderConnected
927
- ? "Builder.io connected"
928
- : "Builder.io is the easiest setup"}
972
+ ? t("settings.builderConnected")
973
+ : t("settings.builderEasySetup")}
929
974
  </div>
930
975
  <p className="mt-0.5 text-xs text-muted-foreground">
931
976
  {builderConnected
932
- ? "Included AI credits and managed transcription are available for Clips."
933
- : "Connect Builder first for included AI credits, object storage, uploads, and managed transcription."}
977
+ ? t("settings.builderAiAvailable")
978
+ : t("settings.builderAiDescription")}
934
979
  </p>
935
980
  </div>
936
981
  {builderConnected ? (
937
982
  <Badge variant="secondary" className="shrink-0">
938
- Connected
983
+ {t("common.connected")}
939
984
  </Badge>
940
985
  ) : (
941
986
  <Button
@@ -958,7 +1003,7 @@ export default function SettingsIndexRoute() {
958
1003
  ) : (
959
1004
  <IconExternalLink className="h-4 w-4" />
960
1005
  )}
961
- Connect Builder.io
1006
+ {t("settings.connectBuilder")}
962
1007
  </Button>
963
1008
  )}
964
1009
  </div>
@@ -976,19 +1021,20 @@ export default function SettingsIndexRoute() {
976
1021
  <div className="min-w-0">
977
1022
  <div className="flex items-center gap-2 text-sm font-medium">
978
1023
  <IconKey className="h-4 w-4 text-muted-foreground" />
979
- Bring your own provider key
1024
+ {t("settings.providerKeyTitle")}
980
1025
  {configuredApiKeyCount > 0 ? (
981
1026
  <Badge
982
1027
  variant="secondary"
983
1028
  className="text-[10px]"
984
1029
  >
985
- {configuredApiKeyCount} set
1030
+ {t("settings.providerKeysSet", {
1031
+ count: configuredApiKeyCount,
1032
+ })}
986
1033
  </Badge>
987
1034
  ) : null}
988
1035
  </div>
989
1036
  <p className="mt-0.5 text-xs text-muted-foreground">
990
- Add Anthropic, OpenAI, Gemini, Groq, or OpenRouter
991
- keys for provider-billed usage.
1037
+ {t("settings.providerKeyDescription")}
992
1038
  </p>
993
1039
  </div>
994
1040
  <IconChevronDown
@@ -1003,7 +1049,7 @@ export default function SettingsIndexRoute() {
1003
1049
  <div className="space-y-3 border-t border-border px-3 py-4">
1004
1050
  {apiKeyStatusLoading ? (
1005
1051
  <div className="text-xs text-muted-foreground">
1006
- Checking provider keys…
1052
+ {t("settings.checkingProviderKeys")}
1007
1053
  </div>
1008
1054
  ) : null}
1009
1055
  <div className="grid gap-3 sm:grid-cols-2">
@@ -1019,7 +1065,7 @@ export default function SettingsIndexRoute() {
1019
1065
  {configured ? (
1020
1066
  <span className="flex items-center gap-1 text-[10px] font-medium text-primary">
1021
1067
  <IconCheck className="h-3 w-3" />
1022
- Set
1068
+ {t("settings.keySet")}
1023
1069
  </span>
1024
1070
  ) : null}
1025
1071
  </div>
@@ -1041,7 +1087,7 @@ export default function SettingsIndexRoute() {
1041
1087
  }}
1042
1088
  placeholder={
1043
1089
  configured
1044
- ? "Replace key…"
1090
+ ? t("settings.replaceKey")
1045
1091
  : field.placeholder
1046
1092
  }
1047
1093
  autoComplete="off"
@@ -1061,7 +1107,7 @@ export default function SettingsIndexRoute() {
1061
1107
  {savingThisKey ? (
1062
1108
  <IconLoader2 className="h-4 w-4 animate-spin" />
1063
1109
  ) : (
1064
- "Save"
1110
+ t("common.save")
1065
1111
  )}
1066
1112
  </Button>
1067
1113
  </div>
@@ -1080,21 +1126,23 @@ export default function SettingsIndexRoute() {
1080
1126
  <CardHeader>
1081
1127
  <CardTitle className="text-base flex items-center gap-2">
1082
1128
  <IconUser className="size-4 text-primary" />
1083
- Profile
1129
+ {t("settings.profile")}
1084
1130
  </CardTitle>
1085
1131
  </CardHeader>
1086
1132
  <CardContent className="space-y-4">
1087
1133
  <div className="space-y-1.5">
1088
- <Label htmlFor="email">Email</Label>
1134
+ <Label htmlFor="email">{t("settings.email")}</Label>
1089
1135
  <Input id="email" value={email} readOnly disabled />
1090
1136
  </div>
1091
1137
  <div className="space-y-1.5">
1092
- <Label htmlFor="display-name">Display name</Label>
1138
+ <Label htmlFor="display-name">
1139
+ {t("settings.displayName")}
1140
+ </Label>
1093
1141
  <Input
1094
1142
  id="display-name"
1095
1143
  value={displayName}
1096
1144
  onChange={(e) => setDisplayName(e.target.value)}
1097
- placeholder="Your name"
1145
+ placeholder={t("settings.displayNamePlaceholder")}
1098
1146
  disabled={loading}
1099
1147
  />
1100
1148
  </div>
@@ -1103,11 +1151,15 @@ export default function SettingsIndexRoute() {
1103
1151
 
1104
1152
  <Card>
1105
1153
  <CardHeader>
1106
- <CardTitle className="text-base">Playback</CardTitle>
1154
+ <CardTitle className="text-base">
1155
+ {t("settings.playback")}
1156
+ </CardTitle>
1107
1157
  </CardHeader>
1108
1158
  <CardContent className="space-y-4">
1109
1159
  <div className="space-y-1.5">
1110
- <Label htmlFor="speed">Default playback speed</Label>
1160
+ <Label htmlFor="speed">
1161
+ {t("settings.defaultPlaybackSpeed")}
1162
+ </Label>
1111
1163
  <Select
1112
1164
  value={defaultSpeed}
1113
1165
  onValueChange={setDefaultSpeed}
@@ -1125,7 +1177,7 @@ export default function SettingsIndexRoute() {
1125
1177
  </SelectContent>
1126
1178
  </Select>
1127
1179
  <p className="text-xs text-muted-foreground">
1128
- Applied automatically when you open a recording.
1180
+ {t("settings.playbackDescription")}
1129
1181
  </p>
1130
1182
  </div>
1131
1183
  </CardContent>
@@ -1133,7 +1185,9 @@ export default function SettingsIndexRoute() {
1133
1185
 
1134
1186
  <Card>
1135
1187
  <CardHeader>
1136
- <CardTitle className="text-base">Transcript</CardTitle>
1188
+ <CardTitle className="text-base">
1189
+ {t("settings.transcript")}
1190
+ </CardTitle>
1137
1191
  </CardHeader>
1138
1192
  <CardContent>
1139
1193
  <div className="flex items-center justify-between gap-4">
@@ -1142,11 +1196,10 @@ export default function SettingsIndexRoute() {
1142
1196
  htmlFor="transcript-cleanup"
1143
1197
  className="cursor-pointer"
1144
1198
  >
1145
- Background cleanup
1199
+ {t("settings.transcriptCleanup")}
1146
1200
  </Label>
1147
1201
  <p className="text-xs text-muted-foreground mt-0.5">
1148
- Show the native transcript immediately, then clean it up
1149
- in the background when available.
1202
+ {t("settings.transcriptCleanupDescription")}
1150
1203
  </p>
1151
1204
  </div>
1152
1205
  <Switch
@@ -1161,17 +1214,18 @@ export default function SettingsIndexRoute() {
1161
1214
 
1162
1215
  <Card>
1163
1216
  <CardHeader>
1164
- <CardTitle className="text-base">Notifications</CardTitle>
1217
+ <CardTitle className="text-base">
1218
+ {t("settings.notifications")}
1219
+ </CardTitle>
1165
1220
  </CardHeader>
1166
1221
  <CardContent>
1167
1222
  <div className="flex items-center justify-between">
1168
1223
  <div>
1169
1224
  <Label htmlFor="email-notif" className="cursor-pointer">
1170
- Email notifications
1225
+ {t("settings.emailNotifications")}
1171
1226
  </Label>
1172
1227
  <p className="text-xs text-muted-foreground mt-0.5">
1173
- Get an email when someone comments, reacts, or shares a
1174
- recording with you.
1228
+ {t("settings.emailNotificationsDescription")}
1175
1229
  </p>
1176
1230
  </div>
1177
1231
  <Switch
@@ -1190,7 +1244,7 @@ export default function SettingsIndexRoute() {
1190
1244
  disabled={loading || saving}
1191
1245
  className="bg-primary hover:bg-primary/90"
1192
1246
  >
1193
- {saving ? "Saving…" : "Save changes"}
1247
+ {saving ? t("common.saving") : t("common.saveChanges")}
1194
1248
  </Button>
1195
1249
  </div>
1196
1250
  </div>
@@ -1205,18 +1259,21 @@ export default function SettingsIndexRoute() {
1205
1259
  >
1206
1260
  <AlertDialogContent>
1207
1261
  <AlertDialogHeader>
1208
- <AlertDialogTitle>Disconnect Slack?</AlertDialogTitle>
1262
+ <AlertDialogTitle>
1263
+ {t("settings.disconnectSlackTitle")}
1264
+ </AlertDialogTitle>
1209
1265
  <AlertDialogDescription>
1210
- Clips will delete the stored bot token for{" "}
1211
- {disconnectSlackTarget?.teamName ||
1212
- disconnectSlackTarget?.teamId ||
1213
- "this workspace"}{" "}
1214
- and stop sending playable Slack previews.
1266
+ {t("settings.disconnectSlackDescription", {
1267
+ team:
1268
+ disconnectSlackTarget?.teamName ||
1269
+ disconnectSlackTarget?.teamId ||
1270
+ t("settings.thisWorkspace"),
1271
+ })}
1215
1272
  </AlertDialogDescription>
1216
1273
  </AlertDialogHeader>
1217
1274
  <AlertDialogFooter>
1218
1275
  <AlertDialogCancel disabled={disconnectingSlack}>
1219
- Cancel
1276
+ {t("common.cancel")}
1220
1277
  </AlertDialogCancel>
1221
1278
  <AlertDialogAction
1222
1279
  onClick={(event) => {
@@ -1225,7 +1282,9 @@ export default function SettingsIndexRoute() {
1225
1282
  }}
1226
1283
  disabled={disconnectingSlack}
1227
1284
  >
1228
- {disconnectingSlack ? "Disconnecting..." : "Disconnect"}
1285
+ {disconnectingSlack
1286
+ ? t("common.disconnecting")
1287
+ : t("common.disconnect")}
1229
1288
  </AlertDialogAction>
1230
1289
  </AlertDialogFooter>
1231
1290
  </AlertDialogContent>
@@ -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.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-06-24
4
+ ---
5
+
6
+ Clips now includes a language picker with Simplified Chinese support for core navigation, empty states, and settings.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: improved
3
+ date: 2026-06-24
4
+ ---
5
+
6
+ Settings now link directly to Agent settings for model, API key, automation, and voice preferences.
@@ -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