Zum Inhalt

Kommandozeile

Das Tool coworkee legt eine Coworkee-Anwendung aus dem Paket Coworkee.Templates an, mit den Modulen, dem Branding und den Entities Ihrer Wahl, und übernimmt die alltäglichen Befehle: starten, Migrationen, neue Module und Entities, Paket-Updates. Außerdem startet es einen MCP-Server für KI-Agenten und öffnet Coworkee Studio, einen Desktop-Assistenten.

Installation

dotnet tool install -g Coworkee.Cli
coworkee doctor

coworkee doctor prüft das .NET SDK (mindestens die Version aus global.json), ob Docker läuft und ob dotnet-ef installiert ist. Die Aspire-CLI ist optional; coworkee run nutzt dotnet run.

Eine neue Anwendung

coworkee new Shop
cd Shop
coworkee run

coworkee new installiert Coworkee.Templates in der Version des Tools, legt die Solution an, erzeugt die Module einer Spezifikation, stellt die Pakete wieder her und legt die Migration an, die die gewählten Module brauchen. Die erzeugte App verweist auf die Coworkee-Pakete genau dieser Version. Der Name muss einfach sein: ein Buchstabe, dann Buchstaben oder Ziffern (Shop, Crm2). Er wird zum Präfix aller Projekte und Namespaces.

Der Migrations-Worker legt einen Administrator admin@<name>.local und die Benutzer von --user oder der Spezifikation an. Am Ende zeigt coworkee new einen Kasten Sign in mit jedem Benutzer, seinem Passwort und seinen Rollen; dieselbe Tabelle steht in LOGIN.md der Solution. Mit Keycloak hat der Realm dieselben Benutzer mit denselben Passwörtern.

coworkee new Shop --keycloak --user "ada@shop.test:Product Manager" --user boss@shop.test:admin

--user nimmt email[:rolle,rolle][:admin] und lässt sich wiederholen; das Passwort wird erzeugt. Die Benutzer stehen in src/<Name>.Migrations/DemoUsers.cs, das der Seed und der AppHost (für Keycloak) beide lesen. Die Passwörter sind nur für die Entwicklung: Ändern Sie sie, bevor Sie irgendwohin deployen.

Optionen

Jede Option ist ein Schalter von coworkee new und, unter ihrer Id, ein Schlüssel in den options einer Spezifikation. coworkee options zeigt sie mit den Gründen, sie zu wählen, coworkee options --json als Daten.

coworkee new Shop --no-samples --chat false --files --event-bus rabbitMq \
  --theme Forest --primary-color "#0a7d5a" --logo ./brand/logo.svg \
  --sign-in-layout Split --sign-in-media ./brand/welcome.mp4 --git
Schalter Id Werte Standard
-o, --output Ordner ./<name> Zielordner
--spec Datei Legt die App aus einer Spezifikation an, siehe unten; Schalter gewinnen gegen die Spezifikation
--template-source Datei oder Ordner nuget.org Template aus einer .nupkg oder einem Ordner installieren, offline oder für einen lokalen Build
--title title Text der Name Anzeigetitel im Browser, in der App-Leiste, auf den Anmeldeseiten und im Aspire-Dashboard
--samples, --no-samples samples bool true Module Catalog (Produkte, Marken, Dashboard) und Documents mit Seiten, Tests und Demodaten
--tests, --no-tests tests bool true API-, Migrations-, App-Host- und Seitentests
--git git bool false git init im neuen Ordner
--auditing auditing bool true Seiten für Audit-Log, Verlauf und Wiederherstellen; das Protokoll selbst wird immer geschrieben
--notifications notifications bool true Benachrichtigungen in der App mit Sammel-Mails
--chat chat bool true Direkt- und Gruppenchat
--ai ai bool true KI-Assistent, MCP-Endpunkt der App und Protokoll der Tool-Aufrufe
--backup backup bool true Datenbank-Backups aus den Admin-Seiten
--files files bool false Ordner und Dateien mit Vorschau und Rechten pro Ordner
--features features bool false Features, Editionen und die Mandantenverwaltung
--social social bool false Kommentare, Tags und Bewertungen
--extended-attributes extendedAttributes bool false Schlüssel/Wert-Attribute für beliebige Entities (das Documents-Beispiel bringt sie ohnehin mit)
--elasticsearch elasticsearch bool false Elasticsearch-Index; der App-Host ergänzt den Container
--event-bus eventBus none, inProcess, rabbitMq none Integrationsereignisse über die Outbox; rabbitMq ergänzt den Transport und einen RabbitMQ-Container
--client-entities clientEntities bool false Browser-Kopien von OData-Sets mit [ClientEntity]; Entities der Spezifikation mit clientEntity schalten es ein
--keycloak keycloak bool false Keycloak-Container als externe Anmeldung
--storage storage fileSystem, azureBlob fileSystem Blob-Speicher; azureBlob startet Azurite im App-Host
--ai-provider aiProvider anthropic, openAI, azureOpenAI, ollama, openAICompatible anthropic Modellanbieter des Assistenten; ollama startet Ollama im App-Host
--redis redis bool true Redis-Container für Backplane, Anwesenheit, Cache-Invalidierung und Sitzungen über Instanzen hinweg (Redis)
--grafana grafana bool true Grafana mit Prometheus, Loki, Tempo und Collector: Telemetrie jedes Dienstes, die App-Datenbank und Dashboards (Grafana und WebDataStudio)
--web-data-studio webDataStudio bool true WebDataStudio, verbunden mit der App-Datenbank (Grafana und WebDataStudio)
--database database postgres, sqlServer, sqlite postgres Datenbank-Engine, siehe Datenbank-Provider; sqlServer startet einen SQL-Server-Container, sqlite eine Datei ohne Container. Sicherungen brauchen postgres
--theme theme Ocean, Coworkee, Classic, Forest, Midnight, Sunset, HighContrast Ocean Standard-Theme
--primary-color primaryColor #rrggbb Markenfarbe: Die App bekommt ein eigenes Theme auf Basis von --theme, benannt wie der Titel, als Standard
--secondary-color secondaryColor #rrggbb Zweite Markenfarbe
--logo logo Datei Coworkee-Symbol Wird in den Web-Client kopiert; App-Leiste, Browser-Tab und Anmeldeseiten
--sign-in-layout signInLayout Card, Split, Slide Slide Layout der Anmeldeseiten
--sign-in-media signInMedia Datei oder http(s)-Adresse Bild oder Video neben dem Anmeldeformular; eine Datei wird nach wwwroot/media des Web-Clients kopiert
--sign-in-media-side signInMediaSide Left, Right Left Seite des Mediums
--mapping mapping manual, mapperly manual DTO-Mapping erzeugter Entities, siehe DTOs und Mapping
--languages languages en, de, durch Kommas getrennt (in einer Spezifikation ein Array) alle mitgelieferten Sprachen von Anfang an, aus denen, für die die Bibliothek Texte mitbringt; weitere fügen Administratoren auf der Seite Sprachen hinzu
--default-language defaultLanguage en, de en Sprache der Benutzer, die keine gewählt haben; muss unter languages sein
--color-mode colorMode system, light, dark system Standard-Farbmodus, angelegt als systemweite Einstellung Theme.Mode
--registration registration bool true Selbstregistrierung auf der Anmeldeseite, angelegt als Einstellung Account.AllowRegistration
--github-actions githubActions bool false .github/workflows/ci.yml: Build und Tests bei jedem Push und Pull Request
--devcontainer devcontainer bool false .devcontainer/devcontainer.json mit dem .NET SDK und Docker in Docker (Codespaces, VS Code)

Ein bool-Schalter ohne Wert bedeutet true (--files), --chat false schaltet aus. Die mitgelieferte erste Migration deckt die Standardmodule ab (mit oder ohne Beispiele). Schalten Sie ein Modul mit Tabellen ein oder aus (Chat, KI, Backup, Benachrichtigungen, Dateien, Features, Social, Event-Bus, erweiterte Attribute ohne Beispiele) oder wählen eine andere Datenbank als postgres, lässt das Template die Migration weg und coworkee new legt nach dem Restore Initial mit dotnet ef an. Mit reinem dotnet new führen Sie coworkee migrations add Initial einmal selbst aus.

App-Spezifikationen

Eine Spezifikation beschreibt die ganze App als JSON: Name, Optionen, Branding und Feature-Module mit ihren Entities. Coworkee Studio und der MCP-Server arbeiten mit diesem Format.

coworkee spec example > shop.json    # ein vollständiges Beispiel
coworkee spec schema > spec.schema.json
coworkee spec validate shop.json
coworkee new --spec shop.json
shop.json
{
  "name": "Shop",
  "output": "shop",
  "options": { "samples": false, "chat": false, "files": true, "mapping": "manual", "languages": [ "en", "de" ], "defaultLanguage": "de" },
  "branding": {
    "title": "Acme Shop",
    "theme": "Forest",
    "primaryColor": "#0a7d5a",
    "logo": "brand/logo.svg",
    "signInLayout": "Split",
    "signInMedia": "brand/welcome.mp4"
  },
  "modules": [
    {
      "name": "Sales",
      "entities": [
        {
          "name": "Customer",
          "properties": [
            { "name": "Name", "required": true, "maxLength": 200, "display": true },
            { "name": "Email", "type": "email", "unique": true },
            { "name": "IsActive", "type": "bool", "default": "true", "facet": true }
          ]
        },
        {
          "name": "Order",
          "clientEntity": true,
          "mapping": "mapperly",
          "properties": [
            { "name": "Number", "required": true, "maxLength": 50, "unique": true },
            { "name": "Customer", "type": "reference", "reference": "Customer", "required": true, "inverse": "Orders", "facet": true },
            { "name": "Status", "type": "enum", "enum": "OrderStatus", "required": true, "default": "Open", "facet": true },
            { "name": "Total", "type": "money", "required": true },
            { "name": "OrderedOn", "type": "dateOnly", "label": "Order date" },
            { "name": "Note", "type": "text" }
          ]
        }
      ]
    }
  ],
  "enums": [ { "name": "OrderStatus", "values": [ "Open", "Paid", "Shipped" ] } ]
}
  • options nimmt die Ids aus der Tabelle oben; branding nimmt title, theme, primaryColor, secondaryColor, logo, signInLayout, signInMedia und signInMediaSide und gewinnt gegen dieselben Ids in options.
  • Dateien und output sind relativ zur Spezifikation und müssen in ihrem Ordner bleiben (keine absoluten Pfade, kein ..). Ein Logo ist ein Bild (svg, png, jpg, jpeg, webp, gif, ico), das Anmeldemedium ein Bild, ein Video (mp4, webm, ogg) oder eine http(s)-Adresse: Beide liegen danach öffentlich im Web-Client. Eine als Schalter angegebene Datei (--logo C:\brand\logo.svg) darf überall liegen. Kommentare und abschließende Kommas sind erlaubt.
  • Der Titel landet unverändert in Code und HTML und darf daher kein ", \, <, >, @ und keine Steuerzeichen enthalten.
  • Typen der Eigenschaften: string, int, long, decimal, double, bool, dateTime (DateTimeOffset), guid, dateOnly, timeOnly, text (langer Text, mehrzeilig im Formular, keine Listenspalte), email und url (Strings mit Prüfung, 256 und 2000 Zeichen, sofern maxLength nichts anderes sagt), money (Decimal mit precision 18 und scale 2, sofern nicht angegeben), enum und reference. Eine Eigenschaft ohne required ist nullable; maxLength gilt für Strings, E-Mails und URLs, precision und scale für Decimal und Money.
  • enum nennt einen Eintrag aus enums (Werte in ihrer Reihenfolge, der erste ist der Standard). Das Enum landet in den Contracts, reist in JSON und OData mit seinem Namen und erscheint mit seinen Namen in Liste, Formular und Facetten.
  • reference verweist auf eine andere Entity über ihren Namen (Customer) oder mit Modul (Crm.Customer): die Eigenschaft ist die Navigation, <Name>Id der Fremdschlüssel. referenceDisplay ist die Texteigenschaft des Ziels, die Liste und Auswahl zeigen (Standard: seine Anzeige-Eigenschaft), onDelete ist restrict (Standard), cascade oder setNull (nur für optionale Referenzen), inverse gibt dem Ziel eine Sammlung (nur im selben Modul). Ein Modul darf andere Module referenzieren, solange keines zurückverweist.
  • default setzt den Anfangswert von Zahlen, Bools, Enums und Texten; unique legt einen eindeutigen Index je Mandant und eine Prüfung im Command an; label ist die Beschriftung von Spalte und Feld; display markiert den Text, der eine Zeile benennt; searchable (Standard: true für Texte) nimmt sie ins Suchfeld; facet bietet sie als Facette neben der Liste an (Bools, Enums, Referenzen, ganze Zahlen, Strings).
  • plural benennt Tabelle, OData-Set, Route und Seite (Standard: ein englischer Plural des Namens). mapping übersteuert die Option mapping.

Benutzer und Rollen

"roles": [ { "name": "Sales", "description": "Takes orders", "permissions": [ "Sales.Customers.View", "Sales.Orders.View", "Sales.Orders.Create", "Sales.Orders.Edit" ] } ],
"users": [
  { "email": "ada@shop.test", "displayName": "Ada Lovelace", "roles": [ "Sales" ] },
  { "email": "grace@shop.test", "roles": [ "User" ], "admin": true, "password": "Grace-2026!" }
]
  • roles werden neben den eigenen Rollen der Vorlage angelegt (mit Beispielen Product Manager und Brand Manager, ohne User). Die Berechtigungen müssen zur App gehören: die der gewählten Module (Identity.Users.View, Chat.Use, Reports.View, ...), der Beispiele und <Modul>.<Plural>.View|Create|Edit|Delete der Entities der Spezifikation; die Prüfung zählt sie auf.
  • users brauchen eine E-Mail; displayName ist ohne Angabe der Teil vor @, roles nennt Rollen der Spezifikation oder der Vorlage, admin gibt alle Berechtigungen. Ohne password wird eines erzeugt; ein angegebenes braucht 8 Zeichen mit Groß- und Kleinbuchstaben, einer Ziffer und einem Sonderzeichen.

coworkee spec validate und coworkee new melden jedes Problem mit seinem Pfad, zum Beispiel modules[0].entities[1].properties[0].name: 'Id' is taken by the entity itself.

Module und Entities

Jedes Modul einer Spezifikation, und coworkee module add, legt das Projekt src/<App>.<Modul> so an, wie Das erste Feature die Marken baut. Pro Entity:

Wo Was
Contracts <Entity>Dto, AddEdit<Entity>Request, <Modul>Permissions.<Plural> (ansehen, anlegen, bearbeiten, löschen)
Modul Entity (AuditedEntity, IMultiTenant, [Realtime], auf Wunsch [ClientEntity], [ProvideFacet] an Facetten), Tabelle mit Maximallängen, Genauigkeiten, Fremdschlüsseln mit Löschverhalten und eindeutigen Indizes, Rechtedefinitionen, OData-Set, Anlegen/Bearbeiten-Command mit Rechteprüfung, Prüfung referenzierter Zeilen, Eindeutigkeitsprüfung und Validator (Pflicht, Längen, E-Mails, URLs, Enums), Lösch-Command, Mapping (ToDto-Methode oder Mapperly-Mapper; eine Referenz bringt Id und Anzeigetext ihres Ziels mit), Endpunkte POST, PUT /{id} und POST /delete unter /api/v1/<plural>
Contracts, einmal je Enum Enums/<Enum>.cs, mit Namen serialisiert
Web-Client Seite /<modul>/<plural> mit Datentabelle (Referenzen erweitert und mit ihrem Text angezeigt, Geldbeträge formatiert), Anlegen, Bearbeiten (Auswahlfelder für Referenzen, mehrzeilig für langen Text) und Löschen, Live-Aktualisierung, API-Client und einem Navigationseintrag in der Gruppe des Moduls

Das Modul kommt in die .slnx, das Infrastrukturprojekt verweist darauf und <App>DatabaseModule hängt davon ab; Program.cs des Web-Clients registriert die API-Clients und Navigationseinträge.

coworkee module add Sales --entity Order --property Number:string:required:50:unique --property Total:money --client-entity
coworkee entity add Sales Invoice -p Number:required:30 -p Order:ref=Order:required:onDelete=cascade -p Status:enum=InvoiceStatus:default=Open:facet \
  --enum InvoiceStatus=Open,Paid --mapping Mapperly
coworkee entity add Sales Delivery -p Name:required:100 -p Carrier:ref=Logistics.Carrier
coworkee migrations add AddSales

--property liest Name[:typ][:required][:maxLänge][:flag][:schlüssel=wert] (Standard: Name:string:required:200). Flags: required, unique, display, facet, searchable. Schlüssel wie in einer Spezifikation: enum, ref (oder reference), referenceDisplay, onDelete, inverse, default, label, precision, scale, searchable. --enum Name=Wert1,Wert2 legt ein Enum in den Contracts an. Eine Referenz darf auf jede Entity der App mit OData-Set zeigen, erzeugt oder aus den Beispielen (ref=Catalog.Brand); das Modul verweist dann auf das Projekt des Ziels. entity add braucht ein von der CLI angelegtes Modul.

Coworkee Studio

coworkee ui
coworkee ui --spec shop.json

coworkee ui startet Coworkee Studio, einen Desktop-Assistenten für Name, Titel, Logo, Farben, Module, Anmeldedesign, Theme und Entities; er legt die App mit dieser CLI an. Das Studio ist das globale Tool Coworkee.Studio (Befehl coworkee-ui): coworkee ui installiert es in der Version der CLI, wenn es fehlt, und aktualisiert es, wenn es älter ist. Weitere Argumente gehen an das Studio, siehe Coworkee Studio. Für lokale Builds: --prerelease, --add-source <ordner> und --studio-version <version>; eine ausdrücklich genannte Version, die älter als die installierte ist, wird ebenfalls installiert. --prerelease nimmt die neueste Vorabversion statt der Version der CLI und entfällt neben --studio-version.

Weitere Befehle

Befehl Was er tut
coworkee run Startet das *.AppHost-Projekt der Solution
coworkee migrations add <name> dotnet ef migrations add <name> mit dem *.Infrastructure-Projekt als Projekt und Startprojekt
coworkee module add <name> Ein Feature-Modul mit seiner ersten Entity, siehe oben
coworkee entity add <modul> <name> Eine weitere Entity in einem Modul, siehe oben
coworkee options [--json] Die Optionen von coworkee new
coworkee spec schema, example, validate <datei> App-Spezifikationen
coworkee update [--version <version>] [--prerelease] Setzt <CoworkeeVersion> in Directory.Packages.props, standardmäßig auf die neueste Version auf nuget.org
coworkee doctor Prüft die Werkzeuge, siehe oben
coworkee ui Coworkee Studio
coworkee mcp MCP-Server über stdio

Nach coworkee update führen Sie dotnet restore aus und legen eine Migration an, falls ein Coworkee-Modul sein Modell geändert hat (coworkee migrations add CoworkeeUpdate).

Ausgabe für Werkzeuge

coworkee new schreibt vor jedem Schritt eine Zeile ==> <schritt> (Template installieren, Solution anlegen, Modul erzeugen, Restore, Migration anlegen, Git), vor jedem Befehl, den es ausführt, > <befehl>, und endet mit einem Code ungleich 0, wenn ein Schritt scheitert. Probleme mit der Eingabe stehen einzeln pro Zeile auf stderr.

Ohne das Tool

Das Template funktioniert auch mit reinem dotnet new; die Schalter heißen wie die Ids der Tabelle (--eventBus, --primaryColor, ...):

dotnet new install Coworkee.Templates
dotnet new coworkee -n Shop --samples false --keycloak true --title "My Shop" --theme Sunset
dotnet run --project Shop/src/Shop.AppHost

dotnet new coworkee --help listet sie auf. Kopieren Sie ein Logo selbst nach src/<Name>.Web.Client/wwwroot, bevor Sie --logo <dateiname> angeben.