From 079e3a9bd68d79b4e2bcd7a4e181afffe53a284f Mon Sep 17 00:00:00 2001 From: Bohdan Triapitsyn Date: Wed, 10 Jun 2026 12:15:15 +0300 Subject: [PATCH] feat(settings): add item search (#1592) Adds item-level search inside Settings so users can find concrete settings like provider auth, agent mode, terminal font size, tunnel options, notification events, and similar controls instead of only filtering top-level pages. Groups search results by Settings page and shows localized labels plus optional descriptions where useful. Supports keyboard navigation with Arrow Up/Down, Enter, and Escape, matching the existing autocomplete interaction style. Opens the correct Settings page or split-page draft state before scrolling to the matching control. Highlights the matched setting with a subtle token-based background so users can see where they landed without an aggressive outline. Adds explicit data-settings-item anchors across Settings pages and a centralized search registry with runtime/mobile availability guards. Updates Settings UI skill guidance so future Settings changes keep search registry entries, anchors, localization, and availability guards in sync. --- .agents/skills/settings-ui-patterns/SKILL.md | 53 ++ SETTINGS_SEARCH_PLAN.md | 150 ++++ .../components/sections/agents/AgentsPage.tsx | 14 +- .../sections/agents/AgentsSidebar.tsx | 1 + .../sections/behavior/BehaviorPage.tsx | 4 +- .../sections/commands/CommandsPage.tsx | 8 +- .../sections/commands/CommandsSidebar.tsx | 1 + .../sections/git-identities/GitPage.tsx | 6 +- .../magic-prompts/MagicPromptsPage.tsx | 7 +- .../src/components/sections/mcp/McpPage.tsx | 8 +- .../components/sections/mcp/McpSidebar.tsx | 1 + .../sections/openchamber/DefaultsSettings.tsx | 7 +- .../openchamber/DesktopNetworkSettings.tsx | 4 +- .../sections/openchamber/GitSettings.tsx | 4 +- .../openchamber/KeyboardShortcutsSettings.tsx | 2 +- .../openchamber/NotificationSettings.tsx | 6 +- .../openchamber/OpenChamberVisualSettings.tsx | 43 +- .../openchamber/OpenCodeCliSettings.tsx | 4 +- .../openchamber/SessionRetentionSettings.tsx | 5 +- .../sections/openchamber/TunnelSettings.tsx | 14 +- .../sections/openchamber/VoiceSettings.tsx | 6 +- .../sections/plugins/AddPluginDialog.tsx | 6 +- .../sections/plugins/PluginsPage.tsx | 6 +- .../sections/plugins/PluginsSidebar.tsx | 7 + .../sections/projects/ProjectsPage.tsx | 8 +- .../sections/providers/ProvidersPage.tsx | 10 +- .../remote-instances/RemoteInstancesPage.tsx | 4 +- .../components/sections/skills/SkillsPage.tsx | 6 +- .../sections/skills/SkillsSidebar.tsx | 1 + .../skills/catalog/SkillsCatalogPage.tsx | 5 +- .../sections/snippets/SnippetsPage.tsx | 2 +- .../sections/snippets/SnippetsSidebar.tsx | 2 +- .../components/sections/usage/UsagePage.tsx | 4 +- .../ui/src/components/views/SettingsView.tsx | 296 ++++++- packages/ui/src/index.css | 6 + .../ui/src/lib/i18n/messages/en.settings.ts | 4 + .../ui/src/lib/i18n/messages/es.settings.ts | 4 + .../ui/src/lib/i18n/messages/ko.settings.ts | 4 + .../ui/src/lib/i18n/messages/pl.settings.ts | 7 + .../src/lib/i18n/messages/pt-BR.settings.ts | 4 + .../ui/src/lib/i18n/messages/uk.settings.ts | 4 + .../src/lib/i18n/messages/zh-CN.settings.ts | 4 + .../src/lib/i18n/messages/zh-TW.settings.ts | 4 + packages/ui/src/lib/settings/search.ts | 769 ++++++++++++++++++ 44 files changed, 1428 insertions(+), 87 deletions(-) create mode 100644 SETTINGS_SEARCH_PLAN.md create mode 100644 packages/ui/src/lib/settings/search.ts diff --git a/.agents/skills/settings-ui-patterns/SKILL.md b/.agents/skills/settings-ui-patterns/SKILL.md index 0fc9276b..c0d012e4 100644 --- a/.agents/skills/settings-ui-patterns/SKILL.md +++ b/.agents/skills/settings-ui-patterns/SKILL.md @@ -226,6 +226,58 @@ For dense icon/color pickers in settings: - **Avoid show/hide button pairs** when a checkbox maps directly to the boolean. - **Do not couple unrelated toggles** under one synthetic section header; keep hierarchy clear. +## Settings Search Integration + +Every Settings UI addition must preserve item search. The registry is explicit: search does not scrape JSX or infer fields automatically. + +### Required Files + +- Add or update search items in `packages/ui/src/lib/settings/search.ts`. +- Add matching `data-settings-item="..."` anchors in the rendered Settings UI. +- Reuse existing localized labels/descriptions where possible; otherwise add keys to all `packages/ui/src/lib/i18n/messages/*.settings.ts` files. +- If adding a new top-level Settings page, add metadata in `packages/ui/src/lib/settings/metadata.ts` and at least one searchable item unless the page is purely navigational like `home`. + +### What To Index + +- Index stable user-facing controls, section headers, and static create/connect actions. +- Use item IDs that match the page and target, for example `appearance.language`, `agents.mode`, `remote-instances.client-auth`. +- Prefer the exact visible label key as `titleKey`; use a concise visible/help text key as `descriptionKey` only when it adds useful context. +- Add `keywords` for common synonyms, acronyms, and words users may type that are not in the label. + +### What Not To Index + +- Do not generate search items from dynamic entities: individual agents, commands, MCP servers, snippets, plugins, skills, providers, projects, catalog rows, remote hosts, or SSH instances. +- Do not index controls hidden behind selected-entity dialogs unless search selection prepares the required state before highlighting. +- Do not add a registry entry for a conditional control unless its `isAvailable` guard matches actual render visibility. + +### Split Page Pattern + +For split pages, search should target predictable static surfaces only. + +- Index sidebar create/connect actions like `agents.create` or `providers.connect`. +- Index editor fields/sections that exist after the existing search preparation opens a draft. +- If a new create result needs draft setup, update `prepareSettingsSearchTarget` in `SettingsView.tsx` so the target is rendered before highlight runs. + +### Availability Guards + +- Match runtime/page availability exactly: VS Code, web, desktop, mobile, and local desktop origin when relevant. +- Page-level guards belong in `metadata.ts`; item-specific guards belong in `search.ts`. +- If a target renders only inside desktop shell UI, guard it with `ctx.isDesktop` or `ctx.isDesktopLocalOrigin` as appropriate. + +### Highlight Target Rules + +- Put `data-settings-item` on the smallest stable container that visually owns the setting. +- Avoid adding layout-only wrappers just for search anchors. +- Highlight styling is intentionally subtle and lives in `packages/ui/src/index.css` under `[data-settings-search-highlight="true"]`; keep it token-based and non-aggressive. + +### Audit Checklist + +- All registry IDs have matching anchors. +- All `titleKey` and `descriptionKey` values exist in every settings locale file. +- Every non-navigational `SettingsPageSlug` has item coverage. +- Search results respect platform/runtime/mobile visibility. +- Query-empty Settings navigation behavior is unchanged. + ## Best Practices - **Density**: Keep options compact; avoid oversized rows/chips in dense settings pages. - **Consistency**: Reuse shared controls (`Checkbox`, `Radio`, `ButtonSmall size="xs"`) instead of inline icon logic. @@ -236,3 +288,4 @@ For dense icon/color pickers in settings: - **Helper blocks**: For small notes/errors under a section, use `mt-1 px-2` with `typography-meta text-muted-foreground/70` (and status token for errors). - **Truncation**: Always consider long text. Use `min-w-0 flex-1 truncate` on text containers that sit next to buttons or icons to prevent layout breakage. - **Theme Variables**: *Always* use CSS variables for colors (e.g., `var(--status-success)`) rather than hardcoded hex values or generic Tailwind colors when indicating semantic states. +- **Search compatibility**: When adding or moving a Settings control, update the search registry and anchor in the same change. diff --git a/SETTINGS_SEARCH_PLAN.md b/SETTINGS_SEARCH_PLAN.md new file mode 100644 index 00000000..55f7531e --- /dev/null +++ b/SETTINGS_SEARCH_PLAN.md @@ -0,0 +1,150 @@ +# Settings Item Search Plan + +## Goal + +Add Settings search that finds individual settings items, not only top-level pages. + +The search should behave like this: + +- User types a query in the Settings navigation area. +- Results show matching concrete settings, grouped or labeled by their Settings page. +- Each result shows the item title and, when available, its description. +- Clicking a result opens the correct Settings page. +- After the page renders, the matching row/card/section scrolls into view. +- The matched item gets a short visual highlight so the user can see where they landed. + +## Current Architecture Notes + +- Settings shell lives in `packages/ui/src/components/views/SettingsView.tsx`. +- Page metadata and slugs live in `packages/ui/src/lib/settings/metadata.ts`. +- Settings localization lives in `packages/ui/src/lib/i18n/messages/*.settings.ts`. +- Settings UI text is read through `useI18n()` and `t(key)`. +- Standard page wrappers live in `packages/ui/src/components/sections/shared/`. + +## Proposed Architecture + +Use an explicit searchable item registry instead of scraping React or the DOM. + +Each searchable item should contain: + +- `id`: stable item id, for example `appearance.language`. +- `page`: target `SettingsPageSlug`, for example `appearance`. +- `titleKey`: localized title key. +- `descriptionKey`: optional localized description key. +- `keywords`: optional non-visible search helpers. +- `isAvailable`: optional runtime/mobile guard for item-level availability. + +Example: + +```ts +{ + id: 'appearance.language', + page: 'appearance', + titleKey: 'settings.appearance.language.label', + descriptionKey: 'settings.appearance.language.description', + keywords: ['locale', 'translation', 'ui language'], +} +``` + +## Implementation Steps + +1. Create `packages/ui/src/lib/settings/search.ts`. + - Export `SETTINGS_SEARCH_ITEMS`. + - Export a helper to build localized search results from `t()`. + - Filter by page availability and `visiblePageSlugs`. + +2. Add search UI to `SettingsView.tsx`. + - Search input should live in the left Settings navigation area on desktop. + - On mobile, keep behavior simple: show results in the nav stage and open target page on select. + - When query is empty, keep the existing navigation list. + - When query has text, replace the normal nav list with concrete search results. + +3. Add click behavior for a search result. + - Set `settingsPage` to the result page. + - Store pending target item id in component state/ref. + - After content renders, find `[data-settings-item=""]`. + - Scroll it into view. + - Add a temporary highlight using a data attribute or CSS class. + +4. Add a tiny shared anchor/highlight pattern. + - Prefer adding `data-settings-item="..."` to existing row/card containers. + - Avoid wrappers that change layout. + - Keep highlight styling generic, for example a short ring/background transition. + +5. Add initial searchable coverage. + - Start with high-value pages that already use many localized strings: + - `appearance` + - `chat` + - `sessions` + - `notifications` + - `git` + - `providers` + - `agents` + - Add more pages incrementally. + +6. Validation. + - Run `bun run type-check`. + - Run `bun run lint`. + - Manually verify search result navigation for at least one single page and one split page. + +## Current Implementation Status + +Done: + +- `packages/ui/src/lib/settings/search.ts` exists and exports the explicit registry plus localized result builder. +- Search input is wired into `SettingsView.tsx`. +- Results are grouped by page header. +- ArrowUp, ArrowDown, Enter, and Escape work while the search input is focused. +- Result click opens the target page and scrolls to `[data-settings-item="..."]`. +- Matching target gets a temporary highlight via `data-settings-search-highlight`. +- Search respects page availability, `visiblePageSlugs`, and item-level platform/runtime/mobile guards. +- Initial anchors exist for `appearance`, `chat`, `sessions`, `notifications`, `git`, and `usage`. + +Covered pages/items so far: + +- `appearance`: themes, localization, PWA/mobile-only controls, layout controls, navigation controls, usage reports. +- `chat`: render mode, transport, reasoning, layout/message toggles, mobile status bar, dotfiles, queue/draft/spellcheck. +- `sessions`: defaults, retention, desktop network controls, OpenCode CLI controls. +- `notifications`: delivery, events, background push. +- `git`: GitHub account, identities, changes view, Gitmoji, gitignored files. +- `usage`: header menu visibility, model quotas section. +- `agents`: create action plus static editor fields for name, mode, model, temperature, Top P, system prompt, and permissions. +- `commands`: create action plus static editor fields for name, agent, model, and template. +- `mcp`: create action plus static editor sections for server, command/URL, environment variables, and advanced remote options. +- `plugins`: add action plus static editor fields for spec, options JSON, and file content. +- `snippets`: create action plus snippet content editor. +- `providers`: connect action plus auth, connection details, and models sections. +- `skills.installed`: create action plus basic information, instructions, and supporting files sections. +- `behavior`: global AGENTS.md and response style sections. +- `projects`: static project metadata fields and worktree section, excluding individual projects. +- `skills.catalog`: source repository, catalog search, and add catalog action, excluding individual catalog skills/sources. +- `magic-prompts`: visible prompt, instructions, and reset-all action, excluding individual prompt result generation beyond the selected editor page. +- `shortcuts`: keyboard shortcut editor section. +- `voice`: voice setup, speech recognition, and playback sections. +- `tunnel`: provider, tunnel type, TTLs, managed remote/local configuration, and start/connect link sections. +- `remote-instances`: client auth/pairing and desktop direct-host sections; SSH instance dialog fields stay out of search because they require selected-instance state. + +Still pending: + +- Add state-aware filtering for settings that are hidden based on current settings values, not just platform. Examples: `chat.activity-default-mode`, `chat.collapsible-reasoning`. +- Add focused tests for `buildSettingsSearchResults`, especially runtime/mobile filtering. + +Out of scope by decision: + +- Do not generate search results from dynamic store entities such as individual agents, commands, MCP servers, snippets, plugins, skills, providers, or projects. +- For split pages, search should cover predictable static create actions, editor fields, and sections only. + +## Important Constraints + +- Do not rely on localized key naming alone for navigation. The registry is the source of truth. +- Do not parse JSX or scrape the DOM to discover settings automatically. +- Search should use current locale strings, with English fallback already handled by i18n. +- Do not introduce broad Zustand state for transient search query/highlight state. Keep it local to `SettingsView` unless another surface needs it. +- Keep page behavior unchanged when the query is empty. +- If a page is unavailable in the current runtime, its search items must not appear. + +## Future Improvements + +- Add fuzzy ranking instead of simple substring matching. +- Support deep-linking to settings items from URLs or app commands. +- Add complete registry coverage for all Settings pages. diff --git a/packages/ui/src/components/sections/agents/AgentsPage.tsx b/packages/ui/src/components/sections/agents/AgentsPage.tsx index 277fe1e6..894e853c 100644 --- a/packages/ui/src/components/sections/agents/AgentsPage.tsx +++ b/packages/ui/src/components/sections/agents/AgentsPage.tsx @@ -655,7 +655,7 @@ export const AgentsPage: React.FC = () => {
{isNewAgent && ( -
+
{t('settings.agents.page.field.agentName')}
@@ -705,7 +705,7 @@ export const AgentsPage: React.FC = () => {
-
+
{t('settings.agents.page.field.mode')} @@ -763,7 +763,7 @@ export const AgentsPage: React.FC = () => {
-
+
{t('settings.agents.page.field.overrideModel')}
@@ -782,7 +782,7 @@ export const AgentsPage: React.FC = () => {
-
+
{t('settings.agents.page.field.temperature')} @@ -826,7 +826,7 @@ export const AgentsPage: React.FC = () => {
-
+
{t('settings.agents.page.field.topP')} @@ -874,7 +874,7 @@ export const AgentsPage: React.FC = () => {
{/* System Prompt */} -
+

{t('settings.agents.page.section.systemPrompt')} @@ -893,7 +893,7 @@ export const AgentsPage: React.FC = () => {

{/* Tool Permissions */} -
+

{t('settings.agents.page.section.toolPermissions')} diff --git a/packages/ui/src/components/sections/agents/AgentsSidebar.tsx b/packages/ui/src/components/sections/agents/AgentsSidebar.tsx index c15c7ad9..51710384 100644 --- a/packages/ui/src/components/sections/agents/AgentsSidebar.tsx +++ b/packages/ui/src/components/sections/agents/AgentsSidebar.tsx @@ -334,6 +334,7 @@ export const AgentsSidebar: React.FC = ({ onItemSelect }) =>
{t('settings.agents.sidebar.total', { count: visibleAgents.length })}

-
+

@@ -288,7 +288,7 @@ export const BehaviorPage: React.FC = () => {

-
+

diff --git a/packages/ui/src/components/sections/commands/CommandsPage.tsx b/packages/ui/src/components/sections/commands/CommandsPage.tsx index 4be6a3bf..8e928ab4 100644 --- a/packages/ui/src/components/sections/commands/CommandsPage.tsx +++ b/packages/ui/src/components/sections/commands/CommandsPage.tsx @@ -215,7 +215,7 @@ export const CommandsPage: React.FC = () => {
{isNewCommand && ( -
+
{t('settings.commands.page.field.commandName')}
@@ -278,7 +278,7 @@ export const CommandsPage: React.FC = () => {
-
+
{t('settings.commands.page.field.overrideAgent')}
@@ -290,7 +290,7 @@ export const CommandsPage: React.FC = () => {
-
+
{t('settings.agents.page.field.overrideModel')}
@@ -313,7 +313,7 @@ export const CommandsPage: React.FC = () => {
{/* Command Template */} -
+

{t('settings.commands.page.section.template')} diff --git a/packages/ui/src/components/sections/commands/CommandsSidebar.tsx b/packages/ui/src/components/sections/commands/CommandsSidebar.tsx index 8ea75914..816b70bf 100644 --- a/packages/ui/src/components/sections/commands/CommandsSidebar.tsx +++ b/packages/ui/src/components/sections/commands/CommandsSidebar.tsx @@ -231,6 +231,7 @@ export const CommandsSidebar: React.FC = ({ onItemSelect }
{t('settings.commands.sidebar.total', { count: commandOnlyItems.length })}
-
+
{t('settings.openchamber.defaults.field.defaultModel')}
@@ -254,7 +254,7 @@ export const DefaultsSettings: React.FC = () => {
-
+
{t('settings.openchamber.defaults.field.defaultThinking')}
@@ -277,7 +277,7 @@ export const DefaultsSettings: React.FC = () => {
-
+
{t('settings.openchamber.defaults.field.defaultAgent')}
@@ -287,6 +287,7 @@ export const DefaultsSettings: React.FC = () => {
{
{launchAtLoginSupported ? (
{
) : null} -
+
@@ -261,6 +262,7 @@ export const DesktopNetworkSettings: React.FC = () => {
{
-
+

{t('settings.openchamber.git.changesViewTitle')}

{viewOptions.map((option) => { @@ -157,6 +157,7 @@ export const GitSettings: React.FC = () => {
{
{ }, [clearShortcutOverride, persistShortcutOverrides, shortcutOverrides]); return ( -
+

{t('settings.openchamber.keyboardShortcuts.title')}

diff --git a/packages/ui/src/components/sections/openchamber/NotificationSettings.tsx b/packages/ui/src/components/sections/openchamber/NotificationSettings.tsx index f02ba10a..388bdcb9 100644 --- a/packages/ui/src/components/sections/openchamber/NotificationSettings.tsx +++ b/packages/ui/src/components/sections/openchamber/NotificationSettings.tsx @@ -441,7 +441,7 @@ export const NotificationSettings: React.FC = () => {
{/* --- Global Delivery Settings --- */} -
+

{t('settings.notifications.page.delivery.title')} @@ -540,7 +540,7 @@ export const NotificationSettings: React.FC = () => { {nativeNotificationsEnabled && canShowNotifications && ( <> {/* --- Events --- */} -
+

{t('settings.notifications.page.events.title')} @@ -672,7 +672,7 @@ export const NotificationSettings: React.FC = () => { {/* --- Background Push Notifications --- */} {isBrowser && ( -
+

{t('settings.notifications.page.push.title')} diff --git a/packages/ui/src/components/sections/openchamber/OpenChamberVisualSettings.tsx b/packages/ui/src/components/sections/openchamber/OpenChamberVisualSettings.tsx index 0d764353..19e7a103 100644 --- a/packages/ui/src/components/sections/openchamber/OpenChamberVisualSettings.tsx +++ b/packages/ui/src/components/sections/openchamber/OpenChamberVisualSettings.tsx @@ -727,7 +727,7 @@ export const OpenChamberVisualSettings: React.FC )}
-
+
{t('settings.openchamber.visual.field.lightTheme')}
-
+
{t('settings.openchamber.visual.field.darkTheme')} handleTimeFormatPreferenceChange(value)}> @@ -899,7 +899,7 @@ export const OpenChamberVisualSettings: React.FC )} {shouldShow('weekStart') && ( -
+
{t('settings.openchamber.visual.field.weekStartsOn')} {
-
+

{t('settings.openchamber.tunnel.field.tunnelType')}

{tunnelModeOptions.map((option) => ( @@ -1381,7 +1381,7 @@ export const TunnelSettings: React.FC = () => {
-
+
{t('settings.openchamber.tunnel.field.connectLinkTtl')} { )} {!isSelectedModeTunnelReady && ( -
+
@@ -1832,7 +1832,7 @@ export const TunnelSettings: React.FC = () => { )} {isSelectedModeTunnelReady && tunnelInfo && ( -
+
diff --git a/packages/ui/src/components/sections/openchamber/VoiceSettings.tsx b/packages/ui/src/components/sections/openchamber/VoiceSettings.tsx index 33b2a0b8..93da103a 100644 --- a/packages/ui/src/components/sections/openchamber/VoiceSettings.tsx +++ b/packages/ui/src/components/sections/openchamber/VoiceSettings.tsx @@ -499,7 +499,7 @@ export const VoiceSettings: React.FC = () => {
{/* Voice Setup */} -
+

{t('settings.voice.page.section.voiceSetup')} @@ -827,7 +827,7 @@ export const VoiceSettings: React.FC = () => { {/* Speech Recognition */} {voiceModeEnabled && ( -
+

{t('settings.voice.page.section.speechRecognition')} @@ -1035,7 +1035,7 @@ export const VoiceSettings: React.FC = () => { )} {/* Playback & Summarization */} -
+

{t('settings.voice.page.section.playbackAndSummary')} diff --git a/packages/ui/src/components/sections/plugins/AddPluginDialog.tsx b/packages/ui/src/components/sections/plugins/AddPluginDialog.tsx index dcff546e..7c6f27c6 100644 --- a/packages/ui/src/components/sections/plugins/AddPluginDialog.tsx +++ b/packages/ui/src/components/sections/plugins/AddPluginDialog.tsx @@ -157,7 +157,7 @@ export const AddPluginDialog: React.FC = ({
{(tab === 'npm' || tab === 'path') && ( <> -
+
@@ -176,7 +176,7 @@ export const AddPluginDialog: React.FC = ({ )}
-
+
@@ -200,7 +200,7 @@ export const AddPluginDialog: React.FC = ({ {tab === 'file' && ( <> -
+
diff --git a/packages/ui/src/components/sections/plugins/PluginsPage.tsx b/packages/ui/src/components/sections/plugins/PluginsPage.tsx index f4244b35..0bb44256 100644 --- a/packages/ui/src/components/sections/plugins/PluginsPage.tsx +++ b/packages/ui/src/components/sections/plugins/PluginsPage.tsx @@ -213,7 +213,7 @@ export const PluginsPage: React.FC = () => { -
+
@@ -228,7 +228,7 @@ export const PluginsPage: React.FC = () => { />
-
+
@@ -338,7 +338,7 @@ export const PluginsPage: React.FC = () => {
-
+
diff --git a/packages/ui/src/components/sections/plugins/PluginsSidebar.tsx b/packages/ui/src/components/sections/plugins/PluginsSidebar.tsx index c5317ba0..7472b47f 100644 --- a/packages/ui/src/components/sections/plugins/PluginsSidebar.tsx +++ b/packages/ui/src/components/sections/plugins/PluginsSidebar.tsx @@ -68,6 +68,12 @@ export const PluginsSidebar: React.FC = ({ void loadPlugins(); }, [loadPlugins]); + React.useEffect(() => { + const handleOpenAdd = () => setIsAddOpen(true); + window.addEventListener('openchamber:settings-open-plugin-add', handleOpenAdd); + return () => window.removeEventListener('openchamber:settings-open-plugin-add', handleOpenAdd); + }, []); + const updateCounts = React.useMemo(() => { const counts = { userEntries: 0, projectEntries: 0 }; for (const entry of entries) { @@ -282,6 +288,7 @@ export const PluginsSidebar: React.FC = ({
{/* Connection Details */} -
+

{t('settings.providers.page.connectionDetails.title')}

@@ -971,7 +971,7 @@ export const ProvidersPage: React.FC = () => {
{/* Models */} -
+

{t('settings.providers.page.models.title')} diff --git a/packages/ui/src/components/sections/remote-instances/RemoteInstancesPage.tsx b/packages/ui/src/components/sections/remote-instances/RemoteInstancesPage.tsx index 0b755f08..638bfac3 100644 --- a/packages/ui/src/components/sections/remote-instances/RemoteInstancesPage.tsx +++ b/packages/ui/src/components/sections/remote-instances/RemoteInstancesPage.tsx @@ -956,7 +956,7 @@ export const RemoteInstancesPage: React.FC = () => { return ( {clientAuth ? ( -
+

{t('settings.remoteInstances.clientAuth.title')}

{t('settings.remoteInstances.clientAuth.description')}

@@ -1029,7 +1029,7 @@ export const RemoteInstancesPage: React.FC = () => {
) : null} - {showInstanceManagement ?
+ {showInstanceManagement ?

{t('settings.remoteInstances.direct.title')}

{t('settings.remoteInstances.direct.description')}

diff --git a/packages/ui/src/components/sections/skills/SkillsPage.tsx b/packages/ui/src/components/sections/skills/SkillsPage.tsx index 9f91f047..1b6d65f6 100644 --- a/packages/ui/src/components/sections/skills/SkillsPage.tsx +++ b/packages/ui/src/components/sections/skills/SkillsPage.tsx @@ -508,7 +508,7 @@ const SkillsInstalledPage: React.FC = () => {
{/* Basic Information */} -
+

{t('settings.skills.page.section.basicInformation')} @@ -583,7 +583,7 @@ const SkillsInstalledPage: React.FC = () => {

{/* Instructions */} -
+

{t('settings.skills.page.section.instructions')} @@ -626,7 +626,7 @@ const SkillsInstalledPage: React.FC = () => {

{/* Supporting Files */} -
+

{t('settings.skills.page.section.supportingFiles')} diff --git a/packages/ui/src/components/sections/skills/SkillsSidebar.tsx b/packages/ui/src/components/sections/skills/SkillsSidebar.tsx index 4dbd0e6f..b62d99aa 100644 --- a/packages/ui/src/components/sections/skills/SkillsSidebar.tsx +++ b/packages/ui/src/components/sections/skills/SkillsSidebar.tsx @@ -236,6 +236,7 @@ export const SkillsSidebar: React.FC = ({ onItemSelect }) =>
{t('settings.skills.sidebar.total', { count: skills.length })}
{/* Source & Search */} -
+

{t('settings.skills.catalog.page.section.sourceRepository')}

@@ -244,6 +244,7 @@ export const SkillsCatalogPage: React.FC = ({ mode, onMo )}
-
+
{
-
+
{t('settings.snippets.page.field.content')}