# Pakete und ihre Fassungen

Fassung und Änderungen der Pakete für Entwickler — API-Client, Apps-SDK, CLI und Verträge, das Neueste zuerst.

> **Typ:** nachschlagen
> **Für wen:** Entwicklerinnen und Entwickler, die mit einem dieser Pakete arbeiten und wissen wollen, was sich in einer Fassung geändert hat.
> **Voraussetzung:** keine.

Die Liste entsteht mit jeder neuen Fassung aus den Änderungsnotizen der Plattform und zeigt deren Abschnitt für Entwickler. Einen öffentlichen Bezugsweg für die Pakete gibt es heute nicht; die Seite sagt, welche Fassung gilt und was sich darin geändert hat.

| Paket | Fassung |
|---|---|
| `@szenera/cli` | `0.4.0` |
| `@szenera/client` | `0.6.0` |

## @szenera/cli

### 0.4.0 · 2026-10-25

**Breaking changes**

- Der gespeicherte Anmeldestand trägt die Felder `token` und `expiresAt`. Umstieg: Ein alter Anmeldestand gilt als nicht angemeldet, die nächste Anmeldung schreibt den neuen. ([#821](https://github.com/HKNovaTechUG/digital-signage-2026/pull/821))

**Added**

- Neue Befehle `szenera proof list`, `szenera proof show` und `szenera proof download`. ([#822](https://github.com/HKNovaTechUG/digital-signage-2026/pull/822))
- Neue Befehle `szenera analytics overview`, `szenera analytics explore` und `szenera analytics delivery <acp_…>`. ([#822](https://github.com/HKNovaTechUG/digital-signage-2026/pull/822))
- Neue Befehle `advertiser list`, `advertiser get`, `advertiser create`, `campaign list`, `campaign get`, `booking list`, `creative list` und `creative approve`. ([#822](https://github.com/HKNovaTechUG/digital-signage-2026/pull/822))

**Changed**

- Das Archiv folgt dem Klienten mit den Erlösaufstellungen, ohne neuen Befehl. ([#822](https://github.com/HKNovaTechUG/digital-signage-2026/pull/822))
- Das Archiv folgt dem Klienten ohne die Lesewege der Minutenzählung und der Insights. Die Befehle bleiben. ([#822](https://github.com/HKNovaTechUG/digital-signage-2026/pull/822))
- Das Archiv folgt dem Klienten mit den Panelquellen `cec`, `ddc` und `none`. Die Befehle bleiben. ([#822](https://github.com/HKNovaTechUG/digital-signage-2026/pull/822))
- Die Kommandozeile bringt den Client mit, der einen eigenen Anmelde-Wirt kennt. Ohne Einstellung ändert sich nichts. ([#825](https://github.com/HKNovaTechUG/digital-signage-2026/pull/825))
- Das Archiv folgt dem Klienten mit `campaignId` je Nachweis des Kampagnenberichts. Die Befehle bleiben. ([#822](https://github.com/HKNovaTechUG/digital-signage-2026/pull/822))
- Das Archiv bündelt den aktuellen Stand der Verträge, die Befehle von `szenera` bleiben gleich. ([#847](https://github.com/HKNovaTechUG/digital-signage-2026/pull/847))
- `szenera playlist get` zeigt einen Werbeblock als „Werbeblock · 3 Plätze à 10 s“ mit seiner Dauer. ([#822](https://github.com/HKNovaTechUG/digital-signage-2026/pull/822))

### 0.3.0 · 2026-10-23

**Breaking changes**

- Die JSON-Ausgabe der Kommandozeile nennt dieselben Namen wie die API. Umstieg: Skripte, die die JSON-Ausgabe lesen, auf die englischen Feldnamen umstellen. ([#761](https://github.com/HKNovaTechUG/digital-signage-2026/pull/761))
- `szenera api-key revoke <akm_…> --compromised` nennt den Grund des Widerrufs. `szenera api-key list` mit einem Schlüssel-Profil antwortet 401. Umstieg: Für `szenera api-key list` ein Profil mit Sitzung verwenden. ([#762](https://github.com/HKNovaTechUG/digital-signage-2026/pull/762))

**Added**

- Die Typen folgen der API: Feed-Katalog, Quellen für den Betrieb und der Fehlercode `FeedSource.NotFound`. ([#801](https://github.com/HKNovaTechUG/digital-signage-2026/pull/801))
- Neue Aufrufe: Zusammenfassung, Sammelaktion und Wiederherstellen von Benachrichtigungen, dazu `state` und `groupKey` an der Liste. ([#795](https://github.com/HKNovaTechUG/digital-signage-2026/pull/795))
- `playerId` an der Vorschau der Widget-Daten und der Lesebereich `player-location`. ([#801](https://github.com/HKNovaTechUG/digital-signage-2026/pull/801))
- Standorte: `region` und `openingHours`, dazu das Ereignis `fleet.location.opening-hours-changed`. ([#801](https://github.com/HKNovaTechUG/digital-signage-2026/pull/801))
- Widget-Definitionen des Katalogs kennen `size` und `preview.states`, Ansichten des Stores kennen `size`. ([#801](https://github.com/HKNovaTechUG/digital-signage-2026/pull/801))

### 0.2.3

**Änderungen**

- `GET /v1/audit/bulk/:correlationId` entfällt und mit ihm `client.audit.auditBulk` und das Schema `GetBulkActionDetailResponse`. ([#742](https://github.com/HKNovaTechUG/digital-signage-2026/pull/742))
- Das Recht `audit.bulk.read`, die Ereignisart `audit.bulk-action.completed` und der Fehlercode `Internal.AuditBulkActionDetailRepositoryUnavailable` entfallen. ([#742](https://github.com/HKNovaTechUG/digital-signage-2026/pull/742))

### 0.2.2

**Änderungen**

- `@szenera/contracts`: neu `CatalogAppSchema`, `AppReleaseNotesSchema` (Notizen je Zielgruppe und Sprache), `AppReleaseEventSchema`, `RestoreAppRelease*`, `ListAppReleaseHistory*` und `GetAppVersionHistory*`. Ein `AppRelease` trägt `notes`, die Wire-Form daneben weiter `releaseNotes`. `PATCH /v1/platform/app-catalog/apps/{appId}/releases/{id}` nimmt `notes` je Zielgruppe oder wie bisher `releaseNotes`. ([#677](https://github.com/HKNovaTechUG/digital-signage-2026/pull/677))
- Ein Grant trägt `installedReleaseId`, `pendingReleaseId`, `pendingReasons` und `pendingDeadline`, ein Zustimmungs-Nachweis `releaseId`, eine offene Zustimmung `fromVersion`, `toVersion`, `reasons` und `deadline`. Entfallen sind `autoUpgrade` am Grant und `ConfigSchemaChangedPayloadSchema`. ([#677](https://github.com/HKNovaTechUG/digital-signage-2026/pull/677))
- `GET /v1/apps/{appId}/history` liefert einer Organisation die Fassungen einer App, die stable erreicht haben, mit Datum und „Neu in dieser Fassung" in der erbetenen Sprache (`?locale=en-US`, ohne Angabe Deutsch). ([#677](https://github.com/HKNovaTechUG/digital-signage-2026/pull/677))
- `@szenera/api-client`: neu `client.platform.appCatalogAppsHistory.list`, `client.platform.appCatalogAppsReleases.restore` und `client.appCatalog.appsHistory.list`. `@szenera/client`: neu `client.appCatalog.appsHistory.list`. `@szenera/cli` bündelt die neuen Verträge, ihre Befehle bleiben, wie sie sind. ([#677](https://github.com/HKNovaTechUG/digital-signage-2026/pull/677))
- Das scenes-Bündel der Momentaufnahme trägt `appVersions` (je App die eine Fassung des Displays) sowie `appRendererHosts` und `appWidgetTypes` je `<appId>@<version>`, alle mit der Vorgabe `{}`. Die Pins der Szenen und Widgets nennen dieselbe Fassung. ([#683](https://github.com/HKNovaTechUG/digital-signage-2026/pull/683))
- `displayAppVersion(pins, installed)` in `@szenera/contracts/composition` rechnet die Fassung eines Displays: die installierte, bei gehaltenen Pins älterer Hauptnummern die niedrigste davon. ([#683](https://github.com/HKNovaTechUG/digital-signage-2026/pull/683))
- Die neue Befundart `AppVersionHeld` ist immer eine Warnung und trägt `appId`, `appName`, `version`, `installedVersion` und `widgetIds`. Die KI-Anbindung erklärt sie. ([#683](https://github.com/HKNovaTechUG/digital-signage-2026/pull/683))
- `@szenera/client`: Der Filter `type` der Integritäts-Befunde einer Szene kennt `AppVersionHeld`. `@szenera/cli` bündelt den erweiterten Vertrag, ihre Befehle bleiben, wie sie sind. ([#683](https://github.com/HKNovaTechUG/digital-signage-2026/pull/683))
- Ein Zustimmungs-Nachweis trägt `version`, die Nummer der Fassung, der zugestimmt wurde (`null` nur bei Nachweisen von davor, deren Fassung schon fehlte). Eine Installation trägt `declinedAt` neben `declinedVersion`. ([#681](https://github.com/HKNovaTechUG/digital-signage-2026/pull/681))
- `GET /v1/apps/{appId}/history` nennt je Fassung `releaseId`, dieselbe Kennung wie an Installation, Nachweis und Update-Entscheidung. ([#681](https://github.com/HKNovaTechUG/digital-signage-2026/pull/681))
- `@szenera/client`: `client.appCatalog.appsHistory.list` nennt je Fassung `releaseId`, eine Installation trägt `declinedAt`. `@szenera/cli` bündelt die erweiterten Verträge, ihre Befehle bleiben, wie sie sind. ([#681](https://github.com/HKNovaTechUG/digital-signage-2026/pull/681))
- `@szenera/widget-editor`: `EditorShell` nimmt `appsAwaitingUpdate` (Apps samt Weg zur Entscheidung). Der App-Bereich zeigt ihre Widgets mit „Update wartet“, ein Klick führt zur Entscheidung statt einzufügen. ([#681](https://github.com/HKNovaTechUG/digital-signage-2026/pull/681))
- Neue Routen der Organisation: `GET /v1/me/apps/updates` und `GET /v1/me/apps/{appId}/update` liefern die Entscheidung über ein Update (Fassung von und nach, Gründe, Neues, Änderungen in Klartext, Folgen, Frist, ob Ablehnen noch geht), `POST /v1/me/apps/{appId}/update/accept` und `…/update/reject` entscheiden mit dem Hash der Ziel-Fassung. ([#680](https://github.com/HKNovaTechUG/digital-signage-2026/pull/680))
- Kanäle mit Publikum: `GET|PUT /v1/me/apps/beta-enrollment` und `POST|DELETE /v1/me/apps/{appId}/beta-enrollment` tragen eine Organisation für Fassungen aus beta ein, global oder je App. Store, App-Seite, Installation und Upgrade nehmen die höchste Fassung, die die Organisation sieht, die Liste trägt dazu `channel`. ([#680](https://github.com/HKNovaTechUG/digital-signage-2026/pull/680))
- Schwimmende Pins: `effectiveAppVersion(pin, installed)` in `@szenera/contracts/composition`. Die Momentaufnahme nennt die gespielte Fassung. `GET /v1/me/apps/{appId}/scene-pins` und `POST …/scene-pins/lift` heben alle Szenen auf die installierte Fassung, je Szene als neue veröffentlichte Fassung. ([#680](https://github.com/HKNovaTechUG/digital-signage-2026/pull/680))
- `POST /v1/marketplace/apps/{appId}/upgrade` geht nur vorwärts und nur auf Fassungen, die die Organisation sieht. Neuer Fehlercode `App.UpdateUnavailable` (409, `details.reason`: `not-forward`, `none`, `not-rejectable`). ([#680](https://github.com/HKNovaTechUG/digital-signage-2026/pull/680))
- Entfallen sind `GET /v1/me/pending-reacceptances`, `POST /v1/marketplace/apps/{appId}/accept` und `…/reject` samt ihren Verträgen. `RetireAppReleaseRequest` nimmt `grace` und `securityAdvisory` statt `graceMonths`. ([#680](https://github.com/HKNovaTechUG/digital-signage-2026/pull/680))
- Neue Ereignisse `marketplace.app.update-declined`, `marketplace.app.update-withdrawn` und `marketplace.app.release-switched`. `app-catalog.app-release.retired` und `…grace-expired` tragen `successorVersion`. Ein Grant trägt `declinedReleaseId` und `declinedVersion`, ein Nachweis `reasons`, eine Fassung `securityAdvisory`. ([#680](https://github.com/HKNovaTechUG/digital-signage-2026/pull/680))
- `@szenera/client` und `@szenera/api-client`: neu `me.appsUpdates.list`, `me.appsUpdate.list/accept/reject`, `me.appsBetaEnrollment.*` und `me.appsScenePins.list/lift`, entfallen `me.pendingReacceptances` und `marketplace.marketplaceApps.accept/reject`. `szenera app accept` und `app reject` nutzen die neuen Routen, ihre Aufrufe bleiben gleich. ([#680](https://github.com/HKNovaTechUG/digital-signage-2026/pull/680))
- `@szenera/client` und `@szenera/cli` bündeln die erweiterten Verträge der Plattform. Ihre Aufrufe und Befehle bleiben, wie sie sind. ([#697](https://github.com/HKNovaTechUG/digital-signage-2026/pull/697))
- `@szenera/contracts` baut je Quelldatei ein Modul (`dist/<domain>/<pfad>.js`), und die `exports`-Karte trägt das Muster `./*`: Jedes Blatt ist ladbar (`@szenera/contracts/app-catalog/app-manifest/locked-app`). Die benannten Subpaths bleiben, auch die drei des Host-Vertrags der App-Laufzeit (`composition`, `media-library`, `shared`): `appRuntimeHostSpecifiers` steht unverändert, die Import-Map der Anzeige kennt keinen neuen Namen. Ein Import aus einem Barrel kostet nur noch die Blätter, deren Exporte gebraucht werden (`sideEffects` nennt allein `openapi-extend`). ([#688](https://github.com/HKNovaTechUG/digital-signage-2026/pull/688))
- Jede Datei, deren Code `.openapi(…)` ruft, importiert `openapi-extend` selbst. Wer ein Blatt direkt lädt, braucht den Barrel seiner Domäne nicht mehr, damit die Zod-Erweiterung vor dem Schema läuft. ([#688](https://github.com/HKNovaTechUG/digital-signage-2026/pull/688))
- `@szenera/apps-sdk` liest Widget-Definition, Konfigurations-Schema und Manifest aus den Blättern des App-Katalogs statt aus dessen Barrel. ([#688](https://github.com/HKNovaTechUG/digital-signage-2026/pull/688))
- `@szenera/client` und `@szenera/cli`: Die Archive sind neu geschnitten, weil die eingebündelten Verträge ihre Nebenwirkungs-Importe je Blatt tragen. Oberfläche und Deckel bleiben, wie sie sind. ([#688](https://github.com/HKNovaTechUG/digital-signage-2026/pull/688))
- Neue Routen des Stores (session): `GET /v1/me/apps/store` (Karten, Filter mit Zahlen, Zählung, Kernfunktionen), `GET /v1/me/apps/store/{appId}` (Eintrag mit fertig entschiedener Lage, Sprache per `locale` oder `Accept-Language`), `GET /v1/me/apps/collections`, `GET /v1/me/apps/{appId}/installed` (App-Seite der installierten Fassung), `POST /v1/me/apps/{appId}/install-request`, `POST /v1/me/apps/{appId}/update/decision-request`, `GET /v1/me/apps/{appId}/data`, `POST` und `DELETE /v1/me/apps/{appId}/data/deletion`. Fehler `OwnerRequest.NotApplicable`, `AppData.NotDeletable` und `AppData.DeletionNotFound`. ([#688](https://github.com/HKNovaTechUG/digital-signage-2026/pull/688))
- Neue Pflege-Routen (Betreiber): `GET`, `POST /v1/platform/app-catalog/collections`, `PATCH …/collections/{collectionKey}`, `PUT …/collections/order`. ([#688](https://github.com/HKNovaTechUG/digital-signage-2026/pull/688))
- `@szenera/contracts`: `StoreEntryView`, `StoreCardView`, `StoreSituation` (Lage, genau eine Handlung, Grund mit Zahlen), Sammlungen, Bitten, App-Daten. Das Manifest trägt am Ende den optionalen Block `compatibility`. `preview.screenshots` wird nicht mehr gelesen, und die Liste des Marktplatzes führt es nicht mehr (Bruch). `InstalledApp.coreFeature`, `GetAppUpdateResponse.decisionRequest`, `SetPlayerProgramResponse.warnings`, `vertical` an der Organisation und im Profil. ([#688](https://github.com/HKNovaTechUG/digital-signage-2026/pull/688))
- `@szenera/client` und `@szenera/api-client`: `me.appsStore`, `me.appsCollections`, `me.appsInstalled`, `me.apps.installRequest`, `me.appsUpdate.decisionRequest`, `me.appsData`, `me.appsDataDeletion`, `platform.appCatalogCollections`. `@szenera/cli` bündelt die erweiterten Verträge, seine Befehle bleiben, wie sie sind. `@szenera/agent` kennt die neuen Fehlercodes. ([#688](https://github.com/HKNovaTechUG/digital-signage-2026/pull/688))
- `@szenera/apps-sdk`: `AppLifecycleHooks` hat zwei weitere freiwillige Punkte, `inventory(tenantId)` (Einträge je Datenbereich) und `purge(tenantId)` (alles endgültig löschen, idempotent). Sie kommen nur zusammen, eine Klasse mit nur einem von beiden lehnt der Boot ab. ([#688](https://github.com/HKNovaTechUG/digital-signage-2026/pull/688))
- `@szenera/contracts`: Das Manifest trägt `translations`, je Sprache ein Block nur mit Texten (`AppManifestTranslationsSchema`). Dazu `appManifestLocales()`, `localizeAppManifest()` und `appManifestTranslationIssues()`. Der Store antwortet in `locale` oder `Accept-Language` und nennt die Sprache der Texte in `textLocale`. Entfallen sind `MarketplaceAppListingSchema` und die Anwendungsfälle der entfallenen Routen, `GetInstalledAppResponse` trägt `history`, die Store-Übersicht `coreFeatures` mit der angebotenen Fassung. `PortalFeatureEntry` trägt keinen Namen mehr, die Namen stehen in den Texten des Stores. ([#699](https://github.com/HKNovaTechUG/digital-signage-2026/pull/699))
- `@szenera/client`: `client.marketplace.apps.list` und `.get` sowie `client.me.installedApps` sind entfallen, `client.me.apps.list({ locale })` liefert die installierten Apps. ([#699](https://github.com/HKNovaTechUG/digital-signage-2026/pull/699))
- `@szenera/apps-sdk`: `defineAppManifest` wirft bei einem unvollständigen Übersetzungsblock und nennt die Stelle. ([#699](https://github.com/HKNovaTechUG/digital-signage-2026/pull/699))
- `@szenera/widget-editor`: `schemaFieldText(schema, pfad)` und `splitFieldDescription()` lesen Beschriftung und Hilfe eines Felds aus `.describe('Titel|Satz')`, `APP_CATEGORY_LABEL_KEYS` ordnet die Kategorien den Beschriftungen der Palette zu. ([#699](https://github.com/HKNovaTechUG/digital-signage-2026/pull/699))
- `@szenera/cli` liest Apps über die Store-Routen, die Befehle bleiben, wie sie sind. ([#699](https://github.com/HKNovaTechUG/digital-signage-2026/pull/699))

### 0.2.1

Ohne Eintrag für Entwickler.

### 0.2.0

**Brüche**

- Die Kommandozeile heißt jetzt `szenera`. Das Paket `@szenera/cli` liefert das Programm unter diesem Namen aus, der Name `signage` entfällt ohne Übergang. ([#618](https://github.com/HKNovaTechUG/digital-signage-2026/pull/618))
- Die Umgebungsvariablen heißen `SZENERA_PROFILE`, `SZENERA_BASE_URL`, `SZENERA_API_KEY`, `SZENERA_OUTPUT` und `SZENERA_PROFILE_FILE`. Variablen mit dem Präfix `SIGNAGE_` liest die Kommandozeile nicht mehr. ([#618](https://github.com/HKNovaTechUG/digital-signage-2026/pull/618))
- Die Profil-Datei liegt unter `~/.config/szenera/profile.json`. Ein zwischengespeichertes Zugriffsmerkmal liegt daneben, nach dem Umzug meldet sich die Kommandozeile einmal neu an. ([#618](https://github.com/HKNovaTechUG/digital-signage-2026/pull/618))
- In der Sitzungsliste erscheint die Kommandozeile als `szenera-cli` mit ihrer Fassung. ([#618](https://github.com/HKNovaTechUG/digital-signage-2026/pull/618))
- Die Befehle des Plattformbetriebs sind nicht mehr enthalten. `szenera` führt 122 Befehle für Organisationen: Medien, Szenen, Programme, Geräte, Team, Schlüssel, Abonnement und den Notausgang `api`. ([#618](https://github.com/HKNovaTechUG/digital-signage-2026/pull/618))
- Ein Profil für den Plattformbetrieb (`"audience": "operator"`) weist die Kommandozeile beim Lesen ab. ([#618](https://github.com/HKNovaTechUG/digital-signage-2026/pull/618))
- `permission catalog --key-eligible` zeigt jetzt die Rechte, die ein Schlüssel der eigenen Organisation tragen darf. ([#618](https://github.com/HKNovaTechUG/digital-signage-2026/pull/618))
- `invoice list` kennt die Flagge `--status` nicht mehr. Für eine Organisation blieb sie bisher ohne Wirkung. ([#618](https://github.com/HKNovaTechUG/digital-signage-2026/pull/618))
- Die Pakete heißen jetzt `@szenera/*` und die Apps `@szenera-app/*`, Importe und Abhängigkeiten sind entsprechend anzupassen. ([#610](https://github.com/HKNovaTechUG/digital-signage-2026/pull/610))

**Änderungen**

- `POST /v1/devices/:id/release` mit `reason` ersetzt `POST /v1/devices/:id/reset`. ([#601](https://github.com/HKNovaTechUG/digital-signage-2026/pull/601))
- Neu sind `POST /v1/devices/:id/block`, `PATCH /v1/devices/:id` sowie `release`, `block` und `unblock` unter `/v1/platform/ops/devices/:id`. ([#601](https://github.com/HKNovaTechUG/digital-signage-2026/pull/601))
- `POST /v1/players/:id/decommission` entfällt, und `DELETE /v1/players/:id` nimmt die Angabe `device` mit `reconnect`, `remove` oder `keep`. ([#601](https://github.com/HKNovaTechUG/digital-signage-2026/pull/601))
- Der Zustand eines Geräts ist nur noch `unclaimed`, `active` oder `blocked`. ([#601](https://github.com/HKNovaTechUG/digital-signage-2026/pull/601))
- Neue Fehlercodes sind `Auth.DeviceBlocked`, `Device.Blocked`, `Device.NotBlocked` und `Player.KeepDeviceNotAllowed`, und `Auth.DeviceSuspended` entfällt. ([#601](https://github.com/HKNovaTechUG/digital-signage-2026/pull/601))
- Die Ereignisse `identity.device.blocked` und `identity.device.unblocked` kommen hinzu, `identity.device.decommissioned` entfällt, und `identity.device.released` trägt einen `reason`. ([#601](https://github.com/HKNovaTechUG/digital-signage-2026/pull/601))
- `POST /v1/devices/register` antwortet einem gekoppelten Gerät mit neuem Schlüssel mit `409 Device.ReregistrationPending` und dem Gerätenamen in `details.deviceName` und ersetzt damit den Code `Device.ReregistrationBlocked`. ([#607](https://github.com/HKNovaTechUG/digital-signage-2026/pull/607))
- Neu ist `POST /v1/devices/:id/reregistration` mit `decision` `keep`, `reconnect` oder `block` samt `reason`, dazu der Fehlercode `Device.ReregistrationNotPending`. ([#607](https://github.com/HKNovaTechUG/digital-signage-2026/pull/607))
- Geräte tragen die Felder `reregistrationRequestedAt`, `reregistrationAttempts`, `reregistrationSourceIp` und `reregistrationAllowedUntil`. ([#607](https://github.com/HKNovaTechUG/digital-signage-2026/pull/607))
- Die Ereignisse `identity.device.reregistration-requested` und `identity.device.reregistration-decided` kommen hinzu, ebenso die Benachrichtigungs-Art `identity.device-reregistration-requested`. ([#607](https://github.com/HKNovaTechUG/digital-signage-2026/pull/607))
- Die Befehlsart `factory-reset` entfällt, denn ein Gerät wird nur noch über die Freigabe geleert. ([#607](https://github.com/HKNovaTechUG/digital-signage-2026/pull/607))
- Die Erstanmeldung eines Browsers unter der Kennung eines gekoppelten WebDisplays antwortet mit `Device.AlreadyClaimed`. ([#607](https://github.com/HKNovaTechUG/digital-signage-2026/pull/607))
- Der Block `host` der Gerätefähigkeiten kennt zwei weitere Plattformen: `vega` für Fire TV mit Vega OS und `extension` für die Erweiterung für Chrome. Bisher meldet kein Gerät sie. ([#636](https://github.com/HKNovaTechUG/digital-signage-2026/pull/636))
- Die Fähigkeiten eines Geräts kennen den Block `remote` nicht mehr. Die Erweiterung meldet sich im Block `host` mit `platform: extension`. Der Block `host` trägt dazu `bridge` (die Brückenfassung des Wirts) und `bootStart` (ob der Wirt von selbst startet). ([#640](https://github.com/HKNovaTechUG/digital-signage-2026/pull/640))
- Die Archive von `@szenera/client` und `@szenera/cli` werden jetzt geprüft, bevor eine Fassung erscheinen darf: Sie tragen nur die eigenen Dateien, keine Route außerhalb der öffentlichen Spezifikation und keinen Verweis auf ein unveröffentlichtes Paket, und die Installation gelingt auf Node 22 und 24. ([#620](https://github.com/HKNovaTechUG/digital-signage-2026/pull/620))
- Die gepackte Größe jedes Archivs ist gedeckelt, und jedes Archiv trägt einen Fingerabdruck seiner Dateien. Ändert sich ein Archiv, gehört dazu eine neue Fassung. ([#620](https://github.com/HKNovaTechUG/digital-signage-2026/pull/620))
- `@szenera/cli` bringt Kern, Befehle, die Module des öffentlichen Klienten und die Verträge in einer einzigen Datei mit. `@szenera/client` bringt seine Typen je Unterpfad mit und braucht neben `zod` nichts aus der Plattform. ([#620](https://github.com/HKNovaTechUG/digital-signage-2026/pull/620))
- Die Kommandozeile nimmt nur noch Schlüssel einer Organisation (`ak_…`) an und nennt in ihrer Kennung die Fassung aus ihrem eigenen Manifest. ([#620](https://github.com/HKNovaTechUG/digital-signage-2026/pull/620))
- Veröffentlicht ist weiterhin nichts. ([#620](https://github.com/HKNovaTechUG/digital-signage-2026/pull/620))
- Der Herzschlag eines Geräts nennt im Block `renderer` die Fassung, den Bau und die Quelle der Anzeige (`bundle` oder `hosted`), dazu die Folge der zuletzt angenommenen Freigabe und seit wann das Bündel aktiv ist. Alle Felder sind optional. ([#633](https://github.com/HKNovaTechUG/digital-signage-2026/pull/633))
- Geräte tragen statt `runtime` den Block `software` (je Baustein Fassung, Bau und angenommene Freigabe), dazu `channel` und `softwareTarget`, das Soll ihres Kanals. Player tragen kein `capabilities` mehr, der gemeldete Zustand kein `reportedState.capabilities`. Was ein Gerät kann, steht in seinen Fähigkeiten, deren Block `software` `runtime` ersetzt. ([#642](https://github.com/HKNovaTechUG/digital-signage-2026/pull/642))
- Der Zustand der Anzeige (`lastTelemetry.renderer`) nennt das Bau-Profil (`modern` oder `legacy`). ([#642](https://github.com/HKNovaTechUG/digital-signage-2026/pull/642))
- `PlayerCapabilitySchema` und die beiden `OS_CHANNELS` entfallen, `ReleaseChannel` lebt in `@szenera/contracts/shared` neben `PROTOCOL_SERVED`. Die Selbstsicht trägt `channel` und `softwareTarget`. `channel` fehlt, solange die Cloud keinen Kanal für das Gerät führt, `currentOsChannel` bleibt für ältere Fernwartungen. ([#642](https://github.com/HKNovaTechUG/digital-signage-2026/pull/642))
- Beispiele der Vorfassungen je Naht liegen unter `packages/contracts/src/samples/protocols/`, Tests in TypeScript und Go legen sie den heutigen Lesern vor. ([#642](https://github.com/HKNovaTechUG/digital-signage-2026/pull/642))
- Die Kommandozeile ändert kein Verhalten. Ihr Archiv trägt den neuen Stand der Verträge (Servicemenü am Gerät), deshalb ein neuer Fingerabdruck. ([#628](https://github.com/HKNovaTechUG/digital-signage-2026/pull/628))
- `HOST_EDITIONS`, `HostEditionSchema` und `HostEdition` stehen in `@szenera/contracts/fleet` und im Einstieg `@szenera/contracts/fleet/host-bridge`. Die Beschreibung eines Wirts in `@szenera/host-bridge` nimmt `edition`. ([#653](https://github.com/HKNovaTechUG/digital-signage-2026/pull/653))
- Das Archiv von `@szenera/cli` ist mit esbuild 0.28 neu gebündelt. Befehle und Verhalten sind unverändert, nur der Fingerabdruck des Archivs ist neu. ([#621](https://github.com/HKNovaTechUG/digital-signage-2026/pull/621))

### 0.1.0

Stand vor den Änderungsnotizen — die erste Fassung mit eigener Zahl. Was davor geschah, steht im Verlauf des Quellbaums; diese Liste beginnt mit der nächsten Fassung.

## @szenera/client

### 0.6.0 · 2026-10-25

**Breaking changes**

- `analytics.analyticsReports` steht auf `@beta` und trägt als Abfrage eine `SavedExploreQuery`. Als Format gibt es nur `csv` und `pdf`. Umstieg: Berichte als Abfrage der freien Auswertung neu anlegen. ([#822](https://github.com/HKNovaTechUG/digital-signage-2026/pull/822))
- `analytics.analyticsPlayback`, `analytics.playersPlayback`, `analytics.mediaAssetsPlayback`, `analytics.analyticsInsightsOverview` und `analytics.analyticsInsights` entfallen. Umstieg: Die neue Auswertung über `analytics.analyticsOverview`, `analytics.analyticsPlayersDay` und `analytics.analyticsExplore` lesen. ([#822](https://github.com/HKNovaTechUG/digital-signage-2026/pull/822))
- Einträge von Playlisten und der Zeitleiste eines Displays kennen die Art `adPod`, den Werbeblock mit Plätzen, Spotlänge und Lückenfüller. Umstieg: Einträge mit `kind: 'adPod'` beim Lesen von Playlisten und Zeitleisten behandeln. ([#822](https://github.com/HKNovaTechUG/digital-signage-2026/pull/822))

**Added**

- `analytics.analyticsExplore.create` und `.export`, `analytics.analyticsCatalog.list` und `analytics.analyticsOverview.list` (beta) für Abfrage, Katalog, Ausgabe und Überblick. ([#822](https://github.com/HKNovaTechUG/digital-signage-2026/pull/822))
- `analytics.analyticsPlayersDay.list`, `analytics.analyticsPlayersPlays.list`, `analytics.analyticsContent.list` und `.byId`, `analytics.analyticsCampaignsDelivery.list` (beta). ([#822](https://github.com/HKNovaTechUG/digital-signage-2026/pull/822))
- `fleet.playersScreenshots.list` und `fleet.playersScreenshots.byId` (beta) lesen die Zeitreihe der Bildschirmaufnahmen eines Displays. ([#822](https://github.com/HKNovaTechUG/digital-signage-2026/pull/822))
- `analytics.analyticsProofs` (`list`, `byId`, `interim`), `analytics.analyticsProofsFiles.byId` und `analytics.analyticsShareLinks` (`list`, `create`, `remove`), alle beta. ([#822](https://github.com/HKNovaTechUG/digital-signage-2026/pull/822))
- `analytics.publicProofKeys.list`, `analytics.publicProofs.verify` und `analytics.publicCampaignReports` (`open`, `proofFile`) rufen ohne Anmeldung, alle beta. ([#822](https://github.com/HKNovaTechUG/digital-signage-2026/pull/822))
- `advertising.advertisingRevenue.list` (beta) liest die Erlösaufstellungen der Organisation, mit Verteilung je Werbekampagne und Verweis auf die Gutschrift. ([#822](https://github.com/HKNovaTechUG/digital-signage-2026/pull/822))
- Die Fabrik nimmt `authBaseUrl` an. Anmeldung, Sitzung, OAuth, SCIM und Einladung gehen an diesen Wirt, alles andere an `baseUrl`. Ohne die Einstellung ändert sich nichts. ([#825](https://github.com/HKNovaTechUG/digital-signage-2026/pull/825))
- `analytics.publicCampaignReports.open` liefert je Nachweis `campaignId`. ([#822](https://github.com/HKNovaTechUG/digital-signage-2026/pull/822))
- Neues Modul `advertising` (beta): Werbepartner, Werbekampagnen, Buchungen, Motive, Werbefläche, Publikum, Teilnahme und Stellgrößen. ([#822](https://github.com/HKNovaTechUG/digital-signage-2026/pull/822))
- Standorte tragen `venueType`, die Art des Ladens. ([#822](https://github.com/HKNovaTechUG/digital-signage-2026/pull/822))

**Changed**

- `analytics.analyticsPlayersDay.list` nennt als Quelle des Panelzustands `cec`, `ddc` oder `none` und als Grund einer Planfassung nur, was die Planung setzt. ([#822](https://github.com/HKNovaTechUG/digital-signage-2026/pull/822))
- Die mitgelieferten Typen folgen dem bereinigten Katalog der Fehlercodes und Ereignisse. Codes und Ereignisse der entfallenen Verteilungs-Kampagnen und des OS-Regals gibt es nicht mehr. ([#847](https://github.com/HKNovaTechUG/digital-signage-2026/pull/847))

### 0.5.0 · 2026-10-23

**Breaking changes**

- Das Paket nutzt das englische API-Format. Felder, Typen und Werte in Billing, Lizenzen, Abbildern und Bündeln heißen anders. Umstieg: Die Namen im eigenen Code ersetzen, etwa `zielstand` durch `targetState` und `herkunft` durch `provenance`. ([#761](https://github.com/HKNovaTechUG/digital-signage-2026/pull/761))
- `me.apiKeys.remove(id, { reason })` verlangt den Grund `owner-rotation` oder `compromised`. Unter `/v1/me` antworten mit einem Schlüssel nur noch fünf Lesewege, alle übrigen mit 401. Umstieg: Den Grund mitsenden und Automation auf die fünf Lesewege beschränken. ([#762](https://github.com/HKNovaTechUG/digital-signage-2026/pull/762))

**Added**

- Dokumente: Varianten `page-<n>` und `page-<n>-sm`, `pageCount` an Medien und der Befund `DocumentPagesChanged`. ([#801](https://github.com/HKNovaTechUG/digital-signage-2026/pull/801))
- Die Typen folgen der API: Feed-Katalog, Quellen für den Betrieb und der Fehlercode `FeedSource.NotFound`. ([#801](https://github.com/HKNovaTechUG/digital-signage-2026/pull/801))
- Neue Aufrufe: Zusammenfassung, Sammelaktion und Wiederherstellen von Benachrichtigungen, dazu `state` und `groupKey` an der Liste. ([#795](https://github.com/HKNovaTechUG/digital-signage-2026/pull/795))
- `playerId` an der Vorschau der Widget-Daten und der Lesebereich `player-location`. ([#801](https://github.com/HKNovaTechUG/digital-signage-2026/pull/801))
- Standorte: `region` und `openingHours`, dazu das Ereignis `fleet.location.opening-hours-changed`. ([#801](https://github.com/HKNovaTechUG/digital-signage-2026/pull/801))
- Widget-Definitionen des Katalogs kennen `size` und `preview.states`, Ansichten des Stores kennen `size`. ([#801](https://github.com/HKNovaTechUG/digital-signage-2026/pull/801))

**Changed**

- Billing: `zielstand` heißt `targetState`, `regel` heißt `rule`, `teilstorno` heißt `partialCancellation`, `staffel` heißt `tierScale`, `testphase` heißt `trialCredit`. ([#761](https://github.com/HKNovaTechUG/digital-signage-2026/pull/761))
- Billing: `belegteBildschirme` heißt `usedDisplays`, `zyklusVormerkung` heißt `pendingBillingCycle`, `restguthabenCents` heißt `remainingCreditCents`, `mindestBildschirme` heißt `minDisplays`. ([#761](https://github.com/HKNovaTechUG/digital-signage-2026/pull/761))
- Lizenzen: `konfliktBis` heißt `conflictUntil`, `lizenzKonfliktBis` heißt `licenseConflictUntil`, `vormerkungWirktAm` heißt `pendingChangeEffectiveAt`, `mandant` heißt `tenant`. ([#761](https://github.com/HKNovaTechUG/digital-signage-2026/pull/761))
- Abbilder und Bündel: `herkunft` heißt `provenance` mit `environment`, `appAnchor` und `otaAnchor`. Die Liste der Abbilder filtert über `?environment=`. ([#761](https://github.com/HKNovaTechUG/digital-signage-2026/pull/761))
- Rollen liest der Client über `assignments` mit `roleId` und `expiresAt` statt über `roleIds`. ([#762](https://github.com/HKNovaTechUG/digital-signage-2026/pull/762))

### 0.4.0

**Brüche**

- `GET /v1/audit/bulk/:correlationId` entfällt und mit ihm `client.audit.auditBulk` und das Schema `GetBulkActionDetailResponse`. ([#742](https://github.com/HKNovaTechUG/digital-signage-2026/pull/742))
- Das Recht `audit.bulk.read`, die Ereignisart `audit.bulk-action.completed` und der Fehlercode `Internal.AuditBulkActionDetailRepositoryUnavailable` entfallen. ([#742](https://github.com/HKNovaTechUG/digital-signage-2026/pull/742))

### 0.3.0

**Brüche**

- Neue Routen der Organisation: `GET /v1/me/apps/updates` und `GET /v1/me/apps/{appId}/update` liefern die Entscheidung über ein Update (Fassung von und nach, Gründe, Neues, Änderungen in Klartext, Folgen, Frist, ob Ablehnen noch geht), `POST /v1/me/apps/{appId}/update/accept` und `…/update/reject` entscheiden mit dem Hash der Ziel-Fassung. ([#680](https://github.com/HKNovaTechUG/digital-signage-2026/pull/680))
- Kanäle mit Publikum: `GET|PUT /v1/me/apps/beta-enrollment` und `POST|DELETE /v1/me/apps/{appId}/beta-enrollment` tragen eine Organisation für Fassungen aus beta ein, global oder je App. Store, App-Seite, Installation und Upgrade nehmen die höchste Fassung, die die Organisation sieht, die Liste trägt dazu `channel`. ([#680](https://github.com/HKNovaTechUG/digital-signage-2026/pull/680))
- Schwimmende Pins: `effectiveAppVersion(pin, installed)` in `@szenera/contracts/composition`. Die Momentaufnahme nennt die gespielte Fassung. `GET /v1/me/apps/{appId}/scene-pins` und `POST …/scene-pins/lift` heben alle Szenen auf die installierte Fassung, je Szene als neue veröffentlichte Fassung. ([#680](https://github.com/HKNovaTechUG/digital-signage-2026/pull/680))
- `POST /v1/marketplace/apps/{appId}/upgrade` geht nur vorwärts und nur auf Fassungen, die die Organisation sieht. Neuer Fehlercode `App.UpdateUnavailable` (409, `details.reason`: `not-forward`, `none`, `not-rejectable`). ([#680](https://github.com/HKNovaTechUG/digital-signage-2026/pull/680))
- Entfallen sind `GET /v1/me/pending-reacceptances`, `POST /v1/marketplace/apps/{appId}/accept` und `…/reject` samt ihren Verträgen. `RetireAppReleaseRequest` nimmt `grace` und `securityAdvisory` statt `graceMonths`. ([#680](https://github.com/HKNovaTechUG/digital-signage-2026/pull/680))
- Neue Ereignisse `marketplace.app.update-declined`, `marketplace.app.update-withdrawn` und `marketplace.app.release-switched`. `app-catalog.app-release.retired` und `…grace-expired` tragen `successorVersion`. Ein Grant trägt `declinedReleaseId` und `declinedVersion`, ein Nachweis `reasons`, eine Fassung `securityAdvisory`. ([#680](https://github.com/HKNovaTechUG/digital-signage-2026/pull/680))
- `@szenera/client` und `@szenera/api-client`: neu `me.appsUpdates.list`, `me.appsUpdate.list/accept/reject`, `me.appsBetaEnrollment.*` und `me.appsScenePins.list/lift`, entfallen `me.pendingReacceptances` und `marketplace.marketplaceApps.accept/reject`. `szenera app accept` und `app reject` nutzen die neuen Routen, ihre Aufrufe bleiben gleich. ([#680](https://github.com/HKNovaTechUG/digital-signage-2026/pull/680))
- Neue Routen des Stores (session): `GET /v1/me/apps/store` (Karten, Filter mit Zahlen, Zählung, Kernfunktionen), `GET /v1/me/apps/store/{appId}` (Eintrag mit fertig entschiedener Lage, Sprache per `locale` oder `Accept-Language`), `GET /v1/me/apps/collections`, `GET /v1/me/apps/{appId}/installed` (App-Seite der installierten Fassung), `POST /v1/me/apps/{appId}/install-request`, `POST /v1/me/apps/{appId}/update/decision-request`, `GET /v1/me/apps/{appId}/data`, `POST` und `DELETE /v1/me/apps/{appId}/data/deletion`. Fehler `OwnerRequest.NotApplicable`, `AppData.NotDeletable` und `AppData.DeletionNotFound`. ([#688](https://github.com/HKNovaTechUG/digital-signage-2026/pull/688))
- Neue Pflege-Routen (Betreiber): `GET`, `POST /v1/platform/app-catalog/collections`, `PATCH …/collections/{collectionKey}`, `PUT …/collections/order`. ([#688](https://github.com/HKNovaTechUG/digital-signage-2026/pull/688))
- `@szenera/contracts`: `StoreEntryView`, `StoreCardView`, `StoreSituation` (Lage, genau eine Handlung, Grund mit Zahlen), Sammlungen, Bitten, App-Daten. Das Manifest trägt am Ende den optionalen Block `compatibility`. `preview.screenshots` wird nicht mehr gelesen, und die Liste des Marktplatzes führt es nicht mehr (Bruch). `InstalledApp.coreFeature`, `GetAppUpdateResponse.decisionRequest`, `SetPlayerProgramResponse.warnings`, `vertical` an der Organisation und im Profil. ([#688](https://github.com/HKNovaTechUG/digital-signage-2026/pull/688))
- `@szenera/client` und `@szenera/api-client`: `me.appsStore`, `me.appsCollections`, `me.appsInstalled`, `me.apps.installRequest`, `me.appsUpdate.decisionRequest`, `me.appsData`, `me.appsDataDeletion`, `platform.appCatalogCollections`. `@szenera/cli` bündelt die erweiterten Verträge, seine Befehle bleiben, wie sie sind. `@szenera/agent` kennt die neuen Fehlercodes. ([#688](https://github.com/HKNovaTechUG/digital-signage-2026/pull/688))
- `@szenera/apps-sdk`: `AppLifecycleHooks` hat zwei weitere freiwillige Punkte, `inventory(tenantId)` (Einträge je Datenbereich) und `purge(tenantId)` (alles endgültig löschen, idempotent). Sie kommen nur zusammen, eine Klasse mit nur einem von beiden lehnt der Boot ab. ([#688](https://github.com/HKNovaTechUG/digital-signage-2026/pull/688))
- `@szenera/contracts`: Das Manifest trägt `translations`, je Sprache ein Block nur mit Texten (`AppManifestTranslationsSchema`). Dazu `appManifestLocales()`, `localizeAppManifest()` und `appManifestTranslationIssues()`. Der Store antwortet in `locale` oder `Accept-Language` und nennt die Sprache der Texte in `textLocale`. Entfallen sind `MarketplaceAppListingSchema` und die Anwendungsfälle der entfallenen Routen, `GetInstalledAppResponse` trägt `history`, die Store-Übersicht `coreFeatures` mit der angebotenen Fassung. `PortalFeatureEntry` trägt keinen Namen mehr, die Namen stehen in den Texten des Stores. ([#699](https://github.com/HKNovaTechUG/digital-signage-2026/pull/699))
- `@szenera/client`: `client.marketplace.apps.list` und `.get` sowie `client.me.installedApps` sind entfallen, `client.me.apps.list({ locale })` liefert die installierten Apps. ([#699](https://github.com/HKNovaTechUG/digital-signage-2026/pull/699))
- `@szenera/apps-sdk`: `defineAppManifest` wirft bei einem unvollständigen Übersetzungsblock und nennt die Stelle. ([#699](https://github.com/HKNovaTechUG/digital-signage-2026/pull/699))
- `@szenera/widget-editor`: `schemaFieldText(schema, pfad)` und `splitFieldDescription()` lesen Beschriftung und Hilfe eines Felds aus `.describe('Titel|Satz')`, `APP_CATEGORY_LABEL_KEYS` ordnet die Kategorien den Beschriftungen der Palette zu. ([#699](https://github.com/HKNovaTechUG/digital-signage-2026/pull/699))
- `@szenera/cli` liest Apps über die Store-Routen, die Befehle bleiben, wie sie sind. ([#699](https://github.com/HKNovaTechUG/digital-signage-2026/pull/699))

**Änderungen**

- `@szenera/contracts`: neu `CatalogAppSchema`, `AppReleaseNotesSchema` (Notizen je Zielgruppe und Sprache), `AppReleaseEventSchema`, `RestoreAppRelease*`, `ListAppReleaseHistory*` und `GetAppVersionHistory*`. Ein `AppRelease` trägt `notes`, die Wire-Form daneben weiter `releaseNotes`. `PATCH /v1/platform/app-catalog/apps/{appId}/releases/{id}` nimmt `notes` je Zielgruppe oder wie bisher `releaseNotes`. ([#677](https://github.com/HKNovaTechUG/digital-signage-2026/pull/677))
- Ein Grant trägt `installedReleaseId`, `pendingReleaseId`, `pendingReasons` und `pendingDeadline`, ein Zustimmungs-Nachweis `releaseId`, eine offene Zustimmung `fromVersion`, `toVersion`, `reasons` und `deadline`. Entfallen sind `autoUpgrade` am Grant und `ConfigSchemaChangedPayloadSchema`. ([#677](https://github.com/HKNovaTechUG/digital-signage-2026/pull/677))
- `GET /v1/apps/{appId}/history` liefert einer Organisation die Fassungen einer App, die stable erreicht haben, mit Datum und „Neu in dieser Fassung" in der erbetenen Sprache (`?locale=en-US`, ohne Angabe Deutsch). ([#677](https://github.com/HKNovaTechUG/digital-signage-2026/pull/677))
- `@szenera/api-client`: neu `client.platform.appCatalogAppsHistory.list`, `client.platform.appCatalogAppsReleases.restore` und `client.appCatalog.appsHistory.list`. `@szenera/client`: neu `client.appCatalog.appsHistory.list`. `@szenera/cli` bündelt die neuen Verträge, ihre Befehle bleiben, wie sie sind. ([#677](https://github.com/HKNovaTechUG/digital-signage-2026/pull/677))
- Das scenes-Bündel der Momentaufnahme trägt `appVersions` (je App die eine Fassung des Displays) sowie `appRendererHosts` und `appWidgetTypes` je `<appId>@<version>`, alle mit der Vorgabe `{}`. Die Pins der Szenen und Widgets nennen dieselbe Fassung. ([#683](https://github.com/HKNovaTechUG/digital-signage-2026/pull/683))
- `displayAppVersion(pins, installed)` in `@szenera/contracts/composition` rechnet die Fassung eines Displays: die installierte, bei gehaltenen Pins älterer Hauptnummern die niedrigste davon. ([#683](https://github.com/HKNovaTechUG/digital-signage-2026/pull/683))
- Die neue Befundart `AppVersionHeld` ist immer eine Warnung und trägt `appId`, `appName`, `version`, `installedVersion` und `widgetIds`. Die KI-Anbindung erklärt sie. ([#683](https://github.com/HKNovaTechUG/digital-signage-2026/pull/683))
- `@szenera/client`: Der Filter `type` der Integritäts-Befunde einer Szene kennt `AppVersionHeld`. `@szenera/cli` bündelt den erweiterten Vertrag, ihre Befehle bleiben, wie sie sind. ([#683](https://github.com/HKNovaTechUG/digital-signage-2026/pull/683))
- Ein Zustimmungs-Nachweis trägt `version`, die Nummer der Fassung, der zugestimmt wurde (`null` nur bei Nachweisen von davor, deren Fassung schon fehlte). Eine Installation trägt `declinedAt` neben `declinedVersion`. ([#681](https://github.com/HKNovaTechUG/digital-signage-2026/pull/681))
- `GET /v1/apps/{appId}/history` nennt je Fassung `releaseId`, dieselbe Kennung wie an Installation, Nachweis und Update-Entscheidung. ([#681](https://github.com/HKNovaTechUG/digital-signage-2026/pull/681))
- `@szenera/client`: `client.appCatalog.appsHistory.list` nennt je Fassung `releaseId`, eine Installation trägt `declinedAt`. `@szenera/cli` bündelt die erweiterten Verträge, ihre Befehle bleiben, wie sie sind. ([#681](https://github.com/HKNovaTechUG/digital-signage-2026/pull/681))
- `@szenera/widget-editor`: `EditorShell` nimmt `appsAwaitingUpdate` (Apps samt Weg zur Entscheidung). Der App-Bereich zeigt ihre Widgets mit „Update wartet“, ein Klick führt zur Entscheidung statt einzufügen. ([#681](https://github.com/HKNovaTechUG/digital-signage-2026/pull/681))
- `@szenera/client` und `@szenera/cli` bündeln die erweiterten Verträge der Plattform. Ihre Aufrufe und Befehle bleiben, wie sie sind. ([#697](https://github.com/HKNovaTechUG/digital-signage-2026/pull/697))
- `@szenera/contracts` baut je Quelldatei ein Modul (`dist/<domain>/<pfad>.js`), und die `exports`-Karte trägt das Muster `./*`: Jedes Blatt ist ladbar (`@szenera/contracts/app-catalog/app-manifest/locked-app`). Die benannten Subpaths bleiben, auch die drei des Host-Vertrags der App-Laufzeit (`composition`, `media-library`, `shared`): `appRuntimeHostSpecifiers` steht unverändert, die Import-Map der Anzeige kennt keinen neuen Namen. Ein Import aus einem Barrel kostet nur noch die Blätter, deren Exporte gebraucht werden (`sideEffects` nennt allein `openapi-extend`). ([#688](https://github.com/HKNovaTechUG/digital-signage-2026/pull/688))
- Jede Datei, deren Code `.openapi(…)` ruft, importiert `openapi-extend` selbst. Wer ein Blatt direkt lädt, braucht den Barrel seiner Domäne nicht mehr, damit die Zod-Erweiterung vor dem Schema läuft. ([#688](https://github.com/HKNovaTechUG/digital-signage-2026/pull/688))
- `@szenera/apps-sdk` liest Widget-Definition, Konfigurations-Schema und Manifest aus den Blättern des App-Katalogs statt aus dessen Barrel. ([#688](https://github.com/HKNovaTechUG/digital-signage-2026/pull/688))
- `@szenera/client` und `@szenera/cli`: Die Archive sind neu geschnitten, weil die eingebündelten Verträge ihre Nebenwirkungs-Importe je Blatt tragen. Oberfläche und Deckel bleiben, wie sie sind. ([#688](https://github.com/HKNovaTechUG/digital-signage-2026/pull/688))

### 0.2.1

Ohne Eintrag für Entwickler.

### 0.2.0

**Brüche**

- Die Fähigkeiten eines Geräts kennen den Block `remote` nicht mehr. Die Erweiterung meldet sich im Block `host` mit `platform: extension`. Der Block `host` trägt dazu `bridge` (die Brückenfassung des Wirts) und `bootStart` (ob der Wirt von selbst startet). ([#640](https://github.com/HKNovaTechUG/digital-signage-2026/pull/640))
- Geräte tragen statt `runtime` den Block `software` (je Baustein Fassung, Bau und angenommene Freigabe), dazu `channel` und `softwareTarget`, das Soll ihres Kanals. Player tragen kein `capabilities` mehr, der gemeldete Zustand kein `reportedState.capabilities`. Was ein Gerät kann, steht in seinen Fähigkeiten, deren Block `software` `runtime` ersetzt. ([#642](https://github.com/HKNovaTechUG/digital-signage-2026/pull/642))
- Der Zustand der Anzeige (`lastTelemetry.renderer`) nennt das Bau-Profil (`modern` oder `legacy`). ([#642](https://github.com/HKNovaTechUG/digital-signage-2026/pull/642))
- `PlayerCapabilitySchema` und die beiden `OS_CHANNELS` entfallen, `ReleaseChannel` lebt in `@szenera/contracts/shared` neben `PROTOCOL_SERVED`. Die Selbstsicht trägt `channel` und `softwareTarget`. `channel` fehlt, solange die Cloud keinen Kanal für das Gerät führt, `currentOsChannel` bleibt für ältere Fernwartungen. ([#642](https://github.com/HKNovaTechUG/digital-signage-2026/pull/642))
- Beispiele der Vorfassungen je Naht liegen unter `packages/contracts/src/samples/protocols/`, Tests in TypeScript und Go legen sie den heutigen Lesern vor. ([#642](https://github.com/HKNovaTechUG/digital-signage-2026/pull/642))
- `HOST_EDITIONS`, `HostEditionSchema` und `HostEdition` stehen in `@szenera/contracts/fleet` und im Einstieg `@szenera/contracts/fleet/host-bridge`. Die Beschreibung eines Wirts in `@szenera/host-bridge` nimmt `edition`. ([#653](https://github.com/HKNovaTechUG/digital-signage-2026/pull/653))

**Änderungen**

- Der Block `host` der Gerätefähigkeiten kennt zwei weitere Plattformen: `vega` für Fire TV mit Vega OS und `extension` für die Erweiterung für Chrome. Bisher meldet kein Gerät sie. ([#636](https://github.com/HKNovaTechUG/digital-signage-2026/pull/636))
- Neu ist das Paket `@szenera/client`, der öffentliche TypeScript-Klient der Schnittstelle. Er spricht genau die Operationen der öffentlichen Spezifikation, je Bereich ein Namensraum, und weist sich mit einem API-Schlüssel `ak_…` oder dem Zugriffstoken `oat_…` eines delegierten Zugangs aus. Veröffentlicht wird er noch nicht. ([#617](https://github.com/HKNovaTechUG/digital-signage-2026/pull/617))
- Jede Methode beider Klienten trägt die Kurzbeschreibung ihrer Operation als Kommentar. Junge Operationen tragen zusätzlich `@beta`, auslaufende `@deprecated` mit ihrem Abschalt-Tag. ([#617](https://github.com/HKNovaTechUG/digital-signage-2026/pull/617))
- Die anmeldefreien Routen `GET /v1/public/status` und `GET /v1/public/maintenance-status` stehen im eigenen Bereich `status` statt unter `ops-console`. Im Klienten heißt ihr Namensraum deshalb `status` statt `opsConsole`. ([#617](https://github.com/HKNovaTechUG/digital-signage-2026/pull/617))
- Die öffentliche Spezifikation führt die Sitzung und die Einrichtung der Betreiber-Konten nicht mehr (`POST /v1/auth/operator/refresh`, `POST /v1/auth/onboarding/consume`). Sie nennt keinen Server auf `localhost` mehr und nur noch die Ausweisarten, die eine ihrer Operationen annimmt. ([#617](https://github.com/HKNovaTechUG/digital-signage-2026/pull/617))
- Das Sicherheitsverfahren `cookie` nennt das Cookie, das es wirklich gibt: `refresh_token`, gelesen nur von `POST /v1/auth/refresh`. ([#617](https://github.com/HKNovaTechUG/digital-signage-2026/pull/617))
- Die Beispiele der Spezifikation zeigen Geräte-Adressen aus dem Dokumentationsbereich `192.0.2.0/24`. ([#617](https://github.com/HKNovaTechUG/digital-signage-2026/pull/617))
- `@szenera/api-client/factory` bietet mit `createBearerClientWith` einen Klienten mit festem Merkmal und frei gewählten Modulen. ([#617](https://github.com/HKNovaTechUG/digital-signage-2026/pull/617))
- Die Archive von `@szenera/client` und `@szenera/cli` werden jetzt geprüft, bevor eine Fassung erscheinen darf: Sie tragen nur die eigenen Dateien, keine Route außerhalb der öffentlichen Spezifikation und keinen Verweis auf ein unveröffentlichtes Paket, und die Installation gelingt auf Node 22 und 24. ([#620](https://github.com/HKNovaTechUG/digital-signage-2026/pull/620))
- Die gepackte Größe jedes Archivs ist gedeckelt, und jedes Archiv trägt einen Fingerabdruck seiner Dateien. Ändert sich ein Archiv, gehört dazu eine neue Fassung. ([#620](https://github.com/HKNovaTechUG/digital-signage-2026/pull/620))
- `@szenera/cli` bringt Kern, Befehle, die Module des öffentlichen Klienten und die Verträge in einer einzigen Datei mit. `@szenera/client` bringt seine Typen je Unterpfad mit und braucht neben `zod` nichts aus der Plattform. ([#620](https://github.com/HKNovaTechUG/digital-signage-2026/pull/620))
- Die Kommandozeile nimmt nur noch Schlüssel einer Organisation (`ak_…`) an und nennt in ihrer Kennung die Fassung aus ihrem eigenen Manifest. ([#620](https://github.com/HKNovaTechUG/digital-signage-2026/pull/620))
- Veröffentlicht ist weiterhin nichts. ([#620](https://github.com/HKNovaTechUG/digital-signage-2026/pull/620))
- Der Herzschlag eines Geräts nennt im Block `renderer` die Fassung, den Bau und die Quelle der Anzeige (`bundle` oder `hosted`), dazu die Folge der zuletzt angenommenen Freigabe und seit wann das Bündel aktiv ist. Alle Felder sind optional. ([#633](https://github.com/HKNovaTechUG/digital-signage-2026/pull/633))
- Neue Verträge `DeviceServiceStatus`, `RendererServiceStatus` und `ServiceFinding` in `@szenera/contracts/fleet`. ([#628](https://github.com/HKNovaTechUG/digital-signage-2026/pull/628))
- `GET /v1/devices/me` liefert `deviceName`, den Namen aus der Geräteakte. ([#628](https://github.com/HKNovaTechUG/digital-signage-2026/pull/628))
- Der Herzschlag nimmt `appFailures` an, höchstens 20 je Meldung mit dem Grund `missing`, `rejected` oder `failed`. Der Agent füllt `time.offsetMs` mit dem Versatz seiner Uhr zur Cloud. ([#628](https://github.com/HKNovaTechUG/digital-signage-2026/pull/628))
- Die Ereignis-Kategorie `service` bringt die Codes `service.menu-opened` (`input`) und `service.menu-closed` (`reason`). Der Agent meldet jetzt auch `content.bundle-failed`. ([#628](https://github.com/HKNovaTechUG/digital-signage-2026/pull/628))
- Der Agent bedient auf `127.0.0.1:8081` die Seite des Menüs und `GET /v1/status`, `/v1/report`, `/v1/input`, `/v1/backdrop` sowie `POST /v1/open` und `/v1/close`. `service.menu-opened` entsteht erst, wenn die Seite das Öffnen meldet. `Origin: null` bekommt 403, außer die Startseite mit ihrem Schlüssel im Kopf `X-Service-Token`. Der Eingabe-Wächter `szenera-input-watch` ist ein eigenes Programm im selben Go-Modul. ([#628](https://github.com/HKNovaTechUG/digital-signage-2026/pull/628))
- Der Katalog der Befunde kennt `app-bundle-download-failed` (`appId`, `version`, `appName`, `httpStatus`, `since`). Die App-Befunde tragen `appName`, `wifi-weak` und `clock-skew` den Auslöser `trigger`. ([#628](https://github.com/HKNovaTechUG/digital-signage-2026/pull/628))

### 0.1.0

Die erste Fassung mit eigener Zahl, noch nicht veröffentlicht. Diese Liste beginnt mit der nächsten Fassung.
