* feat(plugins): group Apps sidebar by plugin manifest category
Implements the plugin SDK's documented PluginManifest.category semantics
(silo-plugin-sdk proto/silo/plugin/v1/common.proto): a slash-delimited
path that groups plugins in the user-facing Apps section, e.g.
"Books/Audiobooks" lands under Apps -> Books. The field existed in the
manifest proto but silo-server never surfaced it.
Server: the user plugin-settings list/detail responses now include an
additive-only `category,omitempty` string sourced from the already-loaded
manifest via GetCategory(); no new parsing paths.
Web: PluginSettingsSummary gains `category?: string`, and AppSidebar
groups Apps entries by the FIRST segment of the category path (one level
of grouping for now; deeper segments intentionally ignored, documented
against the SDK contract). When fewer than 2 distinct categories exist
among the visible app links, today's flat list under the single "Apps"
header is kept; with 2+ categories, per-category sub-headers render via
the existing SidebarSectionHeader (labels hide in the collapsed sidebar
the same way other section headers do). Uncategorized plugins fall under
"Other", which always sorts last.
Tests: Go unit tests for the summary converter (category passthrough and
JSON omission when empty) and vitest coverage for the pure
groupAppNavLinks helper plus grouped/flat/collapsed sidebar rendering.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* docs(plugins): use generic category examples in comments and tests
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* refactor(web): simplify Apps sidebar link list rendering
- fold the duplicated <ul> list markup in the grouped and flat Apps
branches into a single renderAppNavList helper so the list styling
cannot drift between the two render paths
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: rxwatcher <rxwatcher@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Quick104 <31828688+Quick104@users.noreply.github.com>