Environment variables
This guide covers the environment variables Tinka reads and sets. You will learn how to:
- Set the Mode and the directory
.envfiles are read from - Configure an App made from the skeleton Starter kit
- Recognize the variables
actsets for the App, which you never set yourself - Turn Agent mode on or off, and know which variables detect an agent
- Turn colors off in terminal output
- Rewrite golden files in tests
- Let Go download Tinka during the alpha
Overview
Tinka reads few environment variables of its own, and they come in three kinds:
- Core reads them. The
envpackage,Serveand every Command read these, whatever Starter kit the App came from. - Your App reads them. The skeleton Starter kit's
config/*.gofiles readPORT,APP_KEYand the rest. They are your App's code: rename them, add your own, or drop them. actsets them.act serveand Forwarding pass these to the processes they start. Setting them yourself breaks what they coordinate.
Variables read through an Env's getters, such as e.Int("PORT", 3000), come from the real environment or from the Mode's .env files, and the real environment wins. Every other variable on this page is read from the real environment only, so setting it in a .env file has no effect. Configuration & Environment explains how .env files are found, merged and validated.
The Mode and .env files
The env package reads these two before anything else, because they decide which .env files the App reads. Both must come from the real environment.
Any variable read through a getter also has a file form: when KEY is missing and KEY_FILE is set, the getter reads the value from the file KEY_FILE names. See Reading values from files.
The skeleton Starter kit's variables
An App created with tinka new --kit skeleton reads these in config/, and lists them in .env.example. tinka new copies .env.example to .env with a new APP_KEY, and writes a .env.test with a separate test key and LOG_LEVEL=error. The core Starter kit reads none of them: its tinka.New(tinka.HTTPConfig{}) listens on :3000.
The kit's tests.App builds the App in the test Mode whatever APP_ENV says, so tests load .env.test over .env, and never .env.local.
Variables act sets for the App
act serve and Forwarding start other processes and pass them these variables. They are internal: never set them yourself, in a shell or in a .env file.
act caches the App's binary and builds it again when its sources change, or when one of these Go variables does: GOFLAGS, GOOS, GOARCH, GOAMD64, GOARM64, GOEXPERIMENT, CGO_ENABLED, CC, GOTOOLCHAIN, GOPROXY and GOPRIVATE.
Agent mode and agent detection
Every Command decides between output for people and a single JSON result. --json always wins; otherwise these variables decide, in order. See When Agent mode turns on.
When neither names an agent, Tinka turns Agent mode on if any of the variables below is set, to any value, even an empty one; only TERM_PROGRAM needs the value shown. The last four also appear in terminals that people type into, because editors set them for their integrated terminal, so they only count when stdin is not a terminal.
- Cursor:
CURSOR_AGENT - Grok:
GROK_PLUGIN_ROOT,GROK_PLUGIN_DATA - Gemini CLI:
GEMINI_CLI - Codex:
CODEX_SANDBOX,CODEX_CI,CODEX_THREAD_ID,CODEX_SANDBOX_NETWORK_DISABLED - Augment:
AUGMENT_AGENT - OpenCode:
OPENCODE_CLIENT,OPENCODE - Amp:
AMP_CURRENT_THREAD_ID - Claude Cowork:
CLAUDE_CODE_IS_COWORK - Claude Code:
CLAUDE_CODE_CHILD_SESSION - GitHub Copilot:
COPILOT_CLI,COPILOT_MODEL,COPILOT_ALLOW_ALL - Antigravity:
ANTIGRAVITY_AGENT,ANTIGRAVITY_CLI_ALIAS - Pi:
PI_CODING_AGENT - Junie:
JUNIE_DATA,JUNIE_SHIM_PATH,MATTERHORN_SESSION_ID - Kiro:
KIRO_AGENT_PATH - Kimi:
KIMI_PLUGIN_ROOT - Cline:
CLINE_ACTIVE - Goose:
GOOSE_TERMINAL - OpenClaw:
OPENCLAW_SHELL - ZCode:
ZCODE_ENV - Devin: a file at
/opt/.devin, rather than a variable - Claude Code, without a terminal:
CLAUDECODE,CLAUDE_CODE - Cursor, without a terminal:
CURSOR_TRACE_ID - Replit, without a terminal:
REPL_ID - Kiro and Windsurf, without a terminal:
TERM_PROGRAM=kiroorTERM_PROGRAM=windsurf
Terminal output
Commands style their output only when stderr is a terminal. Two variables turn the styling off. See Control colors.
An App's own Command can also read a flag from a variable you choose with f.Env, such as f.Env("batch-size", "IMPORT_BATCH_SIZE"), and the command line wins over the variable. Tinka's own Commands bind no flag to a variable. See Read flags from the environment.
Tests
Where act keeps its files
act records trusted Apps in tinka/trusted-apps under your user config directory. It keeps the binaries it builds for Forwarding, and the locks of --isolated runs, under tinka/ in your user cache directory. Go finds both directories from the environment, the config directory first:
- Linux:
$XDG_CONFIG_HOME, or$HOME/.config, and$XDG_CACHE_HOME, or$HOME/.cache - macOS:
$HOME/Library/Application Supportand$HOME/Library/Caches - Windows:
%AppData%and%LocalAppData%
When Go can't find the cache directory, Forwarding fails with no_cache_dir. See Error codes.
Installing during the alpha
During the alpha the Tinka repository is private, and Go's public module proxy can't download it. Set Go's GOPRIVATE so the go command downloads every github.com/mucolabs module straight from GitHub, bypassing GOPROXY and the checksum database for them:
go env -w GOPRIVATE=github.com/mucolabs/*git must also be able to authenticate to GitHub. Without both, go install fails, and tinka new fails with install_failed after creating the App. See Installation.
See also: Configuration & Environment, Agent mode, Error codes, Commands, Development environment setup