Sunder.Sdk
0.8.7
dotnet add package Sunder.Sdk --version 0.8.7
NuGet\Install-Package Sunder.Sdk -Version 0.8.7
<PackageReference Include="Sunder.Sdk" Version="0.8.7" />
<PackageVersion Include="Sunder.Sdk" Version="0.8.7" />
<PackageReference Include="Sunder.Sdk" />
paket add Sunder.Sdk --version 0.8.7
#r "nuget: Sunder.Sdk, 0.8.7"
#:package Sunder.Sdk@0.8.7
#addin nuget:?package=Sunder.Sdk&version=0.8.7
#tool nuget:?package=Sunder.Sdk&version=0.8.7
Sunder.Sdk
Sunder.Sdk contains the public contracts used to build Sunder runtime packages.
Use this package when you want to create a package that can be loaded by the Sunder runtime, contribute Avalonia views to the Sunder shell, register background services, queue background processes, expose typed extension points, or consume package-scoped storage, configuration, secrets, logging, and theme resources.
SDK/Host compatibility is capability-based. Sunder.Package.Build infers SDK requirements automatically; see docs/SUNDER-SDK-COMPATIBILITY.md in the Sunder Core repository for the full policy.
Install
dotnet add package Sunder.Sdk
Most runtime packages should also reference Sunder.Package.Build so builds generate the Sunder manifest, development output, and distributable archive:
dotnet add package Sunder.Package.Build --private-assets all
For a new package project, the quickest path is the template package:
dotnet new install Sunder.Package.Templates
dotnet new sunder-package --name MyPackage --packageId my.company.package --packageName "My Package"
Package Shape
A Sunder runtime package is a .NET assembly that declares package metadata and exposes exactly one public module implementing ISunderPackageModule.
Typical package projects:
- Target
net10.0. - Reference
Sunder.Sdk. - Reference
Sunder.Package.BuildwithPrivateAssets="all". - Reference Avalonia packages when they provide UI.
- Do not reference
Sunder.ApporSunder.Runtime.Host.
Package Metadata
Package identity and runtime dependencies are declared with assembly attributes from Sunder.Sdk.Packaging.
using Sunder.Sdk.Packaging;
[assembly: SunderPackage(
Id = "my.company.package",
Name = "My Package",
Summary = "Adds a custom Sunder workspace.",
Icon = "assets/icon.png")]
Extension packages can declare runtime package dependencies:
using Sunder.Sdk.Packaging;
[assembly: SunderPackage(
Id = "my.company.extension",
Name = "My Extension",
Summary = "Extends another Sunder package.",
Icon = "assets/icon.png")]
[assembly: SunderPackageDependency(
PackageId = "sunder.package.host",
VersionRange = ">=1.0.0 <2.0.0")]
Package id rules:
- Use lowercase dot-separated ASCII identifiers such as
my.company.package. - Do not use spaces, underscores, or display-name casing.
- Do not rename a package id after publishing.
- Keep
Nameshort and user-facing. - Use
Summaryfor one sentence of package description.
The package version comes from normal MSBuild properties such as Version, not from the metadata attributes.
Package Module
Every runtime package exposes one public, non-abstract module with a public parameterless constructor.
using Microsoft.Extensions.DependencyInjection;
using Sunder.Sdk.Abstractions;
namespace MyCompany.Package;
public sealed class PackageModule : ISunderPackageModule
{
public void ConfigureServices(IServiceCollection services, IPackageContext context)
{
services.AddTransient<MyViewModel>();
}
public void RegisterContributions(IPackageContributionRegistry registry, IServiceProvider services)
{
registry.RegisterPackageView<MyView>(new PackageViewRegistration(
id: "my.company.package.default",
name: "My Package",
icon: "assets/icon.png",
defaultPlacement: PackageViewPlacement.Middle));
}
}
Use ConfigureServices for dependency injection setup. Use RegisterContributions for shell-visible and runtime-visible package contributions.
Contributions
IPackageContributionRegistry currently supports:
RegisterPackageView<TView>(PackageViewRegistration registration)RegisterPackageViewFactory<TFactory>(PackageViewRegistration registration)RegisterSettingsView<TView>()RegisterSettingsViewFactory<TFactory>()RegisterBackgroundService<TService>()RegisterExtension<TContract>(PackageExtensionPoint<TContract> extensionPoint, TContract contribution)RegisterConfigurationSchema(PackageConfigurationSchema schema)
Package views are Avalonia controls registered by code. Use stable view ids scoped under your package id.
registry.RegisterPackageView<MyView>(new PackageViewRegistration(
"my.company.package.main",
"My Package",
icon: "assets/icon.png"));
Package Context
IPackageContext gives your module access to host-provided package services:
PackageIdVersionInstallPathStorageConfigurationSecretsLoggerFactoryLogging
Host-provided services can also be injected into package services and views, including IBackgroundProcessQueue for long-running package work, IPackageNotificationService for user-visible notifications, IPackageShellViewService for hotbar and panel navigation, IPackageSettingsNavigationService for opening settings, and IPackageSessionService for loading/unloading package sessions. Some hosts provide null or disabled implementations for app-only services; check boolean/null results and documented exceptions.
Use package storage, configuration, and secrets abstractions for mutable package data. Do not write mutable state into the installed package folder.
Settings And Package Sessions
Use IPackageSettingsNavigationService when a package needs to open global Sunder settings or another package's settings page:
var opened = await settingsNavigation.OpenPackageSettingsAsync(
"my.company.package",
cancellationToken: cancellationToken);
Use IPackageSessionService when app-hosted package code needs to load, unload, or query installed/dev package sessions:
var status = await packageSessions.LoadPackageAsync(new PackageSessionLoadRequest(
PackageSessionSourceKind.Dev,
@"C:\Path\To\MyPackage\bin\Debug\net10.0\sunder-dev",
Watch: true),
cancellationToken);
These services are app-shell integrations. Runtime-only activation supplies null implementations.
Background Processes
Use IBackgroundProcessQueue for package work that should keep running outside the current button click or view lifecycle, such as downloads, imports, model pulls, or indexing.
queue.Enqueue(new BackgroundProcessRequest(
Title: "Import dataset",
GroupKey: "my.company.package:imports",
Indicator: BackgroundProcessIndicator.Settings,
ConcurrencyMode: BackgroundProcessConcurrencyMode.SequentialWithinGroup,
CanCancel: true,
ExecuteAsync: async context =>
{
context.ReportIndeterminate("Importing dataset...");
await ImportAsync(context.CancellationToken);
context.ReportProgress(100, "Import complete");
},
Metadata: new Dictionary<string, string>
{
["dataset"] = "customers",
}));
BackgroundProcessIndicator.Hidden keeps the process out of all footer indicators. Main, Packages, and Settings show it in exactly one host indicator surface. GroupKey is for concurrency and package-side listing; it is not used for UI placement.
Extension Catalog
Packages can query installed/active contributions through IPackageExtensionCatalog:
var providers = extensionCatalog.GetExtensions(MyExtensionPoints.Providers);
When a package needs to update open UI or cached capability lists as other packages activate/deactivate, inject IPackageExtensionCatalog and cast to IPackageExtensionCatalogMonitor. Changed provides a revision, lifecycle reason, and extension-point changes including package id and contribution type.
Use the change details to refresh only affected state, for example execution-target UI when sunder.package.agent:execution-targets changes.
Callback Sessions
IPackageCallbackHandler is the generic host callback contract for browser or local callback flows. IPackageAuthHandler remains the auth-specific status/disconnect surface.
Register callback handlers in ConfigureServices. Auth-capable packages can register the same implementation as both IPackageAuthHandler and IPackageCallbackHandler.
Theme Resources
Package UI can use semantic Sunder theme keys from Sunder.Sdk.Theming.SunderThemeKeys. These keys let package UI match the active Sunder shell theme without referencing app internals.
Common resource keys include:
Sunder.Brush.Background.AppSunder.Brush.Surface.BaseSunder.Brush.Surface.RaisedSunder.Brush.Surface.WorkspaceSunder.Brush.Foreground.PrimarySunder.Brush.Foreground.SecondarySunder.Brush.AccentSunder.Radius.MediumSunder.Spacing.MediumSunder.FontSize.Body
Example Avalonia usage:
<Border Background="{DynamicResource Sunder.Brush.Surface.Workspace}"
CornerRadius="{DynamicResource Sunder.Radius.Medium}"
Padding="{DynamicResource Sunder.Spacing.Medium}">
<TextBlock Text="Hello from my package"
Foreground="{DynamicResource Sunder.Brush.Foreground.Primary}" />
</Border>
Runtime Dependencies And Contracts
Runtime package dependencies and NuGet contracts dependencies are separate concepts.
Use [assembly: SunderPackageDependency(...)] when your installed package requires another installed Sunder package at runtime.
Use a normal NuGet package reference when you need compile-time contracts from another package, such as a *.Contracts package that declares extension points or contribution interfaces.
Build And Publish
With Sunder.Package.Build referenced, package builds generate an unpacked development package:
dotnet build .\MyPackage\MyPackage.csproj
The generated sunder-dev folder can be loaded into Sunder App for local development:
& "C:\Path\To\Sunder.App.exe" --dev-package ".\MyPackage\bin\Debug\net10.0\sunder-dev"
Publishing produces a distributable .sunderpkg archive:
dotnet publish .\MyPackage\MyPackage.csproj -c Release
Validate before publishing to a registry:
sunder package validate .\MyPackage\bin\Release\net10.0\publish\MyPackage.1.0.0.sunderpkg
More Documentation
- Package author manual: https://github.com/Younics/sunder-core/blob/main/docs/SUNDER-PACKAGE-DEVELOPMENT.md
- Package standard: https://github.com/Younics/sunder-core/blob/main/docs/SUNDER-PACKAGE-STANDARD.md
- Sunder overview: https://github.com/Younics/sunder-core/blob/main/docs/SUNDER.md
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Avalonia (>= 12.0.3)
- Microsoft.Extensions.DependencyInjection (>= 10.0.8)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.8)
- Microsoft.Extensions.Logging (>= 10.0.8)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.8)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.