@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.
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +7 -0
- package/corpus/core/docs/AGENTS.md +1 -0
- package/corpus/core/docs/content/client.md +15 -0
- package/corpus/core/docs/content/internationalization.md +145 -0
- package/corpus/core/docs/content/locales/ar-SA/internationalization.md +102 -0
- package/corpus/core/docs/content/locales/de-DE/internationalization.md +102 -0
- package/corpus/core/docs/content/locales/es-ES/internationalization.md +102 -0
- package/corpus/core/docs/content/locales/fr-FR/internationalization.md +102 -0
- package/corpus/core/docs/content/locales/hi-IN/internationalization.md +102 -0
- package/corpus/core/docs/content/locales/ja-JP/internationalization.md +114 -0
- package/corpus/core/docs/content/locales/ko-KR/internationalization.md +102 -0
- package/corpus/core/docs/content/locales/pt-BR/internationalization.md +102 -0
- package/corpus/core/docs/content/locales/zh-CN/internationalization.md +102 -0
- package/corpus/core/docs/content/skills-guide.md +19 -18
- package/corpus/core/package.json +7 -1
- package/corpus/core/src/client/CommandMenu.tsx +16 -0
- package/corpus/core/src/client/app-providers.tsx +26 -1
- package/corpus/core/src/client/i18n.tsx +605 -0
- package/corpus/core/src/client/index.ts +28 -0
- package/corpus/core/src/index.browser.ts +25 -0
- package/corpus/core/src/localization/actions/get-localization-preference.ts +23 -0
- package/corpus/core/src/localization/actions/set-localization-preference.ts +30 -0
- package/corpus/core/src/localization/index.ts +2 -0
- package/corpus/core/src/localization/server.ts +131 -0
- package/corpus/core/src/localization/shared.ts +163 -0
- package/corpus/core/src/server/action-discovery.ts +8 -0
- package/corpus/core/src/server/index.ts +8 -0
- package/corpus/core/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +5 -0
- package/corpus/core/src/templates/default/.agents/skills/internationalization/SKILL.md +77 -0
- package/corpus/core/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +6 -0
- package/corpus/core/src/templates/default/AGENTS.md +16 -15
- package/corpus/core/src/templates/default/app/i18n/en-US.ts +29 -0
- package/corpus/core/src/templates/default/app/i18n/index.ts +13 -0
- package/corpus/core/src/templates/default/app/root.tsx +20 -1
- package/corpus/core/src/templates/default/app/routes/_index.tsx +24 -9
- package/corpus/core/src/templates/default/app/routes/settings.tsx +67 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +5 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/internationalization/SKILL.md +77 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +6 -0
- package/corpus/core/src/vite/action-types-plugin.ts +10 -0
- package/corpus/templates/analytics/.agents/skills/self-modifying-code/SKILL.md +6 -0
- package/corpus/templates/analytics/app/components/layout/Header.tsx +18 -15
- package/corpus/templates/analytics/app/components/layout/Layout.tsx +7 -5
- package/corpus/templates/analytics/app/components/layout/MobileNav.tsx +9 -3
- package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +5 -3
- package/corpus/templates/analytics/app/i18n/ar-SA.ts +3 -0
- package/corpus/templates/analytics/app/i18n/de-DE.ts +3 -0
- package/corpus/templates/analytics/app/i18n/en-US.ts +3 -0
- package/corpus/templates/analytics/app/i18n/es-ES.ts +3 -0
- package/corpus/templates/analytics/app/i18n/fr-FR.ts +3 -0
- package/corpus/templates/analytics/app/i18n/hi-IN.ts +3 -0
- package/corpus/templates/analytics/app/i18n/index.ts +31 -0
- package/corpus/templates/analytics/app/i18n/ja-JP.ts +3 -0
- package/corpus/templates/analytics/app/i18n/ko-KR.ts +3 -0
- package/corpus/templates/analytics/app/i18n/pt-BR.ts +3 -0
- package/corpus/templates/analytics/app/i18n/zh-CN.ts +3 -0
- package/corpus/templates/analytics/app/i18n-data.ts +433 -0
- package/corpus/templates/analytics/app/pages/Settings.tsx +50 -16
- package/corpus/templates/analytics/app/root.tsx +14 -1
- package/corpus/templates/analytics/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
- package/corpus/templates/analytics/changelog/2026-06-24-settings-now-link-directly-to-agent-settings-for-model-api-k.md +6 -0
- package/corpus/templates/assets/.agents/skills/self-modifying-code/SKILL.md +6 -0
- package/corpus/templates/assets/app/components/layout/Header.tsx +17 -8
- package/corpus/templates/assets/app/components/layout/Layout.tsx +10 -6
- package/corpus/templates/assets/app/components/layout/Sidebar.tsx +40 -23
- package/corpus/templates/assets/app/i18n/ar-SA.ts +3 -0
- package/corpus/templates/assets/app/i18n/de-DE.ts +3 -0
- package/corpus/templates/assets/app/i18n/en-US.ts +3 -0
- package/corpus/templates/assets/app/i18n/es-ES.ts +3 -0
- package/corpus/templates/assets/app/i18n/fr-FR.ts +3 -0
- package/corpus/templates/assets/app/i18n/hi-IN.ts +3 -0
- package/corpus/templates/assets/app/i18n/index.ts +31 -0
- package/corpus/templates/assets/app/i18n/ja-JP.ts +3 -0
- package/corpus/templates/assets/app/i18n/ko-KR.ts +3 -0
- package/corpus/templates/assets/app/i18n/pt-BR.ts +3 -0
- package/corpus/templates/assets/app/i18n/zh-CN.ts +3 -0
- package/corpus/templates/assets/app/i18n-data.ts +668 -0
- package/corpus/templates/assets/app/root.tsx +40 -15
- package/corpus/templates/assets/app/routes/_index.tsx +9 -10
- package/corpus/templates/assets/app/routes/settings.tsx +37 -6
- package/corpus/templates/assets/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
- package/corpus/templates/assets/changelog/2026-06-24-settings-now-link-directly-to-agent-settings-for-model-api-k.md +6 -0
- package/corpus/templates/brain/.agents/skills/adding-a-feature/SKILL.md +5 -0
- package/corpus/templates/brain/.agents/skills/self-modifying-code/SKILL.md +6 -0
- package/corpus/templates/brain/app/components/layout/Layout.tsx +12 -8
- package/corpus/templates/brain/app/components/layout/Sidebar.tsx +23 -12
- package/corpus/templates/brain/app/i18n/ar-SA.ts +3 -0
- package/corpus/templates/brain/app/i18n/de-DE.ts +3 -0
- package/corpus/templates/brain/app/i18n/en-US.ts +3 -0
- package/corpus/templates/brain/app/i18n/es-ES.ts +3 -0
- package/corpus/templates/brain/app/i18n/fr-FR.ts +3 -0
- package/corpus/templates/brain/app/i18n/hi-IN.ts +3 -0
- package/corpus/templates/brain/app/i18n/index.ts +31 -0
- package/corpus/templates/brain/app/i18n/ja-JP.ts +3 -0
- package/corpus/templates/brain/app/i18n/ko-KR.ts +3 -0
- package/corpus/templates/brain/app/i18n/pt-BR.ts +3 -0
- package/corpus/templates/brain/app/i18n/zh-CN.ts +3 -0
- package/corpus/templates/brain/app/i18n-data.ts +624 -0
- package/corpus/templates/brain/app/root.tsx +27 -12
- package/corpus/templates/brain/app/routes/settings.tsx +45 -8
- package/corpus/templates/brain/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
- package/corpus/templates/brain/changelog/2026-06-24-settings-now-link-directly-to-agent-settings-for-model-api-k.md +6 -0
- package/corpus/templates/calendar/.agents/skills/self-modifying-code/SKILL.md +6 -0
- package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +2 -0
- package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +16 -9
- package/corpus/templates/calendar/app/i18n/ar-SA.ts +57 -0
- package/corpus/templates/calendar/app/i18n/de-DE.ts +58 -0
- package/corpus/templates/calendar/app/i18n/en-US.ts +57 -0
- package/corpus/templates/calendar/app/i18n/es-ES.ts +58 -0
- package/corpus/templates/calendar/app/i18n/fr-FR.ts +58 -0
- package/corpus/templates/calendar/app/i18n/hi-IN.ts +57 -0
- package/corpus/templates/calendar/app/i18n/index.ts +31 -0
- package/corpus/templates/calendar/app/i18n/ja-JP.ts +58 -0
- package/corpus/templates/calendar/app/i18n/ko-KR.ts +57 -0
- package/corpus/templates/calendar/app/i18n/pt-BR.ts +57 -0
- package/corpus/templates/calendar/app/i18n/zh-CN.ts +57 -0
- package/corpus/templates/calendar/app/i18n-data.ts +516 -0
- package/corpus/templates/calendar/app/pages/CalendarView.tsx +2 -0
- package/corpus/templates/calendar/app/pages/Settings.tsx +63 -28
- package/corpus/templates/calendar/app/root.tsx +78 -7
- package/corpus/templates/calendar/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
- package/corpus/templates/calendar/changelog/2026-06-24-settings-now-link-directly-to-agent-settings-for-model-api-k.md +6 -0
- package/corpus/templates/chat/.agents/skills/adding-a-feature/SKILL.md +5 -0
- package/corpus/templates/chat/.agents/skills/self-modifying-code/SKILL.md +6 -0
- package/corpus/templates/chat/app/components/layout/Header.tsx +17 -11
- package/corpus/templates/chat/app/components/layout/Layout.tsx +12 -8
- package/corpus/templates/chat/app/components/layout/Sidebar.tsx +47 -18
- package/corpus/templates/chat/app/i18n/ar-SA.ts +62 -0
- package/corpus/templates/chat/app/i18n/de-DE.ts +63 -0
- package/corpus/templates/chat/app/i18n/en-US.ts +63 -0
- package/corpus/templates/chat/app/i18n/es-ES.ts +63 -0
- package/corpus/templates/chat/app/i18n/fr-FR.ts +63 -0
- package/corpus/templates/chat/app/i18n/hi-IN.ts +63 -0
- package/corpus/templates/chat/app/i18n/index.ts +31 -0
- package/corpus/templates/chat/app/i18n/ja-JP.ts +63 -0
- package/corpus/templates/chat/app/i18n/ko-KR.ts +63 -0
- package/corpus/templates/chat/app/i18n/pt-BR.ts +63 -0
- package/corpus/templates/chat/app/i18n/zh-CN.ts +61 -0
- package/corpus/templates/chat/app/i18n-data.ts +475 -0
- package/corpus/templates/chat/app/root.tsx +18 -5
- package/corpus/templates/chat/app/routes/_index.tsx +9 -8
- package/corpus/templates/chat/app/routes/settings.tsx +86 -0
- package/corpus/templates/chat/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
- package/corpus/templates/chat/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
- package/corpus/templates/clips/.agents/skills/self-modifying-code/SKILL.md +6 -0
- package/corpus/templates/clips/app/components/layout/Header.tsx +23 -17
- package/corpus/templates/clips/app/components/library/empty-state.tsx +10 -34
- package/corpus/templates/clips/app/components/library/library-layout.tsx +45 -34
- package/corpus/templates/clips/app/i18n/ar-SA.ts +182 -0
- package/corpus/templates/clips/app/i18n/de-DE.ts +184 -0
- package/corpus/templates/clips/app/i18n/en-US.ts +179 -0
- package/corpus/templates/clips/app/i18n/es-ES.ts +183 -0
- package/corpus/templates/clips/app/i18n/fr-FR.ts +184 -0
- package/corpus/templates/clips/app/i18n/hi-IN.ts +180 -0
- package/corpus/templates/clips/app/i18n/index.ts +41 -0
- package/corpus/templates/clips/app/i18n/ja-JP.ts +180 -0
- package/corpus/templates/clips/app/i18n/ko-KR.ts +178 -0
- package/corpus/templates/clips/app/i18n/pt-BR.ts +183 -0
- package/corpus/templates/clips/app/i18n/zh-CN.ts +173 -0
- package/corpus/templates/clips/app/root.tsx +104 -10
- package/corpus/templates/clips/app/routes/_app.settings._index.tsx +154 -95
- package/corpus/templates/clips/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-24-clips-now-includes-a-language-picker-and-simplified-chinese-ui.md +6 -0
- package/corpus/templates/clips/changelog/2026-06-24-settings-now-link-directly-to-agent-settings-for-model-api-k.md +6 -0
- package/corpus/templates/content/.agents/skills/self-modifying-code/SKILL.md +6 -0
- package/corpus/templates/content/app/components/EmptyState.tsx +7 -5
- package/corpus/templates/content/app/components/ThemeToggle.tsx +4 -2
- package/corpus/templates/content/app/components/layout/Header.tsx +2 -0
- package/corpus/templates/content/app/components/layout/Layout.tsx +8 -7
- package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +41 -1
- package/corpus/templates/content/app/i18n/ar-SA.ts +3 -0
- package/corpus/templates/content/app/i18n/de-DE.ts +3 -0
- package/corpus/templates/content/app/i18n/en-US.ts +3 -0
- package/corpus/templates/content/app/i18n/es-ES.ts +3 -0
- package/corpus/templates/content/app/i18n/fr-FR.ts +3 -0
- package/corpus/templates/content/app/i18n/hi-IN.ts +3 -0
- package/corpus/templates/content/app/i18n/index.ts +31 -0
- package/corpus/templates/content/app/i18n/ja-JP.ts +3 -0
- package/corpus/templates/content/app/i18n/ko-KR.ts +3 -0
- package/corpus/templates/content/app/i18n/pt-BR.ts +3 -0
- package/corpus/templates/content/app/i18n/zh-CN.ts +3 -0
- package/corpus/templates/content/app/i18n-data.ts +490 -0
- package/corpus/templates/content/app/root.tsx +110 -23
- package/corpus/templates/content/app/routes/_app.settings.tsx +84 -0
- package/corpus/templates/content/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
- package/corpus/templates/content/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
- package/corpus/templates/design/.agents/skills/self-modifying-code/SKILL.md +6 -0
- package/corpus/templates/design/app/components/layout/Header.tsx +16 -8
- package/corpus/templates/design/app/components/layout/Layout.tsx +8 -6
- package/corpus/templates/design/app/components/layout/Sidebar.tsx +25 -9
- package/corpus/templates/design/app/i18n/ar-SA.ts +3 -0
- package/corpus/templates/design/app/i18n/de-DE.ts +3 -0
- package/corpus/templates/design/app/i18n/en-US.ts +3 -0
- package/corpus/templates/design/app/i18n/es-ES.ts +3 -0
- package/corpus/templates/design/app/i18n/fr-FR.ts +3 -0
- package/corpus/templates/design/app/i18n/hi-IN.ts +3 -0
- package/corpus/templates/design/app/i18n/index.ts +31 -0
- package/corpus/templates/design/app/i18n/ja-JP.ts +3 -0
- package/corpus/templates/design/app/i18n/ko-KR.ts +3 -0
- package/corpus/templates/design/app/i18n/pt-BR.ts +3 -0
- package/corpus/templates/design/app/i18n/zh-CN.ts +3 -0
- package/corpus/templates/design/app/i18n-data.ts +350 -0
- package/corpus/templates/design/app/root.tsx +40 -15
- package/corpus/templates/design/app/routes/settings.tsx +43 -0
- package/corpus/templates/design/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
- package/corpus/templates/design/changelog/2026-06-24-settings-now-link-directly-to-agent-settings-for-model-api-k.md +6 -0
- package/corpus/templates/dispatch/.agents/skills/self-modifying-code/SKILL.md +6 -0
- package/corpus/templates/dispatch/app/i18n/ar-SA.ts +3 -0
- package/corpus/templates/dispatch/app/i18n/de-DE.ts +3 -0
- package/corpus/templates/dispatch/app/i18n/en-US.ts +3 -0
- package/corpus/templates/dispatch/app/i18n/es-ES.ts +3 -0
- package/corpus/templates/dispatch/app/i18n/fr-FR.ts +3 -0
- package/corpus/templates/dispatch/app/i18n/hi-IN.ts +3 -0
- package/corpus/templates/dispatch/app/i18n/index.ts +31 -0
- package/corpus/templates/dispatch/app/i18n/ja-JP.ts +3 -0
- package/corpus/templates/dispatch/app/i18n/ko-KR.ts +3 -0
- package/corpus/templates/dispatch/app/i18n/pt-BR.ts +3 -0
- package/corpus/templates/dispatch/app/i18n/zh-CN.ts +3 -0
- package/corpus/templates/dispatch/app/i18n-data.ts +267 -0
- package/corpus/templates/dispatch/app/root.tsx +18 -4
- package/corpus/templates/dispatch/app/routes/settings.tsx +86 -0
- package/corpus/templates/dispatch/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
- package/corpus/templates/dispatch/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
- package/corpus/templates/forms/.agents/skills/self-modifying-code/SKILL.md +6 -0
- package/corpus/templates/forms/app/components/layout/Header.tsx +16 -9
- package/corpus/templates/forms/app/components/layout/Layout.tsx +6 -4
- package/corpus/templates/forms/app/components/layout/Sidebar.tsx +34 -17
- package/corpus/templates/forms/app/i18n/ar-SA.ts +58 -0
- package/corpus/templates/forms/app/i18n/de-DE.ts +59 -0
- package/corpus/templates/forms/app/i18n/en-US.ts +59 -0
- package/corpus/templates/forms/app/i18n/es-ES.ts +59 -0
- package/corpus/templates/forms/app/i18n/fr-FR.ts +59 -0
- package/corpus/templates/forms/app/i18n/hi-IN.ts +59 -0
- package/corpus/templates/forms/app/i18n/index.ts +31 -0
- package/corpus/templates/forms/app/i18n/ja-JP.ts +59 -0
- package/corpus/templates/forms/app/i18n/ko-KR.ts +59 -0
- package/corpus/templates/forms/app/i18n/pt-BR.ts +59 -0
- package/corpus/templates/forms/app/i18n/zh-CN.ts +56 -0
- package/corpus/templates/forms/app/root.tsx +65 -16
- package/corpus/templates/forms/app/routes/_app.settings.tsx +85 -0
- package/corpus/templates/forms/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
- package/corpus/templates/forms/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
- package/corpus/templates/macros/app/components/layout/AppLayout.tsx +29 -17
- package/corpus/templates/macros/app/components/layout/Header.tsx +16 -10
- package/corpus/templates/macros/app/i18n/ar-SA.ts +54 -0
- package/corpus/templates/macros/app/i18n/de-DE.ts +55 -0
- package/corpus/templates/macros/app/i18n/en-US.ts +55 -0
- package/corpus/templates/macros/app/i18n/es-ES.ts +55 -0
- package/corpus/templates/macros/app/i18n/fr-FR.ts +55 -0
- package/corpus/templates/macros/app/i18n/hi-IN.ts +55 -0
- package/corpus/templates/macros/app/i18n/index.ts +31 -0
- package/corpus/templates/macros/app/i18n/ja-JP.ts +55 -0
- package/corpus/templates/macros/app/i18n/ko-KR.ts +55 -0
- package/corpus/templates/macros/app/i18n/pt-BR.ts +55 -0
- package/corpus/templates/macros/app/i18n/zh-CN.ts +53 -0
- package/corpus/templates/macros/app/root.tsx +65 -15
- package/corpus/templates/macros/app/routes/settings.tsx +85 -0
- package/corpus/templates/macros/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
- package/corpus/templates/macros/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
- package/corpus/templates/mail/.agents/skills/self-modifying-code/SKILL.md +6 -0
- package/corpus/templates/mail/app/components/layout/AppLayout.tsx +9 -4
- package/corpus/templates/mail/app/i18n/ar-SA.ts +33 -0
- package/corpus/templates/mail/app/i18n/de-DE.ts +33 -0
- package/corpus/templates/mail/app/i18n/en-US.ts +32 -0
- package/corpus/templates/mail/app/i18n/es-ES.ts +33 -0
- package/corpus/templates/mail/app/i18n/fr-FR.ts +33 -0
- package/corpus/templates/mail/app/i18n/hi-IN.ts +32 -0
- package/corpus/templates/mail/app/i18n/index.ts +31 -0
- package/corpus/templates/mail/app/i18n/ja-JP.ts +32 -0
- package/corpus/templates/mail/app/i18n/ko-KR.ts +33 -0
- package/corpus/templates/mail/app/i18n/pt-BR.ts +34 -0
- package/corpus/templates/mail/app/i18n/zh-CN.ts +32 -0
- package/corpus/templates/mail/app/pages/SettingsPage.tsx +67 -13
- package/corpus/templates/mail/app/root.tsx +20 -0
- package/corpus/templates/mail/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
- package/corpus/templates/mail/changelog/2026-06-24-settings-now-link-directly-to-agent-settings-for-model-api-k.md +6 -0
- package/corpus/templates/plan/.agents/skills/adding-a-feature/SKILL.md +5 -0
- package/corpus/templates/plan/.agents/skills/self-modifying-code/SKILL.md +6 -0
- package/corpus/templates/plan/app/components/layout/Header.tsx +19 -12
- package/corpus/templates/plan/app/components/layout/Layout.tsx +11 -7
- package/corpus/templates/plan/app/components/layout/Sidebar.tsx +41 -28
- package/corpus/templates/plan/app/i18n/ar-SA.ts +77 -0
- package/corpus/templates/plan/app/i18n/de-DE.ts +78 -0
- package/corpus/templates/plan/app/i18n/en-US.ts +78 -0
- package/corpus/templates/plan/app/i18n/es-ES.ts +78 -0
- package/corpus/templates/plan/app/i18n/fr-FR.ts +78 -0
- package/corpus/templates/plan/app/i18n/hi-IN.ts +78 -0
- package/corpus/templates/plan/app/i18n/index.ts +31 -0
- package/corpus/templates/plan/app/i18n/ja-JP.ts +79 -0
- package/corpus/templates/plan/app/i18n/ko-KR.ts +77 -0
- package/corpus/templates/plan/app/i18n/pt-BR.ts +78 -0
- package/corpus/templates/plan/app/i18n/zh-CN.ts +74 -0
- package/corpus/templates/plan/app/root.tsx +45 -8
- package/corpus/templates/plan/app/routes/settings.tsx +86 -0
- package/corpus/templates/plan/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
- package/corpus/templates/plan/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
- package/corpus/templates/slides/.agents/skills/self-modifying-code/SKILL.md +6 -0
- package/corpus/templates/slides/app/components/layout/Header.tsx +23 -11
- package/corpus/templates/slides/app/components/layout/Layout.tsx +7 -6
- package/corpus/templates/slides/app/components/layout/Sidebar.tsx +23 -11
- package/corpus/templates/slides/app/i18n/ar-SA.ts +54 -0
- package/corpus/templates/slides/app/i18n/de-DE.ts +56 -0
- package/corpus/templates/slides/app/i18n/en-US.ts +55 -0
- package/corpus/templates/slides/app/i18n/es-ES.ts +55 -0
- package/corpus/templates/slides/app/i18n/fr-FR.ts +55 -0
- package/corpus/templates/slides/app/i18n/hi-IN.ts +55 -0
- package/corpus/templates/slides/app/i18n/index.ts +31 -0
- package/corpus/templates/slides/app/i18n/ja-JP.ts +55 -0
- package/corpus/templates/slides/app/i18n/ko-KR.ts +55 -0
- package/corpus/templates/slides/app/i18n/pt-BR.ts +55 -0
- package/corpus/templates/slides/app/i18n/zh-CN.ts +53 -0
- package/corpus/templates/slides/app/root.tsx +50 -8
- package/corpus/templates/slides/app/routes/settings.tsx +85 -0
- package/corpus/templates/slides/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
- package/corpus/templates/slides/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
- package/corpus/templates/videos/.agents/skills/self-modifying-code/SKILL.md +6 -0
- package/corpus/templates/videos/app/components/NewCompositionPopover.tsx +14 -9
- package/corpus/templates/videos/app/components/Sidebar.tsx +16 -9
- package/corpus/templates/videos/app/components/StudioHeader.tsx +12 -8
- package/corpus/templates/videos/app/components/layout/Header.tsx +21 -15
- package/corpus/templates/videos/app/components/layout/Layout.tsx +10 -7
- package/corpus/templates/videos/app/components/layout/NavSidebar.tsx +21 -6
- package/corpus/templates/videos/app/i18n/ar-SA.ts +73 -0
- package/corpus/templates/videos/app/i18n/de-DE.ts +75 -0
- package/corpus/templates/videos/app/i18n/en-US.ts +74 -0
- package/corpus/templates/videos/app/i18n/es-ES.ts +75 -0
- package/corpus/templates/videos/app/i18n/fr-FR.ts +75 -0
- package/corpus/templates/videos/app/i18n/hi-IN.ts +74 -0
- package/corpus/templates/videos/app/i18n/index.ts +31 -0
- package/corpus/templates/videos/app/i18n/ja-JP.ts +74 -0
- package/corpus/templates/videos/app/i18n/ko-KR.ts +74 -0
- package/corpus/templates/videos/app/i18n/pt-BR.ts +75 -0
- package/corpus/templates/videos/app/i18n/zh-CN.ts +72 -0
- package/corpus/templates/videos/app/pages/Index.tsx +11 -9
- package/corpus/templates/videos/app/root.tsx +45 -7
- package/corpus/templates/videos/app/routes/settings.tsx +85 -0
- package/corpus/templates/videos/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
- package/corpus/templates/videos/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
- package/dist/client/CommandMenu.d.ts +3 -0
- package/dist/client/CommandMenu.d.ts.map +1 -1
- package/dist/client/CommandMenu.js +9 -0
- package/dist/client/CommandMenu.js.map +1 -1
- package/dist/client/app-providers.d.ts +8 -1
- package/dist/client/app-providers.d.ts.map +1 -1
- package/dist/client/app-providers.js +7 -5
- package/dist/client/app-providers.js.map +1 -1
- package/dist/client/i18n.d.ts +54 -0
- package/dist/client/i18n.d.ts.map +1 -0
- package/dist/client/i18n.js +354 -0
- package/dist/client/i18n.js.map +1 -0
- package/dist/client/index.d.ts +2 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +2 -1
- package/dist/client/index.js.map +1 -1
- package/dist/index.browser.d.ts +1 -1
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +1 -1
- package/dist/index.browser.js.map +1 -1
- package/dist/localization/actions/get-localization-preference.d.ts +4 -0
- package/dist/localization/actions/get-localization-preference.d.ts.map +1 -0
- package/dist/localization/actions/get-localization-preference.js +16 -0
- package/dist/localization/actions/get-localization-preference.js.map +1 -0
- package/dist/localization/actions/set-localization-preference.d.ts +6 -0
- package/dist/localization/actions/set-localization-preference.d.ts.map +1 -0
- package/dist/localization/actions/set-localization-preference.js +24 -0
- package/dist/localization/actions/set-localization-preference.js.map +1 -0
- package/dist/localization/index.d.ts +3 -0
- package/dist/localization/index.d.ts.map +1 -0
- package/dist/localization/index.js +3 -0
- package/dist/localization/index.js.map +1 -0
- package/dist/localization/server.d.ts +25 -0
- package/dist/localization/server.d.ts.map +1 -0
- package/dist/localization/server.js +69 -0
- package/dist/localization/server.js.map +1 -0
- package/dist/localization/shared.d.ts +25 -0
- package/dist/localization/shared.d.ts.map +1 -0
- package/dist/localization/shared.js +134 -0
- package/dist/localization/shared.js.map +1 -0
- package/dist/server/action-discovery.d.ts.map +1 -1
- package/dist/server/action-discovery.js +8 -0
- package/dist/server/action-discovery.js.map +1 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -0
- package/dist/server/index.js.map +1 -1
- package/dist/templates/default/.agents/skills/adding-a-feature/SKILL.md +5 -0
- package/dist/templates/default/.agents/skills/internationalization/SKILL.md +77 -0
- package/dist/templates/default/.agents/skills/self-modifying-code/SKILL.md +6 -0
- package/dist/templates/default/AGENTS.md +16 -15
- package/dist/templates/default/app/i18n/en-US.ts +29 -0
- package/dist/templates/default/app/i18n/index.ts +13 -0
- package/dist/templates/default/app/root.tsx +20 -1
- package/dist/templates/default/app/routes/_index.tsx +24 -9
- package/dist/templates/default/app/routes/settings.tsx +67 -0
- package/dist/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +5 -0
- package/dist/templates/workspace-core/.agents/skills/internationalization/SKILL.md +77 -0
- package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +6 -0
- package/dist/vite/action-types-plugin.d.ts.map +1 -1
- package/dist/vite/action-types-plugin.js +8 -0
- package/dist/vite/action-types-plugin.js.map +1 -1
- package/docs/AGENTS.md +1 -0
- package/docs/content/client.md +15 -0
- package/docs/content/internationalization.md +145 -0
- package/docs/content/locales/ar-SA/internationalization.md +102 -0
- package/docs/content/locales/de-DE/internationalization.md +102 -0
- package/docs/content/locales/es-ES/internationalization.md +102 -0
- package/docs/content/locales/fr-FR/internationalization.md +102 -0
- package/docs/content/locales/hi-IN/internationalization.md +102 -0
- package/docs/content/locales/ja-JP/internationalization.md +114 -0
- package/docs/content/locales/ko-KR/internationalization.md +102 -0
- package/docs/content/locales/pt-BR/internationalization.md +102 -0
- package/docs/content/locales/zh-CN/internationalization.md +102 -0
- package/docs/content/skills-guide.md +19 -18
- package/package.json +7 -1
- package/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +5 -0
- package/src/templates/default/.agents/skills/internationalization/SKILL.md +77 -0
- package/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +6 -0
- package/src/templates/default/AGENTS.md +16 -15
- package/src/templates/default/app/i18n/en-US.ts +29 -0
- package/src/templates/default/app/i18n/index.ts +13 -0
- package/src/templates/default/app/root.tsx +20 -1
- package/src/templates/default/app/routes/_index.tsx +24 -9
- package/src/templates/default/app/routes/settings.tsx +67 -0
- package/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +5 -0
- package/src/templates/workspace-core/.agents/skills/internationalization/SKILL.md +77 -0
- package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +6 -0
|
@@ -14,11 +14,13 @@ import { useDbSync } from "@agent-native/core/client";
|
|
|
14
14
|
import {
|
|
15
15
|
AppProviders,
|
|
16
16
|
appPath,
|
|
17
|
+
getLocaleInitScript,
|
|
17
18
|
getThemeInitScript,
|
|
18
19
|
createAgentNativeQueryClient,
|
|
19
20
|
} from "@agent-native/core/client";
|
|
20
21
|
import { configureTracking } from "@agent-native/core/client";
|
|
21
22
|
import { useNavigationState } from "./hooks/use-navigation-state";
|
|
23
|
+
import { i18nCatalog } from "./i18n";
|
|
22
24
|
import { TAB_ID } from "./lib/tab-id";
|
|
23
25
|
configureTracking({
|
|
24
26
|
getDefaultProps: (_name, properties) => ({
|
|
@@ -29,6 +31,7 @@ configureTracking({
|
|
|
29
31
|
import "./global.css";
|
|
30
32
|
|
|
31
33
|
const THEME_INIT_SCRIPT_SELECTOR = "script[data-agent-native-theme-init]";
|
|
34
|
+
const LOCALE_INIT_SCRIPT_SELECTOR = "script[data-agent-native-locale-init]";
|
|
32
35
|
|
|
33
36
|
function getHydrationStableThemeInitScript() {
|
|
34
37
|
if (typeof document !== "undefined") {
|
|
@@ -40,7 +43,18 @@ function getHydrationStableThemeInitScript() {
|
|
|
40
43
|
return getThemeInitScript();
|
|
41
44
|
}
|
|
42
45
|
|
|
46
|
+
function getHydrationStableLocaleInitScript() {
|
|
47
|
+
if (typeof document !== "undefined") {
|
|
48
|
+
const existing = document.querySelector<HTMLScriptElement>(
|
|
49
|
+
LOCALE_INIT_SCRIPT_SELECTOR,
|
|
50
|
+
);
|
|
51
|
+
if (existing?.innerHTML) return existing.innerHTML;
|
|
52
|
+
}
|
|
53
|
+
return getLocaleInitScript();
|
|
54
|
+
}
|
|
55
|
+
|
|
43
56
|
const THEME_INIT_SCRIPT = getHydrationStableThemeInitScript();
|
|
57
|
+
const LOCALE_INIT_SCRIPT = getHydrationStableLocaleInitScript();
|
|
44
58
|
|
|
45
59
|
export function Layout({ children }: { children: React.ReactNode }) {
|
|
46
60
|
return (
|
|
@@ -56,6 +70,11 @@ export function Layout({ children }: { children: React.ReactNode }) {
|
|
|
56
70
|
suppressHydrationWarning
|
|
57
71
|
dangerouslySetInnerHTML={{ __html: THEME_INIT_SCRIPT }}
|
|
58
72
|
/>
|
|
73
|
+
<script
|
|
74
|
+
data-agent-native-locale-init
|
|
75
|
+
suppressHydrationWarning
|
|
76
|
+
dangerouslySetInnerHTML={{ __html: LOCALE_INIT_SCRIPT }}
|
|
77
|
+
/>
|
|
59
78
|
<link rel="manifest" href={appPath("/manifest.json")} />
|
|
60
79
|
<link rel="icon" type="image/svg+xml" href={appPath("/favicon.svg")} />
|
|
61
80
|
<meta name="theme-color" content="#111111" />
|
|
@@ -88,7 +107,7 @@ function DbSyncSetup() {
|
|
|
88
107
|
export default function Root() {
|
|
89
108
|
const [queryClient] = useState(() => createAgentNativeQueryClient());
|
|
90
109
|
return (
|
|
91
|
-
<AppProviders queryClient={queryClient}>
|
|
110
|
+
<AppProviders queryClient={queryClient} i18n={{ catalog: i18nCatalog }}>
|
|
92
111
|
<DbSyncSetup />
|
|
93
112
|
<Outlet />
|
|
94
113
|
</AppProviders>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useTheme } from "next-themes";
|
|
2
|
-
import {
|
|
2
|
+
import { Link } from "react-router";
|
|
3
|
+
import { useActionQuery, useT } from "@agent-native/core/client";
|
|
3
4
|
|
|
4
5
|
export function meta() {
|
|
5
6
|
return [{ title: "{{APP_TITLE}}" }];
|
|
@@ -7,6 +8,7 @@ export function meta() {
|
|
|
7
8
|
|
|
8
9
|
export default function IndexPage() {
|
|
9
10
|
const { resolvedTheme, setTheme } = useTheme();
|
|
11
|
+
const t = useT();
|
|
10
12
|
const isDark = resolvedTheme === "dark";
|
|
11
13
|
const { data } = useActionQuery("hello", { name: "{{APP_TITLE}}" });
|
|
12
14
|
|
|
@@ -15,10 +17,10 @@ export default function IndexPage() {
|
|
|
15
17
|
<div className="max-w-md w-full space-y-8 text-center">
|
|
16
18
|
<div className="space-y-3">
|
|
17
19
|
<h1 className="text-2xl font-semibold tracking-tight text-foreground">
|
|
18
|
-
|
|
20
|
+
{t("home.title")}
|
|
19
21
|
</h1>
|
|
20
22
|
<p className="text-[14px] text-muted-foreground leading-relaxed">
|
|
21
|
-
|
|
23
|
+
{t("home.intro")}{" "}
|
|
22
24
|
<code className="text-[13px] bg-muted px-1.5 py-0.5 rounded font-mono">
|
|
23
25
|
app/routes/_index.tsx
|
|
24
26
|
</code>
|
|
@@ -29,10 +31,10 @@ export default function IndexPage() {
|
|
|
29
31
|
|
|
30
32
|
<div className="rounded-lg border border-border/50 px-4 py-3 text-left">
|
|
31
33
|
<p className="text-[13px] font-medium text-foreground">
|
|
32
|
-
|
|
34
|
+
{t("home.actionCardTitle")}
|
|
33
35
|
</p>
|
|
34
36
|
<p className="text-[12px] text-muted-foreground mt-0.5">
|
|
35
|
-
{data?.message ?? "
|
|
37
|
+
{data?.message ?? t("home.loadingAction")}
|
|
36
38
|
</p>
|
|
37
39
|
</div>
|
|
38
40
|
|
|
@@ -44,21 +46,34 @@ export default function IndexPage() {
|
|
|
44
46
|
className="group rounded-lg border border-border/50 px-4 py-3 hover:bg-accent/50 transition-colors"
|
|
45
47
|
>
|
|
46
48
|
<p className="text-[13px] font-medium text-foreground">
|
|
47
|
-
|
|
49
|
+
{t("home.docsTitle")}
|
|
48
50
|
</p>
|
|
49
51
|
<p className="text-[12px] text-muted-foreground mt-0.5">
|
|
50
|
-
|
|
52
|
+
{t("home.docsDescription")}
|
|
51
53
|
</p>
|
|
52
54
|
</a>
|
|
53
55
|
<button
|
|
54
56
|
onClick={() => setTheme(isDark ? "light" : "dark")}
|
|
55
57
|
className="rounded-lg border border-border/50 px-4 py-3 hover:bg-accent/50 transition-colors text-left"
|
|
56
58
|
>
|
|
57
|
-
<p className="text-[13px] font-medium text-foreground">
|
|
59
|
+
<p className="text-[13px] font-medium text-foreground">
|
|
60
|
+
{t("home.themeTitle")}
|
|
61
|
+
</p>
|
|
58
62
|
<p className="text-[12px] text-muted-foreground mt-0.5">
|
|
59
|
-
|
|
63
|
+
{t("home.themeDescription")}
|
|
60
64
|
</p>
|
|
61
65
|
</button>
|
|
66
|
+
<Link
|
|
67
|
+
to="/settings"
|
|
68
|
+
className="group rounded-lg border border-border/50 px-4 py-3 hover:bg-accent/50 transition-colors"
|
|
69
|
+
>
|
|
70
|
+
<p className="text-[13px] font-medium text-foreground">
|
|
71
|
+
{t("home.settingsTitle")}
|
|
72
|
+
</p>
|
|
73
|
+
<p className="text-[12px] text-muted-foreground mt-0.5">
|
|
74
|
+
{t("home.settingsDescription")}
|
|
75
|
+
</p>
|
|
76
|
+
</Link>
|
|
62
77
|
</div>
|
|
63
78
|
</div>
|
|
64
79
|
</div>
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Link } from "react-router";
|
|
2
|
+
import {
|
|
3
|
+
LanguagePicker,
|
|
4
|
+
openAgentSettings,
|
|
5
|
+
useT,
|
|
6
|
+
} from "@agent-native/core/client";
|
|
7
|
+
|
|
8
|
+
export function meta() {
|
|
9
|
+
return [{ title: "Settings - {{APP_TITLE}}" }];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default function SettingsPage() {
|
|
13
|
+
const t = useT();
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<main className="min-h-screen bg-background px-6 py-10">
|
|
17
|
+
<div className="mx-auto w-full max-w-2xl space-y-6">
|
|
18
|
+
<div className="space-y-2">
|
|
19
|
+
<Link
|
|
20
|
+
to="/"
|
|
21
|
+
className="text-[13px] text-muted-foreground hover:text-foreground"
|
|
22
|
+
>
|
|
23
|
+
{t("settings.backHome")}
|
|
24
|
+
</Link>
|
|
25
|
+
<h1 className="text-2xl font-semibold tracking-tight text-foreground">
|
|
26
|
+
{t("settings.title")}
|
|
27
|
+
</h1>
|
|
28
|
+
<p className="text-[14px] leading-relaxed text-muted-foreground">
|
|
29
|
+
{t("settings.description")}
|
|
30
|
+
</p>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<section className="rounded-lg border border-border/50 bg-card px-4 py-4">
|
|
34
|
+
<div className="space-y-1">
|
|
35
|
+
<h2 className="text-[15px] font-semibold text-foreground">
|
|
36
|
+
{t("settings.languageTitle")}
|
|
37
|
+
</h2>
|
|
38
|
+
<p className="text-[13px] leading-relaxed text-muted-foreground">
|
|
39
|
+
{t("settings.languageDescription")}
|
|
40
|
+
</p>
|
|
41
|
+
</div>
|
|
42
|
+
<div className="mt-4 max-w-xs">
|
|
43
|
+
<LanguagePicker label={t("settings.languageLabel")} />
|
|
44
|
+
</div>
|
|
45
|
+
</section>
|
|
46
|
+
|
|
47
|
+
<section className="rounded-lg border border-border/50 bg-card px-4 py-4">
|
|
48
|
+
<div className="space-y-1">
|
|
49
|
+
<h2 className="text-[15px] font-semibold text-foreground">
|
|
50
|
+
{t("settings.agentTitle")}
|
|
51
|
+
</h2>
|
|
52
|
+
<p className="text-[13px] leading-relaxed text-muted-foreground">
|
|
53
|
+
{t("settings.agentDescription")}
|
|
54
|
+
</p>
|
|
55
|
+
</div>
|
|
56
|
+
<button
|
|
57
|
+
type="button"
|
|
58
|
+
className="mt-4 rounded-md border border-border bg-background px-3 py-2 text-[13px] font-medium text-foreground transition-colors hover:bg-accent/50"
|
|
59
|
+
onClick={() => openAgentSettings()}
|
|
60
|
+
>
|
|
61
|
+
{t("settings.openAgentSettings")}
|
|
62
|
+
</button>
|
|
63
|
+
</section>
|
|
64
|
+
</div>
|
|
65
|
+
</main>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
@@ -86,6 +86,10 @@ Instruction examples may name secret keys like `SLACK_WEBHOOK`, but must use
|
|
|
86
86
|
placeholders such as `${keys.SLACK_WEBHOOK}` or `<SLACK_WEBHOOK>`. Do not paste
|
|
87
87
|
real keys, internal data, or customer data into instructions as examples.
|
|
88
88
|
|
|
89
|
+
If the feature adds or changes visible UI copy, prompts, toasts, labels, empty
|
|
90
|
+
states, or formatting, read `internationalization` and update the app's i18n
|
|
91
|
+
catalogs in the same change.
|
|
92
|
+
|
|
89
93
|
For app-backed skills, declare skill visibility in the app-skill manifest:
|
|
90
94
|
|
|
91
95
|
- `internal` — only the app's own agents should use it.
|
|
@@ -177,3 +181,4 @@ TL;DR: spread `ownableColumns()` into the resource table, pair it with `createSh
|
|
|
177
181
|
- **create-skill** — How to create skills for new patterns (area 3 in detail)
|
|
178
182
|
- **storing-data** — Where to store the feature's data
|
|
179
183
|
- **real-time-sync** — How the UI stays in sync when the agent writes data
|
|
184
|
+
- **internationalization** — How to update localized UI copy and catalogs
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: internationalization
|
|
3
|
+
description: >-
|
|
4
|
+
How to add or edit localized UI copy in agent-native apps. Use when adding,
|
|
5
|
+
removing, or changing user-visible interface text, prompts, toasts, labels,
|
|
6
|
+
empty states, or date/number/list formatting.
|
|
7
|
+
scope: dev
|
|
8
|
+
metadata:
|
|
9
|
+
internal: true
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Internationalization
|
|
13
|
+
|
|
14
|
+
## Rule
|
|
15
|
+
|
|
16
|
+
Visible framework/template UI copy belongs in the app's i18n catalog, not
|
|
17
|
+
inline in components. When you add or edit UI text, update the English source
|
|
18
|
+
catalog first, update existing locale catalogs, and run the i18n guard.
|
|
19
|
+
|
|
20
|
+
## Catalogs
|
|
21
|
+
|
|
22
|
+
Templates use `app/i18n/`:
|
|
23
|
+
|
|
24
|
+
- `en-US.ts` is the canonical source tree and fallback.
|
|
25
|
+
- Other locale files keep the same non-plural keys and the same placeholders.
|
|
26
|
+
- `index.ts` exports an `AgentNativeI18nCatalog` with English bundled and
|
|
27
|
+
non-English catalogs loaded by dynamic import.
|
|
28
|
+
|
|
29
|
+
Use BCP-47 filenames from the supported set: `en-US`, `zh-CN`, `es-ES`,
|
|
30
|
+
`fr-FR`, `de-DE`, `ja-JP`, `ko-KR`, `pt-BR`, `hi-IN`, `ar-SA`.
|
|
31
|
+
|
|
32
|
+
## UI Pattern
|
|
33
|
+
|
|
34
|
+
- Wrap apps with `AppProviders i18n={{ catalog: i18nCatalog }}`.
|
|
35
|
+
- Read strings with `useT()` and keep keys stable.
|
|
36
|
+
- Sidebar apps should expose a `/settings` route in the app sidebar. Put
|
|
37
|
+
`<LanguagePicker />` in that settings page, usually in a Language or General
|
|
38
|
+
section, and keep the header language icon only as a quick-access shortcut.
|
|
39
|
+
- Settings pages should include an "Agent settings" row/card that calls
|
|
40
|
+
`openAgentSettings()` from `@agent-native/core/client` to open the right
|
|
41
|
+
agent sidebar's Settings tab. Localize the title, description, and button.
|
|
42
|
+
- Use `useFormatters()` for dates, numbers, relative time, and lists instead
|
|
43
|
+
of embedding formatted values in translation strings.
|
|
44
|
+
- Do not translate stable identifiers: action names, route names, enum values,
|
|
45
|
+
app-state keys, database values, protocol fields, env var names, or provider
|
|
46
|
+
names.
|
|
47
|
+
|
|
48
|
+
## Plurals And Placeholders
|
|
49
|
+
|
|
50
|
+
Plural strings use i18next/CLDR suffixes. Do not force every locale to copy
|
|
51
|
+
English plural categories:
|
|
52
|
+
|
|
53
|
+
- English uses `_one` and `_other`.
|
|
54
|
+
- Chinese and Japanese usually use `_other`.
|
|
55
|
+
- Arabic uses `_zero`, `_one`, `_two`, `_few`, `_many`, and `_other`.
|
|
56
|
+
|
|
57
|
+
Keep interpolation placeholders identical across locales, such as
|
|
58
|
+
`{{count}}`, `{{name}}`, or ICU-style `{count}` arguments.
|
|
59
|
+
|
|
60
|
+
## RTL
|
|
61
|
+
|
|
62
|
+
New UI should be RTL-safe. Prefer logical CSS utilities/properties such as
|
|
63
|
+
`ms-*`, `me-*`, `ps-*`, `pe-*`, `start-*`, `end-*`, `text-start`, and
|
|
64
|
+
`text-end` when direction matters. Avoid hardcoded left/right positioning for
|
|
65
|
+
new localized UI unless it is genuinely physical.
|
|
66
|
+
|
|
67
|
+
## Verification
|
|
68
|
+
|
|
69
|
+
Run:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pnpm guard:i18n-catalogs
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
For broader changes, also run the affected template tests and `pnpm typecheck`.
|
|
76
|
+
Machine translation is only a starting point; high-visibility strings need
|
|
77
|
+
human review.
|
package/corpus/core/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md
CHANGED
|
@@ -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
|
|
@@ -78,6 +78,16 @@ const CORE_SHARING_ACTIONS: Array<{ name: string; specifier: string }> = [
|
|
|
78
78
|
name: "context-report",
|
|
79
79
|
specifier: "@agent-native/core/agent/context-xray/actions/context-report",
|
|
80
80
|
},
|
|
81
|
+
{
|
|
82
|
+
name: "get-localization-preference",
|
|
83
|
+
specifier:
|
|
84
|
+
"@agent-native/core/localization/actions/get-localization-preference",
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: "set-localization-preference",
|
|
88
|
+
specifier:
|
|
89
|
+
"@agent-native/core/localization/actions/set-localization-preference",
|
|
90
|
+
},
|
|
81
91
|
];
|
|
82
92
|
|
|
83
93
|
function isRuntimeSourceFile(filename: string): boolean {
|
|
@@ -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
|
|
@@ -6,22 +6,23 @@ import {
|
|
|
6
6
|
useHeaderTitle,
|
|
7
7
|
useHeaderActions,
|
|
8
8
|
} from "./HeaderActions";
|
|
9
|
-
import { AgentToggleButton } from "@agent-native/core/client";
|
|
9
|
+
import { AgentToggleButton, LanguagePicker } from "@agent-native/core/client";
|
|
10
10
|
import { RunsTray } from "@agent-native/core/client/progress";
|
|
11
|
+
import { useT } from "@agent-native/core/client";
|
|
11
12
|
|
|
12
|
-
const
|
|
13
|
-
"/": "
|
|
14
|
-
"/data-sources": "
|
|
15
|
-
"/data-dictionary": "
|
|
16
|
-
"/catalog": "
|
|
17
|
-
"/analyses": "
|
|
18
|
-
"/dashboards/explorer": "
|
|
19
|
-
"/team": "
|
|
20
|
-
"/settings": "
|
|
13
|
+
const pageTitleKeys: Record<string, string> = {
|
|
14
|
+
"/": "navigation.overview",
|
|
15
|
+
"/data-sources": "navigation.dataSources",
|
|
16
|
+
"/data-dictionary": "navigation.dataDictionary",
|
|
17
|
+
"/catalog": "navigation.templateCatalog",
|
|
18
|
+
"/analyses": "navigation.analyses",
|
|
19
|
+
"/dashboards/explorer": "navigation.explorer",
|
|
20
|
+
"/team": "navigation.team",
|
|
21
|
+
"/settings": "navigation.settings",
|
|
21
22
|
};
|
|
22
23
|
|
|
23
|
-
function resolveTitle(pathname: string): ReactNode {
|
|
24
|
-
if (
|
|
24
|
+
function resolveTitle(pathname: string, t: (key: string) => string): ReactNode {
|
|
25
|
+
if (pageTitleKeys[pathname]) return t(pageTitleKeys[pathname]);
|
|
25
26
|
|
|
26
27
|
const adhocMatch = pathname.match(/^\/(?:adhoc|dashboards)\/(.+)$/);
|
|
27
28
|
if (adhocMatch) {
|
|
@@ -30,16 +31,17 @@ function resolveTitle(pathname: string): ReactNode {
|
|
|
30
31
|
return dash?.name || <DashboardTitleSkeleton />;
|
|
31
32
|
}
|
|
32
33
|
|
|
33
|
-
if (pathname.startsWith("/analyses/")) return "
|
|
34
|
+
if (pathname.startsWith("/analyses/")) return t("navigation.analyses");
|
|
34
35
|
|
|
35
|
-
return "
|
|
36
|
+
return t("navigation.brand");
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
export function Header() {
|
|
39
40
|
const location = useLocation();
|
|
41
|
+
const t = useT();
|
|
40
42
|
const title = useHeaderTitle();
|
|
41
43
|
const actions = useHeaderActions();
|
|
42
|
-
const fallbackTitle = resolveTitle(location.pathname);
|
|
44
|
+
const fallbackTitle = resolveTitle(location.pathname, t);
|
|
43
45
|
|
|
44
46
|
return (
|
|
45
47
|
<header className="flex h-12 items-center gap-3 border-b border-border bg-background px-4 lg:px-6 shrink-0">
|
|
@@ -55,6 +57,7 @@ export function Header() {
|
|
|
55
57
|
</div>
|
|
56
58
|
<div className="flex items-center gap-2 shrink-0">
|
|
57
59
|
{actions}
|
|
60
|
+
<LanguagePicker variant="icon" />
|
|
58
61
|
<RunsTray pollMs={1500} />
|
|
59
62
|
<AgentToggleButton />
|
|
60
63
|
</div>
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
useAgentChatHomeHandoff,
|
|
13
13
|
useAgentChatHomeHandoffLinks,
|
|
14
14
|
useGuidedQuestionFlow,
|
|
15
|
+
useT,
|
|
15
16
|
} from "@agent-native/core/client";
|
|
16
17
|
import { InvitationBanner } from "@agent-native/core/client/org";
|
|
17
18
|
import { useNavigationState } from "@/hooks/use-navigation-state";
|
|
@@ -27,6 +28,7 @@ export function Layout({ children }: LayoutProps) {
|
|
|
27
28
|
useNavigationState();
|
|
28
29
|
const location = useLocation();
|
|
29
30
|
const navigate = useNavigate();
|
|
31
|
+
const t = useT();
|
|
30
32
|
|
|
31
33
|
// Analytics has two distinct "primary resources" — dashboards
|
|
32
34
|
// (`/dashboards/:id`, legacy `/adhoc/:id`) and ad-hoc analyses
|
|
@@ -149,12 +151,12 @@ export function Layout({ children }: LayoutProps) {
|
|
|
149
151
|
browserTabId={TAB_ID}
|
|
150
152
|
openOnChatRunning={chatHomeHandoffActive}
|
|
151
153
|
onFullscreenRequest={openAskAgentFullscreen}
|
|
152
|
-
emptyStateText="
|
|
154
|
+
emptyStateText={t("chat.emptyState")}
|
|
153
155
|
suggestions={[
|
|
154
|
-
"
|
|
155
|
-
"
|
|
156
|
-
"
|
|
157
|
-
"
|
|
156
|
+
t("chat.suggestionArrGrowth"),
|
|
157
|
+
t("chat.suggestionChurn"),
|
|
158
|
+
t("chat.suggestionAnomalies"),
|
|
159
|
+
t("chat.suggestionMrr"),
|
|
158
160
|
]}
|
|
159
161
|
scope={sidebarScope}
|
|
160
162
|
>
|
|
@@ -3,10 +3,12 @@ import { useLocation } from "react-router";
|
|
|
3
3
|
import { IconMenu, IconChartBar } from "@tabler/icons-react";
|
|
4
4
|
import { Sheet, SheetContent, SheetTitle } from "@/components/ui/sheet";
|
|
5
5
|
import { Sidebar } from "./Sidebar";
|
|
6
|
+
import { useT } from "@agent-native/core/client";
|
|
6
7
|
|
|
7
8
|
export function MobileNav() {
|
|
8
9
|
const [open, setOpen] = useState(false);
|
|
9
10
|
const location = useLocation();
|
|
11
|
+
const t = useT();
|
|
10
12
|
|
|
11
13
|
// Auto-close on route change
|
|
12
14
|
useEffect(() => {
|
|
@@ -18,7 +20,7 @@ export function MobileNav() {
|
|
|
18
20
|
<button
|
|
19
21
|
onClick={() => setOpen(true)}
|
|
20
22
|
className="mr-3 p-2.5 -ml-1 rounded-md hover:bg-sidebar-accent/50"
|
|
21
|
-
aria-label="
|
|
23
|
+
aria-label={t("navigation.openNavigation")}
|
|
22
24
|
>
|
|
23
25
|
<IconMenu className="h-5 w-5 text-foreground" />
|
|
24
26
|
</button>
|
|
@@ -26,12 +28,16 @@ export function MobileNav() {
|
|
|
26
28
|
<div className="flex h-7 w-7 items-center justify-center rounded-lg bg-primary text-primary-foreground">
|
|
27
29
|
<IconChartBar className="h-4 w-4" />
|
|
28
30
|
</div>
|
|
29
|
-
<span className="text-base font-bold tracking-tight">
|
|
31
|
+
<span className="text-base font-bold tracking-tight">
|
|
32
|
+
{t("navigation.brand")}
|
|
33
|
+
</span>
|
|
30
34
|
</div>
|
|
31
35
|
|
|
32
36
|
<Sheet open={open} onOpenChange={setOpen}>
|
|
33
37
|
<SheetContent side="left" className="p-0 w-[280px]">
|
|
34
|
-
<SheetTitle className="sr-only">
|
|
38
|
+
<SheetTitle className="sr-only">
|
|
39
|
+
{t("navigation.navigation")}
|
|
40
|
+
</SheetTitle>
|
|
35
41
|
<Sidebar mobile />
|
|
36
42
|
</SheetContent>
|
|
37
43
|
</Sheet>
|
|
@@ -96,6 +96,7 @@ import {
|
|
|
96
96
|
navigateWithAgentChatViewTransition,
|
|
97
97
|
useActionMutation,
|
|
98
98
|
useChangeVersions,
|
|
99
|
+
useT,
|
|
99
100
|
} from "@agent-native/core/client";
|
|
100
101
|
import { ExtensionsSidebarSection } from "@agent-native/core/client/extensions";
|
|
101
102
|
import { NewDashboardDialog } from "./NewDashboardDialog";
|
|
@@ -143,8 +144,8 @@ import {
|
|
|
143
144
|
import { CSS } from "@dnd-kit/utilities";
|
|
144
145
|
|
|
145
146
|
const bottomItems = [
|
|
146
|
-
{ icon: IconUsers,
|
|
147
|
-
{ icon: IconSettings,
|
|
147
|
+
{ icon: IconUsers, labelKey: "navigation.team", href: "/team" },
|
|
148
|
+
{ icon: IconSettings, labelKey: "navigation.settings", href: "/settings" },
|
|
148
149
|
];
|
|
149
150
|
|
|
150
151
|
function getStoredBoolean(key: string, fallback: boolean): boolean {
|
|
@@ -1143,6 +1144,7 @@ function persistThemePreference(theme: "light" | "dark") {
|
|
|
1143
1144
|
export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
1144
1145
|
const location = useLocation();
|
|
1145
1146
|
const navigate = useNavigate();
|
|
1147
|
+
const t = useT();
|
|
1146
1148
|
const { logout } = useAuth();
|
|
1147
1149
|
const queryClient = useQueryClient();
|
|
1148
1150
|
const { resolvedTheme, setTheme } = useTheme();
|
|
@@ -2191,7 +2193,7 @@ export function Sidebar({ mobile }: { mobile?: boolean } = {}) {
|
|
|
2191
2193
|
)}
|
|
2192
2194
|
>
|
|
2193
2195
|
<Icon className="h-4 w-4" />
|
|
2194
|
-
{item.
|
|
2196
|
+
{t(item.labelKey)}
|
|
2195
2197
|
</Link>
|
|
2196
2198
|
);
|
|
2197
2199
|
})}
|
|
@@ -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;
|