CLI Architecture (packages/cloudburn)

July 29, 2026 · View on GitHub

Command Tree

graph TD
  Root["cloudburn"] --> Scan["scan [path]"]
  Root --> Discover["discover"]
  Root --> Config["config"]
  Root --> Rules["rules"]
  Root --> Estimate["estimate"]
  Root --> Completion["completion"]
  Rules --> RulesList["list"]
  Discover --> DiscoverInit["init"]
  Discover --> DiscoverStatus["status"]
  Discover --> DiscoverTypes["supported-resource-types"]
  Completion --> CompletionBash["bash"]
  Completion --> CompletionFish["fish"]
  Completion --> CompletionZsh["zsh"]

  Root -.- RootFlags["--debug\n--format json|table"]
  Scan -.- ScanFlags["--config path\n--enabled-rules ids\n--disabled-rules ids\n--exit-code\n--fail-on severity"]
  Discover -.- DiscoverFlags["--region region\n--config path\n--enabled-rules ids\n--disabled-rules ids\n--exit-code\n--fail-on severity"]
  Estimate -.- EstimateFlags["--server url"]

Formatter Pipeline

graph LR
  Command["Command action"] --> Response["CliResponse"]
  Response --> Dispatch{"resolved format"}
  Dispatch -->|json| JSON["renderResponse(..., 'json')"]
  Dispatch -->|table| Table["renderResponse(..., 'table')"]
  JSON --> Stdout
  Table --> Stdout

All stdout-producing commands return a typed CliResponse and share the same format resolver.

FormatOutput
jsonPretty JSON for the underlying response payload
tableASCII tables for scans, record lists, string lists, key/value status output, and rules list

Command Behavior

  • scan [path] is static IaC only. It accepts a Terraform file, CloudFormation template, or directory and calls CloudBurnClient.scanStatic(path, config?, { configPath? }).
  • scan accepts --config, --enabled-rules, --disabled-rules, and --service as one-off overrides on top of the config file defaults.
  • discover runs live AWS discovery and rule evaluation through CloudBurnClient.discover({ target, config?, configPath? }).
  • discover accepts --config, --enabled-rules, --disabled-rules, and --service for one-off overrides of discovery config.
  • discover --region <region> overrides the current AWS region resolved from AWS_REGION, AWS_DEFAULT_REGION, aws_region, then the AWS SDK region provider chain.
  • The CLI targets one explicit AWS region per discover run.
  • Multi-region discovery remains an SDK capability through target: { mode: 'regions', regions: [...] } and requires a Resource Explorer aggregator index.
  • discover status reports the current Resource Explorer index state and uses the shared json|table renderer.
  • discover supported-resource-types uses the shared json|table renderer.
  • discover init bootstraps Resource Explorer through the SDK, defaults to the current AWS region, accepts --region <region> as an override, and falls back to local-only setup when cross-region bootstrap is denied.
  • discover init status output includes the resolved setup indexType so users can distinguish local-only setup from aggregator setup.
  • config --init creates .cloudburn.yml in the git root (or current directory when no git root exists), unless a config file already exists there.
  • config --print prints the current discovered config file as raw YAML by default and can render table or JSON when --format is provided.
  • config --print-template prints the starter template without writing a file.
  • rules list, config, and estimate all use the shared formatter system instead of ad hoc string output.
  • completion is a structural parent command. completion bash|fish|zsh prints shell completion scripts for the selected shell.
  • --debug is a global flag that relays SDK and provider execution tracing to stderr without changing normal command output on stdout.
  • discover streams progress lines (catalog ready, datasets completed) to stderr while it runs, but only when stderr is an interactive terminal and --debug is off; piped and scripted invocations keep a quiet stderr, and stdout stays machine-parseable either way.
  • --format is documented as a global option and defaults to table, except config --print and config --print-template, which preserve raw YAML by default for redirection workflows.
  • scan and discover can also source their default format from .cloudburn.yml; explicit --format still wins.
  • The hidden __complete command exists only as the runtime hook for generated shell scripts.
  • --exit-code counts nested matches across all provider and rule groups.
  • --fail-on high|medium|low counts only active findings at or above the inclusive threshold. Suppressed findings do not count toward either gate.
  • Gate precedence is explicit --fail-on, then explicit --exit-code, then the mode's configured fail-on value.
  • Runtime errors still write a structured JSON envelope to stderr.
  • Root help configuration is shared through src/help.ts. New structural parent commands should register through registerParentCommand(...) so bare parent invocations print scoped help and future commands inherit the same help layout automatically.

Help Examples

cloudburn scan ./main.tf
cloudburn scan ./template.yaml
cloudburn scan ./iac
cloudburn scan ./iac --config .cloudburn.yml
cloudburn scan ./iac --enabled-rules CLDBRN-AWS-EBS-1,CLDBRN-AWS-EC2-1
cloudburn scan ./iac --service ec2,s3
cloudburn scan ./iac --fail-on high
cloudburn discover
cloudburn discover --region eu-central-1
cloudburn discover --config .cloudburn.yml --disabled-rules CLDBRN-AWS-S3-1
cloudburn discover --service ec2,s3
cloudburn discover --fail-on medium
cloudburn discover init
cloudburn config --init
cloudburn config --print
cloudburn config --print-template
cloudburn rules
cloudburn rules list
cloudburn rules list --service ec2 --source discovery --severity high
cloudburn completion
cloudburn completion zsh
cloudburn --format json scan ./iac

Exit-Code Contract

ConstantValueMeaning
EXIT_CODE_OK0No active finding meets the selected gate, or no gate is configured
EXIT_CODE_POLICY_VIOLATION1An active finding meets --fail-on, configured fail-on, or the any-finding gate
EXIT_CODE_RUNTIME_ERROR2Runtime failures and usage errors (invalid options or arguments)

Usage errors — unknown options or invalid option arguments such as an unknown --service value or a malformed --region — exit with 2, not Commander's default 1. Exit code 1 stays reserved for policy violations so CI pipelines can distinguish "findings exist" from "the command was invoked incorrectly". Help and version output exit with 0.