Pack-Format
Überblick
Abschnitt betitelt „Überblick“Eine .gtpack-Datei ist ein signiertes Archiv, das Flows, Komponenten und Assets für Greentic enthält.
Dateistruktur
Abschnitt betitelt „Dateistruktur“my-feature.gtpack├── manifest.cbor # Pack metadata (CBOR encoded)├── flows/ # Flow definitions│ ├── main.ygtc│ └── helper.ygtc├── components/ # WASM components│ └── processor.wasm├── assets/ # Static assets│ ├── templates/│ └── cards/├── sbom.json # Software Bill of Materials└── signature.sig # Ed25519 signatureManifest-Schema
Abschnitt betitelt „Manifest-Schema“Die Datei manifest.cbor enthält Pack-Metadaten im CBOR-Format:
struct PackManifest { name: String, version: String, description: Option<String>, authors: Vec<String>, capabilities: Capabilities, flows: HashMap<String, FlowEntry>, components: HashMap<String, ComponentEntry>, assets: HashMap<String, AssetEntry>, dependencies: HashMap<String, VersionReq>, secrets: SecretsConfig, created_at: u64, content_hash: String,}
struct Capabilities { id: String, provides: Vec<String>,}
struct FlowEntry { path: String, hash: String,}
struct ComponentEntry { path: String, hash: String, interface: Option<String>,}
struct AssetEntry { path: String, hash: String,}
struct SecretsConfig { required: Vec<String>, optional: Vec<String>,}pack.toml-Spezifikation
Abschnitt betitelt „pack.toml-Spezifikation“Vollständiges Schema
Abschnitt betitelt „Vollständiges Schema“[pack]name = "my-feature"version = "1.0.0"description = "Feature description"authors = ["Name <email>"]license = "MIT"repository = "https://github.com/org/repo"homepage = "https://example.com"readme = "README.md"
[capabilities]id = "greentic.cap.app.v1"provides = ["feature-name"]
[dependencies]greentic-templates = "^0.4"greentic-llm-openai = "^0.4"
[flows]main = "flows/main.ygtc"setup = "flows/setup.ygtc"# key = path
[components]processor = "components/processor.wasm"# key = path
[assets]templates = "assets/templates/"cards = "assets/cards/"# key = directory
[secrets]required = ["api_key", "bot_token"]optional = ["webhook_secret"]
[config]# Default configuration valuesdefault_model = "gpt-4"max_retries = 3Capability-IDs
Abschnitt betitelt „Capability-IDs“Standard-Capability-Identifikatoren:
| Capability ID | Zweck |
|---|---|
greentic.cap.app.v1 | Application-Pack |
greentic.cap.messaging.provider.v1 | Messaging-Provider |
greentic.cap.events.provider.v1 | Events-Provider |
greentic.cap.component.v1 | Wiederverwendbare Komponente |
greentic.cap.tool.v1 | MCP-Tool |
Content-Hashing
Abschnitt betitelt „Content-Hashing“Alle Pack-Inhalte werden mit BLAKE3 gehasht:
content_hash = blake3( flows_hash || components_hash || assets_hash)
flows_hash = blake3( flow1_hash || flow2_hash || ...)Signaturformat
Abschnitt betitelt „Signaturformat“Packs werden mit Ed25519 signiert:
signature.sig:- Algorithm: Ed25519- Message: content_hash- Format: Raw 64-byte signatureVerifizierung:
let public_key = load_public_key("publisher.pub");let signature = pack.read_signature();let content_hash = pack.compute_content_hash();
verify(&public_key, content_hash, signature)?;SBOM-Format
Abschnitt betitelt „SBOM-Format“Software Bill of Materials im SPDX-JSON-Format:
{ "spdxVersion": "SPDX-2.3", "dataLicense": "CC0-1.0", "SPDXID": "SPDXRef-DOCUMENT", "name": "my-feature-sbom", "packages": [ { "name": "my-feature", "version": "1.0.0", "downloadLocation": "https://example.com" } ], "relationships": []}Komprimierung
Abschnitt betitelt „Komprimierung“Pack-Inhalte werden mit zstd auf Level 3 komprimiert:
let compressed = zstd::encode_all(contents, 3)?;Versionskompatibilität
Abschnitt betitelt „Versionskompatibilität“Die Version des Pack-Formats wird im Manifest gespeichert:
struct PackManifest { pack_format_version: u32, // Currently: 1 // ...}Laden von Packs
Abschnitt betitelt „Laden von Packs“Prozess zum Laden eines Packs zur Laufzeit:
- Archiv entpacken - zstd dekomprimieren
- Manifest parsen - CBOR-Metadaten dekodieren
- Signatur verifizieren - Ed25519-Signatur prüfen
- Hashes validieren - Integrität des Inhalts verifizieren
- Capabilities prüfen - Kompatible Capability sicherstellen
- Flows laden - YAML-Flow-Definitionen parsen
- Komponenten instanziieren - WASM-Module laden
- Registrieren - Zur Runtime-Registry hinzufügen
Aufteilung von Komponentenoperationen
Abschnitt betitelt „Aufteilung von Komponentenoperationen“Wenn Flows auf eine WASM-Komponente mit einer Operation verweisen, z. B. component-templates.render, speichert der Pack-Compiler im Manifest den vollständigen String "component-id.operation" als einzelne Komponenten-ID. Zur Laufzeit teilt der Loader diesen Wert am letzten Punkt, um die Komponenten-ID und den Operationsnamen getrennt zu extrahieren.
Zum Beispiel bei einem Flow-Knoten, der auf component-templates.render verweist:
- Im Manifest gespeichert:
"component-templates.render"(einzelner Schlüssel) - Runtime-Auflösung: wird in die Komponente
component-templatesund die Operationrenderaufgeteilt
Diese Aufteilungsstrategie verwendet den letzten Punkt als Trennzeichen. Dadurch können Komponenten-IDs selbst Punkte enthalten, ohne Mehrdeutigkeit zu erzeugen. Die Runtime sucht die Komponente dann anhand ihrer extrahierten ID und ruft die angegebene Operation auf dem geladenen WASM-Modul auf.
Manifest key Component ID Operation───────────────────────────────── ─────────────────────── ──────────component-templates.render → component-templates rendercomponent-llm-openai.chat → component-llm-openai chatorg.custom.my-tool.execute → org.custom.my-tool executeDieses Verhalten ist für Flow-Autoren transparent. Flows verweisen in der Knotenkonfiguration einfach auf component-id.operation, und der Pack-Compiler sowie die Runtime übernehmen den Rest.
CLI-Referenz
Abschnitt betitelt „CLI-Referenz“# Build packgreentic-pack build ./my-pack --output my-feature.gtpack
# Sign packgreentic-pack sign my-feature.gtpack --key signing-key.pem
# Verify packgreentic-pack verify my-feature.gtpack --pubkey publisher.pub
# Inspect packgreentic-pack info my-feature.gtpack