Zum Inhalt springen

Pakete und ihre Fassungen

Welche Fassung von API-Client, Apps-SDK, CLI und Verträgen gilt und was sich in jeder Fassung für Entwickler geändert hat.

26 Minuten LesezeitÄnderungenStand: 25.10.2026

Auf dieser Seite

Bevor Sie loslegen

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.

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

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)

Added

  • Neue Befehle szenera proof list, szenera proof show und szenera proof download. (#822)
  • Neue Befehle szenera analytics overview, szenera analytics explore und szenera analytics delivery <acp_…>. (#822)
  • Neue Befehle advertiser list, advertiser get, advertiser create, campaign list, campaign get, booking list, creative list und creative approve. (#822)

Changed

  • Das Archiv folgt dem Klienten mit den Erlösaufstellungen, ohne neuen Befehl. (#822)
  • Das Archiv folgt dem Klienten ohne die Lesewege der Minutenzählung und der Insights. Die Befehle bleiben. (#822)
  • Das Archiv folgt dem Klienten mit den Panelquellen cec, ddc und none. Die Befehle bleiben. (#822)
  • Die Kommandozeile bringt den Client mit, der einen eigenen Anmelde-Wirt kennt. Ohne Einstellung ändert sich nichts. (#825)
  • Das Archiv folgt dem Klienten mit campaignId je Nachweis des Kampagnenberichts. Die Befehle bleiben. (#822)
  • Das Archiv bündelt den aktuellen Stand der Verträge, die Befehle von szenera bleiben gleich. (#847)
  • szenera playlist get zeigt einen Werbeblock als „Werbeblock · 3 Plätze à 10 s“ mit seiner Dauer. (#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)
  • 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)

Added

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

0.2.3

Änderungen

  • GET /v1/audit/bulk/:correlationId entfällt und mit ihm client.audit.auditBulk und das Schema GetBulkActionDetailResponse. (#742)
  • Das Recht audit.bulk.read, die Ereignisart audit.bulk-action.completed und der Fehlercode Internal.AuditBulkActionDetailRepositoryUnavailable entfallen. (#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)
  • 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)
  • 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)
  • @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)
  • 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)
  • displayAppVersion(pins, installed) in @szenera/contracts/composition rechnet die Fassung eines Displays: die installierte, bei gehaltenen Pins älterer Hauptnummern die niedrigste davon. (#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)
  • @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)
  • 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)
  • GET /v1/apps/{appId}/history nennt je Fassung releaseId, dieselbe Kennung wie an Installation, Nachweis und Update-Entscheidung. (#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)
  • @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)
  • 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)
  • 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)
  • 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)
  • 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)
  • 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)
  • 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)
  • @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)
  • @szenera/client und @szenera/cli bündeln die erweiterten Verträge der Plattform. Ihre Aufrufe und Befehle bleiben, wie sie sind. (#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)
  • 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)
  • @szenera/apps-sdk liest Widget-Definition, Konfigurations-Schema und Manifest aus den Blättern des App-Katalogs statt aus dessen Barrel. (#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)
  • 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)
  • Neue Pflege-Routen (Betreiber): GET, POST /v1/platform/app-catalog/collections, PATCH …/collections/{collectionKey}, PUT …/collections/order. (#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)
  • @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)
  • @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)
  • @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)
  • @szenera/client: client.marketplace.apps.list und .get sowie client.me.installedApps sind entfallen, client.me.apps.list({ locale }) liefert die installierten Apps. (#699)
  • @szenera/apps-sdk: defineAppManifest wirft bei einem unvollständigen Übersetzungsblock und nennt die Stelle. (#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)
  • @szenera/cli liest Apps über die Store-Routen, die Befehle bleiben, wie sie sind. (#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)
  • 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)
  • 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)
  • In der Sitzungsliste erscheint die Kommandozeile als szenera-cli mit ihrer Fassung. (#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)
  • Ein Profil für den Plattformbetrieb ("audience": "operator") weist die Kommandozeile beim Lesen ab. (#618)
  • permission catalog --key-eligible zeigt jetzt die Rechte, die ein Schlüssel der eigenen Organisation tragen darf. (#618)
  • invoice list kennt die Flagge --status nicht mehr. Für eine Organisation blieb sie bisher ohne Wirkung. (#618)
  • Die Pakete heißen jetzt @szenera/* und die Apps @szenera-app/*, Importe und Abhängigkeiten sind entsprechend anzupassen. (#610)

Änderungen

  • POST /v1/devices/:id/release mit reason ersetzt POST /v1/devices/:id/reset. (#601)
  • Neu sind POST /v1/devices/:id/block, PATCH /v1/devices/:id sowie release, block und unblock unter /v1/platform/ops/devices/:id. (#601)
  • POST /v1/players/:id/decommission entfällt, und DELETE /v1/players/:id nimmt die Angabe device mit reconnect, remove oder keep. (#601)
  • Der Zustand eines Geräts ist nur noch unclaimed, active oder blocked. (#601)
  • Neue Fehlercodes sind Auth.DeviceBlocked, Device.Blocked, Device.NotBlocked und Player.KeepDeviceNotAllowed, und Auth.DeviceSuspended entfällt. (#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)
  • 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)
  • Neu ist POST /v1/devices/:id/reregistration mit decision keep, reconnect oder block samt reason, dazu der Fehlercode Device.ReregistrationNotPending. (#607)
  • Geräte tragen die Felder reregistrationRequestedAt, reregistrationAttempts, reregistrationSourceIp und reregistrationAllowedUntil. (#607)
  • Die Ereignisse identity.device.reregistration-requested und identity.device.reregistration-decided kommen hinzu, ebenso die Benachrichtigungs-Art identity.device-reregistration-requested. (#607)
  • Die Befehlsart factory-reset entfällt, denn ein Gerät wird nur noch über die Freigabe geleert. (#607)
  • Die Erstanmeldung eines Browsers unter der Kennung eines gekoppelten WebDisplays antwortet mit Device.AlreadyClaimed. (#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)
  • 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)
  • 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)
  • 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)
  • @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)
  • Die Kommandozeile nimmt nur noch Schlüssel einer Organisation (ak_…) an und nennt in ihrer Kennung die Fassung aus ihrem eigenen Manifest. (#620)
  • Veröffentlicht ist weiterhin nichts. (#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)
  • 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)
  • Der Zustand der Anzeige (lastTelemetry.renderer) nennt das Bau-Profil (modern oder legacy). (#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)
  • Beispiele der Vorfassungen je Naht liegen unter packages/contracts/src/samples/protocols/, Tests in TypeScript und Go legen sie den heutigen Lesern vor. (#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)
  • 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)
  • 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)

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)
  • 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)
  • 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)

Added

  • analytics.analyticsExplore.create und .export, analytics.analyticsCatalog.list und analytics.analyticsOverview.list (beta) für Abfrage, Katalog, Ausgabe und Überblick. (#822)
  • analytics.analyticsPlayersDay.list, analytics.analyticsPlayersPlays.list, analytics.analyticsContent.list und .byId, analytics.analyticsCampaignsDelivery.list (beta). (#822)
  • fleet.playersScreenshots.list und fleet.playersScreenshots.byId (beta) lesen die Zeitreihe der Bildschirmaufnahmen eines Displays. (#822)
  • analytics.analyticsProofs (list, byId, interim), analytics.analyticsProofsFiles.byId und analytics.analyticsShareLinks (list, create, remove), alle beta. (#822)
  • analytics.publicProofKeys.list, analytics.publicProofs.verify und analytics.publicCampaignReports (open, proofFile) rufen ohne Anmeldung, alle beta. (#822)
  • advertising.advertisingRevenue.list (beta) liest die Erlösaufstellungen der Organisation, mit Verteilung je Werbekampagne und Verweis auf die Gutschrift. (#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)
  • analytics.publicCampaignReports.open liefert je Nachweis campaignId. (#822)
  • Neues Modul advertising (beta): Werbepartner, Werbekampagnen, Buchungen, Motive, Werbefläche, Publikum, Teilnahme und Stellgrößen. (#822)
  • Standorte tragen venueType, die Art des Ladens. (#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)
  • 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)

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)
  • 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)

Added

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

Changed

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

0.4.0

Brüche

  • GET /v1/audit/bulk/:correlationId entfällt und mit ihm client.audit.auditBulk und das Schema GetBulkActionDetailResponse. (#742)
  • Das Recht audit.bulk.read, die Ereignisart audit.bulk-action.completed und der Fehlercode Internal.AuditBulkActionDetailRepositoryUnavailable entfallen. (#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)
  • 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)
  • 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)
  • 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)
  • 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)
  • 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)
  • @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)
  • 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)
  • Neue Pflege-Routen (Betreiber): GET, POST /v1/platform/app-catalog/collections, PATCH …/collections/{collectionKey}, PUT …/collections/order. (#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)
  • @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)
  • @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)
  • @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)
  • @szenera/client: client.marketplace.apps.list und .get sowie client.me.installedApps sind entfallen, client.me.apps.list({ locale }) liefert die installierten Apps. (#699)
  • @szenera/apps-sdk: defineAppManifest wirft bei einem unvollständigen Übersetzungsblock und nennt die Stelle. (#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)
  • @szenera/cli liest Apps über die Store-Routen, die Befehle bleiben, wie sie sind. (#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)
  • 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)
  • 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)
  • @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)
  • 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)
  • displayAppVersion(pins, installed) in @szenera/contracts/composition rechnet die Fassung eines Displays: die installierte, bei gehaltenen Pins älterer Hauptnummern die niedrigste davon. (#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)
  • @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)
  • 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)
  • GET /v1/apps/{appId}/history nennt je Fassung releaseId, dieselbe Kennung wie an Installation, Nachweis und Update-Entscheidung. (#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)
  • @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)
  • @szenera/client und @szenera/cli bündeln die erweiterten Verträge der Plattform. Ihre Aufrufe und Befehle bleiben, wie sie sind. (#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)
  • 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)
  • @szenera/apps-sdk liest Widget-Definition, Konfigurations-Schema und Manifest aus den Blättern des App-Katalogs statt aus dessen Barrel. (#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)

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)
  • 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)
  • Der Zustand der Anzeige (lastTelemetry.renderer) nennt das Bau-Profil (modern oder legacy). (#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)
  • Beispiele der Vorfassungen je Naht liegen unter packages/contracts/src/samples/protocols/, Tests in TypeScript und Go legen sie den heutigen Lesern vor. (#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)

Ä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)
  • 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)
  • 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)
  • 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)
  • 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)
  • Das Sicherheitsverfahren cookie nennt das Cookie, das es wirklich gibt: refresh_token, gelesen nur von POST /v1/auth/refresh. (#617)
  • Die Beispiele der Spezifikation zeigen Geräte-Adressen aus dem Dokumentationsbereich 192.0.2.0/24. (#617)
  • @szenera/api-client/factory bietet mit createBearerClientWith einen Klienten mit festem Merkmal und frei gewählten Modulen. (#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)
  • 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)
  • @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)
  • Die Kommandozeile nimmt nur noch Schlüssel einer Organisation (ak_…) an und nennt in ihrer Kennung die Fassung aus ihrem eigenen Manifest. (#620)
  • Veröffentlicht ist weiterhin nichts. (#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)
  • Neue Verträge DeviceServiceStatus, RendererServiceStatus und ServiceFinding in @szenera/contracts/fleet. (#628)
  • GET /v1/devices/me liefert deviceName, den Namen aus der Geräteakte. (#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)
  • 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)
  • 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)
  • 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)

0.1.0

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