Claude Code Plugins

Community-maintained marketplace

Feedback

|

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name direnv-pattern
description Implements the b00t environment management pattern: direnv → .envrc → dotenv → .env where datums specify WHICH environment variables are required and .env contains the actual secret VALUES. Ensures automatic environment loading per-project.
version 1.0.0
allowed-tools Read, Write, Edit, Bash

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

  1. Datums specify WHICH - ~/.dotfiles/_b00t_/*.ai.toml files specify required variable names
  2. .env contains VALUES - Actual API keys and secrets (gitignored)
  3. direnv loads automatically - No manual source or export needed
  4. 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 .env to .gitignore
  • ✅ Add .envrc to .gitignore (committed: .envrc.example)
  • ✅ Use .env.example as template (committed to git)
  • ✅ Store API keys only in .env files
  • ✅ Use direnv allow to load environment per-project
  • ✅ Validate environment variables before use

❌ DON'T

  • ❌ Commit .env files to git
  • ❌ Commit .envrc with secrets to git
  • ❌ Hard-code API keys in source code
  • ❌ Store secrets in datum TOML files
  • ❌ Share .env files via chat/email
  • ❌ 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

  1. Install direnv and add shell hook
  2. Copy templates: .envrc.example.envrc, .env.example.env
  3. Edit .env with actual API keys
  4. Run direnv allow
  5. Verify with echo $API_KEY or Python

Adding New Keys

  1. Add to .env.example (commented, as template)
  2. Add to .env (actual value)
  3. Update datum to specify required key
  4. Run direnv allow if .envrc changed

Per-Project Configuration

  1. Navigate to project: cd /path/to/project
  2. Create .envrc: Reference .envrc.example
  3. Create .env: Reference .env.example
  4. Allow: direnv allow
  5. 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

  • b00t-j0b-py/docs/ENVIRONMENT_SETUP.md - Complete guide
  • b00t-j0b-py/.envrc.example - Template
  • b00t-j0b-py/.env.example - API keys template
  • b00t-py/src/lib.rs - PyO3 validation functions

Summary

The b00t direnv pattern provides:

  1. DRY: Single source of truth for requirements (datums)
  2. Secure: Secrets in .env (gitignored), not in code
  3. Automatic: direnv loads environment on cd
  4. Validated: Rust checks required vars before execution
  5. Flexible: Supports multiple .env files, local/global keys