feat: plugin settings (#1375)

* feat(settings): add opencode plugins page

Manage opencode `plugin` array entries (npm, scoped npm, versioned,
local paths) and auto-loaded plugin files in `~/.config/opencode/plugins/`
and `<project>/.opencode/plugins/`. Mirrors MCP CRUD pattern.

- Server: `plugins.js` data layer + `plugin-routes.js` REST routes
- UI: PluginsSidebar / PluginsPage / AddPluginDialog
- Store: usePluginsStore (cache TTL, in-flight dedup, narrow selectors)
- i18n: 41 keys across 7 locales

Whitelist /api/config/plugins in JSON body-parser so POST/PATCH bodies
parse; opencode plugin specs runtime-resolve OPENCODE_CONFIG dir so
parallel test files do not cross-pollute module-frozen consts.

* feat(settings/plugins): hook npm registry for update + invalid-version detection

Plugins page now consults registry.npmjs.org with a 1h server cache. Sidebar
rows show an update badge with the latest version, group headers show how
many updates are available, the kebab adds an "Update to latest" action
that reuses the existing PATCH+restart flow, and the editor surfaces a
banner for update-available / missing-version / missing-package / malformed
/ missing-path / unreadable-path / offline-registry states. A refresh
button in the sidebar header forces a cache bypass.

- Server: `npm-registry.js` (cache + in-flight dedup + 5s timeout, 404
  cached, network failures NOT cached) + `plugin-spec.js` (parser + exact
  semver detection) + `GET /api/config/plugins/registry?specs=...&refresh=`
- Routes accept up to 100 specs/request, dedup by npm package name before
  fetching, classify each result by kind, never propagate network failure
  as 500.
- Client: `registryInfo` slice + `loadRegistryInfo` (fire-and-forget after
  loadPlugins, refreshes on mutations) + `updateToLatest(id)`.
- UI: `RegistryBadge` per-row + `RegistryBanner` per-entry editor, both
  use theme tokens (text-only color, no new bg/border tokens) and the
  shared Icon sprite. Per-spec subscriptions only.
- i18n: 24 new keys (incl. split singular/plural for "N update(s)
  available" because the runtime does not parse ICU plural format).

* fix(settings/plugins): keep registry badge visible for long specs

Sidebar entry row used `inline-flex` with `truncate` only on the spec
text. With long npm specs the badge could be pushed past the row edge
and clipped by the parent overflow. Switch to `flex` with spec
`flex-1 min-w-0 truncate` and add `shrink-0` to the badge wrapper so
the update indicator stays anchored to the right of the row.

* fix(settings/plugins): use code-box icon to distinguish from MCP

Plugins nav entry used 'plug' which is visually too close to MCP's
'plug-2' icon. Swap to 'code-box' for clearer differentiation in the
Settings nav list.

* Update packages/ui/src/components/sections/plugins/PluginsPage.tsx

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Signed-off-by: Quat3rnion <81202811+Quat3rnion@users.noreply.github.com>

* Update packages/ui/src/stores/usePluginsStore.ts

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Signed-off-by: Quat3rnion <81202811+Quat3rnion@users.noreply.github.com>

* fix(settings/plugins): validate registry directory + surface save errors

- registry endpoint: return 400 on invalid directory query (was silently falling back to homedir, breaking relative path specs)
- save failure toast: prefer result.message over generic 'Reload failed'

* fix(settings/plugins): address review follow-ups

---------

Signed-off-by: Quat3rnion <81202811+Quat3rnion@users.noreply.github.com>
Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
This commit is contained in:
Quat3rnion
2026-05-25 19:20:04 +03:00
committed by GitHub
co-authored by Bohdan Triapitsyn
parent a25e64099c
commit 2b47d899c6
29 changed files with 4667 additions and 0 deletions
@@ -13,6 +13,8 @@ export const settingsDict = {
'settings.view.home.cards.skillsCatalog.description': 'Install skills from catalogs',
'settings.view.home.cards.mcp.title': 'MCP',
'settings.view.home.cards.mcp.description': 'Configure MCP servers + connections',
'settings.view.home.cards.plugins.title': 'Plugins',
'settings.view.home.cards.plugins.description': 'Manage opencode plugins',
'settings.view.home.cards.usage.title': 'Usage',
'settings.view.home.cards.usage.description': 'Quota + spend visibility',
'settings.view.unavailable.title': 'Not available',
@@ -33,6 +35,7 @@ export const settingsDict = {
'settings.page.agents.title': 'Agents',
'settings.page.commands.title': 'Commands',
'settings.page.mcp.title': 'MCP',
'settings.page.plugins.title': 'Plugins',
'settings.page.skills.title': 'Skills',
'settings.page.skillsCatalog.title': 'Skills Catalog',
'settings.page.git.title': 'Git',
@@ -799,6 +802,73 @@ export const settingsDict = {
'settings.mcp.sidebar.toast.deleteFailed': 'Failed to delete MCP server',
'settings.mcp.sidebar.toast.serverDeleted': 'MCP server "{name}" deleted',
'settings.mcp.sidebar.toast.refreshListIfStale': 'Refresh the MCP list if the UI looks stale.',
'settings.plugins.sidebar.title': 'Plugins',
'settings.plugins.sidebar.total': 'Total {count}',
'settings.plugins.sidebar.actions.addTitle': 'Add plugin',
'settings.plugins.sidebar.actions.deleting': 'Deleting…',
'settings.plugins.sidebar.empty.title': 'No plugins configured',
'settings.plugins.sidebar.empty.description': 'Use the + button above to add one',
'settings.plugins.sidebar.group.userEntries': 'User config',
'settings.plugins.sidebar.group.userFiles': 'User plugin file',
'settings.plugins.sidebar.group.projectEntries': 'Project config',
'settings.plugins.sidebar.group.projectFiles': 'Project plugin file',
'settings.plugins.sidebar.kind.npm': 'npm package',
'settings.plugins.sidebar.kind.path': 'Local path',
'settings.plugins.sidebar.kind.file': 'Plugin file',
'settings.plugins.sidebar.deleteDialog.title': 'Delete plugin',
'settings.plugins.sidebar.deleteDialog.description': 'Are you sure you want to delete "{name}"?',
'settings.plugins.sidebar.toast.deleted': 'Plugin "{name}" deleted',
'settings.plugins.sidebar.toast.deleteFailed': 'Failed to delete plugin',
'settings.plugins.page.empty.select': 'Select a plugin to view or edit',
'settings.plugins.page.empty.add': 'Or click + to add a new plugin',
'settings.plugins.page.header.entry': 'Installed plugin',
'settings.plugins.page.header.file': 'Plugin file',
'settings.plugins.page.field.spec': 'Spec',
'settings.plugins.page.field.spec.placeholder': 'npm-package@version or /absolute/path',
'settings.plugins.page.field.options': 'Options (JSON)',
'settings.plugins.page.field.options.invalidJson': 'Invalid JSON',
'settings.plugins.page.field.fileName': 'Filename',
'settings.plugins.page.field.content': 'Content',
'settings.plugins.page.field.scope': 'Scope',
'settings.plugins.scope.user': 'User',
'settings.plugins.scope.project': 'Project',
'settings.plugins.page.action.save': 'Save',
'settings.plugins.page.action.discard': 'Discard',
'settings.plugins.dialog.add.title': 'Add plugin',
'settings.plugins.dialog.add.tab.npm': 'From npm',
'settings.plugins.dialog.add.tab.path': 'From local path',
'settings.plugins.dialog.add.tab.file': 'New file',
'settings.plugins.dialog.add.action.submit': 'Add',
'settings.plugins.dialog.add.action.cancel': 'Cancel',
'settings.plugins.toast.created': 'Plugin added',
'settings.plugins.toast.updated': 'Plugin updated',
'settings.plugins.toast.reloadFailed': 'opencode reload failed — restart required',
'settings.plugins.validation.fileName': 'Filename must be lowercase, end in .js / .ts / .mjs / .cjs',
'settings.plugins.validation.specRequired': 'Spec is required',
'settings.plugins.registry.badge.update.label': '↑ {version}',
'settings.plugins.registry.badge.update.tooltip': 'Update available: {current} → {latest}',
'settings.plugins.registry.badge.malformed.tooltip': 'Spec is malformed',
'settings.plugins.registry.badge.missingPackage.tooltip': 'Package {name} not found on npm',
'settings.plugins.registry.badge.missingVersion.tooltip': 'Version {version} of {name} not published',
'settings.plugins.registry.badge.pathMissing.tooltip': 'File not found: {path}',
'settings.plugins.registry.badge.pathUnreadable.tooltip': 'File not readable: {path}',
'settings.plugins.registry.badge.network.tooltip': 'Could not reach npm registry',
'settings.plugins.registry.banner.updateAvailable.title': 'Update available',
'settings.plugins.registry.banner.updateAvailable.description': '{current} → {latest}',
'settings.plugins.registry.banner.updateAvailable.action': 'Update to {latest}',
'settings.plugins.registry.banner.invalid.title': 'Invalid plugin',
'settings.plugins.registry.banner.invalid.malformed': 'Spec syntax is malformed',
'settings.plugins.registry.banner.invalid.missingPackage': 'Package not found on npm',
'settings.plugins.registry.banner.invalid.missingVersion': 'Version not published',
'settings.plugins.registry.banner.invalid.pathMissing': 'File does not exist',
'settings.plugins.registry.banner.invalid.pathUnreadable': 'File is not readable',
'settings.plugins.sidebar.actions.updateToLatest': 'Update to latest',
'settings.plugins.sidebar.actions.refresh': 'Check for updates',
'settings.plugins.sidebar.group.updatesAvailable_one': '{count} update available',
'settings.plugins.sidebar.group.updatesAvailable_other': '{count} updates available',
'settings.plugins.toast.updatedToLatest': 'Plugin updated to {version}',
'settings.plugins.toast.refreshing': 'Checking npm for updates…',
'settings.plugins.toast.refreshFailed': 'Could not check npm registry',
'settings.openchamber.keyboardShortcuts.title': 'Keyboard Shortcuts',
'settings.openchamber.keyboardShortcuts.actions.resetAll': 'Reset All',
'settings.openchamber.keyboardShortcuts.actions.overwrite': 'Overwrite',
@@ -13,6 +13,8 @@ export const settingsDict = {
"settings.view.home.cards.skillsCatalog.description": "Instalar habilidades desde catálogos",
"settings.view.home.cards.mcp.title": "MCP",
"settings.view.home.cards.mcp.description": "Configurar servidores + conexiones MCP",
'settings.view.home.cards.plugins.title': 'Plugins',
'settings.view.home.cards.plugins.description': 'Manage opencode plugins',
"settings.view.home.cards.usage.title": "Uso",
"settings.view.home.cards.usage.description": "Cuota + visibilidad del gasto",
"settings.view.unavailable.title": "No disponible",
@@ -33,6 +35,7 @@ export const settingsDict = {
"settings.page.agents.title": "Agentes",
"settings.page.commands.title": "Comandos",
"settings.page.mcp.title": "MCP",
'settings.page.plugins.title': 'Plugins',
"settings.page.skills.title": "Habilidades",
"settings.page.skillsCatalog.title": "Catálogo de habilidades",
"settings.page.git.title": "Git",
@@ -766,6 +769,73 @@ export const settingsDict = {
"settings.mcp.sidebar.toast.deleteFailed": "No se pudo eliminar el servidor MCP",
"settings.mcp.sidebar.toast.serverDeleted": "Servidor MCP \"{name}\" eliminado",
"settings.mcp.sidebar.toast.refreshListIfStale": "Actualiza la lista de MCP si la interfaz parece desactualizada.",
'settings.plugins.sidebar.title': 'Plugins',
'settings.plugins.sidebar.total': 'Total: {count}',
'settings.plugins.sidebar.actions.addTitle': 'Añadir plugin',
'settings.plugins.sidebar.actions.deleting': 'Eliminando…',
'settings.plugins.sidebar.empty.title': 'No hay plugins configurados',
'settings.plugins.sidebar.empty.description': 'Usa el botón + de arriba para añadir uno',
'settings.plugins.sidebar.group.userEntries': 'Configuración de usuario',
'settings.plugins.sidebar.group.userFiles': 'Archivo de plugin de usuario',
'settings.plugins.sidebar.group.projectEntries': 'Configuración del proyecto',
'settings.plugins.sidebar.group.projectFiles': 'Archivo de plugin del proyecto',
'settings.plugins.sidebar.kind.npm': 'paquete npm',
'settings.plugins.sidebar.kind.path': 'Ruta local',
'settings.plugins.sidebar.kind.file': 'Archivo de plugin',
'settings.plugins.sidebar.deleteDialog.title': 'Eliminar plugin',
'settings.plugins.sidebar.deleteDialog.description': '¿Seguro que quieres eliminar "{name}"?',
'settings.plugins.sidebar.toast.deleted': 'Plugin "{name}" eliminado',
'settings.plugins.sidebar.toast.deleteFailed': 'No se pudo eliminar el plugin',
'settings.plugins.page.empty.select': 'Selecciona un plugin para verlo o editarlo',
'settings.plugins.page.empty.add': 'O haz clic en + para añadir un plugin nuevo',
'settings.plugins.page.header.entry': 'Plugin instalado',
'settings.plugins.page.header.file': 'Archivo de plugin',
'settings.plugins.page.field.spec': 'Especificación',
'settings.plugins.page.field.spec.placeholder': 'paquete-npm@versión o /ruta/absoluta',
'settings.plugins.page.field.options': 'Opciones (JSON)',
'settings.plugins.page.field.options.invalidJson': 'JSON no válido',
'settings.plugins.page.field.fileName': 'Nombre de archivo',
'settings.plugins.page.field.content': 'Contenido',
'settings.plugins.page.field.scope': 'Ámbito',
'settings.plugins.scope.user': 'Usuario',
'settings.plugins.scope.project': 'Proyecto',
'settings.plugins.page.action.save': 'Guardar',
'settings.plugins.page.action.discard': 'Descartar',
'settings.plugins.dialog.add.title': 'Añadir plugin',
'settings.plugins.dialog.add.tab.npm': 'Desde npm',
'settings.plugins.dialog.add.tab.path': 'Desde ruta local',
'settings.plugins.dialog.add.tab.file': 'Archivo nuevo',
'settings.plugins.dialog.add.action.submit': 'Añadir',
'settings.plugins.dialog.add.action.cancel': 'Cancelar',
'settings.plugins.toast.created': 'Plugin añadido',
'settings.plugins.toast.updated': 'Plugin actualizado',
'settings.plugins.toast.reloadFailed': 'Falló la recarga de opencode; se requiere reiniciar',
'settings.plugins.validation.fileName': 'El nombre de archivo debe estar en minúsculas y terminar en .js / .ts / .mjs / .cjs',
'settings.plugins.validation.specRequired': 'La especificación es obligatoria',
'settings.plugins.registry.badge.update.label': '↑ {version}',
'settings.plugins.registry.badge.update.tooltip': 'Actualización disponible: {current} → {latest}',
'settings.plugins.registry.badge.malformed.tooltip': 'La especificación no es válida',
'settings.plugins.registry.badge.missingPackage.tooltip': 'No se encontró el paquete {name} en npm',
'settings.plugins.registry.badge.missingVersion.tooltip': 'La versión {version} de {name} no está publicada',
'settings.plugins.registry.badge.pathMissing.tooltip': 'Archivo no encontrado: {path}',
'settings.plugins.registry.badge.pathUnreadable.tooltip': 'No se puede leer el archivo: {path}',
'settings.plugins.registry.badge.network.tooltip': 'No se pudo conectar con el registro de npm',
'settings.plugins.registry.banner.updateAvailable.title': 'Actualización disponible',
'settings.plugins.registry.banner.updateAvailable.description': '{current} → {latest}',
'settings.plugins.registry.banner.updateAvailable.action': 'Actualizar a {latest}',
'settings.plugins.registry.banner.invalid.title': 'Plugin no válido',
'settings.plugins.registry.banner.invalid.malformed': 'La sintaxis de la especificación no es válida',
'settings.plugins.registry.banner.invalid.missingPackage': 'Paquete no encontrado en npm',
'settings.plugins.registry.banner.invalid.missingVersion': 'Versión no publicada',
'settings.plugins.registry.banner.invalid.pathMissing': 'El archivo no existe',
'settings.plugins.registry.banner.invalid.pathUnreadable': 'No se puede leer el archivo',
'settings.plugins.sidebar.actions.updateToLatest': 'Actualizar a la última versión',
'settings.plugins.sidebar.actions.refresh': 'Buscar actualizaciones',
'settings.plugins.sidebar.group.updatesAvailable_one': '{count} actualización disponible',
'settings.plugins.sidebar.group.updatesAvailable_other': '{count} actualizaciones disponibles',
'settings.plugins.toast.updatedToLatest': 'Plugin actualizado a {version}',
'settings.plugins.toast.refreshing': 'Buscando actualizaciones en npm…',
'settings.plugins.toast.refreshFailed': 'No se pudo consultar el registro de npm',
"settings.openchamber.keyboardShortcuts.title": "Atajos de teclado",
"settings.openchamber.keyboardShortcuts.actions.resetAll": "Restablecer todo",
"settings.openchamber.keyboardShortcuts.actions.overwrite": "Sobrescribir",
@@ -13,6 +13,8 @@ export const settingsDict = {
'settings.view.home.cards.skillsCatalog.description': '카탈로그에서 스킬을 설치합니다',
'settings.view.home.cards.mcp.title': 'MCP',
'settings.view.home.cards.mcp.description': 'MCP 서버 연결을 설정하세요',
'settings.view.home.cards.plugins.title': 'Plugins',
'settings.view.home.cards.plugins.description': 'Manage opencode plugins',
'settings.view.home.cards.usage.title': '사용량',
'settings.view.home.cards.usage.description': '할당량 및 지출 현황',
'settings.view.unavailable.title': '사용할 수 없음',
@@ -33,6 +35,7 @@ export const settingsDict = {
'settings.page.agents.title': '에이전트',
'settings.page.commands.title': '명령어',
'settings.page.mcp.title': 'MCP',
'settings.page.plugins.title': 'Plugins',
'settings.page.skills.title': '스킬',
'settings.page.skillsCatalog.title': '스킬 카탈로그',
'settings.page.git.title': 'Git',
@@ -766,6 +769,73 @@ export const settingsDict = {
'settings.mcp.sidebar.toast.deleteFailed': 'MCP 서버를 삭제하지 못했습니다',
'settings.mcp.sidebar.toast.serverDeleted': 'MCP 서버 "{name}"이(가) 삭제되었습니다',
'settings.mcp.sidebar.toast.refreshListIfStale': 'UI가 오래된 것처럼 보이면 MCP 목록을 새로고침하세요.',
'settings.plugins.sidebar.title': '플러그인',
'settings.plugins.sidebar.total': '총 {count}개',
'settings.plugins.sidebar.actions.addTitle': '플러그인 추가',
'settings.plugins.sidebar.actions.deleting': '삭제 중…',
'settings.plugins.sidebar.empty.title': '설정된 플러그인이 없습니다',
'settings.plugins.sidebar.empty.description': '위의 + 버튼을 눌러 추가하세요',
'settings.plugins.sidebar.group.userEntries': '사용자 설정',
'settings.plugins.sidebar.group.userFiles': '사용자 플러그인 파일',
'settings.plugins.sidebar.group.projectEntries': '프로젝트 설정',
'settings.plugins.sidebar.group.projectFiles': '프로젝트 플러그인 파일',
'settings.plugins.sidebar.kind.npm': 'npm 패키지',
'settings.plugins.sidebar.kind.path': '로컬 경로',
'settings.plugins.sidebar.kind.file': '플러그인 파일',
'settings.plugins.sidebar.deleteDialog.title': '플러그인 삭제',
'settings.plugins.sidebar.deleteDialog.description': '"{name}"을(를) 삭제하시겠습니까?',
'settings.plugins.sidebar.toast.deleted': '플러그인 "{name}"이(가) 삭제되었습니다',
'settings.plugins.sidebar.toast.deleteFailed': '플러그인을 삭제하지 못했습니다',
'settings.plugins.page.empty.select': '보거나 편집할 플러그인을 선택하세요',
'settings.plugins.page.empty.add': '또는 +를 눌러 새 플러그인을 추가하세요',
'settings.plugins.page.header.entry': '설치된 플러그인',
'settings.plugins.page.header.file': '플러그인 파일',
'settings.plugins.page.field.spec': '명세',
'settings.plugins.page.field.spec.placeholder': 'npm-패키지@버전 또는 /절대/경로',
'settings.plugins.page.field.options': '옵션(JSON)',
'settings.plugins.page.field.options.invalidJson': '잘못된 JSON',
'settings.plugins.page.field.fileName': '파일 이름',
'settings.plugins.page.field.content': '내용',
'settings.plugins.page.field.scope': '범위',
'settings.plugins.scope.user': '사용자',
'settings.plugins.scope.project': '프로젝트',
'settings.plugins.page.action.save': '저장',
'settings.plugins.page.action.discard': '취소',
'settings.plugins.dialog.add.title': '플러그인 추가',
'settings.plugins.dialog.add.tab.npm': 'npm에서',
'settings.plugins.dialog.add.tab.path': '로컬 경로에서',
'settings.plugins.dialog.add.tab.file': '새 파일',
'settings.plugins.dialog.add.action.submit': '추가',
'settings.plugins.dialog.add.action.cancel': '취소',
'settings.plugins.toast.created': '플러그인이 추가되었습니다',
'settings.plugins.toast.updated': '플러그인이 업데이트되었습니다',
'settings.plugins.toast.reloadFailed': 'opencode 다시 로드 실패; 재시작이 필요합니다',
'settings.plugins.validation.fileName': '파일 이름은 소문자여야 하며 .js / .ts / .mjs / .cjs로 끝나야 합니다',
'settings.plugins.validation.specRequired': '명세는 필수입니다',
'settings.plugins.registry.badge.update.label': '↑ {version}',
'settings.plugins.registry.badge.update.tooltip': '업데이트 가능: {current} → {latest}',
'settings.plugins.registry.badge.malformed.tooltip': '명세 형식이 잘못되었습니다',
'settings.plugins.registry.badge.missingPackage.tooltip': 'npm에서 패키지 {name}을(를) 찾을 수 없습니다',
'settings.plugins.registry.badge.missingVersion.tooltip': '{name}의 {version} 버전이 게시되지 않았습니다',
'settings.plugins.registry.badge.pathMissing.tooltip': '파일을 찾을 수 없음: {path}',
'settings.plugins.registry.badge.pathUnreadable.tooltip': '파일을 읽을 수 없음: {path}',
'settings.plugins.registry.badge.network.tooltip': 'npm 레지스트리에 연결할 수 없습니다',
'settings.plugins.registry.banner.updateAvailable.title': '업데이트 가능',
'settings.plugins.registry.banner.updateAvailable.description': '{current} → {latest}',
'settings.plugins.registry.banner.updateAvailable.action': '{latest}(으)로 업데이트',
'settings.plugins.registry.banner.invalid.title': '잘못된 플러그인',
'settings.plugins.registry.banner.invalid.malformed': '명세 구문이 잘못되었습니다',
'settings.plugins.registry.banner.invalid.missingPackage': 'npm에서 패키지를 찾을 수 없습니다',
'settings.plugins.registry.banner.invalid.missingVersion': '게시되지 않은 버전입니다',
'settings.plugins.registry.banner.invalid.pathMissing': '파일이 존재하지 않습니다',
'settings.plugins.registry.banner.invalid.pathUnreadable': '파일을 읽을 수 없습니다',
'settings.plugins.sidebar.actions.updateToLatest': '최신 버전으로 업데이트',
'settings.plugins.sidebar.actions.refresh': '업데이트 확인',
'settings.plugins.sidebar.group.updatesAvailable_one': '업데이트 {count}개 가능',
'settings.plugins.sidebar.group.updatesAvailable_other': '업데이트 {count}개 가능',
'settings.plugins.toast.updatedToLatest': '플러그인이 {version}(으)로 업데이트되었습니다',
'settings.plugins.toast.refreshing': 'npm에서 업데이트 확인 중…',
'settings.plugins.toast.refreshFailed': 'npm 레지스트리를 확인하지 못했습니다',
'settings.openchamber.keyboardShortcuts.title': '키보드 단축키',
'settings.openchamber.keyboardShortcuts.actions.resetAll': '모두 초기화',
'settings.openchamber.keyboardShortcuts.actions.overwrite': '덮어쓰기',
@@ -479,6 +479,73 @@ export const settingsDict = {
'settings.mcp.sidebar.title': 'Serwery MCP',
'settings.mcp.sidebar.toast.deleteFailed': 'Nie udało się usunąć serwera MCP',
'settings.mcp.sidebar.toast.refreshListIfStale': 'Odśwież listę MCP, jeśli interfejs wydaje się nieaktualny.',
'settings.plugins.sidebar.title': 'Pluginy',
'settings.plugins.sidebar.total': 'Łącznie: {count}',
'settings.plugins.sidebar.actions.addTitle': 'Dodaj plugin',
'settings.plugins.sidebar.actions.deleting': 'Usuwanie…',
'settings.plugins.sidebar.empty.title': 'Brak skonfigurowanych pluginów',
'settings.plugins.sidebar.empty.description': 'Użyj przycisku + powyżej, aby dodać plugin',
'settings.plugins.sidebar.group.userEntries': 'Konfiguracja użytkownika',
'settings.plugins.sidebar.group.userFiles': 'Plik pluginu użytkownika',
'settings.plugins.sidebar.group.projectEntries': 'Konfiguracja projektu',
'settings.plugins.sidebar.group.projectFiles': 'Plik pluginu projektu',
'settings.plugins.sidebar.kind.npm': 'pakiet npm',
'settings.plugins.sidebar.kind.path': 'Ścieżka lokalna',
'settings.plugins.sidebar.kind.file': 'Plik pluginu',
'settings.plugins.sidebar.deleteDialog.title': 'Usuń plugin',
'settings.plugins.sidebar.deleteDialog.description': 'Czy na pewno chcesz usunąć „{name}”?',
'settings.plugins.sidebar.toast.deleted': 'Plugin „{name}” usunięty',
'settings.plugins.sidebar.toast.deleteFailed': 'Nie udało się usunąć pluginu',
'settings.plugins.page.empty.select': 'Wybierz plugin, aby go wyświetlić lub edytować',
'settings.plugins.page.empty.add': 'Albo kliknij +, aby dodać nowy plugin',
'settings.plugins.page.header.entry': 'Zainstalowany plugin',
'settings.plugins.page.header.file': 'Plik pluginu',
'settings.plugins.page.field.spec': 'Specyfikacja',
'settings.plugins.page.field.spec.placeholder': 'pakiet-npm@wersja lub /ścieżka/bezwzględna',
'settings.plugins.page.field.options': 'Opcje (JSON)',
'settings.plugins.page.field.options.invalidJson': 'Nieprawidłowy JSON',
'settings.plugins.page.field.fileName': 'Nazwa pliku',
'settings.plugins.page.field.content': 'Zawartość',
'settings.plugins.page.field.scope': 'Zakres',
'settings.plugins.scope.user': 'Użytkownik',
'settings.plugins.scope.project': 'Projekt',
'settings.plugins.page.action.save': 'Zapisz',
'settings.plugins.page.action.discard': 'Odrzuć',
'settings.plugins.dialog.add.title': 'Dodaj plugin',
'settings.plugins.dialog.add.tab.npm': 'Z npm',
'settings.plugins.dialog.add.tab.path': 'Ze ścieżki lokalnej',
'settings.plugins.dialog.add.tab.file': 'Nowy plik',
'settings.plugins.dialog.add.action.submit': 'Dodaj',
'settings.plugins.dialog.add.action.cancel': 'Anuluj',
'settings.plugins.toast.created': 'Plugin dodany',
'settings.plugins.toast.updated': 'Plugin zaktualizowany',
'settings.plugins.toast.reloadFailed': 'Nie udało się przeładować opencode; wymagany restart',
'settings.plugins.validation.fileName': 'Nazwa pliku musi być małymi literami i kończyć się na .js / .ts / .mjs / .cjs',
'settings.plugins.validation.specRequired': 'Specyfikacja jest wymagana',
'settings.plugins.registry.badge.update.label': '↑ {version}',
'settings.plugins.registry.badge.update.tooltip': 'Dostępna aktualizacja: {current} → {latest}',
'settings.plugins.registry.badge.malformed.tooltip': 'Specyfikacja jest nieprawidłowa',
'settings.plugins.registry.badge.missingPackage.tooltip': 'Nie znaleziono pakietu {name} w npm',
'settings.plugins.registry.badge.missingVersion.tooltip': 'Wersja {version} pakietu {name} nie została opublikowana',
'settings.plugins.registry.badge.pathMissing.tooltip': 'Nie znaleziono pliku: {path}',
'settings.plugins.registry.badge.pathUnreadable.tooltip': 'Nie można odczytać pliku: {path}',
'settings.plugins.registry.badge.network.tooltip': 'Nie można połączyć się z rejestrem npm',
'settings.plugins.registry.banner.updateAvailable.title': 'Dostępna aktualizacja',
'settings.plugins.registry.banner.updateAvailable.description': '{current} → {latest}',
'settings.plugins.registry.banner.updateAvailable.action': 'Aktualizuj do {latest}',
'settings.plugins.registry.banner.invalid.title': 'Nieprawidłowy plugin',
'settings.plugins.registry.banner.invalid.malformed': 'Składnia specyfikacji jest nieprawidłowa',
'settings.plugins.registry.banner.invalid.missingPackage': 'Nie znaleziono pakietu w npm',
'settings.plugins.registry.banner.invalid.missingVersion': 'Wersja nie została opublikowana',
'settings.plugins.registry.banner.invalid.pathMissing': 'Plik nie istnieje',
'settings.plugins.registry.banner.invalid.pathUnreadable': 'Nie można odczytać pliku',
'settings.plugins.sidebar.actions.updateToLatest': 'Aktualizuj do najnowszej wersji',
'settings.plugins.sidebar.actions.refresh': 'Sprawdź aktualizacje',
'settings.plugins.sidebar.group.updatesAvailable_one': 'Dostępna {count} aktualizacja',
'settings.plugins.sidebar.group.updatesAvailable_other': 'Dostępnych aktualizacji: {count}',
'settings.plugins.toast.updatedToLatest': 'Plugin zaktualizowany do {version}',
'settings.plugins.toast.refreshing': 'Sprawdzanie aktualizacji w npm…',
'settings.plugins.toast.refreshFailed': 'Nie udało się sprawdzić rejestru npm',
'settings.mcp.sidebar.toast.serverDeleted': 'Serwer MCP "{name}" został usunięty',
'settings.mcp.sidebar.total': 'Suma: {count}',
'settings.notifications.page.delivery.browserPermissionHint': 'Twoja przeglądarka może poprosić o uprawnienia przy pierwszym uruchomieniu.',
@@ -957,6 +1024,7 @@ export const settingsDict = {
'settings.page.git.title': 'Git',
'settings.page.magicPrompts.title': 'Magiczne Prompty',
'settings.page.mcp.title': 'MCP',
'settings.page.plugins.title': 'Plugins',
'settings.page.notifications.title': 'Powiadomienia',
'settings.page.projects.title': 'Projekty',
'settings.page.providers.title': 'Dostawcy',
@@ -1543,6 +1611,8 @@ export const settingsDict = {
'settings.view.home.cards.agents.title': 'Agenci',
'settings.view.home.cards.mcp.description': 'Skonfiguruj serwery MCP + połączenia',
'settings.view.home.cards.mcp.title': 'MCP',
'settings.view.home.cards.plugins.title': 'Plugins',
'settings.view.home.cards.plugins.description': 'Manage opencode plugins',
'settings.view.home.cards.providers.description': 'Połącz modele + dane uwierzytelniające',
'settings.view.home.cards.providers.title': 'Dostawcy',
'settings.view.home.cards.skillsCatalog.description': 'Zainstaluj skille z katalogów',
@@ -13,6 +13,8 @@ export const settingsDict = {
"settings.view.home.cards.skillsCatalog.description": "Instalar habilidades de catálogos",
"settings.view.home.cards.mcp.title": "MCP",
"settings.view.home.cards.mcp.description": "Configure servidores e conexões MCP",
'settings.view.home.cards.plugins.title': 'Plugins',
'settings.view.home.cards.plugins.description': 'Manage opencode plugins',
"settings.view.home.cards.usage.title": "Uso",
"settings.view.home.cards.usage.description": "Cota + visibilidade dos gastos",
"settings.view.unavailable.title": "Indisponível",
@@ -33,6 +35,7 @@ export const settingsDict = {
"settings.page.agents.title": "Agentes",
"settings.page.commands.title": "Comandos",
"settings.page.mcp.title": "MCP",
'settings.page.plugins.title': 'Plugins',
"settings.page.skills.title": "Habilidades",
"settings.page.skillsCatalog.title": "Catálogo de habilidades",
"settings.page.git.title": "Git",
@@ -766,6 +769,73 @@ export const settingsDict = {
"settings.mcp.sidebar.toast.deleteFailed": "Não foi possível excluir o servidor MCP",
"settings.mcp.sidebar.toast.serverDeleted": "Servidor MCP \"{name}\" excluído",
"settings.mcp.sidebar.toast.refreshListIfStale": "Atualize a lista de MCP se a interface parecer desatualizada.",
'settings.plugins.sidebar.title': 'Plugins',
'settings.plugins.sidebar.total': 'Total: {count}',
'settings.plugins.sidebar.actions.addTitle': 'Adicionar plugin',
'settings.plugins.sidebar.actions.deleting': 'Excluindo…',
'settings.plugins.sidebar.empty.title': 'Nenhum plugin configurado',
'settings.plugins.sidebar.empty.description': 'Use o botão + acima para adicionar um',
'settings.plugins.sidebar.group.userEntries': 'Configuração do usuário',
'settings.plugins.sidebar.group.userFiles': 'Arquivo de plugin do usuário',
'settings.plugins.sidebar.group.projectEntries': 'Configuração do projeto',
'settings.plugins.sidebar.group.projectFiles': 'Arquivo de plugin do projeto',
'settings.plugins.sidebar.kind.npm': 'pacote npm',
'settings.plugins.sidebar.kind.path': 'Caminho local',
'settings.plugins.sidebar.kind.file': 'Arquivo de plugin',
'settings.plugins.sidebar.deleteDialog.title': 'Excluir plugin',
'settings.plugins.sidebar.deleteDialog.description': 'Tem certeza de que deseja excluir "{name}"?',
'settings.plugins.sidebar.toast.deleted': 'Plugin "{name}" excluído',
'settings.plugins.sidebar.toast.deleteFailed': 'Falha ao excluir plugin',
'settings.plugins.page.empty.select': 'Selecione um plugin para ver ou editar',
'settings.plugins.page.empty.add': 'Ou clique em + para adicionar um novo plugin',
'settings.plugins.page.header.entry': 'Plugin instalado',
'settings.plugins.page.header.file': 'Arquivo de plugin',
'settings.plugins.page.field.spec': 'Especificação',
'settings.plugins.page.field.spec.placeholder': 'pacote-npm@versão ou /caminho/absoluto',
'settings.plugins.page.field.options': 'Opções (JSON)',
'settings.plugins.page.field.options.invalidJson': 'JSON inválido',
'settings.plugins.page.field.fileName': 'Nome do arquivo',
'settings.plugins.page.field.content': 'Conteúdo',
'settings.plugins.page.field.scope': 'Escopo',
'settings.plugins.scope.user': 'Usuário',
'settings.plugins.scope.project': 'Projeto',
'settings.plugins.page.action.save': 'Salvar',
'settings.plugins.page.action.discard': 'Descartar',
'settings.plugins.dialog.add.title': 'Adicionar plugin',
'settings.plugins.dialog.add.tab.npm': 'Do npm',
'settings.plugins.dialog.add.tab.path': 'De caminho local',
'settings.plugins.dialog.add.tab.file': 'Novo arquivo',
'settings.plugins.dialog.add.action.submit': 'Adicionar',
'settings.plugins.dialog.add.action.cancel': 'Cancelar',
'settings.plugins.toast.created': 'Plugin adicionado',
'settings.plugins.toast.updated': 'Plugin atualizado',
'settings.plugins.toast.reloadFailed': 'Falha ao recarregar opencode; reinicialização necessária',
'settings.plugins.validation.fileName': 'O nome do arquivo deve estar em minúsculas e terminar em .js / .ts / .mjs / .cjs',
'settings.plugins.validation.specRequired': 'A especificação é obrigatória',
'settings.plugins.registry.badge.update.label': '↑ {version}',
'settings.plugins.registry.badge.update.tooltip': 'Atualização disponível: {current} → {latest}',
'settings.plugins.registry.badge.malformed.tooltip': 'A especificação está malformada',
'settings.plugins.registry.badge.missingPackage.tooltip': 'Pacote {name} não encontrado no npm',
'settings.plugins.registry.badge.missingVersion.tooltip': 'A versão {version} de {name} não foi publicada',
'settings.plugins.registry.badge.pathMissing.tooltip': 'Arquivo não encontrado: {path}',
'settings.plugins.registry.badge.pathUnreadable.tooltip': 'Arquivo não legível: {path}',
'settings.plugins.registry.badge.network.tooltip': 'Não foi possível acessar o registro npm',
'settings.plugins.registry.banner.updateAvailable.title': 'Atualização disponível',
'settings.plugins.registry.banner.updateAvailable.description': '{current} → {latest}',
'settings.plugins.registry.banner.updateAvailable.action': 'Atualizar para {latest}',
'settings.plugins.registry.banner.invalid.title': 'Plugin inválido',
'settings.plugins.registry.banner.invalid.malformed': 'A sintaxe da especificação está malformada',
'settings.plugins.registry.banner.invalid.missingPackage': 'Pacote não encontrado no npm',
'settings.plugins.registry.banner.invalid.missingVersion': 'Versão não publicada',
'settings.plugins.registry.banner.invalid.pathMissing': 'O arquivo não existe',
'settings.plugins.registry.banner.invalid.pathUnreadable': 'O arquivo não é legível',
'settings.plugins.sidebar.actions.updateToLatest': 'Atualizar para a versão mais recente',
'settings.plugins.sidebar.actions.refresh': 'Verificar atualizações',
'settings.plugins.sidebar.group.updatesAvailable_one': '{count} atualização disponível',
'settings.plugins.sidebar.group.updatesAvailable_other': '{count} atualizações disponíveis',
'settings.plugins.toast.updatedToLatest': 'Plugin atualizado para {version}',
'settings.plugins.toast.refreshing': 'Verificando atualizações no npm…',
'settings.plugins.toast.refreshFailed': 'Não foi possível consultar o registro npm',
"settings.openchamber.keyboardShortcuts.title": "Atalhos de teclado",
"settings.openchamber.keyboardShortcuts.actions.resetAll": "Redefinir tudo",
"settings.openchamber.keyboardShortcuts.actions.overwrite": "Sobrescrever",
@@ -13,6 +13,8 @@ export const settingsDict = {
"settings.view.home.cards.skillsCatalog.description": "Встановлення навичок із каталогів",
"settings.view.home.cards.mcp.title": "MCP",
"settings.view.home.cards.mcp.description": "Налаштування MCP серверів і підключень",
'settings.view.home.cards.plugins.title': 'Plugins',
'settings.view.home.cards.plugins.description': 'Manage opencode plugins',
"settings.view.home.cards.usage.title": "Використання",
"settings.view.home.cards.usage.description": "Квота + видимість витрат",
"settings.view.unavailable.title": "Недоступно",
@@ -33,6 +35,7 @@ export const settingsDict = {
"settings.page.agents.title": "Агенти",
"settings.page.commands.title": "Команди",
"settings.page.mcp.title": "MCP",
'settings.page.plugins.title': 'Plugins',
"settings.page.skills.title": "Навички",
"settings.page.skillsCatalog.title": "Каталог навичок",
"settings.page.git.title": "Git",
@@ -766,6 +769,73 @@ export const settingsDict = {
"settings.mcp.sidebar.toast.deleteFailed": "Не вдалося видалити сервер MCP",
"settings.mcp.sidebar.toast.serverDeleted": "MCP сервер \"{name}\" видалено",
"settings.mcp.sidebar.toast.refreshListIfStale": "Оновити список MCP, якщо інтерфейс користувача виглядає застарілим.",
'settings.plugins.sidebar.title': 'Плагіни',
'settings.plugins.sidebar.total': 'Усього: {count}',
'settings.plugins.sidebar.actions.addTitle': 'Додати плагін',
'settings.plugins.sidebar.actions.deleting': 'Видалення…',
'settings.plugins.sidebar.empty.title': 'Плагіни не налаштовано',
'settings.plugins.sidebar.empty.description': 'Натисніть кнопку + вище, щоб додати плагін',
'settings.plugins.sidebar.group.userEntries': 'Конфігурація користувача',
'settings.plugins.sidebar.group.userFiles': 'Файл плагіна користувача',
'settings.plugins.sidebar.group.projectEntries': 'Конфігурація проєкту',
'settings.plugins.sidebar.group.projectFiles': 'Файл плагіна проєкту',
'settings.plugins.sidebar.kind.npm': 'пакет npm',
'settings.plugins.sidebar.kind.path': 'Локальний шлях',
'settings.plugins.sidebar.kind.file': 'Файл плагіна',
'settings.plugins.sidebar.deleteDialog.title': 'Видалити плагін',
'settings.plugins.sidebar.deleteDialog.description': 'Ви впевнені, що хочете видалити "{name}"?',
'settings.plugins.sidebar.toast.deleted': 'Плагін "{name}" видалено',
'settings.plugins.sidebar.toast.deleteFailed': 'Не вдалося видалити плагін',
'settings.plugins.page.empty.select': 'Виберіть плагін, щоб переглянути або змінити його',
'settings.plugins.page.empty.add': 'Або натисніть +, щоб додати новий плагін',
'settings.plugins.page.header.entry': 'Встановлений плагін',
'settings.plugins.page.header.file': 'Файл плагіна',
'settings.plugins.page.field.spec': 'Специфікація',
'settings.plugins.page.field.spec.placeholder': 'npm-пакет@версія або /абсолютний/шлях',
'settings.plugins.page.field.options': 'Параметри (JSON)',
'settings.plugins.page.field.options.invalidJson': 'Некоректний JSON',
'settings.plugins.page.field.fileName': 'Назва файлу',
'settings.plugins.page.field.content': 'Вміст',
'settings.plugins.page.field.scope': 'Область',
'settings.plugins.scope.user': 'Користувач',
'settings.plugins.scope.project': 'Проєкт',
'settings.plugins.page.action.save': 'Зберегти',
'settings.plugins.page.action.discard': 'Скасувати',
'settings.plugins.dialog.add.title': 'Додати плагін',
'settings.plugins.dialog.add.tab.npm': 'З npm',
'settings.plugins.dialog.add.tab.path': 'З локального шляху',
'settings.plugins.dialog.add.tab.file': 'Новий файл',
'settings.plugins.dialog.add.action.submit': 'Додати',
'settings.plugins.dialog.add.action.cancel': 'Скасувати',
'settings.plugins.toast.created': 'Плагін додано',
'settings.plugins.toast.updated': 'Плагін оновлено',
'settings.plugins.toast.reloadFailed': 'Не вдалося перезавантажити opencode; потрібен перезапуск',
'settings.plugins.validation.fileName': 'Назва файлу має бути в нижньому регістрі й закінчуватися на .js / .ts / .mjs / .cjs',
'settings.plugins.validation.specRequired': 'Специфікація обов’язкова',
'settings.plugins.registry.badge.update.label': '↑ {version}',
'settings.plugins.registry.badge.update.tooltip': 'Доступне оновлення: {current} → {latest}',
'settings.plugins.registry.badge.malformed.tooltip': 'Специфікація некоректна',
'settings.plugins.registry.badge.missingPackage.tooltip': 'Пакет {name} не знайдено в npm',
'settings.plugins.registry.badge.missingVersion.tooltip': 'Версію {version} пакета {name} не опубліковано',
'settings.plugins.registry.badge.pathMissing.tooltip': 'Файл не знайдено: {path}',
'settings.plugins.registry.badge.pathUnreadable.tooltip': 'Файл неможливо прочитати: {path}',
'settings.plugins.registry.badge.network.tooltip': 'Не вдалося підключитися до реєстру npm',
'settings.plugins.registry.banner.updateAvailable.title': 'Доступне оновлення',
'settings.plugins.registry.banner.updateAvailable.description': '{current} → {latest}',
'settings.plugins.registry.banner.updateAvailable.action': 'Оновити до {latest}',
'settings.plugins.registry.banner.invalid.title': 'Некоректний плагін',
'settings.plugins.registry.banner.invalid.malformed': 'Синтаксис специфікації некоректний',
'settings.plugins.registry.banner.invalid.missingPackage': 'Пакет не знайдено в npm',
'settings.plugins.registry.banner.invalid.missingVersion': 'Версію не опубліковано',
'settings.plugins.registry.banner.invalid.pathMissing': 'Файл не існує',
'settings.plugins.registry.banner.invalid.pathUnreadable': 'Файл неможливо прочитати',
'settings.plugins.sidebar.actions.updateToLatest': 'Оновити до останньої версії',
'settings.plugins.sidebar.actions.refresh': 'Перевірити оновлення',
'settings.plugins.sidebar.group.updatesAvailable_one': 'Доступне {count} оновлення',
'settings.plugins.sidebar.group.updatesAvailable_other': 'Доступно оновлень: {count}',
'settings.plugins.toast.updatedToLatest': 'Плагін оновлено до {version}',
'settings.plugins.toast.refreshing': 'Перевірка оновлень у npm…',
'settings.plugins.toast.refreshFailed': 'Не вдалося перевірити реєстр npm',
"settings.openchamber.keyboardShortcuts.title": "Комбінації клавіш",
"settings.openchamber.keyboardShortcuts.actions.resetAll": "Скинути все",
"settings.openchamber.keyboardShortcuts.actions.overwrite": "Перезаписати",
@@ -13,6 +13,8 @@ export const settingsDict = {
'settings.view.home.cards.skillsCatalog.description': '从目录安装技能',
'settings.view.home.cards.mcp.title': 'MCP',
'settings.view.home.cards.mcp.description': '配置 MCP 服务器和连接',
'settings.view.home.cards.plugins.title': 'Plugins',
'settings.view.home.cards.plugins.description': 'Manage opencode plugins',
'settings.view.home.cards.usage.title': '用量',
'settings.view.home.cards.usage.description': '配额和花费可见性',
'settings.view.unavailable.title': '不可用',
@@ -33,6 +35,7 @@ export const settingsDict = {
'settings.page.agents.title': '智能体',
'settings.page.commands.title': '命令',
'settings.page.mcp.title': 'MCP',
'settings.page.plugins.title': 'Plugins',
'settings.page.skills.title': '技能',
'settings.page.skillsCatalog.title': '技能目录',
'settings.page.git.title': 'Git',
@@ -766,6 +769,73 @@ export const settingsDict = {
'settings.mcp.sidebar.toast.deleteFailed': '删除 MCP 服务器失败',
'settings.mcp.sidebar.toast.serverDeleted': 'MCP 服务器“{name}”已删除',
'settings.mcp.sidebar.toast.refreshListIfStale': '如果界面看起来未更新,请刷新 MCP 列表。',
'settings.plugins.sidebar.title': '插件',
'settings.plugins.sidebar.total': '总计 {count}',
'settings.plugins.sidebar.actions.addTitle': '添加插件',
'settings.plugins.sidebar.actions.deleting': '正在删除…',
'settings.plugins.sidebar.empty.title': '尚未配置插件',
'settings.plugins.sidebar.empty.description': '使用上方的 + 按钮添加一个插件',
'settings.plugins.sidebar.group.userEntries': '用户配置',
'settings.plugins.sidebar.group.userFiles': '用户插件文件',
'settings.plugins.sidebar.group.projectEntries': '项目配置',
'settings.plugins.sidebar.group.projectFiles': '项目插件文件',
'settings.plugins.sidebar.kind.npm': 'npm 包',
'settings.plugins.sidebar.kind.path': '本地路径',
'settings.plugins.sidebar.kind.file': '插件文件',
'settings.plugins.sidebar.deleteDialog.title': '删除插件',
'settings.plugins.sidebar.deleteDialog.description': '确定要删除“{name}”吗?',
'settings.plugins.sidebar.toast.deleted': '插件“{name}”已删除',
'settings.plugins.sidebar.toast.deleteFailed': '删除插件失败',
'settings.plugins.page.empty.select': '选择一个插件以查看或编辑',
'settings.plugins.page.empty.add': '或点击 + 添加新插件',
'settings.plugins.page.header.entry': '已安装插件',
'settings.plugins.page.header.file': '插件文件',
'settings.plugins.page.field.spec': '规格',
'settings.plugins.page.field.spec.placeholder': 'npm-package@version 或 /absolute/path',
'settings.plugins.page.field.options': '选项(JSON',
'settings.plugins.page.field.options.invalidJson': 'JSON 无效',
'settings.plugins.page.field.fileName': '文件名',
'settings.plugins.page.field.content': '内容',
'settings.plugins.page.field.scope': '范围',
'settings.plugins.scope.user': '用户',
'settings.plugins.scope.project': '项目',
'settings.plugins.page.action.save': '保存',
'settings.plugins.page.action.discard': '放弃',
'settings.plugins.dialog.add.title': '添加插件',
'settings.plugins.dialog.add.tab.npm': '从 npm',
'settings.plugins.dialog.add.tab.path': '从本地路径',
'settings.plugins.dialog.add.tab.file': '新建文件',
'settings.plugins.dialog.add.action.submit': '添加',
'settings.plugins.dialog.add.action.cancel': '取消',
'settings.plugins.toast.created': '插件已添加',
'settings.plugins.toast.updated': '插件已更新',
'settings.plugins.toast.reloadFailed': 'opencode 重新加载失败;需要重启',
'settings.plugins.validation.fileName': '文件名必须为小写,并以 .js / .ts / .mjs / .cjs 结尾',
'settings.plugins.validation.specRequired': '规格为必填项',
'settings.plugins.registry.badge.update.label': '↑ {version}',
'settings.plugins.registry.badge.update.tooltip': '有可用更新:{current} → {latest}',
'settings.plugins.registry.badge.malformed.tooltip': '规格格式不正确',
'settings.plugins.registry.badge.missingPackage.tooltip': 'npm 上找不到包 {name}',
'settings.plugins.registry.badge.missingVersion.tooltip': '{name} 的版本 {version} 尚未发布',
'settings.plugins.registry.badge.pathMissing.tooltip': '找不到文件:{path}',
'settings.plugins.registry.badge.pathUnreadable.tooltip': '无法读取文件:{path}',
'settings.plugins.registry.badge.network.tooltip': '无法连接到 npm 注册表',
'settings.plugins.registry.banner.updateAvailable.title': '有可用更新',
'settings.plugins.registry.banner.updateAvailable.description': '{current} → {latest}',
'settings.plugins.registry.banner.updateAvailable.action': '更新到 {latest}',
'settings.plugins.registry.banner.invalid.title': '插件无效',
'settings.plugins.registry.banner.invalid.malformed': '规格语法格式不正确',
'settings.plugins.registry.banner.invalid.missingPackage': 'npm 上找不到该包',
'settings.plugins.registry.banner.invalid.missingVersion': '版本尚未发布',
'settings.plugins.registry.banner.invalid.pathMissing': '文件不存在',
'settings.plugins.registry.banner.invalid.pathUnreadable': '文件不可读',
'settings.plugins.sidebar.actions.updateToLatest': '更新到最新版',
'settings.plugins.sidebar.actions.refresh': '检查更新',
'settings.plugins.sidebar.group.updatesAvailable_one': '有 {count} 个更新',
'settings.plugins.sidebar.group.updatesAvailable_other': '有 {count} 个更新',
'settings.plugins.toast.updatedToLatest': '插件已更新到 {version}',
'settings.plugins.toast.refreshing': '正在检查 npm 更新…',
'settings.plugins.toast.refreshFailed': '无法检查 npm 注册表',
'settings.openchamber.keyboardShortcuts.title': '键盘快捷键',
'settings.openchamber.keyboardShortcuts.actions.resetAll': '全部重置',
'settings.openchamber.keyboardShortcuts.actions.overwrite': '覆盖',
+8
View File
@@ -10,6 +10,7 @@ export type SettingsPageSlug =
| 'behavior'
| 'commands'
| 'mcp'
| 'plugins'
| 'skills.installed'
| 'skills.catalog'
| 'git'
@@ -126,6 +127,13 @@ export const SETTINGS_PAGE_METADATA: readonly SettingsPageMeta[] = [
kind: 'split',
keywords: ['mcp', 'model context protocol', 'servers', 'tools', 'remote', 'stdio'],
},
{
slug: 'plugins',
title: 'Plugins',
group: 'opencode',
kind: 'split',
keywords: ['plugin', 'plugins', 'extensions', 'addons', 'npm', 'opencode-wakatime'],
},
{
slug: 'skills.installed',
title: 'Skills',