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

usage
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.

FlagMeaning
--apps / --libs / --pluginsBuild only that kind of unit.
--path DIRBuild only targets under the directory (default .).
--out DIROutput directory for built binaries (default: the current directory).
--base PATHWith --os wasm: the path the page is served under (/, /app/), written as the page's <base> so the application's locations open directly and survive a reload on a server that answers them with index.html. Default: none, the folder works under any path from its own page. adm run --os wasm builds with / and answers its locations itself.
--releaseFully optimized (-O3 -DNDEBUG, drops debug-only runtime diagnostics); the default is -O2.
--debugUnoptimized with debug info (-O0 -g).
--backend llvmCompiler backend; llvm is the only one.
--os, --archTarget platform (defaults to the host). --os wasm builds for the web: a folder per application with index.html, the loader <app>.js, the module <app>.wasm, and the fonts a program that draws text carries. Any web server serves it; the compiler carries the C library and the fonts it needs, so nothing else is installed.
--platforms a,bBuild several <os>-<arch> at once; plugins merge into one .admplugin. A cross target needs ADM_SYSROOT_<OS>_<ARCH>.
--runtime static|sharedRuntime linkage; shared is required to load plugins.
--features a,bComma-separated feature list.
--deps-only / --no-depsBuild only dependencies of the selected targets, or none of them.
--no-cacheDisable IR caching.
--perfShow performance metrics.
--jsonReport the build as JSON on stdout, one object per line with an event field, for editors and tools: target (the unit built), step (a stage with done of total, the unit finished last, and on its last step finished/failed/skipped, the note and ms), built (each file written, absolute), diagnostic (file, line, column, end line and column, severity, code, message), warning, error and done (ok, error and warning counts, ms). Everything else the build prints goes to stderr. adm test --json reports its build with the same step events.
--quietDo not show the build's stages. Without it a terminal gets a live view: one line per finished stage (sources, parse, resolve, types, ir, modules, native support, link) with what it processed, what the caches saved and its duration, a progress bar for the stage running, and built <path> with the total; a build of several units leaves one line per unit. A pipe or an IDE console gets the same lines printed as the stages finish.
shell
adm build App1 acme.imaging
adm build --libs samples/imaging
adm build App1 --release --os linux --arch arm64
adm build App1 --os wasm --out site

Builds are incremental. The compiler caches each module's checked and lowered form and its object code under ~/.adm/cache, so after an edit only the modules whose sources or imported interfaces changed are checked and compiled again. An unchanged binary is not linked again. An application or plugin build also drops every function the program cannot reach before code generation (a plugin keeps what it exports). --no-cache, ADM_NO_INCREMENTAL=1 and ADM_NO_SHAKE=1 turn these off.

adm check

usage
adm check [paths...] [flags]

Semantic analysis without building: parses, resolves and type-checks, then prints diagnostics. adm check --all std validates the standard library.

FlagMeaning
--allShow every error (same as --limit=0).
--limit NMaximum number of errors shown (default 10).
--context NLines of context around each error (default 2).
--exclude GLOBSkip paths matching the globs.
--fixApply the fix of every diagnostic that has one (the first, when it offers several) to the files under the paths, then check again; the report is what is left. A file whose fixes overlap is left as it is and named.
--jsonDiagnostics as JSON: each with its code (Diagnostics) and, when the compiler knows the edit that resolves it, its fixes.
--perfShow performance metrics.

adm explain

usage
adm explain [codes...] [flags]

What a diagnostic code stands for: error or warning, its area, the message the compiler reports and its entry on the Diagnostics page.

FlagMeaning
--list [AREA...]Every code, or those of the areas named (TYPE, FFI, ...).
--jsonThe codes as JSON (code, severity, area, message, url).

adm doc

usage
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.

FlagMeaning
--module, -m NAMEOne module's exports (std.io, builtin for the prelude).
--search, -s NAMEFind a symbol by name across modules.
--workspaceWorkspace-wide module overview.
--jsonDocumentation as JSON, with kindName and per-type members.
--full-docInclude doc comments in the workspace listing.
--root PATHWorkspace roots or files to load (default .).
--no-stdSkip the standard library.
--plugin FILEWhat an .admplugin exports, from its metadata alone.
--exclude GLOBSkip paths matching the globs.
shell
adm doc --module std.io
adm doc --search readFile
adm doc --workspace --root std --no-std

adm fmt

usage
adm fmt [paths...] [flags]

Formats .adm files in place; the authoritative formatting, so never hand-align.

FlagMeaning
--checkReport files that would change without writing.
--diffPrint a diff instead of rewriting.
--stdinRead source from stdin and write the result to stdout.
--include / --exclude GLOBLimit to files whose base name matches.
--writeWrite the result back (default on).
shell
adm fmt
adm fmt --check src/

adm run

usage
adm run [appName | file.adm | dir] [-- appArgs...] [flags]

Builds an application, runs it and removes the executable afterwards. Arguments after -- go to the program. A .adm file runs the application that file declares, with the modules beside it; a folder holding several applications needs the application's name. adm run ends with the program's exit status (128 plus the signal for a program a signal ended), and stopping adm run stops the program: Ctrl+C reaches it from the terminal, and adm passes a SIGTERM it receives on to it, every ending signal when it runs without a terminal (from an editor or a script), so the program is never left running. adm test runs its suites the same way.

FlagMeaning
--keepKeep the executable.
--watchRebuild and restart whenever a source file changes.
--hotRebuild whenever a source file changes and swap the changed function bodies into the running program, which keeps its state. Function literals count: a handler written inline takes its new body. A new module variable arrives with the reload and takes its value when it is first read; variables the program has keep theirs. A change that is more than function bodies and new declarations (a type's fields, a variable's type, a function's parameters, a function literal or an annotated function added or removed) restarts the program and says why; a build error leaves it running. A component's view shows an edited argument, handler or structure on the next frame, and an edited style shows on every component, except for the properties the program itself assigned, which keep their values. The run ends when the program exits with 0 (its window was closed); a program that failed is waited on until a change rebuilds it. Linux and Windows.
--path DIRBuild targets under the directory.
--release / --debugOptimization level, as for build.
--quietDo not show the build's stages before the program runs, as for build; the view closes before the program starts, which then owns the terminal.
--env KEY=valueSet a variable in the program's environment (repeatable), on top of the one adm runs in. A web program (--os wasm) has no environment of its own: these entries are all it gets.
--backend, --os, --arch, --features, --no-cacheAs for build. With --os wasm the page is served on a free port of 127.0.0.1 and opened in the browser (ADM_BROWSER, else the desktop's); what the program prints shows in the terminal too, arguments and environment travel in the page's address, and the run ends when the program exits or its tab closes. --hot and --watch are not available on the web. With --os windows on an x86-64 machine that is not Windows, the program runs under Wine (ADM_WINE), --watch and --hot included.
shell
adm run
adm run MyApp -- --help
adm run examples/listen.adm
adm run MyApp --os wasm

adm test

usage
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. A test that crashes or runs out of time is reported failed ([crash], [timeout]) and the run goes on with the next one.

FlagMeaning
--run TEXTOnly tests whose name contains the text (repeatable; = prefix for an exact match).
--os wasmBuild the suites for the web and run them in a headless browser: ADM_BROWSER, else the first of Chrome, Chromium, Edge and Firefox found. Results print as for a native run. --fuzz and coverage are not available on the web.
--os windowsOn an x86-64 machine that is not Windows: build the suites for Windows and run them under Wine (ADM_WINE, else wine on the PATH).
--env KEY=valueSet a variable in the suites' environment (repeatable); on the web (--os wasm) these entries are all the page's environment holds.
--file TEXTOnly tests whose source file contains the text.
--timeout LIMITFail a test that runs longer than the limit (30s, 500ms, 2min) and go on with the next one; a test's own @timeout takes precedence.
--update-goldenWrite the file of each @golden(file) test that differs from it, or has none yet, from what the test returns; those tests then pass.
--fuzz TEXTGenerate inputs for the @fuzz() targets whose name contains the text (. for all) and run nothing else. The source files under the paths are compiled with block counters, so inputs that reach new code are kept (under ~/.adm/cache/fuzz, loaded again by the next run). A failing input is made smaller and written to testdata/fuzz/<target>/ beside the source, where plain runs replay it. --timeout and @timeout bound one input (10s without either).
--fuzz-time LIMITHow long --fuzz generates inputs for each target (default 1min).
--list / --list-benchList discovered tests or benchmarks without running.
--bench TEXTRun benchmarks matching the text (. for all); --bench-count, --bench-time shape the run.
--coverage-reportMeasure line coverage of the source files under the paths (the files holding check suites aside) and print the total. Functions no test reaches count as uncovered. Under --json: a coverage event (percent, lines, covered, per module) and a file_coverage event per file with its fully, partly and never run lines.
--coverageMeasure line coverage and write it as an lcov tracefile to --coverage-out (default ./adm_test.lcov).
--coverage-per-testMeasure line coverage and add [cov N%] to each passed test: the share of the measured lines it ran.
--jsonMachine-readable output. With --list: a JSON array of tests (name, module, file, line, fuzz on a fuzz target). 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.
--plainPrint each test as it runs. Without it, a terminal gets a live view: a line per finished suite, a progress bar for the build and for the run, failures with their output, and totals (suites, tests, passed, failed, skipped, time). Pipes, IDE consoles, --json, --list, --build-only and --bench always get the plain output.
--build-onlyBuild the runner and print ADM_TEST_BIN=<path>.
--out DIRKeep the compiled runner there.
--backend, --release, --debug, --no-cacheAs for build.
shell
adm test std/services
adm test --run TestRule std/services
adm test --list --json std/io

adm package build

usage
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.

FlagMeaning
--app NAMEApplication to package (required).
--dir DIRWhere to look for adm.toml (walks up).
--out PATHArtifact path (default ./dist/<app>-<version>.tar.gz).
--signSign the artifact; --key names the private key, --sig-out the signature file (default <artifact>.zsig).

adm package install

usage
adm package install <artifact.tar.gz> [flags]

Installs a release artifact into the user's application directory, versioned, and updates the current symlink.

FlagMeaning
--sig PATHSignature file (default <artifact>.zsig).
--no-verifySkip signature verification.
--bin NAMESymlink 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

usage
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.

FlagMeaning
--jsonOne object per unit: kind, name, file, line, dir, manifest (or null), version.
shell
adm list testdata/apps --json

adm list packages

usage
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).

FlagMeaning
--dir DIRProject directory (walks up to the nearest adm.lock).
--no-pullUse the local registry clone without pulling, however old it is.
--jsonOne object per package; the same shape as adm lib --json. root is the folder an installed package's sources load from.

adm audit

usage
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. The interfaces the package serves to other processes (@remote<I>) and the ones it calls in them (IPC.connect<I>) are listed after the permissions. 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.

FlagMeaning
--library NAMEAudit one library of the tree.
--json{package, requirements: [{permission, observe, via, sites, description, spec, fields}], foreign, build_scripts, provides, connects} per package. sites runs parallel to via: the file and line where each hop of the chain is declared, relative to the audited directory.
--catalogInstead 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.
shell
adm audit
adm audit testdata/desktop_apps/opengl_window

adm app init

usage
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).

FlagMeaning
--dir DIRWhere to write the manifest.
--private-key-out PATHWhere to write the private key.
--publisher NAMESign as a stored identity (adm publisher list) instead of generating a key.
--gitInitialize a git repository and a .gitignore.
--forceOverwrite an existing manifest.

adm app info

usage
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.

FlagMeaning
--jsonThe whole tree as one object; manifest is null without an adm.toml.

adm app set

usage
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".

shell
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

usage
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

usage
adm app bump <major|minor|patch> --app NAME [--dir DIR]

Increments the application's version in adm.toml.

adm app id

usage
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

usage
adm app rekey [--dir DIR] [--private-key-out PATH] [--publisher NAME]

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. --publisher NAME uses a stored identity's key (adm publisher list) instead of generating one.

adm app sign

usage
adm app sign <artifact> [flags]

Signs an artifact with the manifest's publisher key.

FlagMeaning
--app NAMEWhich application, when the tree builds several.
--key PATHPrivate key (default: the publisher's file under the XDG config directory).
--out PATHSignature file (default <artifact>.zsig).
--forceOverwrite an existing signature.

adm app verify

usage
adm app verify <artifact> [--sig PATH]

Verifies an artifact's signature.

adm app policy init

usage
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.

FlagMeaning
--forceOverwrite an existing file.

adm app policy set

usage
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.

shell
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

usage
adm app policy unset [--package ns:name] <permission> <field.kind|setting>

Removes one rule.

adm app policy get

usage
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

usage
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

usage
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.

FlagMeaning
--jsonOne object per package, the shape of adm list packages --json.
--no-pullUse the local registry clone without pulling, however old it is.

adm lib remove

usage
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

usage
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.

FlagMeaning
--allow-unsignedAccept a container with no publisher.
--jsonOne object, what the registry's gatekeeper reads.

adm new

usage
adm new application|library|plugin <folder> [flags]

Makes a project with its first unit, ready to build and test: adm.toml, the unit's declaration (main.adm, library.adm or plugin.adm), a module named after the unit with a function and its check suite, and a README with the build, run and test lines. The unit is named from the folder (my-app gives the application MyApp; a library gets dotted lower case, image.tools) unless --name says otherwise. The IDE's new-project screen makes the same project through it.

FlagMeaning
--kind ui|service|cli|emptyWhat an application is: a std.ui window, an HTTP server on :8080, a std.cli tool, or a program that prints and exits (the default).
--platform LISTA ui application's platforms (desktop, web) or a plugin's (windows, macos, linux), recorded in the README. android and ios are refused until adm has those targets.
--name NAMEThe unit's name instead of the one derived from the folder.
--into PROJECTAdd the unit to an existing project (a folder with adm.toml); the folder lies under it, no manifest is written, no repository made.
--host NS:NAME, --interface NAMEA plugin's host library, fetched into the project as adm get does (--accept as there), and the interface it implements: its methods are written as stubs on a <Plugin><Interface> type.
--gitInitialise a git repository with a .gitignore (default on; --git=false leaves it out).
--dry-runReport what would be written, write nothing.
--jsonPrint {"project", "units": [{"kind", "name", "path"}], "files", "git", "platforms"}, or {"error": {"code", "message"}} with exit 1; the codes (folder-not-empty, invalid-name, unsupported-platform, unknown-interface, ...) name the field at fault.

Package manager

Fetching, installing, publishing and vendoring libraries; see the Libraries page for the model behind them.

adm get

usage
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); 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.

FlagMeaning
--accept all|none|LISTGrant 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 DIRProject whose lock to update.
--dry-runResolve and report, install nothing; with --json the container is fetched and described (permissions, foreign files, dependencies) without installing.
--jsonThe installed packages as JSON, progress on stderr.
--no-pullUse the local registry clone without pulling, however old it is.
--trustAccept a publisher other than the one the lock pinned.
shell
adm get acme:imaging
adm get acme:imaging@^1.4 --accept adm.storage.*

adm install

usage
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.

FlagMeaning
--accept, --dir, --json, --trustAs for get.
--namespace NAMENamespace to file a package under (a file install defaults to local).
shell
adm install ../lib/acme.files-0.1.admlib --accept all

adm publish

usage
adm publish [flags]

In a library's source tree with a clean git working tree and a GitHub origin: builds and signs the .admlib, tags the source <name>@<version>, pushes the tag, creates its GitHub release with the container as the asset, and opens a pull request on the registry adding the index line. The container never enters the repository. Needs the GitHub CLI (gh), logged in as the account that owns the origin. Refuses when the version is not newer than the registry's, when nothing signs the package, or when the tree is dirty.

Before building, the library's API is compared with the newest version in the registry, read from the sources of both. Anything removed or changed in a way that breaks callers (a parameter renamed or retyped, a default dropped, a method added to an interface, an enum member added) calls for a major release, an addition for a minor one, anything else for a patch. When the version raises less than that, publish lists the changes and suggests the version semantic versioning gives (a break after 0.5.3 suggests 1.0.0): a terminal is asked whether to take it, publish anyway or abort; without a terminal --semver must say.

FlagMeaning
--description TEXTOne line saying what the library is, shown by search (default: description under [apps.<Name>] in adm.toml).
--bump major|minor|patchRaise the library's @manifest(version) first; the change rides in the release commit.
--semver bump|ignoreWhen the version raises less than the API changes call for, or the previous release cannot be compared: bump publishes the suggested version, ignore the declared one. Default: ask on a terminal, else refuse.
--library NAMEWhich library, when the tree declares several.
--registry NAMERegistry from adm.toml (default: the first).
--dry-runBuild and print the index line and the API report, touch nothing.
--no-prPush the release but print the index line instead of opening the pull request.
--dir DIRLibrary source directory.

adm yank

usage
adm yank [NAMESPACE:]NAME@VERSION [flags]

Withdraws a published version: opens a pull request on the registry that adds a yank line for it. adm get and adm search no longer offer the version and a range no longer resolves to it. A project that already has it in adm.lock keeps installing it, with a warning that shows the reason. Nothing is deleted, and the version number is never reused. The pull request must come from the GitHub account that owns the namespace, which is what gh is logged in as.

FlagMeaning
--reason TEXTWhy the version is withdrawn, shown to projects that have it locked.
--undoBring a yanked version back.
--registry NAMERegistry from adm.toml (default: the first).
--dry-runPrint the index line without doing anything.
--no-prPrint the index line instead of opening the pull request.
--dir DIRProject directory; its adm.toml names the registries.

adm publisher new

usage
adm publisher new <name>

Generates a key pair and stores it under a local name: the name in ~/.config/adm/publishers.toml, the key in ~/.config/adm/keys. adm app init --publisher <name> then writes that identity's public key into a new adm.toml, so several repositories sign as one publisher. The name is a local label and is never published.

adm publisher list

usage
adm publisher list

Lists the stored identities.

adm publisher name

usage
adm publisher name <publisher id> <name>

Names a key already in the keys directory, one adm app init made.

adm publisher export

usage
adm publisher export <name>

Prints the identity's private key (base64), for adm publisher import or ADM_SIGNING_KEY.

adm publisher import

usage
adm publisher import <name> <file|->

Stores a private key printed by adm publisher export under the name.

usage
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).

FlagMeaning
--jsonHits as JSON: namespace, name, latest, description, repo, publisher, date, registry, every version newest first.
--indexesList the registry indexes the project uses (--json: name, url, official, local catalog) instead of searching.
--refreshPull every registry clone now, however recent the last pull; alone, just refresh.
--no-pullUse the local clones without pulling, however old they are.
--dir DIRProject whose adm.toml names the registries.
shell
adm search humanize

adm vendor

usage
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

usage
adm dump <file> [flags]

Dumps a compilation stage for one file: tokens, the AST, the IR or LLVM IR.

FlagMeaning
--stage tokens|ast|ir|llvmWhich stage (default ast).
--ir-verboseFull HIR/LIR blocks and instructions.
--commentsInclude comments in token and AST output (default on).
shell
adm dump main.adm --stage llvm

adm lsp

usage
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. Every server also keeps a session journal, ~/.adm/cache/lsp/adm-lsp-<pid>.log (ADM_CACHE): the root the editor gave it, the files it found, each analysis with its error count and the files holding the errors, its restarts; journals idle for a week are removed. The server runs on at most 8 processors and limits its heap to a quarter of the machine's memory (at least 4 GiB); GOMAXPROCS, GOGC and GOMEMLIMIT override. The first analysis leaves the bodies of standard-library modules nobody has open unchecked and fills in their diagnostics and references from what an earlier session stored under ~/.adm/cache/ir/lspbodies (ADM_CACHE); adm clean clears it.

adm mcp

usage
adm mcp [--root DIR] [--log-protocol]
adm mcp install [TOOL...|all]

Starts a Model Context Protocol server on stdio exposing the compiler's resolver and type checker as agent tools. A tool call that names no roots analyzes --root; without it, the folders the client has open, else the current directory. --log-protocol traces every message to stderr.

ToolWhat it answers
adm_docA module's exports with signatures and the first sentence of each doc comment (docs for all of it, filter by name; test-file declarations only with all), a symbol search across modules, or the module inventory.
adm_symbolA symbol by name: module, kind, signature, doc comment, file:line and source. Finds methods; a name may be qualified (Buffer.read, std.io.Buffer). A name nothing declares is answered with the names close to it.
adm_exploreA question in plain words: the source of the symbols it names. Names (Buffer, readFull) come first; a lower-case word resolves only to members of the types named. Overloads count once toward limit, and what the limit leaves out is named.
adm_referencesEvery use of a symbol: calls, reads, writes, type mentions, per declaration of the name.
adm_membersWhat a type has: methods, fields, properties, constants, enum values, each with its signature or type. Built-in types (string, array, map) answer with the prelude's methods.
adm_implementationsThe types that implement an interface, or the interfaces a type satisfies.
adm_type_atWhat the identifier at a file, line and column is: an inferred type, the overload a call resolved to, its module and doc comment.
adm_renameRenames one declaration and every use the type checker resolved to it; lists the sites, writes them with apply, then checks again and reports errors the rename introduced.
adm_graphThe import tree, the chain of imports that loads a module (why), import cycles, the locked libraries, the services.
adm_auditThe permissions the code can reach with the calls that reach them, and the files binding foreign code.
adm_specThe language specification, idioms guide and memory model: contents, a section by heading or number, or the sections that mention given words (most of them, when no section holds them all).
adm_checkType-check: diagnostics as file:line:col.
adm_lintWhat adm lint finds, each with its fix.
adm_fmtFormats files in place; check shows the diff and writes nothing.
adm_fixRewrites for code written for an older adm, as a diff; apply writes them.

The twelve tools that change nothing are marked read-only, so a client can run them without asking; adm_fmt, adm_fix and adm_rename write source files. No tool builds or runs the project's code, check suites included: those are run with adm test in a terminal. A file that is edited, added or removed is seen by the next call. Tool calls run side by side: a long type check does not hold up a lookup, a client can cancel a call, and a call that asks for progress is told every few seconds that it is still running. adm_check, adm_references and adm_lint also return their answer as structured data. The three language documents are offered as resources too (adm://docs/language-specification, adm://docs/idioms, adm://docs/memory-model). Each result names the adm that answered (_meta), and when a newer adm is installed at the server's own path, the server restarts onto it between calls, keeping the session (on Windows the results say so instead). The server speaks the protocol revisions 2024-11-05 to 2025-11-25.

adm mcp install

Registers the server with the AI coding tools on the machine, so an agent can look up ADM symbols, read module documentation, check code and run suites in any project. Without arguments it lists the tools it found and what each one has:

terminal
$ adm mcp install
claude     Claude Code              not registered for every project
                                    ✓ this project: adm mcp --root . (/work/app/.mcp.json)
codex      Codex                    ✓ registered
vscode     VS Code (Copilot chat)   not registered for every project
zed        Zed (agent panel)        not registered for every project
not found: copilot, cursor, gemini, opencode, windsurf

$ adm mcp install claude zed     # the named tools
$ adm mcp install all            # every tool found

The first line of a tool is its user-wide registration, the one that applies in every project. A second line appears when the project in the current directory registers the server in its own files (.mcp.json, .cursor/mcp.json, .vscode/mcp.json, .gemini/settings.json, opencode.json); those are only read, never written. registered as: ... means the tool starts another command line than the one this adm would write, for instance after the binary moved; installing again replaces it.

With names, the server is written to each tool's user-wide settings as the full path of the running adm followed by mcp, with no --root, so it analyzes whichever project the tool has open. Restart a running tool afterwards.

NameToolWhere the server is registered
claudeClaude CodeUser scope, through claude mcp add --scope user.
codexCodex~/.codex/config.toml, through codex mcp add.
copilotGitHub Copilot CLI~/.copilot/mcp-config.json ($COPILOT_HOME moves it).
cursorCursor~/.cursor/mcp.json.
geminiGemini CLI~/.gemini/settings.json.
opencodeopencode~/.config/opencode/opencode.json, or opencode.jsonc when that is the file in use.
vscodeVS Code (Copilot chat)mcp.json of the user profile (~/.config/Code/User on Linux).
windsurfWindsurf~/.config/devin/mcp_config.json; ~/.codeium/windsurf/mcp_config.json when only that older folder exists.
zedZed (agent panel)context_servers in ~/.config/zed/settings.json.

A tool counts as found when its program is on PATH or its settings folder exists. Settings files are edited in place: one entry is set, and comments, key order and formatting stay as they were. A file that does not parse is reported and left untouched. Naming a tool that is not installed, or an unknown name, is an error; with several tools, one failing does not stop the others.

adm env

usage
adm env [--json]

Prints the ADM_HOME, ADM_BIN, ADM_CACHE, ADM_LIB and ADM_PATH variables as set.

FlagMeaning
--jsonThe variables, plus what the compiler resolves from them: version, lib (the folder holding prelude/ and std/), cache, and prelude and std, the folders a build started in the current directory loads.

adm fix

usage
adm fix [PATHS...] [flags]

Rewrites code written for an older adm to what this one expects. A release that changes the language or the standard library (a renamed annotation, a construct spelled another way) ships a fix for it; adm fix runs them over the .adm files under PATHS (the current directory by default) and writes the files back. Each fix recognises the old form by itself: nothing records which version a file was written for, current code is left alone, and a second run changes nothing. Fixes read tokens, so they work on a file the compiler no longer parses. A fix is skipped, with the reason, when the program declares something of its own that the old form would mean. Hidden folders and vendor are not walked. Lint findings are repaired by adm lint --fix, not here.

FlagMeaning
--listList the fixes (name, the day the change landed, what it rewrites) and exit.
--diffPrint what would change; write nothing.
--only NAME,...Run only these fixes.
--skip NAME,...Leave these fixes out.
FixChangedRewrites
proto-field2026-10-03@protobuf(...) on a field becomes @protoField(...).

adm graph

usage
adm graph [DIR] [flags]
adm graph packages [--dir DIR] [flags]
adm graph services [DIR] [flags]

Shows what depends on what. adm graph prints the import graph of the applications, libraries, plugins and modules under DIR (the current directory by default) as a tree. A module already listed above is marked (*) and not expanded again; (cycle) marks an import that leads back to a module it is nested under. Standard library modules are shown where they are imported but not expanded. adm graph packages shows the libraries adm.lock pins, with their versions and which was built against which. adm graph services shows the services and their dependencies; a soft dependency is marked (soft) and drawn dashed.

output
Shop [application]
├── adm.database.sqlite admlang
│   ├── std.data.db
│   └── std.net.url
├── shop
│   ├── std.data.db
│   └── std.services.database
└── std.services.database
FlagMeaning
--format tree|json|dot|svgOutput: the tree (default), JSON (nodes, edges, roots, cycles), Graphviz DOT, or an SVG drawing laid out by adm itself, which follows the viewer's light or dark colour scheme.
--jsonSame as --format json.
--out FILEWrite to a file instead of the terminal.
--why NAMEPrint the shortest chain of dependencies from each root to NAME.
--cyclesList the dependency cycles, one loop per group of nodes that depend on each other.
--root NAMEShow only what NAME reaches (repeatable).
--depth NTree only: stop below N levels.
--stdModules only: expand standard library modules.
--no-stdModules only: leave standard library modules out.

adm lint

usage
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.

CheckReports
unchecked-map-indexA 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 or for let k in m.keys() 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-cycleTwo 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.
closure-cycleA field holding a function literal that captures self, by name or through a bare field or method: object and closure keep each other alive.
observer-cycleA type whose @on handler observes a service the type also holds in a strong field.
needless-weakA weak field whose target type never references the owner through the strong field graph.
large-value-copyA datatype value estimated above 64 bytes passed to a call inside a loop body, copied on every pass.
missing-disposeA type holding a field whose type declares dispose, without a dispose of its own to release it.
unsynchronised-fieldA field written by a task (an async method, or one the type spawns) and used by other methods, without atomic. In a component's controller only another task counts: a task's store and the frame's reads hold the UI's state lock.
dropped-futureA task started as a statement whose result or error nothing awaits.
blocking-observerAn @on handler that reaches adm.storage.* or adm.network.* I/O, which blocks the event dispatcher.
deprecated-useEvery reference to a @deprecated declaration, with the replacement its annotation names.
bare-booleansA call passing two or more boolean literals by position; name the arguments or use an enum.
name-variant-overloadreadFile beside readFileWith or readFileFrom in one body, where an overload or a default argument would do.
could-be-internalAn exported function or type of an application module that no other module refers to.
redundant-internalinternal on a service member; a service exposes only its datatypes, interfaces and @commit, @emit and @query members. The fix deletes the keyword.
non-exhaustive-matchA match without default that leaves out members of a union type, an optional, an errorable or an enum. A value of a missing member takes no clause and falls through; the warning names the missing members.
array-identity== or != between an array and an array literal: it compares which array each side is, so it is always false (or true). The fix writes a.equals(b).
bind-copyA field that is not @bindable passed to a component's bound input (@input(bind = true)) with no change handler (onChange, on<Input>) beside it: the component edits a copy and the field never changes. Fix: mark the field @bindable, or pass the handler that stores the value.
unmatched-pathA constant location given to Link(to = ...), Router.go or new MemoryHistory(...) that no @route page matches: the window shows notFound there. Fix: correct the path or declare the page.
unreachableA statement after a return, fail, break, continue, recover or rollback in the same block (contract blocks excepted).
empty-onerrorAn onerror handler with nothing in it, so the error is dropped without a trace.
self-assignx = x, which changes nothing.
constant-conditionAn if, when, unless or for condition that is a boolean literal or compares an expression with itself.
unused-localA local, parameter or pattern binding nothing reads (parameters of stub bodies excepted).
shadowA local declared under the name of a parameter, outer local, receiver field or module variable it hides.
undeclared-dependencyA 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-permissionA 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-testA @test with no assert, no assert* or expect* helper call and no try: it passes whatever the code does.
untested-exportAn exported function or method no _test.adm under the roots names. Silent when there are no test files at all.
suite-file-without-suiteA _test.adm file with no check block, so adm test runs nothing in it.
prefer-lambdaAn 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-expectsAn 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-whenAn if with no else around one call, return or assignment. The fix writes one when cond, or one unless x for if !x.
prefer-junctionx == 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-blockAn 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-cycleServices 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-importA 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-internalAn internal function, type, const or let nothing refers to.
error-docAn exported function returning !T whose doc comment never says when it fails.
missing-docAn exported declaration without a doc comment.
namingTypes not PascalCase; functions, methods and fields not camelCase. Test files and test functions are exempt.
accessor-prefixgetX() 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. A lone getX() over no field x (a network call, a lookup) is reported as a name to shorten to x().
todoTODO, FIXME, HACK and XXX comments.

What leaks, breaks or is dead is a warning: bind-copy, unmatched-path, ref-cycle, closure-cycle, observer-cycle, missing-dispose, unsynchronised-field, blocking-observer, unchecked-map-index, array-identity, non-exhaustive-match, unreachable, empty-onerror, self-assign, constant-condition, undeclared-dependency, undeclared-permission, assertless-test, suite-file-without-suite, unused-import, unused-internal and unused-local. 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), accessor-prefix, redundant-internal, array-identity and the prefer-* rewrites.

shell
adm lint
adm lint std/io --skip missing-doc,todo
adm lint --fix .
adm lint --list

adm ide

usage
adm ide

Starts the IDE.

Not implemented yet.

Toolchain

The installation itself.

adm doctor

usage
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

usage
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 or the toolchain ships a baseline for it. The sysroot a platform would use is shown.

adm update

usage
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.

FlagMeaning
--checkOnly report whether a newer release exists.
--version VInstall that release.
--forceReinstall even when nothing newer exists.

adm version

usage
adm version [flags]

Shows the version, checking for a newer release unless told not to.

FlagMeaning
--jsonAs JSON.
--plainJust the number, no check.
--skip-versioncheckNo release check.
--verboseDetailed version information.

adm clean

usage
adm clean

Removes every build cache under ADM_CACHE (default ~/.adm/cache).

adm config

usage
adm config

Configures the toolchain.

Not implemented yet.

adm completion

usage
adm completion bash|zsh|fish|powershell

Prints the shell completion script for the named shell.

shell
source <(adm completion zsh)

Environment variables

What the toolchain and the programs it builds read from the environment.

Toolchain

VariableMeaning
ADM_LIBWhere the prelude and standard library are read from (default ~/.adm/lib, else lib/ beside the binary's bin/).
ADM_PKGPackage cache for adm install and dependency roots (default ~/.adm/pkg, on Windows %LOCALAPPDATA%\adm\pkg).
ADM_CACHERoot of every build cache (default ~/.adm/cache, on Windows %LOCALAPPDATA%\adm\cache).
ADM_CATALOGDirectory holding the registry clones search, get and publish pull (default ~/.adm/catalog, on Windows %LOCALAPPDATA%\adm\catalog).
ADM_CATALOG_MAX_AGEHow old a registry clone may be before it is pulled again, a Go duration (default one hour).
ADM_BROWSERThe browser command adm run --os wasm opens the page with and adm test --os wasm runs the suites in (firefox, google-chrome --headless=new), the page's address appended last.
ADM_WINEThe Wine command adm run --os windows and adm test --os windows run a Windows program under, on an x86-64 machine that is not Windows. Unset: wine on the PATH. adm keeps its own Wine prefix under its cache unless WINEPREFIX is set.
ADM_CLANGC compiler driver that links the program (default: the bundled tools/clang, else clang on PATH).
ADM_OS, ADM_ARCHTarget operating system and architecture (default: the host); wasm is the web.
ADM_SYSROOT_<OS>_<ARCH>Sysroot for a target. Unset: adm build links a Linux program against the baseline sysroot shipped in lib/sysroots/ (glibc 2.35) when it holds every library the program links, so the program runs on systems from that glibc on; when a library is missing there it links against the build machine's files and says so. adm run and adm test link against the build machine's files; another platform needs the variable. A path: that sysroot, for every command. host: the build machine's files.
MACOSX_DEPLOYMENT_TARGETOldest macOS a Darwin build runs on (default 12.0): the version in the objects' target triple and in clang's -mmacosx-version-min for C compiles and links.
ADM_SIGNING_KEYBase64 Ed25519 publisher private key used for signing, instead of the key file adm app init wrote.
ADM_DIST_REPOGitHub owner/name whose releases adm version and adm update read (default admlang/adm).
ADM_LLVM_WORKERSProcesses a cold build compiles modules in, the compiler itself counted (n-1 worker processes start; default: one per core, at most 24, bounded by free memory and by what concurrent builds on the machine already hold); 0 or 1 compiles in-process.
ADM_NO_INCREMENTAL1 keys the cache on the whole program instead of reusing unchanged modules, from this program or another one built before.
ADM_NO_SKELETON1 parses every function body. By default a rebuild skips the bodies of the modules whose files are unchanged since the program's last build and whose compiled form is reused, and builds again with a module parsed whole when it needs that module's bodies after all.
ADM_NO_SHAKE1 compiles the whole program instead of dropping unreachable functions.
ADM_FULL_LOAD1 loads every file of each standard library module a program reaches, instead of only the files it names. The IR cache and the lint result cache keep such runs apart.
ADM_NO_OBJ_CACHE, ADM_NO_NATIVE_CACHE, ADM_NO_LINK_CACHE, ADM_NO_LINT_CACHE1 bypasses the object cache, the native-support cache, the link stamp or the lint result cache.
ADM_OBJ_CACHE_MAXSize cap of the object cache (8G, 512M; default 8 GiB).
ADM_ZIG, ADM_RUSTC, ADM_CARGO, ADM_GOThe compilers that build the source @zig, @rust and @go annotations name (default: on PATH). A program that uses one and has no compiler for it stops with what to install.
ADM_NVCCThe nvcc (11.2 or newer) that compiles cuda def bodies (default: on PATH, then the usual CUDA folders); none builds kernels for the CPU path only. Each kernel becomes a fatbin: PTX for its @launch(arch) plus SASS for every newer architecture the toolkit knows, so it loads on any driver of the toolkit's major release; a driver that cannot run the images takes the CPU path, or fails under ADM_CUDA=gpu naming both CUDA versions. ADM_NVCC_FLAGS appends flags.
ADM_NVCC_ARCHSThe architectures the kernel images carry SASS for (89 120 or sm_89,sm_120; none keeps PTX only). Unset: every one nvcc --list-gpu-code lists.
ADM_PHASE_TIMINGFile to append per-phase build timings to.

Compiled programs

Read at startup by every program the compiler builds.

VariableMeaning
ADM_PROCSParallelism bound of the scheduler (default: the CPU count).
ADM_TASK_STACKStack reserved per task (default 32M; pages become resident only when touched).
ADM_TASK_GUARD1 (default) gives each task a guard page; 0 allocates stacks in slabs with canaries, for millions of tasks.
ADM_SCHED_MAX_WORKERSCap on carrier threads for tasks blocked in system calls (default 10000).
ADM_PREEMPT1 preempts a task that runs 10 ms without yielding (Linux x86-64 and arm64, macOS arm64, Windows x64); default is cooperative only.
ADM_SCHED_DEBUGTraces scheduling decisions to stderr.
ADM_AFFINITY_CHECK1: panics when a thread-affine call runs on an unpinned task, or on a pinned task that is not on its own thread.
ADM_CPUbaseline runs the SSE2 copies of SIMD functions; by default the AVX2/FMA copies run on CPUs that have them.
ADM_CUDALaunch path of a cuda def: unset picks the GPU when available, gpu requires it, cpu forces the CPU emulation. ADM_CUDA_DEVICE picks the device ordinal (default 0).
ADM_VULKAN_DEVICEIndex of the Vulkan device the vulkan UI renderer uses (vulkaninfo --summary order); unset picks a discrete GPU before an integrated, virtual or CPU one. ADM_VULKAN_VALIDATION=1 loads the Khronos validation layer and prints its messages; ADM_VULKAN_LOCAL_READ=0 makes the renderer copy each draw's box instead of reading its target in place (VK_KHR_dynamic_rendering_local_read).
ADM_VIDEO_HWGPU video decoding in std.formats.video: auto (default), nvdec, vaapi or off.
SDL_GAMECONTROLLERCONFIGGame pad mappings std.devices.openGamepad reads after the ones it is given, as lines of SDL's game controller database, the way SDL reads them
ADM_APP_HOMEOverrides the application's home folder; see Application home.
ADM_SANDBOX1 applies the OS sandbox at startup from the compiled policy; 0 turns off one the manifest compiled in. See Policy.
ADM_POLICY_PROMPT0 turns off the desktop prompt a policy ask rule raises; the ask then denies.
ADM_HOT_DIRFolder a program built by adm run --hot watches for the reload objects to load; adm run --hot sets it.
ADM_COVERAGE_FILEWhere a test runner built by adm test --coverage* appends its block counters; adm test sets it and reads the file.
ADM_IDE_PORTPort on 127.0.0.1 where std.ide serves the IDE: the services' panels and actions, their labs, the program's metrics. It must also be set when the program is built (adm run does both): only such a build includes the service and, besides a test build, has service labs. The IDE sets it, with ADM_IDE_TOKEN, for the programs it runs.
ADM_IDE_TOKENThe secret a connection to that port must open with; without it the port stays closed. The program removes both variables from its environment as it starts, so the programs it runs never see them.
ADM_MEM_STATS1 prints live, allocated and freed counts every 200k allocations.
ADM_MEM_TRACEFile to record every allocation and free to, with backtraces.