Claude-skill-registry direnv-pattern
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/direnv-pattern" ~/.claude/skills/majiayu000-claude-skill-registry-direnv-pattern && rm -rf "$T"
manifest:
skills/data/direnv-pattern/SKILL.mdsource content
What This Skill Does
The b00t direnv pattern provides secure, automatic environment variable management for projects. This skill helps you:
- Set up direnv + .envrc + .env configuration
- Follow the b00t pattern: WHICH (datums) vs VALUES (.env)
- Validate environment variables before execution
- Support multiple environments (dev, staging, prod)
- Integrate with b00t datum system
When It Activates
Activate this skill when you see phrases like:
- "setup environment variables"
- "configure direnv"
- "create .envrc file"
- "add API keys"
- "environment not loading"
- "missing environment variables"
- "configure .env file"
- "setup direnv pattern"
The b00t Pattern Flow
Developer enters directory ↓ direnv detects .envrc file ↓ .envrc calls: dotenv ↓ dotenv loads .env file ↓ Environment variables available ↓ Rust validates via datum ↓ ✅ Agent runs
Key Principles
- Datums specify WHICH -
files specify required variable names~/.dotfiles/_b00t_/*.ai.toml
contains VALUES - Actual API keys and secrets (gitignored).env
loads automatically - No manualdirenv
orsource
neededexport- Rust validates - Via PyO3 bindings, DRY approach
File Structure
project/ ├── .envrc # ← Loaded by direnv (calls dotenv) ├── .env # ← Contains actual API keys (GITIGNORED!) ├── .envrc.example # ← Template for .envrc (committed) ├── .env.example # ← Shows required keys (committed) └── .gitignore # ← Must include .env and .envrc
Setup Instructions
1. Install direnv
# macOS brew install direnv # Ubuntu/Debian sudo apt-get install direnv # Add to shell (choose one): # bash: echo 'eval "$(direnv hook bash)"' >> ~/.bashrc # zsh: echo 'eval "$(direnv hook zsh)"' >> ~/.zshrc # fish: echo 'direnv hook fish | source' >> ~/.config/fish/config.fish
2. Create .envrc
# b00t direnv configuration # This file demonstrates the b00t pattern: direnv → .envrc → dotenv → .env # Load project .env file (contains API keys) dotenv # Optionally load home directory .env for global keys # dotenv ~/.env # Optionally load environment-specific configs # dotenv .env.local # dotenv .env.development
3. Create .env with API Keys
# OpenRouter (200+ models via single API) OPENROUTER_API_KEY=sk-or-v1-abc123... # Anthropic (Claude) ANTHROPIC_API_KEY=sk-ant-api03-xyz789... # OpenAI OPENAI_API_KEY=sk-proj-def456... # HuggingFace HF_TOKEN=hf_ghi789... # Groq (ultra-fast inference) GROQ_API_KEY=gsk_jkl012...
4. Allow direnv
direnv allow
5. Verify Setup
# Check environment variables are loaded echo $OPENROUTER_API_KEY # Test with Python python3 -c "import os; print('✅ Loaded' if os.getenv('OPENROUTER_API_KEY') else '❌ Not loaded')"
.envrc.example Template
# b00t direnv configuration # Setup: # 1. Copy: cp .envrc.example .envrc # 2. Copy: cp .env.example .env # 3. Edit .env with your actual API keys # 4. Enable: direnv allow # Load project .env file (contains API keys) dotenv # Optionally load home directory .env for global keys # dotenv ~/.env # Optionally load environment-specific configs # dotenv .env.local # Layout python - ensures direnv works with Python virtual environments # Uncomment if using a venv: # layout python python3.12
.env.example Template
# b00t Environment Configuration # ========================================== # API keys are loaded via direnv → .envrc → dotenv → .env pattern. # # Setup: # 1. Copy: cp .env.example .env # 2. Fill in your actual API keys in .env # 3. Enable: direnv allow (after copying .envrc.example to .envrc) # # The b00t pattern: # - Datums (~/.dotfiles/_b00t_/*.ai.toml) specify WHICH vars are required # - This .env file contains the actual VALUES # - direnv loads them automatically when entering the directory # OpenAI (gpt-4, gpt-3.5-turbo, etc.) # OPENAI_API_KEY=sk-proj-... # Anthropic (claude-3.5-sonnet, claude-3-opus, etc.) # ANTHROPIC_API_KEY=sk-ant-api03-... # Google Gemini # GOOGLE_API_KEY=... # Groq (llama-3.1, mixtral, etc.) # GROQ_API_KEY=gsk_... # OpenRouter (200+ models via single API) # OPENROUTER_API_KEY=sk-or-... # HuggingFace # HF_TOKEN=hf_... # Ollama (local models) # OLLAMA_BASE_URL=http://localhost:11434
Integration with Datums
Provider Datum Example
[env] # Required: Must be present in .env file required = ["OPENROUTER_API_KEY"] # Optional: Default values for non-secret configuration defaults = { OPENROUTER_API_BASE = "https://openrouter.ai/api/v1" }
Validation in Python
import b00t_py import os # Ensure direnv loaded the environment assert os.getenv('OPENROUTER_API_KEY'), "Run 'direnv allow' first!" # Validate via datum system validation = b00t_py.check_provider_env("openrouter", "~/.dotfiles/_b00t_") if validation["available"]: print("✅ OpenRouter environment ready") else: print(f"❌ Missing: {validation['missing_env_vars']}") print("Add them to your .env file and run 'direnv allow'")
Advanced Patterns
Multiple Environment Files
Load both global and project-specific keys:
# .envrc # Load global keys from home directory dotenv ~/.env # Load project-specific keys (can override global) dotenv
Environment-Specific Configuration
# .envrc # Load base environment dotenv # Load environment-specific overrides if [ "$ENVIRONMENT" = "production" ]; then dotenv .env.production elif [ "$ENVIRONMENT" = "staging" ]; then dotenv .env.staging else dotenv .env.development fi
Custom Validation in .envrc
#!/usr/bin/env bash # Load environment dotenv # Validate required keys are present required_vars=("OPENROUTER_API_KEY" "ANTHROPIC_API_KEY") for var in "${required_vars[@]}"; do if [ -z "${!var}" ]; then echo "❌ Missing: $var" echo " Add it to your .env file" return 1 fi done echo "✅ All required environment variables loaded"
Security Best Practices
✅ DO
- ✅ Add
to.env.gitignore - ✅ Add
to.envrc
(committed:.gitignore
).envrc.example - ✅ Use
as template (committed to git).env.example - ✅ Store API keys only in
files.env - ✅ Use
to load environment per-projectdirenv allow - ✅ Validate environment variables before use
❌ DON'T
- ❌ Commit
files to git.env - ❌ Commit
with secrets to git.envrc - ❌ Hard-code API keys in source code
- ❌ Store secrets in datum TOML files
- ❌ Share
files via chat/email.env - ❌ Use production keys in examples
.gitignore Configuration
# Environment files (secrets) .env .envrc .env.local .env.*.local # Keep examples (templates) !.env.example !.envrc.example
Troubleshooting
Variables Not Loading
# Check if direnv is hooked direnv status # Re-allow .envrc direnv allow # Check what direnv loaded direnv export bash | grep API_KEY
Missing Required Variables
import b00t_py # List available providers providers = b00t_py.list_ai_providers("~/.dotfiles/_b00t_") print(f"Available: {providers}") # Check specific provider validation = b00t_py.check_provider_env("openrouter", "~/.dotfiles/_b00t_") if not validation["available"]: print(f"Missing: {validation['missing_env_vars']}")
Permission Denied
# Re-allow direnv allow # Check .envrc syntax bash -n .envrc
CI/CD Integration
For environments where direnv isn't available:
# .gitlab-ci.yml variables: OPENROUTER_API_KEY: ${CI_OPENROUTER_API_KEY} test: script: - python3 -m pytest
# .github/workflows/test.yml env: OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - run: python3 -m pytest
Workflow
Initial Setup
- Install direnv and add shell hook
- Copy templates:
→.envrc.example
,.envrc
→.env.example.env - Edit .env with actual API keys
- Run
direnv allow - Verify with
or Pythonecho $API_KEY
Adding New Keys
- Add to .env.example (commented, as template)
- Add to .env (actual value)
- Update datum to specify required key
- Run
if .envrc changeddirenv allow
Per-Project Configuration
- Navigate to project:
cd /path/to/project - Create .envrc: Reference
.envrc.example - Create .env: Reference
.env.example - Allow:
direnv allow - Test: Python imports should have env vars
Related Skills
- datum-system: Specifies WHICH env vars are required
- dry-philosophy: Rust validates env, Python just uses it
- justfile-usage: Add environment setup commands
References
- Complete guideb00t-j0b-py/docs/ENVIRONMENT_SETUP.md
- Templateb00t-j0b-py/.envrc.example
- API keys templateb00t-j0b-py/.env.example
- PyO3 validation functionsb00t-py/src/lib.rs
Summary
The b00t direnv pattern provides:
- DRY: Single source of truth for requirements (datums)
- Secure: Secrets in
(gitignored), not in code.env - Automatic:
loads environment ondirenvcd - Validated: Rust checks required vars before execution
- Flexible: Supports multiple
files, local/global keys.env