Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Environment variables

Every variable the binary reads, and what it changes. None of them is required: with the environment empty but for PATH, every verb works, and the variables below adjust who is acting, where a file is found, and how output looks.

Every variable

VariableRead byWhat it changes
ANK_AGENTevery verb, and ank mcpthe identity this session acts as: who holds a claim, who wrote an entity, who ran done. Unset or blank, <user>@<hostname>, and ank mcp writes under ank-mcp/<version>
USERNAMEevery verb, with ANK_AGENT unsetthe <user> of the fallback identity; the first of USERNAME, USER, LOGNAME set and not blank wins, and none gives unknown
USERevery verb, with ANK_AGENT unsetthe <user> of the fallback identity, when USERNAME gives none
LOGNAMEevery verb, with ANK_AGENT unsetthe <user> of the fallback identity, when USERNAME and USER give none
COMPUTERNAMEevery verb, with ANK_AGENT unsetthe <hostname> of the fallback identity, cut at its first dot and lowercased; the first of COMPUTERNAME, HOSTNAME set wins, and none asks the hostname program, then says localhost
HOSTNAMEevery verb, with ANK_AGENT unsetthe <hostname> of the fallback identity, when COMPUTERNAME gives none
ANK_UPDATE_REPOSITORYank updatethe repository release tags are read from, in place of https://github.com/haksolot/ank; empty counts as unset
NO_COLORevery verb at a terminal, and ank tuiset and not empty, takes the colour and nothing else; the empty value is not an opt-out
TERMevery verb at a terminal, and ank tuidumb takes the colour, as NO_COLOR=1 does, and draws the structure of ank tui in ASCII; on Windows, set at all, it says the console renders escape sequences
WT_SESSIONevery verb at a Windows terminalset, says the console renders escape sequences; with none of WT_SESSION, TERM, TERM_PROGRAM, ConEmuANSI, ANSICON set, the output is plain
TERM_PROGRAMevery verb at a Windows terminalset, says the console renders escape sequences
ConEmuANSIevery verb at a Windows terminalset, says the console renders escape sequences
ANSICONevery verb at a Windows terminalset, says the console renders escape sequences
EDITORank editthe editor ank edit <id> opens when given no field to change; unset or blank, the verb refuses at exit 9
APPDATAank config --user, --repo, ank mcp, ank watch, ank tuion Windows, the reader’s configuration directory is %APPDATA%\ank; unset, a verb that needs it refuses at exit 9
XDG_CONFIG_HOMEank config --user, --repo, ank mcp, ank watch, ank tuielsewhere than Windows, the reader’s configuration directory is $XDG_CONFIG_HOME/ank; empty counts as unset
HOMEank config --user, --repo, ank mcp, ank watch, ank tuiwith XDG_CONFIG_HOME unset, the reader’s configuration directory is $HOME/.config/ank; neither set, a verb that needs it refuses at exit 9
PATHank done, ank skills --install, ank updatewhere sh and git, npx, and npm, powershell, pwsh and curl are looked for; a program found on none of its directories is refused by name
PATHEXTank skills --install, ank update, on Windowsthe extensions tried on PATH, in its order, of .COM, .EXE, .BAT, .CMD; unset, those four

The test suite sets these to observe the binary. They are not an interface, and a release may change or remove any of them without notice:

VariableRead byWhat it changes
ANK_INDEX_BUSY_MSevery verb that opens the indexhow long, in milliseconds, a connection waits on an index another process holds locked; unset, five seconds
ANK_INDEX_STEPSevery verb that writes the indexa file the SQLite steps a refresh executed are written to
ANK_INDEX_REFRESHEDevery verb that opens the indexa file every refresh appends what it hashed and reindexed to
ANK_TRACE_READSevery verb that reads the corpusan absolute path every entity parse and every index opening appends a line to

ANK_AGENT

The identity this session acts as: who holds a claim, who wrote an entity, who ran done. Unset, it falls back to <user>@<hostname>, which carries no actor type and makes two sessions on one machine one agent. ank status says which one is in force and where it came from:

$ ank status
branch main
warning: no default branch, so completion refs are neither pruned nor judged (ank config default_branch <name>)
identity claude-code/opus-5+docs (ANK_AGENT)
no claim
elsewhere no claim by another agent
perimeter the whole repository, 0 constraint(s)
queue 0 proposal(s), 0 finished elsewhere
corpus 0 fault(s), 2 signal(s)

> ank context

How to write one, and why a concurrent session needs its own, is Claims and identity. ank mcp writes under ank-mcp/<version> unless this variable names another identity.

ANK_UPDATE_REPOSITORY

Where releases are read from. ank update is the only verb that reads it, because it is the only verb that asks the network anything (ADR-64f32c74a0f9). It replaces https://github.com/haksolot/ank in the git ls-remote --tags --refs the check makes, so a mirror, an internal clone or a fixture all serve. Against a bare clone tagged v0.9.0 and v0.7.0:

$ ANK_UPDATE_REPOSITORY=/srv/ank-mirror.git ank update --check --json
{"contract":1,"current":"0.8.0","latest":"0.9.0","newer":true}

A repository carrying no tag it can parse answers "latest":null and "newer":false, and still exits 0. What update does with the answer is Install.

NO_COLOR and TERM

NO_COLOR takes the colour and nothing else. Colour is emitted only when stdout is a terminal, so a pipe, a file and --json are plain already and the variable changes nothing for a program reading them. It matters when a person has the terminal: through a pseudo-terminal ank status came back 538 bytes carrying 22 escape sequences, and NO_COLOR=1 448 bytes carrying none. The empty value is deliberately not an opt-out – NO_COLOR= is how a shell spells “unset this for the child” – and it measured 538 bytes and 22 sequences, exactly as unset did. TERM=dumb is read the same way as NO_COLOR=1.

EDITOR

What ank edit <id> opens when it is given no field to change. It is read by that verb alone, and its absence is an environment to repair rather than a failure of the work:

$ env -u EDITOR ank edit TASK-b700
error[9]: EDITOR is not set, and there is no editor to open
  -> EDITOR=vi ank edit TASK-b7004333d81f

Where the reader’s configuration lives

Three files belong to the person running ank rather than to any repository: corpora.yml, the corpora the MCP server may reach; watch.yml, what the watcher keeps warm; and events.jsonl, the stream the watcher writes. They sit in one directory: %APPDATA%\ank on Windows, and elsewhere $XDG_CONFIG_HOME/ank, falling back to $HOME/.config/ank. ank watch --where prints the path it resolved: with XDG_CONFIG_HOME=/srv/cfg it printed /srv/cfg/ank/watch.yml, and with that variable unset and HOME=/home/me, /home/me/.config/ank/watch.yml.

With none of the three set, a verb that needs the directory refuses at exit 9 and names the variable to set.

Variables that are not an interface

Three ANK_ names appear in the source and in no table above. ANK_COMMIT, ANK_SKILL and ANK_RELEASED_SCHEMA are read by the build, not at run time: they are what ank --version and the schema warning print. The ANK_INDEX_ names and ANK_TRACE_READS are read at run time, which is why the table lists them, but they exist for the test suite to observe the index and the reads, and a release may change or remove any of them without notice.