CLI Tools

The boa command-line interface for managing blocks, workflows, and projects.

Command Reference

All commands are run from your project root directory.

Command Description Example
boa init Initialize a new BOA project boa init
boa block create <Name> Scaffold a new block boa block create MyBlock --layer domain --runtime node
boa registry-ls List all registered blocks boa registry-ls
boa test <BlockRef> Run FIXTURE tests for a block boa test Add@1.0.0
boa validate Validate all blocks, fixtures, and workflow wiring boa validate
boa impact <BlockRef> Show where a block is used boa impact CalculateOrderValue@1.0.0
boa run <workflow> --input-file <file> Execute a workflow boa run workflows/order/workflow.boa --input-file data.json

boa init

Creates the scaffolding for a new BOA project in the current directory. This generates all the files and folders you need to start building blocks and workflows.

Generated Structure

  • project.boa — Project manifest with name, version, and description
  • blocks.boa — Block registry (initially empty)
  • src/ — Source directory with layer subdirectories
  • workflows/ — Workflow definitions directory

Example

# Create and enter a new project directory
$ mkdir MyProject && cd MyProject

# Initialize the BOA project
$ boa init

  CREATE project.boa
  CREATE blocks.boa
  CREATE src/
  CREATE src/Primitives/
  CREATE src/Capabilities/
  CREATE src/DomainBlocks/
  CREATE workflows/

  Project initialized successfully.

boa block create

Scaffolds a new block with all required files. The block is automatically registered in blocks.boa.

Options

Option Description Default
--layer <layer> Block layer: primitive capability domain workflow interface ui-block ui-capability domain
--runtime <runtime> Runtime environment: node, python, js node
--group <group> Subdirectory within the layer folder for organizing related blocks (none)

Generated Files

  • block.boa — Block manifest with BLOCK, LAYER, RUNTIME, ENTRY, and placeholder INTENT, RULE, FIXTURE
  • index.ts (or main.py for Python) — Implementation file with URP boilerplate
  • test file — Test scaffold
  • README.md — Block documentation

Example

$ boa block create ComputeDiscount --layer domain --runtime node --group Pricing

  CREATE src/DomainBlocks/Pricing/ComputeDiscount/block.boa
  CREATE src/DomainBlocks/Pricing/ComputeDiscount/index.ts
  CREATE src/DomainBlocks/Pricing/ComputeDiscount/test/
  CREATE src/DomainBlocks/Pricing/ComputeDiscount/README.md
  UPDATE blocks.boa

  Block ComputeDiscount@1.0.0 created successfully.

The generated block.boa will look like this:

BLOCK ComputeDiscount 1.0.0
LAYER domain
RUNTIME node
ENTRY index.js
DESC TODO: Describe what this block does.
INTENT TODO: The user's original requirement.

RULE TODO: Business rule or constraint.

IN inputField:type!
OUT outputField:type

FIXTURE {"inputField":"value"} -> {"outputField":"expected"}

boa registry-ls

Lists all blocks registered in blocks.boa for the current project. Displays each block's name, version, and path.

Example

$ boa registry-ls

  BLOCK                          VERSION   PATH
  Add                            1.0.0     src/Primitives/Math/Add
  Multiply                       1.0.0     src/Primitives/Math/Multiply
  FormatString                   1.0.0     src/Primitives/String/FormatString
  CalculateOrderValue            1.0.0     src/DomainBlocks/Order/CalculateOrderValue
  ComputeTax                     1.0.0     src/DomainBlocks/Order/ComputeTax

  5 blocks registered.

boa test

Runs the FIXTURE declarations from a block's block.boa manifest. Each fixture defines an input/output pair that the block must satisfy.

How It Works

  • Backend blocks (node, python runtime) — Spawns a child process using the Universal Runtime Protocol (URP). Sends the fixture input as a JSON envelope on STDIN and validates the output on STDOUT.
  • UI blocks (ui-block / ui-capability with js runtime) — Imports the module directly and calls the default exported function with the fixture input.
  • Capability blocks with MOCK — Validates that contract shapes match (input/output keys align with the manifest's IN/OUT declarations).

Example

$ boa test Add@1.0.0

  Testing Add@1.0.0 (node)
  OK   fixture 1: {"a":3,"b":5} -> {"result":8}
  OK   fixture 2: {"a":-1,"b":1} -> {"result":0}

  Results: 2 passed, 0 failed
Tip Every block should include at least one FIXTURE declaration. This makes blocks self-testing — no separate test files needed.

boa validate

Runs a comprehensive validation across the entire project. This is the single command you need to verify everything is wired correctly.

Validation Steps

  1. Block manifests — Verifies that every entry in blocks.boa points to a valid block directory with a loadable block.boa manifest.
  2. Fixtures — Runs all FIXTURE and MOCK tests for every registered block.
  3. Workflow wiring — Validates all MAP references in workflow files, ensures referenced blocks exist in the registry, and checks that step IDs are unique.

Example

$ boa validate

  --- Block Manifests ---
  OK  Add@1.0.0
  OK  Multiply@1.0.0
  OK  FormatString@1.0.0
  OK  CalculateOrderValue@1.0.0
  OK  ComputeTax@1.0.0

  --- Fixtures ---
  OK  Add@1.0.0            2/2 passed
  OK  Multiply@1.0.0       2/2 passed
  OK  FormatString@1.0.0   1/1 passed
  OK  CalculateOrderValue  2/2 passed
  OK  ComputeTax@1.0.0     1/1 passed

  --- Workflow Wiring ---
  OK  workflows/math/workflow.boa       (2 steps)
  OK  workflows/order/workflow.boa      (3 steps)

  --- Summary ---
  Blocks:    5 registered, 5 valid
  Fixtures:  8 passed, 0 failed
  Workflows: 2 valid, 0 errors
  Status:    OK All valid
Best Practice Run boa validate after every change to blocks or workflows. It catches broken references, missing blocks, and failing fixtures before they become runtime errors.

boa impact

Shows the blast radius of changing a block. Before modifying any existing block, run this command to understand what depends on it and what might be affected.

What It Reports

  • Which workflows use the block
  • What data it receives (MAP inputs from upstream steps)
  • What downstream steps consume its output
  • Whether it is used as an ON_ERROR handler
  • WHEN conditions on the step (conditional execution)

Example

$ boa impact CalculateOrderValue@1.0.0

  Impact analysis for CalculateOrderValue@1.0.0

  --- Used in Workflows ---
  workflows/order/workflow.boa
    Step: calcValue
    MAP inputs:
      items <- _initial.items
    Consumed by:
      calcTax.subtotal <- calcValue.subtotal
      format.total     <- calcTax.total (indirect)
    ON_ERROR: none
    WHEN:     none

  --- Summary ---
  Workflows affected: 1
  Downstream steps:   2
  Risk level:         MEDIUM
Warning Always run boa impact before modifying an existing block. Changing a block's output shape can break downstream steps in workflows that depend on it.

boa run

Executes a backend workflow end-to-end. Each step in the workflow is run sequentially, with data passed between blocks via the workflow context.

Options

Option Description
--input-file <path> Path to a JSON file containing the workflow input. The contents are available as _initial in MAP expressions.

Example

Given an input file order.json:

{
  "items": [
    { "price": 50, "quantity": 2 },
    { "price": 30, "quantity": 1 }
  ],
  "taxRate": 0.08,
  "template": "Order total: ${total}"
}

Run the workflow:

$ boa run workflows/order/workflow.boa --input-file order.json

  STEP calcValue   = CalculateOrderValue@1.0.0  OK  (12ms)
  STEP calcTax     = ComputeTax@1.0.0             OK  (8ms)
  STEP format      = FormatString@1.0.0           OK  (4ms)

  --- Output ---
  {
    "result": "Order total: $140.40"
  }

  Workflow completed in 24ms.
Windows Users On Windows, always use --input-file instead of piping JSON via echo. The Windows echo command strips double quotes from JSON strings, causing parse errors.