Environment variables
Every variable a shipped crucible reads, and what it does with each, grouped the way you are likely to look for them. Each entry says what the variable does and which page owns the behaviour, and where unset matters, what happens without it.
Two rules hold across the list. A variable crucible reads to configure itself
begins with CRUCIBLE_CODE_, and nothing else it reads does: every other name
here belongs to a vendor or to the operating system, and crucible reads it
without deciding what it means. And crucible never writes to its own
environment; the one exception is a library it opens the clipboard with, noted
in that entry. What it sets, it sets for the processes it starts, which the
last two sections cover, plus one internal setting it hands its own Windows
sandbox helper.
Two more are read only if crucible crashes: Rust's own RUST_BACKTRACE and
RUST_LIB_BACKTRACE decide whether the crash message carries a backtrace.
crucible's own settings
CRUCIBLE_CODE_HOME: where crucible keeps its files:config.json,auth.json, the cached release check, thesessionsdirectory and theextensionsdirectory. It is taken as the directory itself, not as somewhere to put a.crucibleinside, and only when it is an absolute path; a relative one is ignored. Unset:.crucibleunder your home directory. It is read to find the configuration file, so it is the one setting of crucible's own that no configuration file can carry: a file that sets it is refused withenv cannot set CRUCIBLE_CODE_HOME. SeeCRUCIBLE_CODE_HOME.CRUCIBLE_CODE_MOUSE_SCROLL_SPEED: how many rows of the transcript one notch of the wheel moves, a whole number from3to30. Unset:6. It can also be written in theenvblock of a configuration file, as an integer or a string, and the shell you start crucible in wins over the block. A value crucible cannot read is refused rather than rounded into range: in a file withis not set to an answer crucible takes, in the shell withCRUCIBLE_CODE_MOUSE_SCROLL_SPEED is not set to an answer crucible takes, each followed by what it does take,a whole number of rows from 3 to 30. SeeCRUCIBLE_CODE_MOUSE_SCROLL_SPEED.
The env block is the environment the commands crucible runs are started
with, and crucible's own settings are read from it under this prefix. A
configuration file under the working directory may set only names that begin
with CRUCIBLE_CODE_; any other name there is refused with env cannot set
and the name, and the message ends: Only crucible's own settings, which start with CRUCIBLE_CODE_, are read from one. Put this in the configuration file in your home directory, or set it in the shell you start crucible in. See
the workspace files.
Where crucible keeps its files
HOME: your home directory. crucible's own directory is.crucibleunder it, unlessCRUCIBLE_CODE_HOMEmoves it. Only an absolute path counts. With neither variable naming a directory, crucible stops before reading any file:crucible has nowhere to keep its files: set HOME, or set CRUCIBLE_CODE_HOME to the absolute path of the directory you want it to use. See the files.USERPROFILE: on Windows only, asked whenHOMEis unset or is not an absolute path. AHOMEinherited from Git Bash can arrive as/c/Users/ada, which Windows does not call absolute, soUSERPROFILEanswers instead and both shells land in the same directory.XDG_DATA_HOME: read only to find session logs written by crucible 0.0.2 or earlier. Whensessionsunder crucible's directory is not a directory and$XDG_DATA_HOME/crucible/sessionsis (or, withXDG_DATA_HOMEunset or not an absolute path,$HOME/.local/share/crucible/sessions, whereHOMEis again the absolute one and neverUSERPROFILE), sessions stay there and are read in place; nothing is copied or moved. WithCRUCIBLE_CODE_HOMEset, the older tree is not looked for. See if you used crucible 0.0.2 or earlier.
Searching the tree
GIT_CONFIG_GLOBAL,GIT_CONFIG_SYSTEM,XDG_CONFIG_HOME: read whengreporglobwalks the tree, by the library that walks it, to find your global git excludes list. The list is the filecore.excludesFilenames in the first of these that sets it: the fileGIT_CONFIG_GLOBALnames, then.gitconfigin your home directory, thengit/configunderXDG_CONFIG_HOME(or under.configin your home directory), then the fileGIT_CONFIG_SYSTEMnames, or/etc/gitconfig. With none, it isgit/ignoreunderXDG_CONFIG_HOME, or.config/git/ignorein your home directory. A~in the setting stands for your home directory. Any of the three set to nothing counts as unset, and your home directory here isHOMEon Unix andUSERPROFILEon Windows, or the account's own when that is unset or empty. See what both of them skip.
Provider keys
ANTHROPIC_API_KEY,DASHSCOPE_API_KEY,DEEPSEEK_API_KEY,GEMINI_API_KEY,META_API_KEY,MIMO_API_KEY,MINIMAX_API_KEY,MOONSHOT_API_KEY,OPENAI_API_KEY,XAI_API_KEY,ZAI_API_KEY: the key foranthropic,qwen,deepseek,google,meta,mimo,minimax,moonshot,openai,xaiandzairespectively, unlessproviders.<name>.apiKeyEnvnames another variable to read instead. The value is trimmed, and unset or blank is treated as no key, which is how a shell turns a variable off for one run. A key inDASHSCOPE_API_KEY,MINIMAX_API_KEYorZAI_API_KEYis sent to the vendor's international site; a key of its mainland China site is given through/login, or reaches it withproviders.<name>.baseUrl. What a provider is used with is settled in this order: an account login stored for it (where the provider supports one and nobaseUrlis set), then the variable, then a key stored inauth.json. See keys and a key written down instead of exported.envFromin anmcp.serversrecord names variables in crucible's own environment whose values are handed to that server as credentials. One that is not set stops the server from starting:envFrom names NAME, which is not set in crucible's own environment. The record'senvvalues go as written, and the server is started with those two blocks and nothing else. See MCP servers.
Proxy and TLS
ALL_PROXY,all_proxy,HTTPS_PROXY,https_proxy,HTTP_PROXY,http_proxy: tried in that order, and the first that holds an address crucible can read is the proxy for every request, whatever the address's scheme. No scheme meanshttp. Asocks://,socks4://orsocks5://address is taken and then connected past, straight to the host; asocks4a://orsocks5h://one refuses every request to a hostNO_PROXYdoes not name. Unset: crucible connects directly. These are read once, from the environment crucible was started in; theenvblock reaches the commands crucible runs and not crucible's own requests, and no proxy setting of the operating system is read. A value that is not valid Unicode counts as unset. See through a proxy.NO_PROXY,no_proxy: hosts reached directly. The first that is set is used, even when set to nothing, soNO_PROXY=hidesno_proxy. Entries are separated by commas and not trimmed. See hosts that skip the proxy.- Certificates: no variable. crucible trusts the Mozilla roots built into it,
over TLS 1.2 or 1.3, and reads neither
SSL_CERT_FILE,SSL_CERT_DIRnor the operating system's store. See certificates.
Terminal and colour
All of these are read at start, and configuration overrides some of them.
output.color decides whether colour is written at all: always writes it
on a terminal despite NO_COLOR, and never writes none. An output that is
not a terminal gets no colour whichever is set. Neither raises what TERM
allows, so always with TERM at dumb or unset still writes no colour
unless COLORTERM says truecolor or 24bit. output.theme set to anything
but auto decides which table is drawn whatever COLORFGBG says. No key in
configuration overrides
COLORTERM, TERM, or the four that stop the terminal being asked.
NO_COLOR: set to anything but empty, withcoloratauto(the default), turns colour off.alwaysandneverdecide without reading it. It does not affect links, which are written whenever a terminal is attached andTERMis notdumb.TERM:dumbturns colour off and stops crucible writing links. A value containing256colorgives the indexed table of 256 colours; any other value gives the sixteen basic colours. Unset turns colour off, because whatever is reading is not saying it is a terminal.TERMINAL_EMULATOR:JetBrains-JediTerm, which a JetBrains IDE sets in its terminal, writes the line of a link to a file as:12after the path, the form that terminal reads. Any other value, or none, writes it as#12, which VS Code and kitty read and the desktop's file opener drops.COLORTERM:truecoloror24bitgives exact colours, whateverTERMsays. Any other value is ignored.COLORFGBG:fg;bg, orfg;other;bg, the rxvt convention. The last field is the background:0to6and8mean dark,7and9to15mean light, anything else says nothing. Withthemeatauto, it seeds which table crucible draws with; a background the terminal reports when asked outranks it, and with neither,autois dark. Unset: the terminal is asked, or dark.SSH_CONNECTION,SSH_CLIENT,SSH_TTY,TMUX: any of these set to something non-empty, orTERMstarting withscreen, says the terminal is somewhere else or behind a multiplexer, where asking it for its background would be slow. crucible then does not ask, andCOLORFGBGor the dark table stands in. The terminal is asked only when colour will be written and both input and output are a terminal.
The argument parser draws its own colour, for --help, --version and a
mistyped flag, before any configuration is read, and decides it from a
separate set of rules. NO_COLOR set to anything but empty turns it off.
Otherwise CLICOLOR_FORCE set to anything but empty turns it on even down a
pipe, and CLICOLOR at 0 turns it off. On a terminal it is drawn when
TERM allows colour, or when CLICOLOR is set to anything else, or when CI
is set at all. On Windows an unset TERM allows colour too; anywhere,
TERM=dumb does not. output.color has no say here.
The clipboard
WAYLAND_DISPLAY,WAYLAND_SOCKET,XDG_RUNTIME_DIR,DISPLAY,XAUTHORITY: on Linux, read when you press Ctrl+V to paste an image, to open the desktop clipboard. WithWAYLAND_DISPLAYset, the Wayland clipboard is tried first:WAYLAND_SOCKETis the file descriptor number of a connection already open, and without itWAYLAND_DISPLAYis the socket's path, absolute as it stands or a name underXDG_RUNTIME_DIR, which has to be absolute. The library removesWAYLAND_SOCKETfrom crucible's environment once it has read it. WithoutWAYLAND_DISPLAY, or when the Wayland clipboard cannot be opened, the X11 clipboard is tried:DISPLAYnames the server, andXAUTHORITYnames the authority file, or.XauthorityunderHOME. When neither opens, the paste is refused withthe clipboard could not be openedand the library's reason, written under the box. It is opened at the first paste and kept for the later ones. macOS and Windows read no variable for this. See run it.
What a command is started with
A command run by the bash tool is not started with the environment crucible
was started in. It gets the variables below, read once when crucible starts,
with whatever the env block adds. A
name in the block replaces the inherited one, and an inherited name that is
unset stays unset. Nothing else crosses, your provider key included. See
what a command is started with.
- On Unix:
PATH,HOME,LC_ALL,LC_CTYPE,LANG,TERM,TMPDIR. - On Windows:
PATH,PATHEXT,COMSPEC,SystemRoot,SystemDrive,windir,TEMP,TMP,HOME,USERPROFILE,HOMEDRIVE,HOMEPATH,APPDATA,LOCALAPPDATA,ProgramFiles,ProgramFiles(x86),ProgramData,TERM. A name in theenvblock replaces an inherited one only where the two are spelled with the same case: a block'sPATHbeside an inheritedPathleaves both in the map. Unconfined, the block's one is what the command sees; a confined command is not started, withWindows sandbox environment is ambiguous.
Some of the same variables are read by crucible itself, to find a program:
PATH: where the shell is looked for, in absolute directories only; a relative entry is never looked in. On Unix,shon thePATH, then/bin/sh, then/usr/bin/sh. On Windows,sh.exeon thePATH, thenusr\bin\sh.exeunderGitinProgramFiles,ProgramFiles(x86)andLocalAppData\Programs. Without one, every command fails withno POSIX shell to run it with, and the reason given isno sh on the PATH or in the places one liveson Unix andinstall Git for Windows, which carries one, or put an sh.exe on the PATHon Windows. On Linux,PATHis also where a system Bubblewrap is looked for when confinement is turned on, and its absence is reported asPATH is unavailable while discovering system Bubblewrap. See operating-system confinement.PATH, and on WindowsProgramFiles,ProgramFiles(x86),LOCALAPPDATA,ProgramDataandUSERPROFILE: whenreadmeets a document, spreadsheet or video it cannot read as text, it names a converter to run.soffice,ffmpegorffprobeis named bare when thePATHfinds it, and by its absolute path when it sits where an installer or package manager put it instead:LibreOffice\programunderProgramFilesorProgramFiles(x86), and the WinGet, Chocolatey and Scoop shim directories underLOCALAPPDATA,ProgramFiles,ProgramDataandUSERPROFILE. On macOS the places looked in are fixed directories; on Linux only thePATHis searched. See a document is read by converting it first.PATH: also where an MCP server'scommandis looked for when it is not written as an absolute path, asNAME(NAME.exeon Windows) in the same absolute directories. One not found stops the server:no NAME on the PATH, with the command as written in place ofNAME. See MCP servers.
What confinement sets or clears
A confined command receives the map above through a cleared process environment, with these changes made by the platform's backend. See environment and credentials.
- Linux:
HOMEandTMPDIRare dropped from the map, andSSH_AUTH_SOCKandGPG_AGENT_INFOare removed even if theenvblock names them; thenHOMEis set to/crucible-homeandTMPDIRto/tmp, both private to the command. - macOS:
TMPDIRis set to a private scratch directory that is removed with the command. It is made under the directoryTMPDIRnames in crucible's own environment, or with that unset, the per-user temporary directory macOS reports, or/tmp. - Windows:
TEMPandTMP, however they are capitalised, are replaced with one private directory that is removed with the command. It is made under the temporary directory Windows reports for the process. The helper that starts the command,crucible-sandbox-broker.exe, is itself started through a cleared environment holding onlySystemRoot, kept because Windows resolves system components through it; the command's map reaches it on its standard input instead. - A command under a network domains policy is given
HTTP_PROXY,HTTPS_PROXY,ALL_PROXY,http_proxy,https_proxyandall_proxy, all set to crucible's own per-command proxy ashttp://name:secret@address, andNO_PROXYandno_proxyset to nothing. These replace whateverenvset, bypass lists included. Linux sets them for any domains policy; macOS only where the policy allows at least one domain. Windows has no per-command proxy and sets none of them. See commands connect on their own.
Unconfined execution also starts from a cleared environment and hands the
command the same map, unchanged. See
unconfined execution. An MCP
server is started the same way, with its record's env and envFrom as the
whole of its map.
The program /login opens your browser with (xdg-open on Linux, open on
macOS, explorer.exe on Windows) is the one child started with crucible's own
environment, because a browser needs your display and desktop session to open.
It is started without the variables a provider key is read from: each
provider's usual one, such as ANTHROPIC_API_KEY, and any variable an
apiKeyEnv setting names. A variable an MCP server's envFrom names is not
withheld: the browser opener inherits it. It gets the address to open as its
only argument. See
account login today.