CLI Specification

See Use Cases for the functional overview of all CLI commands.

Command Overview

Command Description Status

bausteinsicht init

Initialize a new architecture model with default specification, sample model, and template

Implemented

bausteinsicht sync

Bidirectional synchronization between model and draw.io diagrams

Implemented

bausteinsicht validate

Validate the architecture model for consistency and report errors/warnings

Implemented

bausteinsicht watch

Watch mode — continuously sync on file changes

Implemented

bausteinsicht add element

Add a new element to the model (LLM-friendly)

Implemented

bausteinsicht add relationship

Add a new relationship to the model (LLM-friendly)

Implemented

bausteinsicht export

Export diagram views to PNG or SVG using the draw.io CLI

Implemented

bausteinsicht export-table

Export element attributes as AsciiDoc or Markdown table per view

Implemented

bausteinsicht export-diagram

Export views as PlantUML C4 or Mermaid C4 text diagrams

Implemented

bausteinsicht --version

Display version number

Implemented

Global Flags

These flags are available on all subcommands via persistent flags on the root command.

Flag Description Default

--format text|json

Output format. json produces machine-readable output suitable for LLM and scripting use. Errors in JSON mode are written to stderr as {"error": "…​", "code": N}.

text

--model <path>

Path to the model file (.jsonc). When omitted, auto-detection scans the current directory for *.jsonc files and uses the first match.

auto-detect

--template <path>

Path to a custom draw.io template file. Must have a .drawio extension. When omitted, the built-in default template is used.

built-in template

--verbose

Enable verbose output. Verbose messages are written to stderr so they do not interfere with JSON output on stdout.

false

Note
--version is a root-level flag only, not a global flag. It is used as bausteinsicht --version and prints the version string.

Auto-Detection Behavior

When --model is not specified, all commands that require a model file invoke auto-detection:

  1. The current working directory is scanned for files matching *.jsonc.

  2. If one or more .jsonc files are found, the first match (alphabetically) is used.

  3. If no .jsonc file is found, the command exits with code 2 and an error message.

Exit Codes

Code Meaning

0

Success

1

Validation error, sync conflict, duplicate element/relationship, or partial export failure

2

File not found, I/O error, invalid arguments, or missing prerequisites

Detailed Command Specifications

bausteinsicht init

Initializes a new Bausteinsicht project in the current directory by creating a sample model, a default template, an initial draw.io diagram, and the sync state file.

Flags: No command-specific flags. Uses global flags only.

Created files:

  • architecture.jsonc — sample architecture model

  • template.drawio — default draw.io template

  • architecture.drawio — initial diagram generated via forward sync

  • .bausteinsicht-sync — sync state file

Behavior:

  • If any of the four files already exist, the command aborts with exit code 2.

  • After writing the model and template, an initial forward sync is performed to generate the draw.io diagram.

  • A page is created for each view defined in the sample model.

Exit codes:

  • 0 — project initialized successfully

  • 2 — file already exists, or I/O error

Example:

$ bausteinsicht init
Initialized Bausteinsicht project:
  - architecture.jsonc
  - template.drawio
  - architecture.drawio
  - .bausteinsicht-sync

$ bausteinsicht init --format json
{"files":["architecture.jsonc","template.drawio","architecture.drawio",".bausteinsicht-sync"],"success":true}

bausteinsicht validate

Validates the architecture model file for consistency. Reports both errors and warnings.

Flags: No command-specific flags. Uses global flags only.

Behavior:

  • Loads the model (via --model or auto-detection).

  • Runs validation checks including referential integrity and model consistency.

  • In --verbose mode, prints element/relationship/view counts to stderr before validation.

  • Warnings are printed with WARNING: prefix; errors with ERROR: prefix.

JSON output structure:

{
  "valid": true,
  "errors": [],
  "warnings": [
    {"path": "relationships[0]", "message": "..."}
  ]
}

Exit codes:

  • 0 — model is valid (may include warnings)

  • 1 — validation errors found

  • 2 — model file not found or cannot be loaded

Example:

$ bausteinsicht validate
Model is valid.

$ bausteinsicht validate --model my-arch.jsonc --verbose
Validating model: my-arch.jsonc
  5 elements, 3 relationships, 2 views
Model is valid.

$ bausteinsicht validate --format json
{
  "valid": true,
  "errors": [],
  "warnings": []
}

bausteinsicht sync

Runs one bidirectional synchronization cycle between the architecture model and the draw.io diagram.

Flags:

  • --relayout — Re-apply auto-layout to all view pages, resetting element positions to the layout engine’s computed positions. Without this flag, existing element positions are preserved.

Behavior:

  • Loads the model, draw.io document, sync state, and template.

  • Validates the model before syncing. If validation fails, the sync is aborted with exit code 1.

  • If the draw.io file is missing or has no diagram pages, it is recreated from the template and sync state is reset.

  • Pages are created for new views and orphaned pages (views removed from model) are deleted.

  • Forward sync propagates model changes to draw.io; reverse sync propagates draw.io changes back to the model.

  • Conflicts are resolved with model wins strategy.

  • Model saves preserve JSONC comments and key ordering when possible (patch save), falling back to full save for structural changes.

Derived file paths: The draw.io file and sync state file paths are derived from the model file location:

  • <model-dir>/architecture.drawio

  • <model-dir>/.bausteinsicht-sync

JSON output structure:

{
  "forward_added": 2,
  "forward_updated": 1,
  "forward_deleted": 0,
  "reverse_added": 0,
  "reverse_updated": 0,
  "reverse_deleted": 0,
  "conflicts": 0
}

Exit codes:

  • 0 — sync completed without conflicts

  • 1 — sync completed but conflicts were detected (resolved with model wins), or model validation failed

  • 2 — file not found or I/O error

Example:

$ bausteinsicht sync
Forward (model -> draw.io): 3 added, 0 updated, 0 deleted

$ bausteinsicht sync --verbose
Syncing model: architecture.jsonc
  5 elements, 3 relationships, 2 views
Forward sync: 2 elements created, 1 updated, 0 deleted; 1 connectors created, 0 updated, 0 deleted
Already in sync. No changes.

$ bausteinsicht sync --format json
{
  "forward_added": 0,
  "forward_updated": 0,
  "forward_deleted": 0,
  "reverse_added": 0,
  "reverse_updated": 0,
  "reverse_deleted": 0,
  "conflicts": 0
}

bausteinsicht watch

Watches the model and draw.io files for changes and automatically runs a sync cycle on each detected change.

Flags: No command-specific flags. Uses global flags only.

Behavior:

  • Loads the model path (via --model or auto-detection) and derives the draw.io path.

  • Both files must exist before the watcher starts (exit code 2 otherwise).

  • Uses file system notifications with debouncing to detect changes.

  • On each change, runs a full sync cycle (same logic as bausteinsicht sync).

  • Blocks until SIGINT or SIGTERM is received, then stops gracefully.

  • The watcher suppresses sync-triggered file events to avoid infinite loops.

Exit codes:

  • 0 — watcher stopped gracefully via signal

  • 2 — model or draw.io file not found, or watcher creation failed

Example:

$ bausteinsicht watch
Watching architecture.jsonc and architecture.drawio...
[14:32:05] Sync triggered by architecture.jsonc
Forward (model -> draw.io): 1 added, 0 updated, 0 deleted
^CStopped watching.

$ bausteinsicht watch --model path/to/model.jsonc
Watching path/to/model.jsonc and path/to/architecture.drawio...

bausteinsicht add element

Adds a new element to the architecture model. Designed for LLM-driven workflows.

Flags:

Flag Description Required Default

--id

Unique identifier for the element. Must match [a-zA-Z][a-zA-Z0-9_-]* (no dots).

Yes

 — 

--kind

Element kind as defined in the model’s specification section.

Yes

 — 

--title

Display title for the element. Must not be empty.

Yes

 — 

--parent

Parent element ID in dot notation (e.g., webshop.backend). The parent must exist and its kind must be a container.

No

(top-level)

--technology

Technology description for the element.

No

(empty)

--description

Element description.

No

(empty)

Behavior:

  • Validates the ID format, kind against the model specification, and parent existence.

  • Checks for duplicate elements at the target level.

  • Uses comment-preserving insertion to update the JSONC file, falling back to full save if patching fails.

  • The full element ID is <parent>.<id> when a parent is specified, or just <id> at the top level.

Exit codes:

  • 0 — element added successfully

  • 1 — invalid ID, unknown kind, parent not found, parent is not a container, or duplicate element

  • 2 — model file not found or I/O error

Example:

$ bausteinsicht add element --id api --kind component --title "REST API" \
    --parent webshop --technology "Go/Gin"
Added element 'webshop.api' (kind: component) to model.

$ bausteinsicht add element --id customer-portal --kind system --title "Customer Portal" \
    --format json
{"id":"customer-portal","kind":"system","title":"Customer Portal"}

bausteinsicht add relationship

Adds a new relationship between two existing elements. Designed for LLM-driven workflows.

Flags:

Flag Description Required Default

--from

Source element in dot notation (e.g., webshop.api).

Yes

 — 

--to

Target element in dot notation (e.g., webshop.db).

Yes

 — 

--label

Relationship label displayed on the connector.

No

(empty)

--kind

Relationship kind as defined in the model’s specification section.

No

(empty)

--description

Relationship description.

No

(empty)

Behavior:

  • Validates that both --from and --to elements exist in the model.

  • If --kind is specified, validates it against the model’s specification.

  • Checks for duplicate relationships (same from, to, and kind combination).

  • Uses comment-preserving array append to update the JSONC file, falling back to full save if patching fails.

Exit codes:

  • 0 — relationship added successfully

  • 1 — element not found, unknown kind, or duplicate relationship

  • 2 — model file not found or I/O error

Example:

$ bausteinsicht add relationship --from webshop.api --to webshop.db \
    --label "reads/writes" --kind uses
Added relationship: webshop.api -> webshop.db (reads/writes)

$ bausteinsicht add relationship --from webshop.api --to webshop.db --format json
{
  "from": "webshop.api",
  "to": "webshop.db"
}

bausteinsicht export

Exports draw.io diagram views to image files (PNG or SVG) using the draw.io CLI.

Flags:

Flag Description Required Default

--image-format

Image format for export: png or svg.

No

png

--view

Export only a specific view by its key. When omitted, all views are exported.

No

(all views)

--output

Output directory for exported files.

No

. (current directory)

--embed-diagram

Embed the draw.io XML source in the exported image file.

No

false

Behavior:

  • Loads the model and draw.io document to determine which pages to export.

  • Detects the draw.io CLI binary automatically. Exits with code 2 if not found.

  • Creates the output directory if it does not exist.

  • Output files are named <view-key>.<format> (e.g., context.png).

  • Each view page is exported individually; partial failures are reported.

JSON output structure:

{
  "files": ["./context.png", "./container.png"],
  "errors": [],
  "success": true
}

Exit codes:

  • 0 — all views exported successfully

  • 1 — one or more exports failed (partial failure)

  • 2 — unsupported format, model/diagram not found, draw.io CLI not available, or no views to export

Example:

$ bausteinsicht export
Exported: ./context.png
Exported: ./container.png

$ bausteinsicht export --image-format svg --output docs/images --view context
Exported: docs/images/context.svg

$ bausteinsicht export --format json --embed-diagram
{
  "files": ["./context.png"],
  "errors": [],
  "success": true
}

bausteinsicht export-table

Exports element attributes as an AsciiDoc or Markdown table per view or as a combined table across all views.

Flags:

Flag Description Required Default

--view

Export only a specific view by its key. When omitted, all views are exported.

No

(all views)

--table-format

Table output format: adoc (AsciiDoc) or md (Markdown).

No

adoc

--output

Output directory for exported files.

No

. (current directory)

--combined

Export a single combined table with elements from all views, deduplicated.

No

false

Behavior:

  • Loads the model and resolves view elements.

  • For each view, generates a table with columns: ID, Kind, Title, Technology, Description.

  • Elements are sorted alphabetically by ID within each table.

  • Output files are named <view-key>.adoc or <view-key>.md (e.g., context.adoc).

  • With --combined, produces a single file combined.adoc (or .md) containing all elements across views, deduplicated by ID.

  • Creates the output directory if it does not exist.

JSON output structure:

{
  "files": ["./context.adoc", "./container.adoc"],
  "success": true
}

Exit codes:

  • 0 — all tables exported successfully

  • 1 — one or more exports failed (partial failure)

  • 2 — model file not found, invalid format, or no views to export

Example:

$ bausteinsicht export-table
Exported: ./context.adoc
Exported: ./container.adoc

$ bausteinsicht export-table --table-format md --output docs/tables --view context
Exported: docs/tables/context.md

$ bausteinsicht export-table --combined --output docs/tables
Exported: docs/tables/combined.adoc

$ bausteinsicht export-table --format json
{
  "files": ["./context.adoc"],
  "success": true
}

bausteinsicht export-diagram

Exports views as PlantUML C4 or Mermaid C4 text diagrams.

Flags:

Flag Description Required Default

--view

Export only a specific view by its key. When omitted, all views are exported.

No

(all views)

--diagram-format

Diagram output format: plantuml or mermaid.

No

plantuml

--output

Output directory for exported files.

No

. (current directory)

Behavior:

  • Loads the model and resolves view elements and relationships.

  • Auto-detects the C4 level (Context, Container, or Component) from the view content.

  • Generates C4 diagram source using the appropriate macros (Person, System, System_Ext, Container, Component, System_Boundary, Container_Boundary).

  • Relationships are filtered to those visible in the view. Endpoints are lifted to visible ancestor elements when the original endpoints are not included in the view.

  • PlantUML output uses the local stdlib include syntax (!include <C4/C4_Context>, etc.).

  • Output files are named <view-key>.puml (PlantUML) or <view-key>.mmd (Mermaid).

  • Creates the output directory if it does not exist.

JSON output structure:

{
  "files": ["./context.puml", "./container.puml"],
  "success": true
}

Exit codes:

  • 0 — all diagrams exported successfully

  • 1 — one or more exports failed (partial failure)

  • 2 — model file not found, invalid format, or no views to export

Example:

$ bausteinsicht export-diagram
Exported: ./context.puml
Exported: ./container.puml

$ bausteinsicht export-diagram --diagram-format mermaid --output docs/diagrams --view context
Exported: docs/diagrams/context.mmd

$ bausteinsicht export-diagram --format json
{
  "files": ["./context.puml"],
  "success": true
}