Skip to content

cards2pack

cards2pack is a CLI tool that converts Adaptive Card JSON files into Greentic packs. It:

  • 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
Terminal window
cargo install greentic-cards2pack

Required tools:

Terminal window
cargo install greentic-flow greentic-pack
cargo install greentic-i18n-translator # optional, for --auto-translate
  1. Create Adaptive Cards

    cards/welcome.json
    {
    "type": "AdaptiveCard",
    "version": "1.4",
    "body": [
    { "type": "TextBlock", "text": "Welcome!", "size": "Large" },
    { "type": "TextBlock", "text": "How can I help you today?" }
    ],
    "actions": [
    {
    "type": "Action.Submit",
    "title": "Get Started",
    "data": { "flow": "demo", "step": "next-card" }
    }
    ]
    }
  2. Generate pack

    Terminal window
    greentic-cards2pack generate \
    --cards ./cards \
    --out ./my-pack \
    --name my-pack
  3. Output

    my-pack/
    pack.yaml
    flows/main.ygtc
    assets/cards/welcome.json
    dist/my-pack.gtpack
    .cards2pack/manifest.json

Main command — scan cards, generate flows, build pack.

Terminal window
greentic-cards2pack generate [OPTIONS]
FlagDescription
--cards <DIR>Directory of Adaptive Card JSON files (required)
--out <DIR>Output workspace directory (required)
--name <NAME>Pack name (required)
--strictErrors on missing targets, duplicates, invalid JSON
--group-by <MODE>Flow grouping: folder or flow-field
--default-flow <NAME>Default flow name for ungrouped cards
--promptEnable prompt-based routing (adds prompt2flow node)
--prompt-json <FILE>Answers JSON for prompt routing (requires --prompt)
--auto-translateAuto-translate cards with up to 8 parallel threads (requires greentic-i18n-translator)
--langs <CODES>Comma-separated language codes; omit to translate to all 65+ supported locales
--glossary <FILE>Glossary JSON for consistent translations
--verbosePrint detailed output

Extract translatable strings from cards into a JSON bundle.

Terminal window
greentic-cards2pack extract-i18n [OPTIONS]
FlagDescription
--input <DIR>Directory of card JSON files (required)
--output <FILE>Output JSON path (default: i18n/en.json)
--prefix <PREFIX>Key prefix (default: card)
--include-existingInclude strings that already contain $t() patterns
--verbosePrint extraction report

Cards are identified by (in order of priority):

  1. greentic.cardId field in the card JSON
  2. Filename stem (e.g., welcome.jsonwelcome)

Cards are grouped into flows by:

  • flow field in action data
  • --group-by folder (directory structure)
  • --default-flow fallback
Terminal window
greentic-cards2pack extract-i18n \
--input ./cards \
--output i18n/en.json \
--verbose

Output:

i18n/en.json
{
"card.welcome.body_0.text": "Welcome!",
"card.welcome.body_1.text": "How can I help you today?",
"card.welcome.actions_0.title": "Get Started"
}
FieldSource
textTextBlock content
titleAction titles, card titles, toggle titles
labelInput labels
placeholderInput placeholders
errorMessageValidation errors
altTextImage alt text
fallbackTextFallback content
FactSet title/valueFact entries
ChoiceSet titleChoice options
Terminal window
greentic-cards2pack generate \
--cards ./cards \
--out ./my-pack \
--name my-pack \
--auto-translate \
--langs fr,de

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/
en.json # English (source)
fr.json # French
de.json # German

Use a glossary to keep brand names and technical terms consistent:

glossary.json
{
"Greentic": "Greentic",
"Dashboard": "Dashboard"
}
Terminal window
greentic-cards2pack generate \
--cards ./cards --out ./pack --name demo \
--auto-translate --langs fr,de \
--glossary glossary.json

Generated flow sections are wrapped in markers:

# BEGIN GENERATED (cards2pack)
# ... generated nodes ...
# END GENERATED (cards2pack)
# Developer space below (preserved on regen)

Content outside the markers is preserved when you regenerate.

With --strict:

  • Missing route targets cause errors (instead of stub nodes)
  • Duplicate cardId values cause errors
  • Invalid JSON causes errors

Use Handlebars syntax for dynamic content:

{
"type": "TextBlock",
"text": "Hello, {{name}}!"
}
Terminal window
# Create cards in cards/ directory, then:
greentic-cards2pack generate \
--cards ./cards \
--out ./checkout-pack \
--name checkout \
--auto-translate \
--langs fr,ja,es \
--glossary glossary.json \
--strict

See the translate-demo example for a complete walkthrough.