Skip to content

feat: companion package recommendations via NuGet tags #36

@kirkone

Description

@kirkone

Summary

Show users friendly recommendations for related packages when browsing or installing plugins/themes. No hard dependencies — purely advisory hints.

Problem

When a user installs the Statistics plugin, they get EXIF analysis data — but nothing tells them they need a theme extension (like Lumina.Statistics) to actually display that data. Conversely, installing Lumina.Statistics without the Statistics plugin gives empty templates.

Currently there are zero cross-references between related packages.

Design Decision: No Hard Dependencies

All package relationships in Revela are recommendations, not requirements:

Relationship Example Why not hard?
Theme Extension → Base Theme Lumina.Statistics → Lumina User can extract to local and use with custom theme
Plugin → Theme Extension Statistics → Lumina.Statistics Data exists, just invisible without templates
Theme Extension → Plugin Lumina.Statistics → Statistics Template renders, just shows empty data

There is no scenario where a missing companion makes the system crash or corrupt data. Everything degrades gracefully.

Implementation: companion: Tag Convention

In .csproj (packed into nuspec)

<!-- Statistics Plugin -->
<PackageType>RevelaPlugin</PackageType>
<PackageTags>revela;plugin;statistics;exif;companion:Spectara.Revela.Themes.Lumina.Statistics</PackageTags>

<!-- Lumina.Statistics Theme Extension -->
<PackageType>RevelaTheme</PackageType>
<PackageTags>revela;theme;lumina;statistics;companion:Spectara.Revela.Plugins.Statistics</PackageTags>

Why Tags?

  • ✅ Available from NuGet Search API (no download needed)
  • ✅ Available from local .nuspec (already parsed)
  • ✅ No conflict with existing PackageType mechanism
  • ✅ Standard NuGet field — no custom extensions
  • ✅ Works with any NuGet feed (nuget.org, private, local)

Parsing

Tags with companion: prefix are extracted during revela packages refresh and stored in packages.json:

{
  "id": "Spectara.Revela.Plugins.Statistics",
  "version": "1.0.0",
  "description": "EXIF statistics for galleries",
  "types": ["RevelaPlugin"],
  "companions": ["Spectara.Revela.Themes.Lumina.Statistics"]
}

UX: Two Touch Points

1. Discovery (brief, one line)

revela plugin list --online

  Statistics        EXIF analysis for your galleries
                    🔗 Theme: Lumina.Statistics

  Compress          Gzip/Brotli pre-compression
  Serve             Local development server

2. After Install (actionable)

revela plugin install Statistics

✓ Statistics installed (1.0.0)

ℹ To display statistics on your site, your theme needs
  statistics templates. Options:
  • revela plugin install Lumina.Statistics
  • Or add statistics/ templates to your custom theme

Migration: RequiredPackages / ExtendsPackages

The existing PackageMetadata.RequiredPackages and ExtendsPackages fields are unused — no plugin or theme declares them. Options:

  1. Keep as-is — Leave fields for future hard-dependency scenarios (unlikely)
  2. Replace with CompanionPackages — Single field, advisory only
  3. Remove — Simplify metadata, companions come from tags only

Recommendation: Option 2 — Replace both with a single CompanionPackages list populated from NuGet tags at index time. The plugin validation logic in ValidatePluginDependencies() can be simplified to only warn about missing companions.

Implementation Steps

  1. Add companion: tags to all plugin/theme .csproj files
  2. Parse companion: tags in RefreshCommand and PackageSearchService
  3. Add Companions field to PackageIndexEntry
  4. Show companion hints in plugin list --online / theme list --online
  5. Show companion hints after plugin install / theme install
  6. Decide on RequiredPackages/ExtendsPackages migration (can be separate PR)

Context

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions