diff --git a/astro.config.mjs b/astro.config.mjs index 48cb578..eaeee30 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -172,6 +172,9 @@ export default defineConfig({ label: 'Reference', items: [ { label: 'Flow YAML Schema', slug: 'reference/flow-schema' }, + { label: 'Flow Node Kinds', slug: 'reference/flow-node-kinds' }, + { label: 'Channel Data Access', slug: 'reference/channel-data-access' }, + { label: 'Secret Seeding', slug: 'reference/secret-seeding' }, { label: 'Pack Format', slug: 'reference/pack-format' }, { label: 'WIT Interfaces', slug: 'reference/wit-interfaces' }, { label: 'Configuration', slug: 'reference/configuration' }, diff --git a/src/content/docs/components/cards2pack.mdx b/src/content/docs/components/cards2pack.mdx index 1900c29..d03cbd1 100644 --- a/src/content/docs/components/cards2pack.mdx +++ b/src/content/docs/components/cards2pack.mdx @@ -14,6 +14,18 @@ import { Aside, Steps } from '@astrojs/starlight/components'; - Auto-translates cards via `greentic-i18n-translator` - Packages everything into a deployable `.gtpack` + + ## Installation ```bash diff --git a/src/content/docs/de/components/cards2pack.mdx b/src/content/docs/de/components/cards2pack.mdx index 89284f4..d03cbd1 100644 --- a/src/content/docs/de/components/cards2pack.mdx +++ b/src/content/docs/de/components/cards2pack.mdx @@ -1,18 +1,30 @@ --- title: cards2pack -description: Adaptive Cards in Greentic-Packs umwandeln +description: Convert Adaptive Cards to Greentic packs --- import { Aside, Steps } from '@astrojs/starlight/components'; -## Überblick +## Overview -**cards2pack** ist ein CLI-Tool, das Adaptive-Card-JSON-Dateien in Greentic-Packs umwandelt. Es: +**cards2pack** is a CLI tool that converts Adaptive Card JSON files into Greentic packs. It: -- Scannt Karten, erstellt einen Abhängigkeitsgraphen und generiert `.ygtc`-Flows -- Extrahiert übersetzbare Zeichenketten für i18n -- Übersetzt Karten automatisch über `greentic-i18n-translator` -- Verpackt alles in ein bereitstellbares `.gtpack` +- Scans cards, builds a dependency graph, generates `.ygtc` flows +- Extracts translatable strings for i18n +- Auto-translates cards via `greentic-i18n-translator` +- Packages everything into a deployable `.gtpack` + + ## Installation @@ -20,18 +32,18 @@ import { Aside, Steps } from '@astrojs/starlight/components'; cargo install greentic-cards2pack ``` -Erforderliche Tools: +Required tools: ```bash cargo install greentic-flow greentic-pack cargo install greentic-i18n-translator # optional, for --auto-translate ``` -## Schnellstart +## Quick Start -1. **Adaptive Cards erstellen** +1. **Create Adaptive Cards** ```json title="cards/welcome.json" { @@ -51,7 +63,7 @@ cargo install greentic-i18n-translator # optional, for --auto-translate } ``` -2. **Pack generieren** +2. **Generate pack** ```bash greentic-cards2pack generate \ @@ -60,7 +72,7 @@ cargo install greentic-i18n-translator # optional, for --auto-translate --name my-pack ``` -3. **Ausgabe** +3. **Output** ``` my-pack/ @@ -73,61 +85,61 @@ cargo install greentic-i18n-translator # optional, for --auto-translate -## CLI-Referenz +## CLI Reference ### `generate` -Hauptbefehl: Karten scannen, Flows generieren, Pack bauen. +Main command — scan cards, generate flows, build pack. ```bash greentic-cards2pack generate [OPTIONS] ``` -| Flag | Beschreibung | +| Flag | Description | |------|-------------| -| `--cards ` | Verzeichnis mit Adaptive-Card-JSON-Dateien (erforderlich) | -| `--out ` | Ausgabeverzeichnis für den Workspace (erforderlich) | -| `--name ` | Pack-Name (erforderlich) | -| `--strict` | Fehler bei fehlenden Zielen, Duplikaten und ungültigem JSON | -| `--group-by ` | Flow-Gruppierung: `folder` oder `flow-field` | -| `--default-flow ` | Standard-Flow-Name für nicht gruppierte Karten | -| `--prompt` | Prompt-basierte Weiterleitung aktivieren (fügt `prompt2flow`-Knoten hinzu) | -| `--prompt-json ` | Answers-JSON für Prompt-Weiterleitung (erfordert `--prompt`) | -| `--auto-translate` | Karten automatisch mit bis zu 8 parallelen Threads übersetzen (erfordert `greentic-i18n-translator`) | -| `--langs ` | Kommagetrennte Sprachcodes; weglassen, um in alle über 65 unterstützten Locale-Varianten zu übersetzen | -| `--glossary ` | Glossar-JSON für konsistente Übersetzungen | -| `--verbose` | Detaillierte Ausgabe ausgeben | +| `--cards ` | Directory of Adaptive Card JSON files (required) | +| `--out ` | Output workspace directory (required) | +| `--name ` | Pack name (required) | +| `--strict` | Errors on missing targets, duplicates, invalid JSON | +| `--group-by ` | Flow grouping: `folder` or `flow-field` | +| `--default-flow ` | Default flow name for ungrouped cards | +| `--prompt` | Enable prompt-based routing (adds `prompt2flow` node) | +| `--prompt-json ` | Answers JSON for prompt routing (requires `--prompt`) | +| `--auto-translate` | Auto-translate cards with up to 8 parallel threads (requires `greentic-i18n-translator`) | +| `--langs ` | Comma-separated language codes; omit to translate to all 65+ supported locales | +| `--glossary ` | Glossary JSON for consistent translations | +| `--verbose` | Print detailed output | ### `extract-i18n` -Übersetzbare Zeichenketten aus Karten in ein JSON-Bundle extrahieren. +Extract translatable strings from cards into a JSON bundle. ```bash greentic-cards2pack extract-i18n [OPTIONS] ``` -| Flag | Beschreibung | +| Flag | Description | |------|-------------| -| `--input ` | Verzeichnis mit Karten-JSON-Dateien (erforderlich) | -| `--output ` | Ausgabe-JSON-Pfad (Standard: `i18n/en.json`) | -| `--prefix ` | Schlüsselpräfix (Standard: `card`) | -| `--include-existing` | Zeichenketten einschließen, die bereits `$t()`-Muster enthalten | -| `--verbose` | Extraktionsbericht ausgeben | +| `--input ` | Directory of card JSON files (required) | +| `--output ` | Output JSON path (default: `i18n/en.json`) | +| `--prefix ` | Key prefix (default: `card`) | +| `--include-existing` | Include strings that already contain `$t()` patterns | +| `--verbose` | Print extraction report | -## Kartenidentifikation +## Card Identification -Karten werden identifiziert über (in dieser Prioritätsreihenfolge): -1. Das Feld `greentic.cardId` im Karten-JSON -2. Den Dateinamen ohne Endung (z. B. `welcome.json` → `welcome`) +Cards are identified by (in order of priority): +1. `greentic.cardId` field in the card JSON +2. Filename stem (e.g., `welcome.json` → `welcome`) -Karten werden gruppiert in Flows über: -- Das Feld `flow` in den Aktionsdaten -- `--group-by folder` (Verzeichnisstruktur) -- Den Fallback `--default-flow` +Cards are grouped into flows by: +- `flow` field in action data +- `--group-by folder` (directory structure) +- `--default-flow` fallback -## i18n und Auto-Übersetzung +## i18n & Auto-Translation -### Zeichenketten extrahieren +### Extract strings ```bash greentic-cards2pack extract-i18n \ @@ -136,7 +148,7 @@ greentic-cards2pack extract-i18n \ --verbose ``` -Ausgabe: +Output: ```json title="i18n/en.json" { @@ -147,28 +159,28 @@ Ausgabe: ``` -### Extrahierte Feldtypen +### Extracted field types -| Feld | Quelle | +| Field | Source | |-------|--------| -| `text` | Inhalt von TextBlock | -| `title` | Aktionstitel, Kartentitel, Toggle-Titel | -| `label` | Labels von Eingaben | -| `placeholder` | Platzhalter von Eingaben | -| `errorMessage` | Validierungsfehler | -| `altText` | Alternativtext für Bilder | -| `fallbackText` | Fallback-Inhalt | -| FactSet `title`/`value` | Fact-Einträge | -| ChoiceSet `title` | Auswahloptionen | - -### Auto-übersetzen (ein Befehl) +| `text` | TextBlock content | +| `title` | Action titles, card titles, toggle titles | +| `label` | Input labels | +| `placeholder` | Input placeholders | +| `errorMessage` | Validation errors | +| `altText` | Image alt text | +| `fallbackText` | Fallback content | +| FactSet `title`/`value` | Fact entries | +| ChoiceSet `title` | Choice options | + +### Auto-translate (one command) ```bash greentic-cards2pack generate \ @@ -179,7 +191,7 @@ greentic-cards2pack generate \ --langs fr,de ``` -Dies extrahiert Zeichenketten aus den ursprünglichen Kartendateien, übersetzt sie über `greentic-i18n-translator` mit bis zu 8 parallelen Threads und bündelt alles: +This extracts strings from the original card files, translates via `greentic-i18n-translator` using up to 8 concurrent threads, and bundles everything: ``` my-pack/assets/i18n/ @@ -189,12 +201,12 @@ my-pack/assets/i18n/ ``` -### Glossar +### Glossary -Verwende ein Glossar, um Markennamen und technische Begriffe konsistent zu halten: +Use a glossary to keep brand names and technical terms consistent: ```json title="glossary.json" { @@ -210,9 +222,9 @@ greentic-cards2pack generate \ --glossary glossary.json ``` -## Flow-Generierung +## Flow Generation -Generierte Flow-Abschnitte werden in Marker eingeschlossen: +Generated flow sections are wrapped in markers: ```yaml # BEGIN GENERATED (cards2pack) @@ -222,18 +234,18 @@ Generierte Flow-Abschnitte werden in Marker eingeschlossen: # Developer space below (preserved on regen) ``` -Inhalte außerhalb der Marker bleiben erhalten, wenn du erneut generierst. +Content outside the markers is preserved when you regenerate. -### Strikter Modus +### Strict mode -Mit `--strict`: -- Verursachen fehlende Routing-Ziele Fehler (statt Stub-Knoten) -- Verursachen doppelte `cardId`-Werte Fehler -- Verursacht ungültiges JSON Fehler +With `--strict`: +- Missing route targets cause errors (instead of stub nodes) +- Duplicate `cardId` values cause errors +- Invalid JSON causes errors -## Template-Variablen +## Template Variables -Verwende Handlebars-Syntax für dynamische Inhalte: +Use Handlebars syntax for dynamic content: ```json { @@ -243,10 +255,10 @@ Verwende Handlebars-Syntax für dynamische Inhalte: ``` -## Beispiel: Mehrstufiges Formular mit Übersetzung +## Example: Multi-Step Form with Translation ```bash # Create cards in cards/ directory, then: @@ -260,11 +272,11 @@ greentic-cards2pack generate \ --strict ``` -Siehe das [translate-demo-Beispiel](https://github.com/greentic-ai/greentic-cards2pack/tree/master/examples/translate-demo) für eine vollständige Schritt-für-Schritt-Anleitung. +See the [translate-demo example](https://github.com/greentic-ai/greentic-cards2pack/tree/master/examples/translate-demo) for a complete walkthrough. -## Nächste Schritte +## Next Steps -- [Leitfaden zur Kartenübersetzung](/de/i18n/cards-translation/) -- [i18n Überblick](/de/i18n/overview/) -- [Flows-Leitfaden](/de/concepts/flows/) +- [Cards Translation Guide](/i18n/cards-translation/) +- [i18n Overview](/i18n/overview/) +- [Flows Guide](/concepts/flows/) - [Adaptive Cards Designer](https://adaptivecards.io/designer/) diff --git a/src/content/docs/es/components/cards2pack.mdx b/src/content/docs/es/components/cards2pack.mdx index c006b36..d03cbd1 100644 --- a/src/content/docs/es/components/cards2pack.mdx +++ b/src/content/docs/es/components/cards2pack.mdx @@ -1,37 +1,49 @@ --- title: cards2pack -description: Convierte Adaptive Cards en packs de Greentic +description: Convert Adaptive Cards to Greentic packs --- import { Aside, Steps } from '@astrojs/starlight/components'; -## Resumen +## Overview -**cards2pack** es una herramienta CLI que convierte archivos JSON de Adaptive Card en packs de Greentic. Hace lo siguiente: +**cards2pack** is a CLI tool that converts Adaptive Card JSON files into Greentic packs. It: -- Escanea cards, construye un grafo de dependencias y genera flows `.ygtc` -- Extrae cadenas traducibles para i18n -- Traduce automáticamente cards mediante `greentic-i18n-translator` -- Empaqueta todo en un `.gtpack` listo para desplegar +- Scans cards, builds a dependency graph, generates `.ygtc` flows +- Extracts translatable strings for i18n +- Auto-translates cards via `greentic-i18n-translator` +- Packages everything into a deployable `.gtpack` -## Instalación + + +## Installation ```bash cargo install greentic-cards2pack ``` -Herramientas requeridas: +Required tools: ```bash cargo install greentic-flow greentic-pack cargo install greentic-i18n-translator # optional, for --auto-translate ``` -## Inicio rápido +## Quick Start -1. **Crear Adaptive Cards** +1. **Create Adaptive Cards** ```json title="cards/welcome.json" { @@ -51,7 +63,7 @@ cargo install greentic-i18n-translator # optional, for --auto-translate } ``` -2. **Generar el pack** +2. **Generate pack** ```bash greentic-cards2pack generate \ @@ -60,7 +72,7 @@ cargo install greentic-i18n-translator # optional, for --auto-translate --name my-pack ``` -3. **Salida** +3. **Output** ``` my-pack/ @@ -73,61 +85,61 @@ cargo install greentic-i18n-translator # optional, for --auto-translate -## Referencia CLI +## CLI Reference ### `generate` -Comando principal: escanea cards, genera flows y construye el pack. +Main command — scan cards, generate flows, build pack. ```bash greentic-cards2pack generate [OPTIONS] ``` -| Flag | Descripción | +| Flag | Description | |------|-------------| -| `--cards ` | Directorio con archivos JSON de Adaptive Card (requerido) | -| `--out ` | Directorio de workspace de salida (requerido) | -| `--name ` | Nombre del pack (requerido) | -| `--strict` | Produce errores por destinos faltantes, duplicados o JSON no válido | -| `--group-by ` | Agrupación de flows: `folder` o `flow-field` | -| `--default-flow ` | Nombre del flow por defecto para cards sin agrupar | -| `--prompt` | Habilita enrutamiento basado en prompt (agrega nodo `prompt2flow`) | -| `--prompt-json ` | JSON de respuestas para enrutamiento por prompt (requiere `--prompt`) | -| `--auto-translate` | Traduce cards automáticamente con hasta 8 hilos en paralelo (requiere `greentic-i18n-translator`) | -| `--langs ` | Códigos de idioma separados por comas; si se omite, traduce a los más de 65 locales compatibles | -| `--glossary ` | JSON de glosario para traducciones consistentes | -| `--verbose` | Imprime salida detallada | +| `--cards ` | Directory of Adaptive Card JSON files (required) | +| `--out ` | Output workspace directory (required) | +| `--name ` | Pack name (required) | +| `--strict` | Errors on missing targets, duplicates, invalid JSON | +| `--group-by ` | Flow grouping: `folder` or `flow-field` | +| `--default-flow ` | Default flow name for ungrouped cards | +| `--prompt` | Enable prompt-based routing (adds `prompt2flow` node) | +| `--prompt-json ` | Answers JSON for prompt routing (requires `--prompt`) | +| `--auto-translate` | Auto-translate cards with up to 8 parallel threads (requires `greentic-i18n-translator`) | +| `--langs ` | Comma-separated language codes; omit to translate to all 65+ supported locales | +| `--glossary ` | Glossary JSON for consistent translations | +| `--verbose` | Print detailed output | ### `extract-i18n` -Extrae cadenas traducibles de las cards en un bundle JSON. +Extract translatable strings from cards into a JSON bundle. ```bash greentic-cards2pack extract-i18n [OPTIONS] ``` -| Flag | Descripción | +| Flag | Description | |------|-------------| -| `--input ` | Directorio de archivos JSON de cards (requerido) | -| `--output ` | Ruta del JSON de salida (por defecto: `i18n/en.json`) | -| `--prefix ` | Prefijo de clave (por defecto: `card`) | -| `--include-existing` | Incluye cadenas que ya contienen patrones `$t()` | -| `--verbose` | Imprime el informe de extracción | +| `--input ` | Directory of card JSON files (required) | +| `--output ` | Output JSON path (default: `i18n/en.json`) | +| `--prefix ` | Key prefix (default: `card`) | +| `--include-existing` | Include strings that already contain `$t()` patterns | +| `--verbose` | Print extraction report | -## Identificación de Cards +## Card Identification -Las cards se identifican por (en orden de prioridad): -1. El campo `greentic.cardId` en el JSON de la card -2. El nombre base del archivo (por ejemplo, `welcome.json` → `welcome`) +Cards are identified by (in order of priority): +1. `greentic.cardId` field in the card JSON +2. Filename stem (e.g., `welcome.json` → `welcome`) -Las cards se agrupan en flows por: -- El campo `flow` en los datos de la acción -- `--group-by folder` (estructura de directorios) -- El fallback `--default-flow` +Cards are grouped into flows by: +- `flow` field in action data +- `--group-by folder` (directory structure) +- `--default-flow` fallback -## i18n y traducción automática +## i18n & Auto-Translation -### Extraer cadenas +### Extract strings ```bash greentic-cards2pack extract-i18n \ @@ -136,7 +148,7 @@ greentic-cards2pack extract-i18n \ --verbose ``` -Salida: +Output: ```json title="i18n/en.json" { @@ -147,28 +159,28 @@ Salida: ``` -### Tipos de campos extraídos +### Extracted field types -| Campo | Origen | +| Field | Source | |-------|--------| -| `text` | Contenido de TextBlock | -| `title` | Títulos de acciones, títulos de cards y títulos de toggles | -| `label` | Etiquetas de inputs | -| `placeholder` | Placeholders de inputs | -| `errorMessage` | Errores de validación | -| `altText` | Texto alternativo de imágenes | -| `fallbackText` | Contenido fallback | -| FactSet `title`/`value` | Entradas de facts | -| ChoiceSet `title` | Opciones de choice | - -### Traducción automática (un solo comando) +| `text` | TextBlock content | +| `title` | Action titles, card titles, toggle titles | +| `label` | Input labels | +| `placeholder` | Input placeholders | +| `errorMessage` | Validation errors | +| `altText` | Image alt text | +| `fallbackText` | Fallback content | +| FactSet `title`/`value` | Fact entries | +| ChoiceSet `title` | Choice options | + +### Auto-translate (one command) ```bash greentic-cards2pack generate \ @@ -179,7 +191,7 @@ greentic-cards2pack generate \ --langs fr,de ``` -Esto extrae cadenas de los archivos originales de cards, las traduce mediante `greentic-i18n-translator` usando hasta 8 hilos concurrentes y empaqueta todo: +This extracts strings from the original card files, translates via `greentic-i18n-translator` using up to 8 concurrent threads, and bundles everything: ``` my-pack/assets/i18n/ @@ -189,12 +201,12 @@ my-pack/assets/i18n/ ``` -### Glosario +### Glossary -Usa un glosario para mantener consistentes los nombres de marca y términos técnicos: +Use a glossary to keep brand names and technical terms consistent: ```json title="glossary.json" { @@ -210,9 +222,9 @@ greentic-cards2pack generate \ --glossary glossary.json ``` -## Generación de Flows +## Flow Generation -Las secciones de flow generadas se envuelven en marcadores: +Generated flow sections are wrapped in markers: ```yaml # BEGIN GENERATED (cards2pack) @@ -222,18 +234,18 @@ Las secciones de flow generadas se envuelven en marcadores: # Developer space below (preserved on regen) ``` -El contenido fuera de los marcadores se conserva cuando regeneras. +Content outside the markers is preserved when you regenerate. -### Modo estricto +### Strict mode -Con `--strict`: -- Los destinos de ruta faltantes producen errores (en lugar de nodos stub) -- Los valores duplicados de `cardId` producen errores -- El JSON no válido produce errores +With `--strict`: +- Missing route targets cause errors (instead of stub nodes) +- Duplicate `cardId` values cause errors +- Invalid JSON causes errors -## Variables de plantilla +## Template Variables -Usa sintaxis Handlebars para contenido dinámico: +Use Handlebars syntax for dynamic content: ```json { @@ -243,10 +255,10 @@ Usa sintaxis Handlebars para contenido dinámico: ``` -## Ejemplo: Formulario de varios pasos con traducción +## Example: Multi-Step Form with Translation ```bash # Create cards in cards/ directory, then: @@ -260,11 +272,11 @@ greentic-cards2pack generate \ --strict ``` -Consulta el [ejemplo translate-demo](https://github.com/greentic-ai/greentic-cards2pack/tree/master/examples/translate-demo) para ver un recorrido completo. +See the [translate-demo example](https://github.com/greentic-ai/greentic-cards2pack/tree/master/examples/translate-demo) for a complete walkthrough. -## Siguientes pasos +## Next Steps -- [Guía de traducción de Cards](/es/i18n/cards-translation/) -- [Resumen de i18n](/es/i18n/overview/) -- [Guía de Flows](/es/concepts/flows/) +- [Cards Translation Guide](/i18n/cards-translation/) +- [i18n Overview](/i18n/overview/) +- [Flows Guide](/concepts/flows/) - [Adaptive Cards Designer](https://adaptivecards.io/designer/) diff --git a/src/content/docs/id/components/cards2pack.mdx b/src/content/docs/id/components/cards2pack.mdx index 36fb534..d03cbd1 100644 --- a/src/content/docs/id/components/cards2pack.mdx +++ b/src/content/docs/id/components/cards2pack.mdx @@ -1,37 +1,49 @@ --- title: cards2pack -description: Ubah Adaptive Cards menjadi pack Greentic +description: Convert Adaptive Cards to Greentic packs --- import { Aside, Steps } from '@astrojs/starlight/components'; -## Gambaran Umum +## Overview -**cards2pack** adalah alat CLI yang mengubah file JSON Adaptive Card menjadi pack Greentic. Alat ini: +**cards2pack** is a CLI tool that converts Adaptive Card JSON files into Greentic packs. It: -- Memindai card, membangun grafik dependensi, menghasilkan flow `.ygtc` -- Mengekstrak string yang dapat diterjemahkan untuk i18n -- Menerjemahkan card secara otomatis via `greentic-i18n-translator` -- Mengemas semuanya menjadi `.gtpack` yang siap di-deploy +- Scans cards, builds a dependency graph, generates `.ygtc` flows +- Extracts translatable strings for i18n +- Auto-translates cards via `greentic-i18n-translator` +- Packages everything into a deployable `.gtpack` -## Instalasi + + +## Installation ```bash cargo install greentic-cards2pack ``` -Alat yang dibutuhkan: +Required tools: ```bash cargo install greentic-flow greentic-pack cargo install greentic-i18n-translator # optional, for --auto-translate ``` -## Mulai Cepat +## Quick Start -1. **Buat Adaptive Cards** +1. **Create Adaptive Cards** ```json title="cards/welcome.json" { @@ -51,7 +63,7 @@ cargo install greentic-i18n-translator # optional, for --auto-translate } ``` -2. **Hasilkan pack** +2. **Generate pack** ```bash greentic-cards2pack generate \ @@ -60,7 +72,7 @@ cargo install greentic-i18n-translator # optional, for --auto-translate --name my-pack ``` -3. **Hasil** +3. **Output** ``` my-pack/ @@ -73,61 +85,61 @@ cargo install greentic-i18n-translator # optional, for --auto-translate -## Referensi CLI +## CLI Reference ### `generate` -Perintah utama, memindai card, menghasilkan flow, dan membangun pack. +Main command — scan cards, generate flows, build pack. ```bash greentic-cards2pack generate [OPTIONS] ``` -| Flag | Deskripsi | -|------|-----------| -| `--cards ` | Direktori file JSON Adaptive Card (wajib) | -| `--out ` | Direktori workspace output (wajib) | -| `--name ` | Nama pack (wajib) | -| `--strict` | Error saat target hilang, duplikat, atau JSON tidak valid | -| `--group-by ` | Pengelompokan flow: `folder` atau `flow-field` | -| `--default-flow ` | Nama flow default untuk card yang tidak dikelompokkan | -| `--prompt` | Aktifkan routing berbasis prompt (menambahkan node `prompt2flow`) | -| `--prompt-json ` | JSON jawaban untuk routing prompt (memerlukan `--prompt`) | -| `--auto-translate` | Terjemahkan card otomatis dengan hingga 8 thread paralel (memerlukan `greentic-i18n-translator`) | -| `--langs ` | Kode bahasa dipisahkan koma; kosongkan untuk menerjemahkan ke semua 65+ locale yang didukung | -| `--glossary ` | Glossary JSON untuk terjemahan yang konsisten | -| `--verbose` | Cetak output terperinci | +| Flag | Description | +|------|-------------| +| `--cards ` | Directory of Adaptive Card JSON files (required) | +| `--out ` | Output workspace directory (required) | +| `--name ` | Pack name (required) | +| `--strict` | Errors on missing targets, duplicates, invalid JSON | +| `--group-by ` | Flow grouping: `folder` or `flow-field` | +| `--default-flow ` | Default flow name for ungrouped cards | +| `--prompt` | Enable prompt-based routing (adds `prompt2flow` node) | +| `--prompt-json ` | Answers JSON for prompt routing (requires `--prompt`) | +| `--auto-translate` | Auto-translate cards with up to 8 parallel threads (requires `greentic-i18n-translator`) | +| `--langs ` | Comma-separated language codes; omit to translate to all 65+ supported locales | +| `--glossary ` | Glossary JSON for consistent translations | +| `--verbose` | Print detailed output | ### `extract-i18n` -Ekstrak string yang dapat diterjemahkan dari card ke dalam bundle JSON. +Extract translatable strings from cards into a JSON bundle. ```bash greentic-cards2pack extract-i18n [OPTIONS] ``` -| Flag | Deskripsi | -|------|-----------| -| `--input ` | Direktori file JSON card (wajib) | -| `--output ` | Path JSON output (default: `i18n/en.json`) | -| `--prefix ` | Prefiks key (default: `card`) | -| `--include-existing` | Sertakan string yang sudah mengandung pola `$t()` | -| `--verbose` | Cetak laporan ekstraksi | +| Flag | Description | +|------|-------------| +| `--input ` | Directory of card JSON files (required) | +| `--output ` | Output JSON path (default: `i18n/en.json`) | +| `--prefix ` | Key prefix (default: `card`) | +| `--include-existing` | Include strings that already contain `$t()` patterns | +| `--verbose` | Print extraction report | -## Identifikasi Card +## Card Identification -Card diidentifikasi berdasarkan (urutan prioritas): -1. Field `greentic.cardId` di JSON card -2. Stem nama file (misalnya, `welcome.json` → `welcome`) +Cards are identified by (in order of priority): +1. `greentic.cardId` field in the card JSON +2. Filename stem (e.g., `welcome.json` → `welcome`) -Card dikelompokkan ke dalam flow berdasarkan: -- Field `flow` di action data -- `--group-by folder` (struktur direktori) -- Fallback `--default-flow` +Cards are grouped into flows by: +- `flow` field in action data +- `--group-by folder` (directory structure) +- `--default-flow` fallback -## i18n & Terjemahan Otomatis +## i18n & Auto-Translation -### Ekstrak string +### Extract strings ```bash greentic-cards2pack extract-i18n \ @@ -136,7 +148,7 @@ greentic-cards2pack extract-i18n \ --verbose ``` -Hasil: +Output: ```json title="i18n/en.json" { @@ -147,28 +159,28 @@ Hasil: ``` -### Jenis field yang diekstrak +### Extracted field types -| Field | Sumber | +| Field | Source | |-------|--------| -| `text` | Konten TextBlock | -| `title` | Judul action, judul card, judul toggle | -| `label` | Label input | -| `placeholder` | Placeholder input | -| `errorMessage` | Error validasi | -| `altText` | Alt text gambar | -| `fallbackText` | Konten fallback | -| FactSet `title`/`value` | Entri fakta | -| ChoiceSet `title` | Opsi pilihan | - -### Terjemahan otomatis (satu perintah) +| `text` | TextBlock content | +| `title` | Action titles, card titles, toggle titles | +| `label` | Input labels | +| `placeholder` | Input placeholders | +| `errorMessage` | Validation errors | +| `altText` | Image alt text | +| `fallbackText` | Fallback content | +| FactSet `title`/`value` | Fact entries | +| ChoiceSet `title` | Choice options | + +### Auto-translate (one command) ```bash greentic-cards2pack generate \ @@ -179,7 +191,7 @@ greentic-cards2pack generate \ --langs fr,de ``` -Perintah ini mengekstrak string dari file card asli, menerjemahkannya via `greentic-i18n-translator` menggunakan hingga 8 thread konkuren, lalu membundel semuanya: +This extracts strings from the original card files, translates via `greentic-i18n-translator` using up to 8 concurrent threads, and bundles everything: ``` my-pack/assets/i18n/ @@ -189,12 +201,12 @@ my-pack/assets/i18n/ ``` ### Glossary -Gunakan glossary untuk menjaga nama brand dan istilah teknis tetap konsisten: +Use a glossary to keep brand names and technical terms consistent: ```json title="glossary.json" { @@ -210,9 +222,9 @@ greentic-cards2pack generate \ --glossary glossary.json ``` -## Pembuatan Flow +## Flow Generation -Bagian flow yang dihasilkan dibungkus dalam marker: +Generated flow sections are wrapped in markers: ```yaml # BEGIN GENERATED (cards2pack) @@ -222,18 +234,18 @@ Bagian flow yang dihasilkan dibungkus dalam marker: # Developer space below (preserved on regen) ``` -Konten di luar marker akan dipertahankan saat Anda melakukan generate ulang. +Content outside the markers is preserved when you regenerate. -### Mode strict +### Strict mode -Dengan `--strict`: -- Target route yang hilang menyebabkan error (bukan node stub) -- Nilai `cardId` yang duplikat menyebabkan error -- JSON yang tidak valid menyebabkan error +With `--strict`: +- Missing route targets cause errors (instead of stub nodes) +- Duplicate `cardId` values cause errors +- Invalid JSON causes errors -## Variabel Template +## Template Variables -Gunakan sintaks Handlebars untuk konten dinamis: +Use Handlebars syntax for dynamic content: ```json { @@ -243,10 +255,10 @@ Gunakan sintaks Handlebars untuk konten dinamis: ``` -## Contoh: Form Multi-Langkah dengan Terjemahan +## Example: Multi-Step Form with Translation ```bash # Create cards in cards/ directory, then: @@ -260,11 +272,11 @@ greentic-cards2pack generate \ --strict ``` -Lihat [contoh translate-demo](https://github.com/greentic-ai/greentic-cards2pack/tree/master/examples/translate-demo) untuk walkthrough lengkap. +See the [translate-demo example](https://github.com/greentic-ai/greentic-cards2pack/tree/master/examples/translate-demo) for a complete walkthrough. -## Langkah Berikutnya +## Next Steps -- [Panduan Terjemahan Cards](/id/i18n/cards-translation/) -- [Ikhtisar i18n](/id/i18n/overview/) -- [Panduan Flows](/id/concepts/flows/) +- [Cards Translation Guide](/i18n/cards-translation/) +- [i18n Overview](/i18n/overview/) +- [Flows Guide](/concepts/flows/) - [Adaptive Cards Designer](https://adaptivecards.io/designer/) diff --git a/src/content/docs/ja/components/cards2pack.mdx b/src/content/docs/ja/components/cards2pack.mdx index 278c3ef..d03cbd1 100644 --- a/src/content/docs/ja/components/cards2pack.mdx +++ b/src/content/docs/ja/components/cards2pack.mdx @@ -1,37 +1,49 @@ --- title: cards2pack -description: Adaptive Cards を Greentic packs に変換する +description: Convert Adaptive Cards to Greentic packs --- import { Aside, Steps } from '@astrojs/starlight/components'; -## 概要 +## Overview -**cards2pack** は Adaptive Card の JSON ファイルを Greentic packs に変換する CLI ツールです。次のことを行います: +**cards2pack** is a CLI tool that converts Adaptive Card JSON files into Greentic packs. It: -- cards を走査し、依存グラフを構築して `.ygtc` flows を生成する -- i18n 用に翻訳可能な文字列を抽出する -- `greentic-i18n-translator` によって cards を自動翻訳する -- すべてをデプロイ可能な `.gtpack` にパッケージングする +- Scans cards, builds a dependency graph, generates `.ygtc` flows +- Extracts translatable strings for i18n +- Auto-translates cards via `greentic-i18n-translator` +- Packages everything into a deployable `.gtpack` -## インストール + + +## Installation ```bash cargo install greentic-cards2pack ``` -必要なツール: +Required tools: ```bash cargo install greentic-flow greentic-pack cargo install greentic-i18n-translator # optional, for --auto-translate ``` -## クイックスタート +## Quick Start -1. **Adaptive Cards を作成する** +1. **Create Adaptive Cards** ```json title="cards/welcome.json" { @@ -51,7 +63,7 @@ cargo install greentic-i18n-translator # optional, for --auto-translate } ``` -2. **pack を生成する** +2. **Generate pack** ```bash greentic-cards2pack generate \ @@ -60,7 +72,7 @@ cargo install greentic-i18n-translator # optional, for --auto-translate --name my-pack ``` -3. **出力** +3. **Output** ``` my-pack/ @@ -73,61 +85,61 @@ cargo install greentic-i18n-translator # optional, for --auto-translate -## CLI リファレンス +## CLI Reference ### `generate` -メインコマンドです。cards を走査し、flows を生成して、pack をビルドします。 +Main command — scan cards, generate flows, build pack. ```bash greentic-cards2pack generate [OPTIONS] ``` -| Flag | 説明 | +| Flag | Description | |------|-------------| -| `--cards ` | Adaptive Card JSON ファイルのディレクトリ(必須) | -| `--out ` | 出力 workspace ディレクトリ(必須) | -| `--name ` | Pack 名(必須) | -| `--strict` | 欠落した target、重複、無効な JSON をエラーにする | -| `--group-by ` | Flow のグループ化: `folder` または `flow-field` | -| `--default-flow ` | グループ化されない cards のデフォルト flow 名 | -| `--prompt` | prompt ベースのルーティングを有効にする(`prompt2flow` node を追加) | -| `--prompt-json ` | prompt ルーティング用の回答 JSON(`--prompt` が必要) | -| `--auto-translate` | 最大 8 並列スレッドで cards を自動翻訳する(`greentic-i18n-translator` が必要) | -| `--langs ` | カンマ区切りの言語コード。省略すると対応する 65 以上のすべての locale に翻訳 | -| `--glossary ` | 一貫した翻訳のための glossary JSON | -| `--verbose` | 詳細出力を表示する | +| `--cards ` | Directory of Adaptive Card JSON files (required) | +| `--out ` | Output workspace directory (required) | +| `--name ` | Pack name (required) | +| `--strict` | Errors on missing targets, duplicates, invalid JSON | +| `--group-by ` | Flow grouping: `folder` or `flow-field` | +| `--default-flow ` | Default flow name for ungrouped cards | +| `--prompt` | Enable prompt-based routing (adds `prompt2flow` node) | +| `--prompt-json ` | Answers JSON for prompt routing (requires `--prompt`) | +| `--auto-translate` | Auto-translate cards with up to 8 parallel threads (requires `greentic-i18n-translator`) | +| `--langs ` | Comma-separated language codes; omit to translate to all 65+ supported locales | +| `--glossary ` | Glossary JSON for consistent translations | +| `--verbose` | Print detailed output | ### `extract-i18n` -cards から翻訳可能な文字列を JSON bundle に抽出します。 +Extract translatable strings from cards into a JSON bundle. ```bash greentic-cards2pack extract-i18n [OPTIONS] ``` -| Flag | 説明 | +| Flag | Description | |------|-------------| -| `--input ` | card JSON ファイルのディレクトリ(必須) | -| `--output ` | 出力 JSON パス(デフォルト: `i18n/en.json`) | -| `--prefix ` | キー接頭辞(デフォルト: `card`) | -| `--include-existing` | すでに `$t()` パターンを含む文字列も含める | -| `--verbose` | 抽出レポートを表示する | +| `--input ` | Directory of card JSON files (required) | +| `--output ` | Output JSON path (default: `i18n/en.json`) | +| `--prefix ` | Key prefix (default: `card`) | +| `--include-existing` | Include strings that already contain `$t()` patterns | +| `--verbose` | Print extraction report | -## Card の識別 +## Card Identification -cards は次の優先順で識別されます: -1. card JSON 内の `greentic.cardId` フィールド -2. ファイル名の stem(例: `welcome.json` → `welcome`) +Cards are identified by (in order of priority): +1. `greentic.cardId` field in the card JSON +2. Filename stem (e.g., `welcome.json` → `welcome`) -cards は次の方法で flows にグループ化されます: -- action data 内の `flow` フィールド -- `--group-by folder`(ディレクトリ構造) +Cards are grouped into flows by: +- `flow` field in action data +- `--group-by folder` (directory structure) - `--default-flow` fallback -## i18n と自動翻訳 +## i18n & Auto-Translation -### 文字列を抽出する +### Extract strings ```bash greentic-cards2pack extract-i18n \ @@ -136,7 +148,7 @@ greentic-cards2pack extract-i18n \ --verbose ``` -出力: +Output: ```json title="i18n/en.json" { @@ -147,28 +159,28 @@ greentic-cards2pack extract-i18n \ ``` -### 抽出されるフィールドの種類 +### Extracted field types -| Field | ソース | +| Field | Source | |-------|--------| -| `text` | TextBlock の内容 | -| `title` | Action titles、card titles、toggle titles | +| `text` | TextBlock content | +| `title` | Action titles, card titles, toggle titles | | `label` | Input labels | | `placeholder` | Input placeholders | | `errorMessage` | Validation errors | -| `altText` | 画像の代替テキスト | -| `fallbackText` | フォールバック内容 | +| `altText` | Image alt text | +| `fallbackText` | Fallback content | | FactSet `title`/`value` | Fact entries | | ChoiceSet `title` | Choice options | -### 自動翻訳(1 コマンド) +### Auto-translate (one command) ```bash greentic-cards2pack generate \ @@ -179,7 +191,7 @@ greentic-cards2pack generate \ --langs fr,de ``` -これにより、元の card ファイルから文字列を抽出し、最大 8 並列スレッドで `greentic-i18n-translator` によって翻訳し、すべてをまとめて bundle します: +This extracts strings from the original card files, translates via `greentic-i18n-translator` using up to 8 concurrent threads, and bundles everything: ``` my-pack/assets/i18n/ @@ -189,12 +201,12 @@ my-pack/assets/i18n/ ``` ### Glossary -brand 名や技術用語の表記を統一するには glossary を使います: +Use a glossary to keep brand names and technical terms consistent: ```json title="glossary.json" { @@ -210,9 +222,9 @@ greentic-cards2pack generate \ --glossary glossary.json ``` -## Flow の生成 +## Flow Generation -生成された flow セクションは markers で囲まれます: +Generated flow sections are wrapped in markers: ```yaml # BEGIN GENERATED (cards2pack) @@ -222,18 +234,18 @@ greentic-cards2pack generate \ # Developer space below (preserved on regen) ``` -markers の外側の内容は再生成時にも保持されます。 +Content outside the markers is preserved when you regenerate. -### strict モード +### Strict mode -`--strict` を使うと: -- 欠落した route targets はエラーになる(stub nodes ではなく) -- 重複した `cardId` 値はエラーになる -- 無効な JSON はエラーになる +With `--strict`: +- Missing route targets cause errors (instead of stub nodes) +- Duplicate `cardId` values cause errors +- Invalid JSON causes errors -## テンプレート変数 +## Template Variables -動的コンテンツには Handlebars 構文を使います: +Use Handlebars syntax for dynamic content: ```json { @@ -243,10 +255,10 @@ markers の外側の内容は再生成時にも保持されます。 ``` -## 例: 翻訳付きマルチステップフォーム +## Example: Multi-Step Form with Translation ```bash # Create cards in cards/ directory, then: @@ -259,3 +271,12 @@ greentic-cards2pack generate \ --glossary glossary.json \ --strict ``` + +See the [translate-demo example](https://github.com/greentic-ai/greentic-cards2pack/tree/master/examples/translate-demo) for a complete walkthrough. + +## Next Steps + +- [Cards Translation Guide](/i18n/cards-translation/) +- [i18n Overview](/i18n/overview/) +- [Flows Guide](/concepts/flows/) +- [Adaptive Cards Designer](https://adaptivecards.io/designer/) diff --git a/src/content/docs/reference/channel-data-access.mdx b/src/content/docs/reference/channel-data-access.mdx new file mode 100644 index 0000000..fc8ee5a --- /dev/null +++ b/src/content/docs/reference/channel-data-access.mdx @@ -0,0 +1,177 @@ +--- +title: Channel Data Access Pattern +description: How DirectLine channelData reaches flow templates and WASM components as envelope extensions. +--- + +import { Aside, Steps } from '@astrojs/starlight/components'; + +## Overview + +WebChat and other DirectLine-compatible clients can attach free-form +per-channel metadata to an activity via the DirectLine `channelData` +field. In Greentic this metadata is not dropped and it is not treated as +channel-specific plumbing — it becomes part of the normalized +`ChannelMessageEnvelope` that flows through the whole runtime and reaches +your flow templates and WASM components verbatim. + +This page documents the end-to-end contract. It is the canonical pattern +used by the R1 demo (Paul's principals scenario): the front-end sets +`channelData.r1_principals`, the flow reads it, and a WASM component +receives it as structured input. + + + +## The wire contract + +### 1. Provider normalisation (camelCase -> snake_case) + +`messaging-provider-webchat` copies the DirectLine activity's +`channelData` into the envelope's `extensions` map under the +`channel_data` key. The rename from camelCase to snake_case is +intentional: every well-known extension key uses snake_case inside +Greentic so that flow templates and WASM components see a single, +consistent naming convention. + +| Source (DirectLine wire) | Destination (Greentic envelope) | +|--------------------------|---------------------------------| +| `activity.channelData` | `envelope.extensions.channel_data` | + +The provider passes the payload through verbatim — it does not strip or +normalise keys nested inside `channelData`. Whatever shape the client +sends is the shape your flow receives. + +### 2. Flow-input scope + +Once the envelope is routed to a flow, the runtime builds a template +context where the envelope is exposed under `entry.input`. Extensions +are reachable at: + +``` +entry.input.extensions.channel_data +``` + +This is the scope used by inline `{{ ... }}` template expressions in the +flow YAML. + +### 3. Node-input scope (auto-merge) + +Before each node is dispatched, the flow engine merges envelope-level +extensions into the node's WASM input as a top-level `extensions` field, +**unless** the node's `input` mapping already defines an explicit +`extensions` key (user mappings always win). + +As a result, WASM components see the extensions object directly on +`input`: + +``` +input.extensions.channel_data +``` + +The merge is defined in `greentic-runner-host` (see +`src/runner/extensions.rs`). It is a no-op when `entry.input.extensions` +is missing, empty, or not a JSON object. + +## End-to-end example + +The R1 demo front-end sends: + +```json +{ + "type": "message", + "text": "Summarise my open incidents", + "channelData": { + "r1_principals": { + "user": "paul@example.com", + "groups": ["noc-operators"] + } + } +} +``` + +### Flow YAML — read from the template context + +```yaml +nodes: + - id: call_handler + component: component-some-handler + operation: handle_message + input: + principals: '{{ entry.input.extensions.channel_data.r1_principals }}' + message: '{{ entry.input.payload.text }}' +``` + +Here `principals` is passed into the component as a nested object, and +`message` pulls from `payload.text` on the envelope. + +### WASM component — read from the auto-merged input + +Because the engine auto-merges extensions into every node's input, a +component can skip the template binding entirely and read extensions +directly off its `input`: + +```rust +use serde_json::Value; + +fn handle(input: &Value) -> anyhow::Result { + let principals = input["extensions"]["channel_data"]["r1_principals"].clone(); + // ... use principals + Ok(serde_json::json!({ "ok": true })) +} +``` + + + +## Naming rules + + + +1. **On the wire (DirectLine):** camelCase — `channelData`. + +2. **Inside the Greentic envelope:** snake_case — `extensions.channel_data`. + +3. **In flow templates and WASM components:** snake_case — always. + + + +The provider is the only place where the rename happens. Flows and +components never see the camelCase form. + +## Well-known extension keys + +`channel_data` is one of a small set of well-known keys defined in +`greentic-types` (`src/messaging/extensions.rs`). All of them follow the +same auto-merge rule on the node-input side, and all of them round-trip +verbatim on the egress side. See the [WebChat +provider](/providers/messaging/webchat/) page for the full table of +canonical keys, including `adaptive_card`, `entities`, `attachments`, +`suggested_actions`, `speak`, and `input_hint`. + +## Regression test + +The propagation contract is pinned by +`run_app_flow_input_preserves_envelope_extensions_channel_data` in +`greentic-start` (`src/messaging_app.rs`). The test builds an envelope +with `extensions.channel_data.r1_principals`, runs it through the full +messaging app path, and asserts the value survives verbatim at +`/input/extensions/channel_data/r1_principals` in the resulting +`ExecutionState.entry`. + +If you are changing anything between HTTP ingress and +`engine.execute` (envelope routing, request building, runner glue), +re-run that test first. + +## Next steps + +- [WebChat provider](/providers/messaging/webchat/) — envelope extensions table, attachment shapes, egress round-trip. +- [Flow YAML Schema](/reference/flow-schema/) — template context variables (`{{entry.*}}`). +- [Flow Node Kinds](/reference/flow-node-kinds/) — builtin operators and the component-node model. diff --git a/src/content/docs/reference/flow-node-kinds.mdx b/src/content/docs/reference/flow-node-kinds.mdx new file mode 100644 index 0000000..ddc0bfb --- /dev/null +++ b/src/content/docs/reference/flow-node-kinds.mdx @@ -0,0 +1,234 @@ +--- +title: Flow Node Kinds +description: The node kinds understood by the flow engine — component nodes, builtin operators, and the state-store gap as of greentic-runner 0.5.11. +--- + +import { Aside, Steps } from '@astrojs/starlight/components'; + +## Overview + +A flow is a DAG whose nodes are either **component nodes** (WASM +components loaded from the pack or a cross-pack resolver) or **builtin +operators** — short-circuit nodes the flow engine executes itself. +This page lists every node kind the engine recognises today, plus the +state-store gap the runner currently exposes. + + + +## Component nodes + +Component nodes run a WASM component from the pack. They are the +default: any node whose `component` field does not resolve to a +builtin prefix is dispatched as a component node. + +```yaml +nodes: + - id: llm + component: component-llm-openai # pack-local component id + operation: complete # operation exported by the component + config: + api_key_secret: "llm-api-key" + input: + prompt: '{{ entry.input.payload.text }}' +``` + +Component nodes may also reference components provisioned by other +packs through the **cross-pack resolver**; the engine falls back to +that resolver when the `component` id does not exist locally. See +[Packs](/concepts/packs/) for the pack-local vs cross-pack lookup +rules. + +## Builtin operators + +Builtin operators are identified by a reserved prefix on the +`component` (or legacy `operation` / `target`) field. The engine +dispatches them directly — no WASM call, no pack lookup. As of +`greentic-runner` 0.5.11 the full set is: + +| Operator | Purpose | +|----------|---------| +| `emit.response` | Emit a response back to the originating channel. Terminal. | +| `emit.log` | Emit a structured log line without affecting the message envelope. | +| `session.wait` | Pause the flow on a named route until a matching resume event arrives. | +| `flow.call` | Invoke another flow as a subroutine and resume when it returns. | +| `provider.invoke` | Call an operation on a provider component (cross-pack aware). | + +Any `component` value starting with `emit.`, `session.`, `flow.`, or +`provider.` is routed into the builtin table. Unknown prefixes in +those namespaces are a hard error — the engine does not fall back to +component resolution for reserved prefixes. + +### `emit.response` + +```yaml +- id: reply + component: emit.response + input: + text: '{{ entry.input.payload.text }}' +``` + +Terminates the current flow path and emits the node's `input` as the +response envelope. Downstream providers (WebChat, Slack, Telegram, ...) +render the envelope per channel. + +### `emit.log` + +```yaml +- id: trace + component: emit.log + input: + level: info + msg: "handled principals for {{ entry.input.extensions.channel_data.r1_principals.user }}" +``` + +Does not terminate — the flow continues to the `next` node. Useful for +marking points in the flow that should surface in runtime logs without +involving a full WASM component. + +### `session.wait` + +```yaml +- id: await_answer + component: session.wait + config: + route: "confirm_order" + timeout_ms: 30000 + next: on_answer +``` + +Persists a `FlowSnapshot` keyed by the session key +(`{tenant}:{provider}:{conversation}:{user}`) and pauses. The matching +resume event is routed by the `route` name. See the runner architecture +overview for the full pause/resume semantics. + +### `flow.call` + +```yaml +- id: verify + component: flow.call + config: + flow_id: verify-user + input: + user: '{{ entry.input.payload.from.id }}' + next: after_verify +``` + +Invokes another flow as a subroutine. The subflow's terminal response +becomes this node's output. `flow.call` fails the parent flow if the +subflow pauses (use `session.wait` at the parent level for +pause-compatible subcalls). + +### `provider.invoke` + +```yaml +- id: send_dm + component: provider.invoke + config: + provider_id: messaging-provider-slack + op: send_message + input: + to: '{{ entry.input.payload.from.id }}' + text: "Got it." +``` + +Calls a typed operation on a provider component, respecting the +cross-pack resolver and the provider's declared capabilities. This is +how flows reach outbound messaging without binding to a specific pack +layout. + +## State store gap + + + +### What ships today + +- **Storage backends ship as provider packs.** `state-memory` and + `state-redis` are available as packs that expose the + `greentic:state/state-store` host capability to WASM components. +- **WASM components can read and write state.** A component in a pack + that declares `greentic:state/state-store` as a required host + capability gets a typed handle to the store via `wit-bindgen` and + can perform get/put/delete/list/cas operations from inside the + component. +- **Manifest default is permissive.** When a component manifest omits + `host.state`, the runner defaults to allowing the state-store host + call (see the `state-store-default-allow` fix). Explicit deny is + still honoured. + +### What is not shipping + +There is no flow-level `state.*` builtin operator. The roadmap +tracks flow-callable state primitives, but the 0.5.11 engine does not +dispatch them. + +### Recommended workaround + +When a flow needs to persist data across turns, invoke a custom WASM +component that reads/writes via the host capability: + +```yaml +- id: remember_principals + component: component-state-helper + operation: put + input: + key: 'principals/{{ entry.input.payload.from.id }}' + value: '{{ entry.input.extensions.channel_data.r1_principals }}' +``` + +Inside `component-state-helper`, the handler calls the +`greentic:state/state-store` host API directly. The component is +responsible for key namespacing and serialisation; the runner only +enforces the capability grant. + +### Forward-looking example + +The `qa-demo` flow in the demo catalog contains `state.get` / +`state.put` nodes as a forward-looking example. **That flow is not +runnable end-to-end on 0.5.11** — it is staged for the release that +introduces flow-level state builtins. Use it as a reference for the +intended YAML shape, not as a working flow today. + +## Legacy `type:` shorthand + +Some older `.ygtc` files use a `type: ` shorthand instead of +`component: `. The engine still accepts the shorthand for +backwards compatibility, but the canonical form going forward is +`component:` (pack-local id or builtin prefix) plus `operation:` +(the WIT-exported op name for component nodes). + +```yaml +# Legacy +- id: reply + type: reply + config: + message: "Hello" + +# Canonical +- id: reply + component: emit.response + input: + text: "Hello" +``` + +New flows should use the canonical form. The legacy shorthand will +remain accepted but is not guaranteed to receive new features +(for example, per-node cross-pack resolver hints). + +## Next steps + +- [Flow YAML Schema](/reference/flow-schema/) — full YAML structure, template context, expression syntax. +- [Channel Data Access](/reference/channel-data-access/) — how envelope extensions reach node inputs. +- [Secret Seeding](/reference/secret-seeding/) — pack-scoped secret URIs for component nodes. +- [Packs](/concepts/packs/) — pack-local vs cross-pack component resolution. diff --git a/src/content/docs/reference/secret-seeding.mdx b/src/content/docs/reference/secret-seeding.mdx new file mode 100644 index 0000000..b26becb --- /dev/null +++ b/src/content/docs/reference/secret-seeding.mdx @@ -0,0 +1,218 @@ +--- +title: Secret Seeding Recipe +description: Canonical patterns for seeding secrets into a Greentic bundle so packs and flows can resolve them at runtime. +--- + +import { Aside, Steps } from '@astrojs/starlight/components'; + +## Overview + +Greentic secrets are addressed by a pack-scoped URI and resolved lazily +by the runtime when a flow references them. Getting the URI right is +the most common source of the runtime error + +``` +Secret was not found or not provisioned for this component. +``` + +This page documents the canonical URI scheme and the two supported +seeding paths. **Prefer Path A (`setup.yaml` wizard)** — it gets the +pack scope right by construction. Path B (manual seeding) is only +necessary when a pack does not ship a `setup.yaml`. + +## URI scheme + +``` +secrets://{env}/{tenant}/{team}/{pack_id}/{key} +``` + +| Segment | Description | +|---------|-------------| +| `env` | Environment name, e.g. `dev`, `demo`, `prod`. | +| `tenant` | Tenant ID the secret belongs to. | +| `team` | Visibility scope within the tenant (`default` or a team name). | +| `pack_id` | The **pack manifest id** of the consuming pack — **not** a component id. | +| `key` | The short secret name referenced from the flow (e.g. `llm-api-key`). | + + + +## Path A — `setup.yaml` (preferred) + +When a pack ships an `assets/setup.yaml` with `secret: true` questions, +the `gtc setup` wizard handles the URI construction for you. This is +the recommended path for every production pack. + +### Pack side + +Declare the secret question in the pack's setup file: + +```yaml title="assets/setup.yaml" +questions: + - id: llm-api-key + label: "OpenAI API key" + kind: string + required: true + secret: true + help: | + Used by the LLM handler to call OpenAI. Starts with `sk-`. +``` + +The wizard: + +- prompts the user (or reads the value from `--answers`), +- persists the value at + `secrets://{env}/{tenant}/{team}/{this-pack-id}/llm-api-key`, and +- never writes the value to disk in plaintext outside the secrets + backend. + +### Operator side + +Running setup seeds the secret at the correct URI: + +```bash +gtc setup --pack deep-research-demo.gtpack --tenant demo +``` + +Or non-interactively: + +```bash +gtc setup --answers deep-research-answers.json ./deep-research-demo-bundle +``` + +The wizard reads the bundle's tenant automatically and writes each +answer under the owning pack's id — no manual URI assembly required. + +### Flow side + +The flow references the secret by its short `key` part only: + +```yaml title="flows/chat.ygtc" +nodes: + - id: llm + component: component-llm-openai + operation: complete + config: + api_key_secret: "llm-api-key" + input: + prompt: '{{ entry.input.payload.text }}' +``` + +The runner expands `"llm-api-key"` to the full +`secrets://{env}/{tenant}/{team}/{pack_id}/llm-api-key` URI using the +**consuming pack's** id at resolve time. You never hand-write the URI +in the flow. + + + +## Path B — manual `greentic-secrets admin set` + +Use this only when the pack does not ship a `setup.yaml` or when you +are seeding secrets for a locally-built pack during development. + +```bash +greentic-secrets admin set \ + --tenant demo \ + --pack-id training-m1 \ + --name llm-api-key \ + --visibility team \ + --value sk-...redacted... +``` + +| Flag | Meaning | +|------|---------| +| `--tenant` | Tenant segment of the URI. | +| `--pack-id` | **Pack manifest id** — must match the consuming pack's id. | +| `--name` | Short key part of the URI (`llm-api-key` in the example). | +| `--visibility` | `team` (default) or `tenant`. Maps to the `team` segment. | +| `--value` | The secret value. Prefer `--value-stdin` in CI. | + + + +### Verifying what was written + +```bash +greentic-secrets admin list --tenant demo +``` + +This prints the URIs of all secrets visible to the tenant, which is +the fastest way to confirm the `pack_id` segment matches what the pack +is actually resolving. + +## Component manifest: empty `required` list is by design + +A pack's component manifest typically looks like: + +```yaml +capabilities: + host: + secrets: + required: [] +``` + +An empty list does **not** mean "this component uses no secrets". It +means "this component accepts any secret name; the pack and flow decide +which ones". Concrete names are fixed at flow-configuration time +(`api_key_secret: "llm-api-key"`) rather than pinned in the component. + +This design lets one WASM component (for example `component-llm-openai`) +be reused across packs with different secret conventions without +recompiling. + +## Troubleshooting + +### `Secret was not found or not provisioned for this component` + + + +1. **Check the `pack_id` segment.** The URI the runner looks up uses the + id of the pack that owns the flow, not the component id. Run + `greentic-secrets admin list --tenant ` and confirm the + `pack_id` segment matches the pack that contains the flow. + +2. **Check the `env` segment.** The CLI `--env` flag defaults to + `"demo"` in some commands and `"dev"` in others. If the runner is + started with `GREENTIC_ENV=dev`, secrets seeded under `env=demo` + will not be found. Use the same env on both sides. + +3. **Check the `team` segment.** `--visibility team` writes to + `team=default` (or the team you configured); `--visibility tenant` + writes to `team=tenant`. The flow resolves under the team scope the + pack declares. + +4. **Re-run the wizard.** If the pack ships a `setup.yaml`, running + `gtc setup --force` re-seeds the secret at the correct URI and is + safer than hand-seeding with `admin set`. + + + +### Secret value silently truncated + +Some shells interpret `$` in secret values. Use `--value-stdin` or a +single-quoted argument when the value contains shell metacharacters. + +## Next steps + +- [gtc setup](/cli/setup/) — wizard-driven seeding via `setup.yaml`. +- [Pack Format](/reference/pack-format/) — where `setup.yaml` lives in a pack. +- [Multi-Tenancy](/concepts/multi-tenancy/) — tenant, team, and environment scopes. diff --git a/src/content/docs/zh/components/cards2pack.mdx b/src/content/docs/zh/components/cards2pack.mdx index 4cfeedd..d03cbd1 100644 --- a/src/content/docs/zh/components/cards2pack.mdx +++ b/src/content/docs/zh/components/cards2pack.mdx @@ -1,37 +1,49 @@ --- title: cards2pack -description: 将 Adaptive Cards 转换为 Greentic packs +description: Convert Adaptive Cards to Greentic packs --- import { Aside, Steps } from '@astrojs/starlight/components'; -## 概述 +## Overview -**cards2pack** 是一个 CLI 工具,用于将 Adaptive Card JSON 文件转换为 Greentic packs。它会: +**cards2pack** is a CLI tool that converts Adaptive Card JSON files into Greentic packs. It: -- 扫描卡片、构建依赖图并生成 `.ygtc` flows -- 提取用于 i18n 的可翻译字符串 -- 通过 `greentic-i18n-translator` 自动翻译卡片 -- 将所有内容打包成可部署的 `.gtpack` +- Scans cards, builds a dependency graph, generates `.ygtc` flows +- Extracts translatable strings for i18n +- Auto-translates cards via `greentic-i18n-translator` +- Packages everything into a deployable `.gtpack` -## 安装 + + +## Installation ```bash cargo install greentic-cards2pack ``` -所需工具: +Required tools: ```bash cargo install greentic-flow greentic-pack cargo install greentic-i18n-translator # optional, for --auto-translate ``` -## 快速开始 +## Quick Start -1. **创建 Adaptive Cards** +1. **Create Adaptive Cards** ```json title="cards/welcome.json" { @@ -51,7 +63,7 @@ cargo install greentic-i18n-translator # optional, for --auto-translate } ``` -2. **生成 pack** +2. **Generate pack** ```bash greentic-cards2pack generate \ @@ -60,7 +72,7 @@ cargo install greentic-i18n-translator # optional, for --auto-translate --name my-pack ``` -3. **输出结果** +3. **Output** ``` my-pack/ @@ -73,61 +85,61 @@ cargo install greentic-i18n-translator # optional, for --auto-translate -## CLI 参考 +## CLI Reference ### `generate` -主命令,用于扫描卡片、生成 flows 并构建 pack。 +Main command — scan cards, generate flows, build pack. ```bash greentic-cards2pack generate [OPTIONS] ``` -| 标志 | 说明 | +| Flag | Description | |------|-------------| -| `--cards ` | Adaptive Card JSON 文件目录(必需) | -| `--out ` | 输出工作区目录(必需) | -| `--name ` | Pack 名称(必需) | -| `--strict` | 对缺失目标、重复项和无效 JSON 直接报错 | -| `--group-by ` | Flow 分组方式:`folder` 或 `flow-field` | -| `--default-flow ` | 未分组卡片的默认 flow 名称 | -| `--prompt` | 启用基于 prompt 的路由(添加 `prompt2flow` 节点) | -| `--prompt-json ` | 用于 prompt 路由的 answers JSON(需要 `--prompt`) | -| `--auto-translate` | 最多使用 8 个并行线程自动翻译卡片(需要 `greentic-i18n-translator`) | -| `--langs ` | 逗号分隔的语言代码;省略时会翻译到所有 65+ 个受支持的语言区域 | -| `--glossary ` | 用于保持翻译一致性的 glossary JSON | -| `--verbose` | 打印详细输出 | +| `--cards ` | Directory of Adaptive Card JSON files (required) | +| `--out ` | Output workspace directory (required) | +| `--name ` | Pack name (required) | +| `--strict` | Errors on missing targets, duplicates, invalid JSON | +| `--group-by ` | Flow grouping: `folder` or `flow-field` | +| `--default-flow ` | Default flow name for ungrouped cards | +| `--prompt` | Enable prompt-based routing (adds `prompt2flow` node) | +| `--prompt-json ` | Answers JSON for prompt routing (requires `--prompt`) | +| `--auto-translate` | Auto-translate cards with up to 8 parallel threads (requires `greentic-i18n-translator`) | +| `--langs ` | Comma-separated language codes; omit to translate to all 65+ supported locales | +| `--glossary ` | Glossary JSON for consistent translations | +| `--verbose` | Print detailed output | ### `extract-i18n` -将卡片中的可翻译字符串提取为一个 JSON bundle。 +Extract translatable strings from cards into a JSON bundle. ```bash greentic-cards2pack extract-i18n [OPTIONS] ``` -| 标志 | 说明 | +| Flag | Description | |------|-------------| -| `--input ` | 卡片 JSON 文件目录(必需) | -| `--output ` | 输出 JSON 路径(默认:`i18n/en.json`) | -| `--prefix ` | 键前缀(默认:`card`) | -| `--include-existing` | 包含已经带有 `$t()` 模式的字符串 | -| `--verbose` | 打印提取报告 | +| `--input ` | Directory of card JSON files (required) | +| `--output ` | Output JSON path (default: `i18n/en.json`) | +| `--prefix ` | Key prefix (default: `card`) | +| `--include-existing` | Include strings that already contain `$t()` patterns | +| `--verbose` | Print extraction report | -## 卡片识别 +## Card Identification -卡片按以下优先级识别: -1. 卡片 JSON 中的 `greentic.cardId` 字段 -2. 文件名主干(例如 `welcome.json` → `welcome`) +Cards are identified by (in order of priority): +1. `greentic.cardId` field in the card JSON +2. Filename stem (e.g., `welcome.json` → `welcome`) -卡片会按以下方式分组到 flows 中: -- action data 中的 `flow` 字段 -- `--group-by folder`(目录结构) -- `--default-flow` 兜底 +Cards are grouped into flows by: +- `flow` field in action data +- `--group-by folder` (directory structure) +- `--default-flow` fallback -## i18n 与自动翻译 +## i18n & Auto-Translation -### 提取字符串 +### Extract strings ```bash greentic-cards2pack extract-i18n \ @@ -136,7 +148,7 @@ greentic-cards2pack extract-i18n \ --verbose ``` -输出: +Output: ```json title="i18n/en.json" { @@ -147,28 +159,28 @@ greentic-cards2pack extract-i18n \ ``` -### 提取的字段类型 +### Extracted field types -| 字段 | 来源 | +| Field | Source | |-------|--------| -| `text` | TextBlock 内容 | -| `title` | Action 标题、卡片标题、toggle 标题 | -| `label` | Input 标签 | -| `placeholder` | Input 占位文本 | -| `errorMessage` | 验证错误信息 | -| `altText` | 图片替代文本 | -| `fallbackText` | 回退内容 | -| FactSet `title`/`value` | Fact 条目 | -| ChoiceSet `title` | 选项标题 | - -### 自动翻译(单条命令) +| `text` | TextBlock content | +| `title` | Action titles, card titles, toggle titles | +| `label` | Input labels | +| `placeholder` | Input placeholders | +| `errorMessage` | Validation errors | +| `altText` | Image alt text | +| `fallbackText` | Fallback content | +| FactSet `title`/`value` | Fact entries | +| ChoiceSet `title` | Choice options | + +### Auto-translate (one command) ```bash greentic-cards2pack generate \ @@ -179,7 +191,7 @@ greentic-cards2pack generate \ --langs fr,de ``` -这会从原始卡片文件中提取字符串,通过 `greentic-i18n-translator` 使用最多 8 个并发线程进行翻译,并将所有内容打包: +This extracts strings from the original card files, translates via `greentic-i18n-translator` using up to 8 concurrent threads, and bundles everything: ``` my-pack/assets/i18n/ @@ -189,12 +201,12 @@ my-pack/assets/i18n/ ``` ### Glossary -使用 glossary 来保持品牌名和技术术语一致: +Use a glossary to keep brand names and technical terms consistent: ```json title="glossary.json" { @@ -210,9 +222,9 @@ greentic-cards2pack generate \ --glossary glossary.json ``` -## Flow 生成 +## Flow Generation -生成的 flow 片段会包裹在标记中: +Generated flow sections are wrapped in markers: ```yaml # BEGIN GENERATED (cards2pack) @@ -222,18 +234,18 @@ greentic-cards2pack generate \ # Developer space below (preserved on regen) ``` -重新生成时,标记之外的内容会被保留。 +Content outside the markers is preserved when you regenerate. -### Strict 模式 +### Strict mode -启用 `--strict` 时: -- 缺失的路由目标会报错(而不是生成 stub 节点) -- 重复的 `cardId` 值会报错 -- 无效 JSON 会报错 +With `--strict`: +- Missing route targets cause errors (instead of stub nodes) +- Duplicate `cardId` values cause errors +- Invalid JSON causes errors -## 模板变量 +## Template Variables -使用 Handlebars 语法表示动态内容: +Use Handlebars syntax for dynamic content: ```json { @@ -243,10 +255,10 @@ greentic-cards2pack generate \ ``` -## 示例:带翻译的多步骤表单 +## Example: Multi-Step Form with Translation ```bash # Create cards in cards/ directory, then: @@ -260,11 +272,11 @@ greentic-cards2pack generate \ --strict ``` -请参阅 [translate-demo example](https://github.com/greentic-ai/greentic-cards2pack/tree/master/examples/translate-demo) 获取完整演练。 +See the [translate-demo example](https://github.com/greentic-ai/greentic-cards2pack/tree/master/examples/translate-demo) for a complete walkthrough. -## 下一步 +## Next Steps -- [Cards Translation Guide](/zh/i18n/cards-translation/) -- [i18n Overview](/zh/i18n/overview/) -- [Flows Guide](/zh/concepts/flows/) +- [Cards Translation Guide](/i18n/cards-translation/) +- [i18n Overview](/i18n/overview/) +- [Flows Guide](/concepts/flows/) - [Adaptive Cards Designer](https://adaptivecards.io/designer/) diff --git a/updates/2026-04-25/greentic-docs.md b/updates/2026-04-25/greentic-docs.md new file mode 100644 index 0000000..71c9379 --- /dev/null +++ b/updates/2026-04-25/greentic-docs.md @@ -0,0 +1,53 @@ +# greentic-docs — canonical patterns (2026-04-25) + +Three new Reference pages close gaps surfaced by the 3Point team and +Maarten's R1 demo debugging. Branch: `docs/canonical-patterns-2026-04-25`. + +## Pages added + +- `src/content/docs/reference/channel-data-access.mdx` — DirectLine + `channelData` -> `envelope.extensions.channel_data` -> flow template + `{{ entry.input.extensions.channel_data.* }}` -> WASM + `input.extensions.channel_data.*` (auto-merged by runner 0.5.11+). + Documents the camelCase/snake_case rename and points at the + regression test in `greentic-start/src/messaging_app.rs`. + + **Closes:** 3Point's "how do we read `r1_principals` from a flow" + question from the R1 demo; Maarten's request for a canonical + pattern after the channelData plumbing fix. + +- `src/content/docs/reference/secret-seeding.mdx` — canonical URI + scheme `secrets://{env}/{tenant}/{team}/{pack_id}/{key}`, with + preferred Path A (`setup.yaml` wizard) and fallback Path B + (`greentic-secrets admin set`). Calls out `--category` as the + legacy alias of `--pack-id` and warns that the value must be the + pack manifest id, never a component id. + + **Closes:** 3Point hitting "Secret was not found or not provisioned + for this component" because they passed `component-llm-openai` to + `--category`; Maarten's ask to make the pack-id-vs-component-id + rule explicit in docs. + +- `src/content/docs/reference/flow-node-kinds.mdx` — authoritative + list of node kinds recognised by runner 0.5.11: component nodes + plus `emit.response`, `emit.log`, `session.wait`, `flow.call`, + `provider.invoke`. Explicit gap note that no flow-callable + `state.*` builtin ships today; documents the state-memory / + state-redis backend + host-capability workaround and flags the + `qa-demo` state flow as a forward-looking (not runnable) example. + + **Closes:** 3Point's confusion about why `state.get` nodes do not + dispatch; Maarten's request to set expectations for the state + roadmap item. + +## Config change + +- `astro.config.mjs` — three new Reference sidebar entries between + `flow-schema` and `pack-format`. + +## Not done + +- Translations — will run via `scripts/translate-docs.mjs` after merge. +- State-store builtin docs — blocked on runner work (Option B framing + shipped instead of Option A because the runner does not yet + dispatch `state.*`).