Adds 70 missing translation keys across 3 namespaces (logViewer, pipeline, debug) to messages/en.json. These namespaces are referenced by existing components but were absent, causing raw keys to render.\n\nFixes #416
- Add `workspace` skill root (~/.openclaw/workspace/skills) for
workspace-local skill discovery alongside the existing 5 roots
- Make group cards clickable to filter the installed skills list by root
- Add `workspace` as valid target for skill creation and registry install
- Add `showAllRoots` i18n key to all 10 locale files
Closes#364
Previously the agent select in the OrchestrationBar only listed agents
with a session_key set (agents.filter(a => a.session_key)), causing the
dropdown to appear completely empty when agents exist but none have an
active session. This was confusing — users thought no agents were
registered.
Fix: show all registered agents in the dropdown. Agents without an
active session_key are shown as disabled with a '— no session' suffix
and a tooltip explaining why they can't be messaged. The 'No agents
registered' placeholder is shown only when the agents array is truly
empty.
The send button remains correctly disabled when no valid agent is
selected.
Fixes#321
Replace the unhelpful "POST /api/agents with X-Api-Key header" message
with a user-friendly hint explaining that agents are auto-discovered
from Claude, Codex, and Hermes directories, and that gateway mode shows
registered agents.
Adds missing noAgentsHint translation key across all 10 locales.
Closes#321
* feat: add i18n with 10 languages (en, zh, ja, ko, es, fr, de, pt, ru, ar)
Add internationalization infrastructure using next-intl with cookie-based
locale detection (NEXT_LOCALE cookie -> Accept-Language header -> default).
- Install next-intl and wire into Next.js config + root layout
- Create translation files for 10 languages covering auth pages,
navigation labels, common UI strings, and settings
- Translate login page, setup page, and nav-rail labels
- Add LanguageSwitcher component (compact dropdown) to login page,
setup page, nav-rail sidebar, and settings panel
- Support RTL layout for Arabic (dir="rtl" on html element)
- No URL-based locale routing — uses cookie-only approach to avoid
breaking existing URLs and the custom proxy middleware
Panel internals are left with English strings for incremental
translation in follow-up PRs.
Based on the approach from PR #312 by richard-able, expanded to
10 languages with proper infrastructure.
* test(e2e): add i18n language switcher Playwright tests
Tests verify English default, all 10 language options, Chinese/Spanish
translations, cookie persistence across reload, and round-trip switching.
* test(e2e): fix i18n language switcher tests for cookie-based reload
Use direct cookie injection + page.goto instead of selectOption to
avoid race conditions with window.location.reload(). Fix Spanish
translation text to match actual es.json content.
* feat: complete full-app i18n — all components translated to 10 languages
Wire useTranslations() across 13 components with 293 keys in 12 namespaces:
- Boot loader: step labels, title, tagline
- Main page: skip-link, footer, full/local mode nudges
- Header bar: search, command palette, mode badge, SSE badge, tooltips
- Banners: local-mode, update, openclaw-update, openclaw-doctor
- Live feed: header, empty states, session labels
- Nav rail: context switcher, interface toggle, org section
- Onboarding wizard: all 4 steps (welcome, interface, gateway, credentials)
- Error boundary: extracted functional component for hook support
All 10 languages fully translated (en, zh, ja, ko, es, fr, de, pt, ru, ar)
with ICU plural format and proper per-language plural rules.
* feat(i18n): translate all panels and redesign language switcher
- Internationalize all 38 panel components with useTranslations()
- Expand translation keys from 293 to 1752 across 45 namespaces
- All 10 languages: en, zh, ja, ko, es, fr, de, pt, ru, ar
- Redesign language switcher: popover dropdown in header bar
(replaces native <select> in sidebar)
- Keep LanguageSwitcherSelect for login, setup, and settings pages
- Fix github-sync-panel to use t.rich() for JSX interpolation