====== Manifest (plugin.json) ====== Das Manifest ist das Herzstück eines jeden Add-ins. Es ist eine JSON-Datei namens ''plugin.json'', die im Wurzelverzeichnis des [[paketformat|.wvdsx-Pakets]] liegt. Der Host liest dieses Manifest, bevor er die DLL des Add-ins lädt, und verwendet es, um Kompatibilität zu prüfen, Contributions zu registrieren und die Benutzeroberfläche vorzubereiten. Das Manifest dient zwei Zwecken: Es identifiziert das Add-in eindeutig und beschreibt vollständig, was das Add-in zur Shell beiträgt. Alles, was der Host wissen muss, um Menüpunkte, Toolbar-Buttons, Seitenleisten und Tastenkürzel anzuzeigen, steht in dieser Datei. Die DLL wird erst geladen, wenn sie tatsächlich gebraucht wird. Zurück zur [[start|Übersicht]]. ===== Vollständiges Beispiel ===== { "id": "wvds.assets-manager", "name": "assets-manager", "displayName": "Assets Manager", "description": "Verwaltung von Anlagevermögen und Inventar", "version": "1.2.0", "publisher": "wvds", "kind": "native", "main": "bin/AssetsManager.dll", "engineVersion": "^1.0.0", "activationEvents": [ "onCommand:assets.open", "onCommand:assets.list" ], "dependencies": [ { "id": "wvds.core-services", "version": "^1.0.0" } ], "servicesProvided": ["IAssetDataService"], "servicesConsumed": ["IDocumentPrintService"], "permissions": ["fs.read", "fs.write", "net.http"], "dllChecksum": "sha256:a1b2c3d4e5f6...", "contributes": { "commands": [ { "command": "assets.open", "title": "Anlage öffnen", "category": "Assets", "icon": "media/asset-open.svg" }, { "command": "assets.list", "title": "Anlageliste", "category": "Assets", "icon": "media/asset-list.svg" } ], "submenus": [ { "id": "assets", "label": "Assets" } ], "menus": { "menuBar": [ { "submenu": "assets", "group": "modules", "order": 200 } ], "assets": [ { "command": "assets.open", "group": "navigation", "order": 1 }, { "command": "assets.list", "group": "navigation", "order": 2 } ], "commandPalette": [ { "command": "assets.open" }, { "command": "assets.list" } ] }, "toolbar": [ { "toolbarId": "main", "command": "assets.list", "icon": "media/asset-list.svg", "tooltip": "Anlageliste öffnen", "when": "" } ], "keybindings": [ { "command": "assets.list", "key": "Ctrl+Shift+A", "when": "" } ], "views": { "sidebar": [ { "id": "assets.navigator", "name": "Assets-Navigator", "icon": "media/navigator.svg", "containerId": "assets-explorer" } ] }, "viewsWelcome": [ { "viewId": "assets.navigator", "content": "Keine Anlagen vorhanden.\n[Anlage erstellen](command:assets.create)", "when": "!hasAssets", "group": "main", "order": 1 } ], "welcomePage": [ { "title": "Anlagenverwaltung", "icon": "codicon-package", "order": 10, "contents": [ { "label": "Anlageliste öffnen", "command": "assets.list", "icon": "codicon-list-flat" }, { "label": "Neue Anlage erfassen", "command": "assets.create", "icon": "codicon-add" } ] } ], "configuration": { "title": "Assets Manager", "properties": { "assets.defaultCurrency": { "type": "string", "default": "EUR", "description": "Standard-Währung für neue Anlagen" }, "assets.pageSize": { "type": "number", "default": 50, "description": "Anzahl der Einträge pro Seite in der Anlageliste" } } }, "themes": [ { "id": "assets.highlight", "label": "Assets Highlight", "path": "themes/highlight.json", "uiTheme": "wvds-light" } ] } } ===== Felder im Detail ===== ==== Identität ==== | **Feld** | **Typ** | **Pflicht** | **Beschreibung** | | ''id'' | string | ja | Eindeutiger Bezeichner im Format ''publisher.name''. Der Host verwendet diesen Wert, um Add-ins zu unterscheiden, Abhängigkeiten aufzulösen und Berechtigungen zuzuordnen. Einmal veröffentlicht, darf sich die Id nicht mehr ändern. | | ''name'' | string | ja | Kurzname ohne Publisher-Prefix. Wird intern für Dateipfade und Konfigurationsschlüssel verwendet. | | ''displayName'' | string | ja | Anzeigename, den der Benutzer in der Erweiterungsliste und in Benachrichtigungen sieht. Darf Leerzeichen und Sonderzeichen enthalten. | | ''description'' | string | nein | Einzeilige Beschreibung des Add-ins. Erscheint in der Erweiterungsliste unterhalb des Anzeigenamens. | | ''version'' | string | ja | Versionsnummer im SemVer-Format (''MAJOR.MINOR.PATCH''). Der Host verwendet diese Version für Update-Prüfungen und Abhängigkeitsauflösung. | | ''publisher'' | string | ja | Name des Herausgebers. Zusammen mit ''name'' ergibt sich die vollständige Id. | ==== Typ und Einstiegspunkt ==== | **Feld** | **Typ** | **Pflicht** | **Beschreibung** | | ''kind'' | string | nein | Art des Add-ins. Mögliche Werte: ''native'' (Standard, enthält eine DLL), ''script'' (PowerShell-basiert, keine DLL nötig) oder ''theme'' (reines Theme ohne Code). Wenn das Feld fehlt, nimmt der Host ''native'' an. Bei ''script'' verweisen Commands auf ''.ps1''-Dateien statt auf eine DLL — siehe [[sdk:script-host|ScriptHost]]. | | ''main'' | string | ja (bei native) | Relativer Pfad zur DLL innerhalb des Pakets. Der Host löst diesen Pfad relativ zum Installationsverzeichnis des Add-ins auf. Bei ''kind: "script"'' entfällt dieses Feld. | ==== Kompatibilität ==== | **Feld** | **Typ** | **Pflicht** | **Beschreibung** | | ''engineVersion'' | string | nein | SemVer-Constraint für die Host-Version (z.B. ''^1.0.0''). Wenn das Add-in eine Host-Version erfordert, die nicht installiert ist, wird es nicht geladen. Fehlt das Feld, wird keine Prüfung durchgeführt. | ==== Aktivierung ==== | **Feld** | **Typ** | **Pflicht** | **Beschreibung** | | ''activationEvents'' | string[] | ja (bei native) | Liste der Ereignisse, die das Laden der DLL auslösen. | Unterstützte Aktivierungsereignisse: * ''onStartup'' — Das Add-in wird beim Start der Anwendung aktiviert. Sparsam verwenden, da es den Start verlangsamt. * ''onCommand:command.id'' — Das Add-in wird aktiviert, wenn der Benutzer den angegebenen Command zum ersten Mal aufruft. Der Host registriert bis dahin einen Lazy-Stub, der die Aktivierung auslöst. Die Verwendung von ''onCommand:'' ist der bevorzugte Weg, weil das Add-in so erst geladen wird, wenn es tatsächlich gebraucht wird. Das hält den Anwendungsstart schnell und den Speicherverbrauch niedrig. ==== Abhängigkeiten ==== | **Feld** | **Typ** | **Pflicht** | **Beschreibung** | | ''dependencies'' | array | nein | Liste von Add-ins, die vor diesem Add-in aktiviert werden müssen. Jeder Eintrag enthält ''id'' und ''version''. | | ''servicesProvided'' | string[] | nein | Vertragsnamen der Services, die dieses Add-in über die [[sdk:inter-addin|IServiceRegistry]] anbietet. | | ''servicesConsumed'' | string[] | nein | Vertragsnamen der Services, die dieses Add-in von anderen Add-ins benötigt. Der Host stellt sicher, dass anbietende Add-ins zuerst aktiviert werden. | ==== Sicherheit ==== | **Feld** | **Typ** | **Pflicht** | **Beschreibung** | | ''permissions'' | string[] | nein | Liste der Berechtigungen, die das Add-in benötigt. Der Benutzer wird beim ersten Start um Zustimmung gebeten. Details zu den verfügbaren Berechtigungen stehen unter [[sicherheit|Sicherheit]]. | | ''dllChecksum'' | string | nein | SHA256-Prüfsumme der DLL im Format ''sha256:hexwert''. Der Host verifiziert diesen Wert vor dem Laden der DLL. | ===== Contributions ===== Der ''contributes''-Block im Manifest deklariert alles, was das Add-in zur Benutzeroberfläche beiträgt. Jeder Contribution-Typ hat eine eigene Struktur und wird auf einer eigenen Seite ausführlich beschrieben. ==== Commands ==== Commands sind die zentrale Aktionseinheit. Jeder Menüpunkt, jeder Toolbar-Button und jedes Tastenkürzel verweist auf einen Command. Das Manifest deklariert den Command mit Titel, Kategorie und Icon. Der eigentliche Handler wird zur Laufzeit vom Add-in registriert. "commands": [ { "command": "assets.open", "title": "Anlage öffnen", "category": "Assets", "icon": "media/asset-open.svg" } ] | **Feld** | **Beschreibung** | | ''command'' | Eindeutiger Bezeichner des Commands. Konvention: ''addin-name.aktion''. | | ''title'' | Anzeigename in Menüs und der CommandPalette. Kann über [[lokalisierung|NLS]] übersetzt werden. | | ''category'' | Gruppierung in der CommandPalette. Erscheint als Prefix vor dem Titel. | | ''icon'' | Relativer Pfad zu einer SVG- oder PNG-Datei im Paket. | Ausführliche Beschreibung: [[contributions:commands|Commands]]. ==== Menüs und Submenüs ==== Das ''menus''-Objekt ordnet Commands bestimmten Stellen in der Oberfläche zu. Der Schlüssel bestimmt den Ort (''menuBar'', ''commandPalette'', ''view/title'', ''view/item/context''), der Wert ist ein Array von Einträgen. "submenus": [ { "id": "assets", "label": "Assets", "icon": "media/assets.svg" } ], "menus": { "menuBar": [ { "submenu": "assets", "group": "modules", "order": 200 } ], "assets": [ { "command": "assets.open", "group": "navigation", "order": 1, "when": "" } ] } | **Feld** | **Beschreibung** | | ''submenu'' | Referenziert eine Submenu-Id. Erzeugt ein Untermenü an der angegebenen Stelle. | | ''command'' | Referenziert einen Command. Erzeugt einen Menüpunkt, der den Command auslöst. | | ''group'' | Sortiergruppe. Innerhalb eines Menüs werden Gruppen durch Trennstriche getrennt. | | ''order'' | Numerische Priorität innerhalb der Gruppe. Niedrigere Werte stehen weiter oben. | | ''when'' | Kontextausdruck für bedingte Sichtbarkeit (z.B. ''hasActiveDocument && !readOnly''). Leerer String oder fehlendes Feld bedeutet: immer sichtbar. | Ausführliche Beschreibung mit Merge-Verfahren: [[contributions:menus|Menü-Merge]]. ==== Toolbar ==== "toolbar": [ { "toolbarId": "main", "command": "assets.list", "icon": "media/asset-list.svg", "tooltip": "Anlageliste öffnen", "when": "" } ] Ausführliche Beschreibung: [[contributions:toolbar|Toolbar]]. ==== Views (Seitenleiste) ==== "views": { "sidebar": [ { "id": "assets.navigator", "name": "Assets-Navigator", "icon": "media/navigator.svg", "containerId": "assets-explorer" } ] } Views mit demselben ''containerId'' werden vom Host in einem Accordion gruppiert. Das erlaubt mehreren Add-ins, verwandte Panels in einer gemeinsamen Seitenleisten-Gruppe anzuzeigen. Ausführliche Beschreibung: [[contributions:sidebarviews|Sidebar-Views]]. ==== Keybindings ==== "keybindings": [ { "command": "assets.list", "key": "Ctrl+Shift+A", "mac": "Cmd+Shift+A", "when": "" } ] Ausführliche Beschreibung: [[contributions:keybindings|Keybindings]]. ==== Configuration ==== "configuration": { "title": "Assets Manager", "properties": { "assets.defaultCurrency": { "type": "string", "default": "EUR", "description": "Standard-Währung für neue Anlagen" } } } Konfigurationswerte werden in der mehrstufigen Konfigurationshierarchie des Hosts gespeichert: Standardwerte aus dem Manifest, Benutzer-Einstellungen, Workspace-Einstellungen und Laufzeit-Überschreibungen. Das Add-in liest sie über ''IHost.Configuration''. ==== Themes ==== "themes": [ { "id": "assets.highlight", "label": "Assets Highlight", "path": "themes/highlight.json", "uiTheme": "wvds-light" } ] Theme-Contributions werden beim Start registriert und stehen dem Benutzer in der Theme-Auswahl zur Verfügung. Die Theme-Datei enthält Farbdefinitionen nach dem [[skin-contract|Skin-Vertrag]]. ==== ViewsWelcome ==== "viewsWelcome": [ { "viewId": "assets.navigator", "content": "Keine Anlagen vorhanden.\n[Anlage erstellen](command:assets.create)", "when": "!hasAssets", "group": "main", "order": 1 } ] Welcome-Inhalte werden in leeren Views angezeigt, solange keine Daten vorhanden sind. Der ''content'' unterstützt Markdown-Links im Format ''[Text](command:command.id)'', die beim Klick den referenzierten Command auslösen. ==== WelcomePage ==== "welcomePage": [ { "title": "WIS Prüfungen", "icon": "codicon-shield", "order": 10, "contents": [ { "label": "Prüfungen ausführen", "command": "wis.proofExec.open", "icon": "codicon-checklist" }, { "label": "Prüfungen planen", "command": "wis.proofPlan.open", "icon": "codicon-calendar" } ] } ] WelcomePage-Sektionen erscheinen auf der zentralen Willkommensseite unterhalb der eingebauten Quick Links. Jede Sektion besteht aus einer Überschrift und einer Liste von Command-Links. Mehrere Add-ins liefern ihre Sektionen unabhängig — der Host sortiert sie nach ''order'' und rendert sie als HTML-Blöcke. Im Unterschied zu ''viewsWelcome'' (oben) adressiert ''welcomePage'' den zentralen Welcome-Tab im Dokumentbereich, nicht einzelne Sidebar-Views. Ausführliche Beschreibung: [[contributions:welcomepage|Welcome-Page Sections]]. ===== NLS-Übersetzung ===== Alle Texte im Manifest können über NLS-Platzhalter übersetzt werden. Dazu wird der Textwert durch ''%schlüssel%'' ersetzt und der tatsächliche Text in einer separaten Datei bereitgestellt. Details dazu stehen unter [[lokalisierung|Lokalisierung]]. Weiter zu [[paketformat|Paketformat]] oder zurück zur [[start|Übersicht]].