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
npm install -g @archlang/cliThat 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.
archlang --helparchlang --version--version prints the toolchain version. --help lists the four subcommands and their flags.
archlang validate
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.
archlang validate . # current directoryarchlang validate examples/demo # a specific packagearchlang 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 droppedcheckout.arch:8:9 ERROR Process step callee 'Payments' resolves to a module, not an interfaceWatch mode
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:
- run: npm install -g @archlang/cli- run: archlang validate .Pull requests fail until validation passes. Combine with format --check below.
archlang format
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:
archlang format --check <path> # exit non-zero if anything would changearchlang 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
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
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 infoagainst 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 bashset -earchlang 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.txtFormat-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. validatefor the inner loop;checkfor CI;infofor summaries.formatnormalizes layout (whitespace, indentation, multi-line strings);--checkfor CI,--difffor 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.