feat(cabana): plugin updates and marketplace search on the Plugins screen

- GET /plugins looks up each versioned plugin's releases through
  kiosk.Client and applies plugin:update's rule (NewestCompatible above
  the BaseVersion), with the update command and the framework a newer
  release needs
- GET /plugins/marketplace forwards q and category (validated like the
  registry), marks installed and incompatible plugins and returns the
  install command; ids outside the plugin ID shape are dropped
- 4 s per-call timeout, at most 4 lookups at once, in-process cache
  (searches 5 min, releases 15 min, failures 1 min); a failing registry
  gives status unavailable, an empty plugins.registry_url sends nothing
- SPA: update badges and Marketplace tab with copy buttons (clipboard
  fallback), hidden when the registry is disabled; no install button
- OpenAPI, SPA types, inventories, conformance case, en/pl strings, docs
This commit is contained in:
Jakub Zych
2026-10-29 19:20:14 +01:00
parent c4b1ac4076
commit 7e8a19399d
18 changed files with 1624 additions and 79 deletions

View File

@@ -648,6 +648,12 @@
"backend::lang.permissions.view_plugins": {
"other": "Podgląd wtyczek"
},
"backend::lang.plugins.category_all": {
"other": "Wszystkie kategorie"
},
"backend::lang.plugins.category_label": {
"other": "Kategoria"
},
"backend::lang.plugins.column_plugin": {
"other": "Wtyczka"
},
@@ -657,24 +663,66 @@
"backend::lang.plugins.column_version": {
"other": "Wersja"
},
"backend::lang.plugins.command_label": {
"other": "Polecenie"
},
"backend::lang.plugins.copied": {
"other": "Skopiowano"
},
"backend::lang.plugins.copied_announce": {
"other": "Skopiowano polecenie do schowka."
},
"backend::lang.plugins.copy": {
"other": "Kopiuj"
},
"backend::lang.plugins.copy_failed": {
"other": "Nie udało się skopiować. Polecenie jest zaznaczone; skopiuj je skrótem Ctrl+C."
},
"backend::lang.plugins.empty": {
"other": "Brak zainstalowanych wtyczek."
},
"backend::lang.plugins.featured": {
"other": "Wyróżniona"
},
"backend::lang.plugins.framework": {
"other": "Framework :version"
},
"backend::lang.plugins.install_hint": {
"other": "Wtyczki instaluje się i aktualizuje z wiersza poleceń: uruchom polecenie w katalogu aplikacji, potem summer build, i wdróż nowy plik binarny."
},
"backend::lang.plugins.load_failed": {
"other": "Nie udało się wczytać listy wtyczek."
},
"backend::lang.plugins.marker_installed": {
"other": "Zainstalowana"
},
"backend::lang.plugins.marker_needs_framework": {
"other": "Wymaga frameworka :version"
},
"backend::lang.plugins.marketplace_empty": {
"other": "Brak pasujących wtyczek."
},
"backend::lang.plugins.menu_description": {
"other": "Zainstalowane wtyczki, ich wersje i dostępne aktualizacje oraz katalog wtyczek."
},
"backend::lang.plugins.menu_label": {
"other": "Wtyczki"
},
"backend::lang.plugins.needs_framework": {
"other": "Nowsze wydanie wymaga frameworka :version."
},
"backend::lang.plugins.no_version": {
"other": "Brak wersji"
},
"backend::lang.plugins.registry_unavailable": {
"other": "Katalog wtyczek nie odpowiada, więc informacje o aktualizacjach i katalog są chwilowo niedostępne."
},
"backend::lang.plugins.search_label": {
"other": "Szukaj wtyczek"
},
"backend::lang.plugins.search_placeholder": {
"other": "Szukaj po nazwie lub opisie"
},
"backend::lang.plugins.source_local": {
"other": "W aplikacji"
},
@@ -696,6 +744,9 @@
"backend::lang.plugins.title": {
"other": "Wtyczki"
},
"backend::lang.plugins.update_available": {
"other": "Dostępna aktualizacja do :version"
},
"backend::lang.relation.add": {
"other": "Dodaj"
},