* feat(plugins): add local plugin surfaces and RPCs Keep plugin execution scoped to its daemon while allowing one local TypeScript entry point to contribute validated RPCs and native client surfaces. Paseo owns host selection, navigation chrome, and per-installation query caches. * feat(plugins): add Linear attachment source * fix(nix): refresh npm dependency hash * test(server): exclude internal sessions from Hub counts * test(server): distinguish Hub execution sessions * feat(plugins): make local plugins explicitly opt-in Keep plugin loading dormant until configuration enables it, and collect unsupported examples under one directory. * refactor(plugins): establish host boundaries * fix(nix): refresh plugin dependency hash * fix(plugins): complete packaging and startup rollback * feat(plugins): add managed local lifecycle Make trusted local plugins recoverable and authorable through daemon-owned lifecycle operations, host settings, and a capability-gated CLI. Reloads fully stop the previous plugin before starting new code, while generated projects provide strict TSX checking without changing runtime dependency ownership. * fix(nix): refresh plugin dependency hash
381 lines
16 KiB
TypeScript
381 lines
16 KiB
TypeScript
const shared = {
|
||
directoryPlaceholder: "/absolute/path/on/host",
|
||
} as const;
|
||
|
||
export const pluginSettings = {
|
||
ar: {
|
||
...shared,
|
||
title: "الإضافات",
|
||
trustedTitle: "الإضافات تعليمات برمجية موثوقة",
|
||
trustedDescription:
|
||
"تعمل على هذا المضيف وداخل التطبيق دون عزل. ثبّت فقط التعليمات البرمجية التي تثق بها.",
|
||
globalTitle: "تفعيل الإضافات",
|
||
globalHint: "مفتاح عام لكل الإضافات المضبوطة",
|
||
directoryLabel: "مجلد الإضافة",
|
||
idLabel: "معرّف تثبيت الإضافة",
|
||
idHint: "اتركه فارغًا لاستخدام paseo-plugin.json",
|
||
idPlaceholder: "القيمة الافتراضية للبيان",
|
||
install: "تثبيت المجلد",
|
||
installing: "جارٍ التثبيت…",
|
||
status: { running: "قيد التشغيل", disabled: "معطّلة", failed: "فشلت" },
|
||
actions: {
|
||
reload: "إعادة تحميل",
|
||
reloading: "جارٍ إعادة التحميل…",
|
||
enable: "تفعيل",
|
||
enabling: "جارٍ التفعيل…",
|
||
disable: "تعطيل",
|
||
disabling: "جارٍ التعطيل…",
|
||
remove: "إزالة",
|
||
removing: "جارٍ الإزالة…",
|
||
},
|
||
feedback: {
|
||
installed: "تم تثبيت {{id}}",
|
||
reload: "تمت إعادة تحميل {{id}}",
|
||
enable: "تم تفعيل {{id}}",
|
||
disable: "تم تعطيل {{id}}",
|
||
remove: "تمت إزالة {{id}}",
|
||
kept: "تم الإبقاء على {{id}}",
|
||
globalEnabled: "تم تفعيل الإضافات",
|
||
globalDisabled: "تم تعطيل الإضافات",
|
||
},
|
||
removeConfirmTitle: "إزالة {{id}}؟",
|
||
removeConfirmMessage: "يؤدي هذا إلى إزالة الإعداد فقط. لن يُحذف مجلد المصدر.",
|
||
states: {
|
||
offlineTitle: "مضيف الإضافات غير متصل",
|
||
offlineDescription: "أعد الاتصال بهذا المضيف لإدارة إضافاته.",
|
||
updateTitle: "حدّث هذا المضيف لإدارة الإضافات",
|
||
loading: "جارٍ تحميل الإضافات…",
|
||
errorTitle: "تعذّر تحميل الإضافات",
|
||
retry: "إعادة المحاولة",
|
||
empty: "لا توجد إضافات مضبوطة",
|
||
},
|
||
},
|
||
es: {
|
||
...shared,
|
||
title: "Plugins",
|
||
trustedTitle: "Los plugins son código de confianza",
|
||
trustedDescription:
|
||
"Se ejecutan en este host y dentro de la app sin aislamiento. Instala solo código de confianza.",
|
||
globalTitle: "Activar plugins",
|
||
globalHint: "Interruptor global para todos los plugins configurados",
|
||
directoryLabel: "Directorio del plugin",
|
||
idLabel: "ID de instalación del plugin",
|
||
idHint: "Déjalo vacío para usar paseo-plugin.json",
|
||
idPlaceholder: "Valor del manifiesto",
|
||
install: "Instalar directorio",
|
||
installing: "Instalando…",
|
||
status: { running: "en ejecución", disabled: "desactivado", failed: "fallido" },
|
||
actions: {
|
||
reload: "Recargar",
|
||
reloading: "Recargando…",
|
||
enable: "Activar",
|
||
enabling: "Activando…",
|
||
disable: "Desactivar",
|
||
disabling: "Desactivando…",
|
||
remove: "Eliminar",
|
||
removing: "Eliminando…",
|
||
},
|
||
feedback: {
|
||
installed: "{{id}} instalado",
|
||
reload: "{{id}} recargado",
|
||
enable: "{{id}} activado",
|
||
disable: "{{id}} desactivado",
|
||
remove: "{{id}} eliminado",
|
||
kept: "Se conservó {{id}}",
|
||
globalEnabled: "Plugins activados",
|
||
globalDisabled: "Plugins desactivados",
|
||
},
|
||
removeConfirmTitle: "¿Eliminar {{id}}?",
|
||
removeConfirmMessage: "Esto elimina la configuración. El directorio de origen no se borra.",
|
||
states: {
|
||
offlineTitle: "El host de plugins está sin conexión",
|
||
offlineDescription: "Vuelve a conectar este host para gestionar sus plugins.",
|
||
updateTitle: "Actualiza este host para gestionar plugins",
|
||
loading: "Cargando plugins…",
|
||
errorTitle: "No se pudieron cargar los plugins",
|
||
retry: "Reintentar",
|
||
empty: "No hay plugins configurados",
|
||
},
|
||
},
|
||
fr: {
|
||
...shared,
|
||
title: "Plugins",
|
||
trustedTitle: "Les plugins sont du code de confiance",
|
||
trustedDescription:
|
||
"Ils s’exécutent sur cet hôte et dans l’app sans isolation. N’installez que du code fiable.",
|
||
globalTitle: "Activer les plugins",
|
||
globalHint: "Interrupteur global pour tous les plugins configurés",
|
||
directoryLabel: "Dossier du plugin",
|
||
idLabel: "ID d’installation du plugin",
|
||
idHint: "Laissez vide pour utiliser paseo-plugin.json",
|
||
idPlaceholder: "Valeur du manifeste",
|
||
install: "Installer le dossier",
|
||
installing: "Installation…",
|
||
status: { running: "actif", disabled: "désactivé", failed: "échec" },
|
||
actions: {
|
||
reload: "Recharger",
|
||
reloading: "Rechargement…",
|
||
enable: "Activer",
|
||
enabling: "Activation…",
|
||
disable: "Désactiver",
|
||
disabling: "Désactivation…",
|
||
remove: "Supprimer",
|
||
removing: "Suppression…",
|
||
},
|
||
feedback: {
|
||
installed: "{{id}} installé",
|
||
reload: "{{id}} rechargé",
|
||
enable: "{{id}} activé",
|
||
disable: "{{id}} désactivé",
|
||
remove: "{{id}} supprimé",
|
||
kept: "{{id}} conservé",
|
||
globalEnabled: "Plugins activés",
|
||
globalDisabled: "Plugins désactivés",
|
||
},
|
||
removeConfirmTitle: "Supprimer {{id}} ?",
|
||
removeConfirmMessage: "La configuration sera supprimée. Le dossier source ne sera pas effacé.",
|
||
states: {
|
||
offlineTitle: "L’hôte des plugins est hors ligne",
|
||
offlineDescription: "Reconnectez cet hôte pour gérer ses plugins.",
|
||
updateTitle: "Mettez cet hôte à jour pour gérer les plugins",
|
||
loading: "Chargement des plugins…",
|
||
errorTitle: "Impossible de charger les plugins",
|
||
retry: "Réessayer",
|
||
empty: "Aucun plugin configuré",
|
||
},
|
||
},
|
||
ja: {
|
||
...shared,
|
||
title: "プラグイン",
|
||
trustedTitle: "プラグインは信頼済みコードです",
|
||
trustedDescription:
|
||
"ホストとアプリ内で分離されずに実行されます。信頼できるコードのみインストールしてください。",
|
||
globalTitle: "プラグインを有効化",
|
||
globalHint: "設定済みプラグインすべての共通スイッチ",
|
||
directoryLabel: "プラグインディレクトリ",
|
||
idLabel: "プラグインのインストール ID",
|
||
idHint: "paseo-plugin.json を使う場合は空欄にします",
|
||
idPlaceholder: "マニフェストの既定値",
|
||
install: "ディレクトリをインストール",
|
||
installing: "インストール中…",
|
||
status: { running: "実行中", disabled: "無効", failed: "失敗" },
|
||
actions: {
|
||
reload: "再読み込み",
|
||
reloading: "再読み込み中…",
|
||
enable: "有効化",
|
||
enabling: "有効化中…",
|
||
disable: "無効化",
|
||
disabling: "無効化中…",
|
||
remove: "削除",
|
||
removing: "削除中…",
|
||
},
|
||
feedback: {
|
||
installed: "{{id}} をインストールしました",
|
||
reload: "{{id}} を再読み込みしました",
|
||
enable: "{{id}} を有効にしました",
|
||
disable: "{{id}} を無効にしました",
|
||
remove: "{{id}} を削除しました",
|
||
kept: "{{id}} を保持しました",
|
||
globalEnabled: "プラグインを有効にしました",
|
||
globalDisabled: "プラグインを無効にしました",
|
||
},
|
||
removeConfirmTitle: "{{id}} を削除しますか?",
|
||
removeConfirmMessage: "設定のみを削除します。ソースディレクトリは削除されません。",
|
||
states: {
|
||
offlineTitle: "プラグインホストはオフラインです",
|
||
offlineDescription: "プラグインを管理するにはホストに再接続してください。",
|
||
updateTitle: "プラグインを管理するにはホストを更新してください",
|
||
loading: "プラグインを読み込み中…",
|
||
errorTitle: "プラグインを読み込めません",
|
||
retry: "再試行",
|
||
empty: "設定済みプラグインはありません",
|
||
},
|
||
},
|
||
ko: {
|
||
...shared,
|
||
title: "플러그인",
|
||
trustedTitle: "플러그인은 신뢰하는 코드입니다",
|
||
trustedDescription: "호스트와 앱 안에서 격리 없이 실행됩니다. 신뢰하는 코드만 설치하세요.",
|
||
globalTitle: "플러그인 활성화",
|
||
globalHint: "설정된 모든 플러그인의 전역 스위치",
|
||
directoryLabel: "플러그인 디렉터리",
|
||
idLabel: "플러그인 설치 ID",
|
||
idHint: "paseo-plugin.json을 사용하려면 비워 두세요",
|
||
idPlaceholder: "매니페스트 기본값",
|
||
install: "디렉터리 설치",
|
||
installing: "설치 중…",
|
||
status: { running: "실행 중", disabled: "비활성화", failed: "실패" },
|
||
actions: {
|
||
reload: "다시 로드",
|
||
reloading: "다시 로드 중…",
|
||
enable: "활성화",
|
||
enabling: "활성화 중…",
|
||
disable: "비활성화",
|
||
disabling: "비활성화 중…",
|
||
remove: "제거",
|
||
removing: "제거 중…",
|
||
},
|
||
feedback: {
|
||
installed: "{{id}} 설치됨",
|
||
reload: "{{id}} 다시 로드됨",
|
||
enable: "{{id}} 활성화됨",
|
||
disable: "{{id}} 비활성화됨",
|
||
remove: "{{id}} 제거됨",
|
||
kept: "{{id}} 유지됨",
|
||
globalEnabled: "플러그인 활성화됨",
|
||
globalDisabled: "플러그인 비활성화됨",
|
||
},
|
||
removeConfirmTitle: "{{id}}을(를) 제거할까요?",
|
||
removeConfirmMessage: "설정만 제거합니다. 소스 디렉터리는 삭제되지 않습니다.",
|
||
states: {
|
||
offlineTitle: "플러그인 호스트가 오프라인입니다",
|
||
offlineDescription: "플러그인을 관리하려면 호스트에 다시 연결하세요.",
|
||
updateTitle: "플러그인을 관리하려면 호스트를 업데이트하세요",
|
||
loading: "플러그인 로드 중…",
|
||
errorTitle: "플러그인을 로드할 수 없습니다",
|
||
retry: "다시 시도",
|
||
empty: "설정된 플러그인이 없습니다",
|
||
},
|
||
},
|
||
"pt-BR": {
|
||
...shared,
|
||
title: "Plugins",
|
||
trustedTitle: "Plugins são código confiável",
|
||
trustedDescription:
|
||
"Eles rodam neste host e dentro do app sem isolamento. Instale apenas código confiável.",
|
||
globalTitle: "Ativar plugins",
|
||
globalHint: "Controle global para todos os plugins configurados",
|
||
directoryLabel: "Diretório do plugin",
|
||
idLabel: "ID de instalação do plugin",
|
||
idHint: "Deixe vazio para usar paseo-plugin.json",
|
||
idPlaceholder: "Padrão do manifesto",
|
||
install: "Instalar diretório",
|
||
installing: "Instalando…",
|
||
status: { running: "em execução", disabled: "desativado", failed: "falhou" },
|
||
actions: {
|
||
reload: "Recarregar",
|
||
reloading: "Recarregando…",
|
||
enable: "Ativar",
|
||
enabling: "Ativando…",
|
||
disable: "Desativar",
|
||
disabling: "Desativando…",
|
||
remove: "Remover",
|
||
removing: "Removendo…",
|
||
},
|
||
feedback: {
|
||
installed: "{{id}} instalado",
|
||
reload: "{{id}} recarregado",
|
||
enable: "{{id}} ativado",
|
||
disable: "{{id}} desativado",
|
||
remove: "{{id}} removido",
|
||
kept: "{{id}} mantido",
|
||
globalEnabled: "Plugins ativados",
|
||
globalDisabled: "Plugins desativados",
|
||
},
|
||
removeConfirmTitle: "Remover {{id}}?",
|
||
removeConfirmMessage: "Isso remove a configuração. O diretório de origem não será excluído.",
|
||
states: {
|
||
offlineTitle: "O host de plugins está offline",
|
||
offlineDescription: "Reconecte este host para gerenciar seus plugins.",
|
||
updateTitle: "Atualize este host para gerenciar plugins",
|
||
loading: "Carregando plugins…",
|
||
errorTitle: "Não foi possível carregar os plugins",
|
||
retry: "Tentar novamente",
|
||
empty: "Nenhum plugin configurado",
|
||
},
|
||
},
|
||
ru: {
|
||
...shared,
|
||
title: "Плагины",
|
||
trustedTitle: "Плагины — доверенный код",
|
||
trustedDescription:
|
||
"Они выполняются на хосте и в приложении без изоляции. Устанавливайте только доверенный код.",
|
||
globalTitle: "Включить плагины",
|
||
globalHint: "Общий переключатель для всех настроенных плагинов",
|
||
directoryLabel: "Каталог плагина",
|
||
idLabel: "ID установки плагина",
|
||
idHint: "Оставьте пустым, чтобы использовать paseo-plugin.json",
|
||
idPlaceholder: "Значение из манифеста",
|
||
install: "Установить каталог",
|
||
installing: "Установка…",
|
||
status: { running: "работает", disabled: "отключён", failed: "ошибка" },
|
||
actions: {
|
||
reload: "Перезагрузить",
|
||
reloading: "Перезагрузка…",
|
||
enable: "Включить",
|
||
enabling: "Включение…",
|
||
disable: "Отключить",
|
||
disabling: "Отключение…",
|
||
remove: "Удалить",
|
||
removing: "Удаление…",
|
||
},
|
||
feedback: {
|
||
installed: "{{id}} установлен",
|
||
reload: "{{id}} перезагружен",
|
||
enable: "{{id}} включён",
|
||
disable: "{{id}} отключён",
|
||
remove: "{{id}} удалён",
|
||
kept: "{{id}} сохранён",
|
||
globalEnabled: "Плагины включены",
|
||
globalDisabled: "Плагины отключены",
|
||
},
|
||
removeConfirmTitle: "Удалить {{id}}?",
|
||
removeConfirmMessage: "Конфигурация будет удалена. Исходный каталог останется на месте.",
|
||
states: {
|
||
offlineTitle: "Хост плагинов не в сети",
|
||
offlineDescription: "Подключите хост снова, чтобы управлять плагинами.",
|
||
updateTitle: "Обновите хост для управления плагинами",
|
||
loading: "Загрузка плагинов…",
|
||
errorTitle: "Не удалось загрузить плагины",
|
||
retry: "Повторить",
|
||
empty: "Нет настроенных плагинов",
|
||
},
|
||
},
|
||
"zh-CN": {
|
||
...shared,
|
||
title: "插件",
|
||
trustedTitle: "插件是受信任的代码",
|
||
trustedDescription: "它们会在此主机和应用内运行,且没有隔离。请仅安装你信任的代码。",
|
||
globalTitle: "启用插件",
|
||
globalHint: "所有已配置插件的全局开关",
|
||
directoryLabel: "插件目录",
|
||
idLabel: "插件安装 ID",
|
||
idHint: "留空以使用 paseo-plugin.json",
|
||
idPlaceholder: "清单默认值",
|
||
install: "安装目录",
|
||
installing: "正在安装…",
|
||
status: { running: "运行中", disabled: "已禁用", failed: "失败" },
|
||
actions: {
|
||
reload: "重新加载",
|
||
reloading: "正在重新加载…",
|
||
enable: "启用",
|
||
enabling: "正在启用…",
|
||
disable: "禁用",
|
||
disabling: "正在禁用…",
|
||
remove: "移除",
|
||
removing: "正在移除…",
|
||
},
|
||
feedback: {
|
||
installed: "已安装 {{id}}",
|
||
reload: "已重新加载 {{id}}",
|
||
enable: "已启用 {{id}}",
|
||
disable: "已禁用 {{id}}",
|
||
remove: "已移除 {{id}}",
|
||
kept: "已保留 {{id}}",
|
||
globalEnabled: "插件已启用",
|
||
globalDisabled: "插件已禁用",
|
||
},
|
||
removeConfirmTitle: "移除 {{id}}?",
|
||
removeConfirmMessage: "这会移除配置,但不会删除源目录。",
|
||
states: {
|
||
offlineTitle: "插件主机离线",
|
||
offlineDescription: "重新连接此主机以管理其插件。",
|
||
updateTitle: "更新此主机以管理插件",
|
||
loading: "正在加载插件…",
|
||
errorTitle: "无法加载插件",
|
||
retry: "重试",
|
||
empty: "没有已配置的插件",
|
||
},
|
||
},
|
||
} as const;
|