Variables and Interpolation
This guide teaches you how to use variables for dynamic content in your canonical files.
What Is Interpolation
Interpolation is the substitution of variable references with their values during transpilation. When Agloom encounters a pattern like ${agloom:VAR} in your files, it replaces it with the actual value before writing the output.
Variable Namespaces
Agloom supports three variable namespaces:
${agloom:VAR} — Agloom Variables
These are adapter-dependent path variables. They resolve to different values depending on which adapter is being transpiled.
Dynamic variables resolve to directories of the adapter currently being transpiled:
| Variable | Example (Claude) |
|---|---|
SKILLS_DIR | .claude/skills |
AGENTS_DIR | .claude/agents |
COMMANDS_DIR | .claude/commands |
DOCS_DIR | .claude/docs |
SCHEMAS_DIR | .claude/schemas |
Each adapter owns a different set of directories, so a dynamic variable
is only available when the current adapter defines it. For instance,
${agloom:COMMANDS_DIR} is undefined when transpiling for Codex,
because Codex has no project-level commands directory. Referencing an
undefined variable fails transpilation.
Canonical variables (fixed, do not change per adapter):
| Variable | Value |
|---|---|
PROJECT_DIR | Absolute path to project root |
AGLOOM_DIR | .agloom |
AGLOOM_SKILLS_DIR | .agloom/skills |
AGLOOM_AGENTS_DIR | .agloom/agents |
AGLOOM_DOCS_DIR | .agloom/docs |
AGLOOM_SCHEMAS_DIR | .agloom/schemas |
PROJECT_DIR is the only canonical variable that contains an absolute
path. All other canonical variables contain paths relative to the
project root. You can compose absolute paths by concatenating
${agloom:PROJECT_DIR} with any relative variable, for example
${agloom:PROJECT_DIR}/${agloom:AGLOOM_DIR} expands to
<projectRoot>/.agloom.
Per-adapter variables address another adapter's directories
regardless of which adapter is currently being transpiled. Their names
follow the pattern {ADAPTER}_<KIND>_DIR, where {ADAPTER} is the
uppercased adapter id:
${agloom:CLAUDE_SKILLS_DIR} → .claude/skills
${agloom:OPENCODE_AGENTS_DIR} → .opencode/agents
${agloom:GEMINI_COMMANDS_DIR} → .gemini/commands
Each adapter generates the prefixed variables only for the directories
it owns. Two exceptions are worth remembering: CODEX_COMMANDS_DIR does
not exist (Codex has no commands directory), and the agentsmd adapter
generates no per-adapter variables at all because it owns no directory
of its own — it only emits an AGENTS.md file. For the complete list
of paths per adapter, see reference/adapters.
Example usage in an agent file:
Read the protocol at `${agloom:DOCS_DIR}/protocol.md`.
Skills are located at `${agloom:SKILLS_DIR}/`.
When transpiling for Claude, this becomes:
Read the protocol at `.claude/docs/protocol.md`.
Skills are located at `.claude/skills/`.
${env:VAR} — Environment Variables
Reference environment variables from process.env:
Project: ${env:PROJECT_NAME}
API endpoint: ${env:API_URL}
Agloom automatically loads a .env file from your project root (if it exists) before transpilation. Variables defined in process.env take precedence over .env values.
If the referenced variable is not defined, transpilation fails with an error.
${values:VAR} — Plugin and Project Values
Reference resolved values from plugins or project variables:
Team: ${values:team_name}
Base URL: ${values:base_url}
These values come from two sources:
- Plugin values — resolved from plugin variable declarations and the
valuesfield in your config (see Plugins). - Project variables — resolved from the
variablessection ofconfig.yml(see below).
Each plugin receives only its own resolved values — plugins cannot access each other's values.
Project Variables
Declare project-level variables in the variables section of config.yml:
adapters:
- claude
variables:
project_name: "${env:PROJECT_NAME}"
team:
description: "Team name"
default: "platform"
api_key:
description: "API key for external service"
default: "${env:API_KEY}"
sensitive: true
required: true
Shorthand Form
A string value is shorthand for { default: "<value>" }:
variables:
project_name: "${env:PROJECT_NAME}"
This is equivalent to:
variables:
project_name:
default: "${env:PROJECT_NAME}"
Full Form
The full form supports these fields:
description— human-readable description (optional in config, required in plugin manifests).default— default value. Can contain${env:VAR}references.required— iftrue, the variable must have a value (from default or environment). Defaults tofalse.sensitive— iftrue, the value must reference an environment variable (${env:VAR}). Inline values are rejected. Defaults tofalse.
.env File
Agloom loads a .env file from the project root before transpilation. This file follows the standard dotenv format:
PROJECT_NAME=my-app
API_KEY=secret-key-123
Variables from .env are available through ${env:VAR} in instructions, skills, agents, overlays, and variable defaults.
If .env does not exist, Agloom silently continues without it.
Where Interpolation Applies
Interpolation runs in the following contexts:
- Instructions —
AGLOOM.mdfiles (.md) - Skills —
.mdfiles within skill directories - Agents —
.mdagent definition files - Docs —
.mdfiles in the docs directory - Schemas —
.mdfiles in the schemas directory - Overlays — files with interpolatable extensions:
.md,.txt,.json,.jsonc,.jsonl,.xml,.html,.svg,.toml,.yml,.yaml
Binary files and non-interpolatable extensions are always copied as-is.
Escaping
To include a literal ${agloom:VAR} in your output (without interpolation), prefix with a backslash:
Use \${agloom:SKILLS_DIR} to reference the skills directory.
This outputs the literal text ${agloom:SKILLS_DIR}.
Example
Here is an end-to-end example: declaring a variable in config, using it in a skill, and seeing the result after transpile.
Step 1: Declare the variable in config.yml:
adapters:
- claude
variables:
team_name: "platform"
Step 2: Use it in a skill:
---
name: deploy
description: Deploy the application
---
# Deploy
Deploy the application for the ${values:team_name} team.
Artifacts are stored in `${agloom:DOCS_DIR}/deployments/`.
Step 3: Run agloom transpile. The output in .claude/skills/deploy/SKILL.md:
---
name: deploy
description: Deploy the application
---
# Deploy
Deploy the application for the platform team.
Artifacts are stored in `.claude/docs/deployments/`.
The ${values:team_name} was replaced with "platform" and ${agloom:DOCS_DIR} was replaced with .claude/docs.