Skip to content

21. The CLI

The archlang CLI is small on purpose. Four subcommands cover the entire ground a working project needs: validate a package, format files, run derived checks, and summarize a package. No serve, no diff, no plugins — the editor extensions and the viewer cover those surfaces. This chapter walks through what each subcommand does, what flags it takes, and how to fit them into CI and pre-commit hooks.

Install

Terminal window
npm install -g @archlang/cli

That puts archlang on your PATH. The CLI is a thin layer over @archlang/core, @archlang/parser, and @archlang/lsp — everything in node_modules for those packages ships inside the binary. No native dependencies, no Java, no Docker.

Terminal window
archlang --help
archlang --version

--version prints the toolchain version. --help lists the four subcommands and their flags.

archlang validate

Terminal window
archlang validate <path>

Parses every .arch file under <path> (recursively, respecting nested package.archspace boundaries), runs the resolver, runs the validator. Prints diagnostics to stdout. Exits non-zero if anything failed.

Terminal window
archlang validate . # current directory
archlang validate examples/demo # a specific package
archlang validate orders.arch # a single file (its package is auto-detected)

The diagnostics use the same format the LSP produces, which means the same error you see in your editor is the one the CLI prints. Examples:

orders.arch:14:5 ERROR Required field 'team' is not fulfilled and not dropped
checkout.arch:8:9 ERROR Process step callee 'Payments' resolves to a module, not an interface

Watch mode

Terminal window
archlang validate --watch <path>

Re-runs validation on every .arch save. Useful for keeping a terminal pane open next to your editor when you don’t want to enable the inline preview.

CI use

The non-zero exit code is the contract. In CI:

.github/workflows/arch.yml
- run: npm install -g @archlang/cli
- run: archlang validate .

Pull requests fail until validation passes. Combine with format --check below.

archlang format

Terminal window
archlang format <path>

Rewrites the file (or every .arch file under a directory) into canonical form: normalized whitespace, consistent indentation, dedented multi-line strings. The formatter does not change semantic content — it only normalizes layout.

Two flags change behavior:

Terminal window
archlang format --check <path> # exit non-zero if anything would change
archlang format --diff <path> # print the diff that would be applied, but don't write

--check is the CI flag. --diff is the local “what would this do?” flag.

Stable IDs

Stable IDs are minted by the toolchain when a declaration is created without one. Editor extensions handle this on save through the language server. From the CLI, the relevant step happens through format and validate paths that touch source. Don’t hand-edit stable IDs once written; renames anchor on them (Chapter 13).

archlang check

Terminal window
archlang check <path>

Runs validate and additionally runs every derived check the validator can produce: cascade integrity, label invariants, process step well-formedness, cross-package reference resolution, missing-required-blank detection.

check is the heavier sibling of validate. Use validate in the inner editor loop where you want fast feedback; use check in CI and at major checkpoints.

archlang info

Terminal window
archlang info <path>

Prints a summary of the package: name, version, dependencies, every module with its kind and team, every interface with its kind, every process with its step count, every view.

Use cases:

  • Onboarding. New team member runs archlang info against the package they’re about to work in; they get a one-screen overview without opening files.
  • CI artifacts. Save the output as a build artifact so PR reviewers can see what a branch’s architecture looks like at a glance.
  • Migration audits. Run against a legacy package being modeled, then re-run after each refactor pass.

Combining the commands

A representative pre-commit hook:

#!/usr/bin/env bash
set -e
archlang format --check .
archlang validate .

A representative CI job:

- run: npm install -g @archlang/cli
- run: archlang format --check .
- run: archlang check .
- run: archlang info . > arch-summary.txt
- uses: actions/upload-artifact@v4
with:
name: arch-summary
path: arch-summary.txt

Format-check ensures every file is canonical. check runs the full validator. info produces the artifact for reviewers.

Exit codes

Treat any non-zero exit as failure for CI purposes. The CLI returns:

  • 0 — success, no errors.
  • Non-zero — errors, usage problems, or watch mode interrupted.

format --check returns non-zero if anything would be reformatted. validate --watch runs until you Ctrl-C; exit code reflects the last validation result.

What the CLI doesn’t do

  • No viewer or server. Diagrams are rendered by the editor extensions (inline preview) or the hosted/embedded viewer (Chapter 23). The CLI doesn’t ship a renderer.
  • No diff subcommand. Diff is exposed as a library API (Chapter 24) and surfaced by the viewer in diff mode. Pipelines that need diff output consume the library.
  • No language-server stdio runner. Editor extensions bundle the LSP directly. If you’re building your own editor integration, see Chapter 22.
  • No plugin system. Everything the CLI does is one of these four subcommands. Customization happens via the library APIs.

Summary

  • Four subcommands: validate, format, check, info.
  • validate for the inner loop; check for CI; info for summaries.
  • format normalizes layout (whitespace, indentation, multi-line strings); --check for CI, --diff for local introspection.
  • Exit codes are stable; pipelines key off them.
  • No renderer, no diff command, no plugin system — those live elsewhere by design.

What’s next

Chapter 22: Editor Integration → — what the LSP gives you in VS Code and JetBrains.