Docs
Command line
Every adm command and subcommand with its flags. adm <command> --help prints the same for the installed version; commands that tools read have a --json form.
Source code
Compile, check, format, run and test what is in the tree. Every command takes the current directory as its tree unless a path or names say otherwise.
adm build
adm build [targets...] [flags]
Builds the applications, libraries and plugins found in a source tree. Without names every unit is built; names select units of any kind, a directory or .adm file argument is the source path. An application becomes an executable, a library an .admlib source package (its permissions audited into the manifest), a plugin an .admplugin.
| Flag | Meaning |
|---|---|
--apps / --libs / --plugins | Build only that kind of unit. |
--path DIR | Build only targets under the directory (default .). |
--out DIR | Output directory for built binaries (default: the current directory). |
--release | Fully optimized (-O3 -DNDEBUG, drops debug-only runtime diagnostics); the default is -O2. |
--debug | Unoptimized with debug info (-O0 -g). |
--backend llvm|c | Compiler backend (default llvm). |
--os, --arch | Target platform (defaults to the host). |
--platforms a,b | Build several <os>-<arch> at once; plugins merge into one .admplugin. A cross target needs ADM_SYSROOT_<OS>_<ARCH>. |
--runtime static|shared | Runtime linkage; shared is required to load plugins. |
--features a,b | Comma-separated feature list. |
--deps-only / --no-deps | Build only dependencies of the selected targets, or none of them. |
--no-cache | Disable IR caching. |
--perf | Show performance metrics. |
adm build App1 acme.imaging
adm build --libs samples/imaging
adm build App1 --release --os linux --arch arm64
adm check
adm check [paths...] [flags]
Semantic analysis without building: parses, resolves and type-checks, then prints diagnostics. adm check --all std validates the standard library.
| Flag | Meaning |
|---|---|
--all | Show every error (same as --limit=0). |
--limit N | Maximum number of errors shown (default 10). |
--context N | Lines of context around each error (default 2). |
--exclude GLOB | Skip paths matching the globs. |
--json | Diagnostics as JSON. |
--perf | Show performance metrics. |
adm doc
adm doc [module-or-symbol] [flags]
Documentation from the compiler's own resolver: a module's exports with signatures and doc comments, a workspace overview, or a symbol search across modules. Methods, fields and properties are not module exports and do not appear in a search; the language server and the MCP server's adm_symbol find those.
| Flag | Meaning |
|---|---|
--module, -m NAME | One module's exports (std.io, builtin for the prelude). |
--search, -s NAME | Find a symbol by name across modules. |
--workspace | Workspace-wide module overview. |
--json | Documentation as JSON, with kindName and per-type members. |
--full-doc | Include doc comments in the workspace listing. |
--root PATH | Workspace roots or files to load (default .). |
--no-std | Skip the standard library. |
--plugin FILE | What an .admplugin exports, from its metadata alone. |
--exclude GLOB | Skip paths matching the globs. |
adm doc --module std.io
adm doc --search readFile
adm doc --workspace --root std --no-std
adm fmt
adm fmt [paths...] [flags]
Formats .adm files in place; the authoritative formatting, so never hand-align.
| Flag | Meaning |
|---|---|
--check | Report files that would change without writing. |
--diff | Print a diff instead of rewriting. |
--stdin | Read source from stdin and write the result to stdout. |
--include / --exclude GLOB | Limit to files whose base name matches. |
--write | Write the result back (default on). |
adm fmt
adm fmt --check src/
adm run
adm run [appName] [-- appArgs...] [flags]
Builds an application, runs it and removes the executable afterwards. Arguments after -- go to the program.
| Flag | Meaning |
|---|---|
--keep | Keep the executable. |
--watch | Rebuild and restart whenever a source file changes. |
--path DIR | Build targets under the directory. |
--release / --debug | Optimization level, as for build. |
--backend, --os, --arch, --features, --no-cache | As for build. |
adm run
adm run MyApp -- --help
adm test
adm test [paths...] [flags]
Builds and runs the check suites under the paths (adm test std runs the whole standard library's). Only tests whose files lie under the paths run; the standard library and the dependencies the runner links are left out unless named. Each program gets its own scratch application folder through ADM_APP_HOME, so suites never touch real user folders.
| Flag | Meaning |
|---|---|
--run TEXT | Only tests whose name contains the text (repeatable; = prefix for an exact match). |
--file TEXT | Only tests whose source file contains the text. |
--list / --list-bench | List discovered tests or benchmarks without running. |
--bench TEXT | Run benchmarks matching the text (. for all); --bench-count, --bench-time shape the run. |
--coverage | Emit a clang coverage profile to ./adm_test.profraw (--coverage-out names the file). --coverage-report prints the line coverage of the modules whose tests ran and keeps the profile in the build's temporary folder; with --json it also reports every module and every source line as covered, partly covered or not covered. --coverage-per-test re-runs each test on its own (slow). Only the C backend instruments module bodies, so pass --backend c for coverage. |
--json | Machine-readable output. With --list: a JSON array of tests (name, module, file, line). Otherwise one JSON event per line (status, diagnostic, run, pass, fail, skip, output, summary, coverage, file_coverage, error, done); the IDE test panel reads this. |
--build-only | Build the runner and print ADM_TEST_BIN=<path>. |
--out DIR | Keep the compiled runner there. |
--backend, --release, --debug, --no-cache | As for build. |
adm test std/services
adm test --run TestRule std/services
adm test --list --json std/io
adm test --json --coverage-report --backend c .
adm package build
adm package build --app NAME [flags]
Builds a tar.gz release artifact from the [package] rules of adm.toml, versioned from [apps.<Name>] (0.1 when unset), optionally signed.
| Flag | Meaning |
|---|---|
--app NAME | Application to package (required). |
--dir DIR | Where to look for adm.toml (walks up). |
--out PATH | Artifact path (default ./dist/<app>-<version>.tar.gz). |
--sign | Sign the artifact; --key names the private key, --sig-out the signature file (default <artifact>.zsig). |
adm package install
adm package install <artifact.tar.gz> [flags]
Installs a release artifact into the user's application directory, versioned, and updates the current symlink.
| Flag | Meaning |
|---|---|
--sig PATH | Signature file (default <artifact>.zsig). |
--no-verify | Skip signature verification. |
--bin NAME | Symlink name under ~/.local/bin (default: the signed app name). |
Project and application
The manifest, the application's identity and policy, the units and dependencies of a tree.
adm list
adm list [DIR] [flags]
Lists every application, library and plugin declared under a directory: kind, name, file and line, folder, the nearest adm.toml above it and its version. A monorepo lists many units, some with a manifest and some without.
| Flag | Meaning |
|---|---|
--json | One object per unit: kind, name, file, line, dir, manifest (or null), version. |
adm list testdata/apps --json
adm list packages
adm list packages [--dir DIR] [flags]
The project's dependencies from adm.lock: version, whether each is installed, the newest version the registry offers, the permissions accepted at install, the description, and the package's own requirements (the permissions its code reaches, with the chains).
| Flag | Meaning |
|---|---|
--dir DIR | Project directory (walks up to the nearest adm.lock). |
--no-pull | Use the local registry clone without pulling, however old it is. |
--json | One object per package; the same shape as adm lib --json. |
adm audit
adm audit [DIR] [flags]
Lists the permissions a package's code reaches: every function is walked and each call followed, through the standard library and dependencies, to the gated functions it can reach (a service method with @commit(policy = ...) or @query(policy = ...), a function with @requires). Each permission comes with the chain that reaches it; an @on observer of a gated commit is listed as observe, and files binding foreign code (@c, @native) are named, since no policy can verify them. In a library tree the package is each library's exported modules and their closure; elsewhere it is the application's own modules. A library build writes the same set into the package manifest and fails when adm.toml narrows it with [requires] permissions = [...] to less than the code reaches.
| Flag | Meaning |
|---|---|
--library NAME | Audit one library of the tree. |
--json | {package, requirements: [{permission, observe, via, sites, description, spec, fields}], foreign} per package. sites runs parallel to via: the file and line where each hop of the chain is declared, relative to the audited directory. |
--catalog | Instead of what the code reaches, every permission the program's services declare, with its description and rule fields; --json gives [{permission, description, fields}]. The IDE's permission picker for [requires] reads it. |
adm audit
adm audit testdata/desktop_apps/opengl_window
adm app init
adm app init [flags]
Generates adm.toml with a fresh Ed25519 publisher key and repo salt, and writes the private key outside the repository (~/.config/adm/keys/<publisher id>.ed25519).
| Flag | Meaning |
|---|---|
--dir DIR | Where to write the manifest. |
--private-key-out PATH | Where to write the private key. |
--git | Initialize a git repository and a .gitignore. |
--force | Overwrite an existing manifest. |
adm app info
adm app info [--dir DIR] [--app NAME] [flags]
The application's identity and everything adm.toml configures: publisher (id, public key, salt presence, private key path and whether it exists, creation date), the resolved app id, name, version and update feed, the [apps] tables, packaging rules, dependencies, registries, the [requires] narrowing and the policy flag. Without a manifest the identity comes from the application declaration.
| Flag | Meaning |
|---|---|
--json | The whole tree as one object; manifest is null without an adm.toml. |
adm app set
adm app set <table.key> <value> [--dir DIR] [--app NAME]
Writes one adm.toml value, keeping every other line and comment: the key's line is replaced, appended to its table, or the table is appended. With --app, version, slug, update.* and package.* address that application's tables. Values are written by the key's type: policy.sandbox as a bool, requires.permissions and registries.order as arrays from a comma list, everything else as a string. package.files replaces the whole file-rule list from from=>to[:mode], ...; without --app it writes the file-level [package] table, which is what a library or plugin build ships under files/. adm package build adds every installed library's shipped files to the archive under share/<namespace>/<name>/ on its own. Quote a segment holding a dot or a colon: apps."My App".version, deps."acme:utils".
adm app set --app Main version 1.2.0
adm app set update.feed https://example.com/feed.json
adm app set registries.order "corp, public"
adm app set --app Main package.files "dist/app=>bin/app:0755, README.md=>share/doc/README.md"
adm app unset
adm app unset <table.key | table> [--dir DIR] [--app NAME]
Removes one key, or a whole table when the name is one: registries.acme drops [registries.acme] and takes it out of the order list; with --app, package.files drops every file rule.
adm app bump
adm app bump <major|minor|patch> --app NAME [--dir DIR]
Increments the application's version in adm.toml.
adm app id
adm app id [AppName] [--dir DIR]
Prints the resolved identity and update configuration the build bakes in as __app_id__, __app_name__, __app_version__ and the update constants.
adm app rekey
adm app rekey [--dir DIR] [--private-key-out PATH]
Gives an existing manifest a new key pair and repo salt, rewriting [publisher] in place and writing the new private key where init would. The publisher id and every app id change with it; signing looks only at the default key path or ADM_SIGNING_KEY, so a custom key path needs the variable.
adm app sign
adm app sign <artifact> [flags]
Signs an artifact with the manifest's publisher key.
| Flag | Meaning |
|---|---|
--app NAME | Which application, when the tree builds several. |
--key PATH | Private key (default: the publisher's file under the XDG config directory). |
--out PATH | Signature file (default <artifact>.zsig). |
--force | Overwrite an existing signature. |
adm app verify
adm app verify <artifact> [--sig PATH]
Verifies an artifact's signature.
adm app policy init
adm app policy init [--dir DIR] [--app NAME] [--force]
Writes a commented policy.toml template into the application's folder (ADM_APP_HOME, else ~/.local/share/<app name>): the grants compiled into the program per package, then one table per held permission with the fields it can narrow. The Policy service reads the file at startup; it can only narrow what the build granted.
| Flag | Meaning |
|---|---|
--force | Overwrite an existing file. |
adm app policy set
adm app policy set [--package ns:name] <permission> <field.kind|setting> <values>
adm app policy set [--package ns:name] <permission> allow|deny|ask
Writes one rule into policy.toml, for the whole program or for one dependency: field.allow, field.deny or field.ask with a comma-separated list (globs, IPv4 networks, ${app.home}), or a scalar setting. A kind alone rules on the permission as a whole, the field *, which is the only rule a permission without fields (adm.clipboard.read, adm.runtime.spawn, adm.notifications.show) can have: it writes "*".deny = ["*"]. The file is created when missing.
adm app policy set adm.network.connect host.deny "*.example.net, 10.0.0.0/8"
adm app policy set --package acme:imaging adm.storage.read path.allow "${app.home}/**"
adm app policy set adm.clipboard.read deny
adm app policy unset
adm app policy unset [--package ns:name] <permission> <field.kind|setting>
Removes one rule.
adm app policy get
adm app policy get [--json]
Prints every rule of the file: subject (* or the package), permission, field (* for a rule on the whole permission), kind and values.
adm app policy log
adm app policy log [--dir DIR] [--app NAME] [--clear]
Prints the decision log the Policy service keeps beside the file: denials, asks, live answers, file loads, the sandbox report. --clear deletes the log; the service starts a fresh one at its next decision.
adm lib
adm lib [--dir DIR] [flags]
Lists the libraries the project depends on: version, publisher, where each came from, whether it is in the cache or in vendor/, and a newer registry version when one exists.
| Flag | Meaning |
|---|---|
--json | One object per package, the shape of adm list packages --json. |
--no-pull | Use the local registry clone without pulling, however old it is. |
adm lib remove
adm lib remove [namespace:]name [--dir DIR]
Drops a dependency from adm.lock and its line from [deps] in adm.toml; the cached package stays for other projects.
adm lib verify
adm lib verify <package.admlib | plugin.admplugin> [flags]
Reads a container the way the compiler does before using one: every file must match the checksums and the publisher signature must verify. Prints name, version, publisher id, SHA-256 and dependencies; exits non-zero on a corrupt, tampered or unsigned container.
| Flag | Meaning |
|---|---|
--allow-unsigned | Accept a container with no publisher. |
--json | One object, what the registry's gatekeeper reads. |
adm new
adm new
Generates boilerplate: modules, services, views.
Not implemented yet; prints a placeholder and exits.
Package manager
Fetching, installing, publishing and vendoring libraries; see the Libraries page for the model behind them.
adm get
adm get [namespace:]name[@range] ... [flags]
Resolves each library in the configured registries, picks the highest version in range that is not yanked, downloads the container from the library's own repository, verifies it (index hash, checksums, signature, publisher, module ownership) and installs it into the package cache, recording it in adm.lock; dependencies the library declares follow. Then the permissions the package asks for are shown as a checklist, grouped by package, with one more row when the package binds foreign code (@c, @link, @native, @extern); the accepted set goes into the lock (permissions=, and foreign=yes for the bindings) and a later version asking for more, or starting to bind foreign code, is refused until accepted again. With no arguments every [deps] entry the lock does not cover yet is fetched.
| Flag | Meaning |
|---|---|
--accept all|none|LIST | Grant without asking: everything, nothing, or a comma-separated list of names and globs (adm.storage.*); the token foreign in a list accepts the package's foreign code (all includes it). Required without a terminal. |
--dir DIR | Project whose lock to update. |
--dry-run | Resolve and report, install nothing; with --json the container is fetched and described (permissions, foreign files, dependencies) without installing. |
--json | The installed packages as JSON, progress on stderr. |
--no-pull | Use the local registry clone without pulling, however old it is. |
--trust | Accept a publisher other than the one the lock pinned. |
adm get acme:imaging
adm get acme:imaging@^1.4 --accept adm.storage.*
adm install
adm install [package.admlib | URL ...] [flags]
Installs .admlib packages from files or URLs into the cache and records them in adm.lock, with the same verification and the same permission checklist as get. With no arguments every package the lock names but the cache lacks is fetched again from its recorded source.
| Flag | Meaning |
|---|---|
--accept, --dir, --json, --trust | As for get. |
--namespace NAME | Namespace to file a package under (a file install defaults to local). |
adm install ../lib/acme.files-0.1.admlib --accept all
adm publish
adm publish [flags]
In a library's source tree with a clean git working tree and a GitHub origin: builds and signs the .admlib, commits it as dist/<name>-<version>.admlib, tags v<version>, pushes, and opens a pull request on the registry adding the index line. Refuses when the version is not newer than the registry's, when nothing signs the package, or when the tree is dirty.
| Flag | Meaning |
|---|---|
--description TEXT | One line saying what the library is (required, shown by search). |
--library NAME | Which library, when the tree declares several. |
--registry NAME | Registry from adm.toml (default: the first). |
--dry-run | Build and print the index line, touch nothing. |
--no-pr | Push the release but print the index line instead of opening the pull request. |
--dir DIR | Library source directory. |
adm search
adm search [text] [flags]
Lists every library whose name, namespace or description contains the text (all of them without text). The registries are pulled when their local clones are more than an hour old (ADM_CATALOG_MAX_AGE, a Go duration, changes that).
| Flag | Meaning |
|---|---|
--json | Hits as JSON: namespace, name, latest, description, repo, publisher, date, registry, every version newest first. |
--indexes | List the registry indexes the project uses (--json: name, url, official, local catalog) instead of searching. |
--refresh | Pull every registry clone now, however recent the last pull; alone, just refresh. |
--no-pull | Use the local clones without pulling, however old they are. |
--dir DIR | Project whose adm.toml names the registries. |
adm search humanize
adm vendor
adm vendor [--dir DIR]
Copies every locked package from the cache into vendor/ beside the lock, the same layout; when that directory exists the compiler and the language server read dependencies from it instead of ~/.adm/pkg, so a checkout builds without get or network access.
Developer tools
Compiler internals and editor integration.
adm dump
adm dump <file> [flags]
Dumps a compilation stage for one file: tokens, the AST, the IR, LLVM IR or the generated C.
| Flag | Meaning |
|---|---|
--stage tokens|ast|ir|llvm|c | Which stage (default ast). |
--ir-verbose | Full IR/MIR/LIR blocks and instructions. |
--comments | Include comments in token and AST output (default on). |
adm dump main.adm --stage c
adm lsp
adm lsp [--log-protocol]
Starts the language server on stdio (go to definition, references, hover, workspace symbols, diagnostics); --log-protocol traces every request to stderr.
adm mcp
adm mcp [--root DIR] [--log-protocol]
Starts a Model Context Protocol server on stdio exposing the compiler's resolver and type checker as agent tools: adm_doc, adm_symbol, adm_explore, adm_check, adm_test.
adm env
adm env
Prints environment information.
adm fix
adm fix
Applies automatic safe rewrites.
Not implemented yet.
adm graph
adm graph
Shows the dependency graph.
Not implemented yet.
adm lint
adm lint [paths...] [--json] [--fix] [--skip CODE,...] [--exclude GLOB] [--list]
Static checks over a program that type-checks, reported for the files under the given paths (default .); the standard library is loaded but never reported on. The text report groups findings by file and ends with a count per check. --json prints an array of {file, line, column, code, severity, message, fix, edits}, which the IDE's Lint tab reads. A finding with edits can be fixed mechanically: --fix applies every such edit on disk and names the files changed, and the Lint tab's Fix button does the same for one finding or a whole group. The language server runs the same checks on the open files, so editors show the findings inline (warnings and weak warnings, source adm-lint) with the fixes as code actions; initializationOptions.lint takes enabled and a skip list, and the adm/lint request returns every finding under a directory from the server's current analysis. On the command line an unchanged tree answers from a result cache under ~/.adm/cache/lint (every file the last run loaded still hashes the same and the roots hold the same files); ADM_NO_LINT_CACHE=1 bypasses it and --fix always runs.
| Check | Reports |
|---|---|
unchecked-map-index | A read m[k] of a map where nothing before it established the key, which panics when the key is missing. An earlier m[k] = v or m.set(k, v) in the block, a hasKey(k), get(k) or k in m check earlier or in an enclosing condition, a for let (k, v) in m loop around the read, or a map literal declaring the key all count as establishing it. m[w] = m[w] + 1 still fires: it reads before it writes. |
ref-cycle | Two types holding strong references to each other, or a type holding itself through two fields where one is named as a back reference (a tree's parent beside children, a list's prev beside next), so neither instance is ever freed. A node whose self links all point forward, such as children and next, is not reported, nor is one whose links all point up, and two types that hold arrays of each other are a tree of parts, not a cycle. The fix names the field to mark weak. |
undeclared-dependency | A service calling or observing another service that its dependencies field lists under neither hard nor soft. The fix appends it to the hard list. |
undeclared-permission | A library reaching a permission its adm.toml does not list under [requires] permissions, shown with the call chain. The library build fails on the same thing. |
assertless-test | A @test with no assert, no assert* or expect* helper call and no try: it passes whatever the code does. |
untested-export | An exported function or method no _test.adm under the roots names. Silent when there are no test files at all. |
suite-file-without-suite | A _test.adm file with no check block, so adm test runs nothing in it. |
prefer-lambda | An anonymous def passed as an argument whose body is one return. The fix rewrites it as (a, b) => a + b, or v => v + 1 for one untyped parameter. |
prefer-expects | An errorable function opening with fail ... when, fail ... unless or if cond { fail } guards on its parameters. The fix rewrites them as an expects block. |
prefer-when | An if with no else around one call, return or assignment. The fix writes one when cond, or one unless x for if !x. |
prefer-junction | x == a || x == b || x == c with literals, or x == /a/ && x == /b/ with regexes. The fix writes the junction x := a || b || c. |
prefer-empty-block | An emptiness check paired with a loop over the same collection, as an else branch or the statement before. The fix moves the check into the loop's empty block. |
service-dependency-cycle | Services whose dependencies fields form a loop through a soft edge: it starts, but calls between the two can recurse. A loop over hard edges alone is a compile error already. |
unused-import | A use whose alias, module name and exports appear nowhere in the file. A module kept for what it registers is written use m as _, which the check skips. |
unused-internal | An internal function, type, const or let nothing refers to. |
error-doc | An exported function returning !T whose doc comment never says when it fails. |
missing-doc | An exported declaration without a doc comment. |
naming | Types not PascalCase; functions, methods and fields not camelCase. Test files and test functions are exempt. |
accessor-prefix | getX() and setX(v) methods over a field, which ADM reads as a property. When both do nothing but read and write the field, the fix rewrites the field into a property block carrying the accessors' doc comments, deletes the methods and turns every caller into o.x or o.x = v. A getter with logic, or a setter used as an expression, is reported without a fix. |
todo | TODO, FIXME, HACK and XXX comments. |
ref-cycle, unchecked-map-index, unused-import and unused-internal are warnings; the rest are informational. Test files skip the naming and documentation checks, and constructors and destructors need no doc comment. --skip leaves checks out; the exit code is 0 either way. Fixes exist for ref-cycle (inserts weak on the optional field), unused-import (removes the line or the name) and accessor-prefix.
adm lint
adm lint std/io --skip missing-doc,todo
adm lint --fix .
adm lint --list
adm ide
adm ide
Starts the IDE.
Not implemented yet.
Toolchain
The installation itself.
adm doctor
adm doctor [--json] [--verbose]
Diagnoses the installation: compiler, C toolchain, library paths, caches. --json prints one result per check with title, status, message and a fix hint.
adm targets
adm targets
Prints every <os>-<arch> the build accepts, the clang triple it maps to and whether it can be linked here: the host always, another platform only when ADM_SYSROOT_<OS>_<ARCH> points at a sysroot.
adm update
adm update [flags]
Looks up the latest language package on the distribution repository and installs it over this installation (bin/, lib/, tools/; caches, packages and catalogs are kept). A development checkout is refused.
| Flag | Meaning |
|---|---|
--check | Only report whether a newer release exists. |
--version V | Install that release. |
--force | Reinstall even when nothing newer exists. |
adm version
adm version [flags]
Shows the version, checking for a newer release unless told not to.
| Flag | Meaning |
|---|---|
--json | As JSON. |
--plain | Just the number, no check. |
--skip-versioncheck | No release check. |
--verbose | Detailed version information. |
adm clean
adm clean
Removes build artifacts.
adm config
adm config
Configures the toolchain.
Not implemented yet.
adm completion
adm completion bash|zsh|fish|powershell
Prints the shell completion script for the named shell.
source <(adm completion zsh)