Reference

Configuration Reference

This page covers various configuration methods and tools for managing your development environment, with a focus on environment variables and secrets management.

Configuration Reference

This page covers various configuration methods and tools for managing your development environment, with a focus on environment variables and secrets management.

Table of Contents

Organization Pattern

We recommend organizing your development projects using a consistent directory structure that makes it easy to navigate between different organizations, repositories, and branches. The recommended pattern is:

~/dev/[github-org]/[root-repo]/[branch]

Example Structure

~/dev/
├── sigaostudios/
│   ├── sigao-ai-devkit/
│   │   ├── main/           # Primary branch (clone)
│   │   ├── feature-auth/   # Git worktree
│   │   ├── bugfix-123/     # Git worktree
│   │   └── .envrc          # Shared environment variables
│   └── another-project/
│       ├── main/
│       └── .envrc
├── personal/
│   └── my-project/
│       ├── main/
│       └── develop/
└── client-work/
    └── client-api/
        ├── main/
        └── staging/

Benefits of This Structure

  1. Clear Organization: Instantly know which organization owns each project
  2. Multiple Checkouts: Work on different branches simultaneously without stashing
  3. Isolation: Each project has its own environment configuration
  4. Consistency: Team members can use the same structure for easy collaboration
  5. Navigation: Easy to script and create aliases for common directories

Git Worktrees

Git worktrees allow you to have multiple branches checked out simultaneously in different directories, which is perfect for our directory structure.

Setting Up Worktrees

  1. Initial Clone (for the main branch):
    cd ~/dev/sigaostudios
    git clone https://github.com/sigaostudios/sigao-ai-devkit.git sigao-ai-devkit
    cd sigao-ai-devkit
    mv * .* ../sigao-ai-devkit-temp 2>/dev/null || true
    cd ..
    mv sigao-ai-devkit sigao-ai-devkit-main
    mkdir sigao-ai-devkit
    mv sigao-ai-devkit-main sigao-ai-devkit/main
    cd sigao-ai-devkit
    

    Or more simply, clone directly into the desired structure:
    cd ~/dev/sigaostudios
    mkdir sigao-ai-devkit
    cd sigao-ai-devkit
    git clone https://github.com/sigaostudios/sigao-ai-devkit.git main
    
  2. Add a New Worktree for a feature branch:
    cd ~/dev/sigaostudios/sigao-ai-devkit/main
    git worktree add ../feature-auth -b feature-auth
    
  3. Work on Existing Branch:
    cd ~/dev/sigaostudios/sigao-ai-devkit/main
    git worktree add ../bugfix-123 bugfix-123
    
  4. List All Worktrees:
    git worktree list
    
  5. Remove a Worktree when done:
    cd ~/dev/sigaostudios/sigao-ai-devkit/main
    git worktree remove ../feature-auth
    

Worktree Best Practices

  • Main Branch: Keep your main branch in the main/ directory
  • Feature Branches: Create worktrees for active development
  • Cleanup: Remove worktrees after merging to keep things tidy
  • Naming: Use descriptive branch names that indicate purpose

Environment Configuration

Place your .envrc file at the repository root level (not in individual worktree directories) so it's shared across all branches:

~/dev/sigaostudios/sigao-ai-devkit/
├── .envrc          # Shared across all worktrees
├── main/
├── feature-auth/
└── bugfix-123/

Repository-Level .envrc

Create your .envrc at the repository root:

cd ~/dev/sigaostudios/sigao-ai-devkit
cat > .envrc << 'EOF'
# Project-wide environment variables
export PROJECT_NAME="sigao-ai-devkit"
export API_KEY="your-api-key"
export DATABASE_URL="postgresql://localhost/sigao_dev"

# Add all worktree bin directories to PATH
for dir in */bin; do
    if [ -d "$dir" ]; then
        export PATH="$PWD/$dir:$PATH"
    fi
done

# Node.js project setup
if [ -d "main/node_modules/.bin" ]; then
    export PATH="$PWD/main/node_modules/.bin:$PATH"
fi

# Python virtual environment (if needed)
if [ -f "main/.venv/bin/activate" ]; then
    source main/.venv/bin/activate
fi

# Load branch-specific overrides if they exist
CURRENT_BRANCH=$(basename $PWD)
if [ -f ".envrc.$CURRENT_BRANCH" ]; then
    source_env ".envrc.$CURRENT_BRANCH"
fi
EOF

direnv allow

Branch-Specific Configuration

When you need branch-specific environment variables, create additional files:

# .envrc.feature-auth
export API_ENDPOINT="http://localhost:3001"  # Different port for auth testing
export ENABLE_AUTH_DEBUG="true"

Add these aliases to your ~/.bashrc or ~/.zshrc:

# Quick navigation
alias dev="cd ~/dev"
alias devs="cd ~/dev/sigaostudios"

# Project navigation function
proj() {
    if [ -z "$1" ]; then
        cd ~/dev
    elif [ -z "$2" ]; then
        cd ~/dev/*/$1 2>/dev/null || cd ~/dev/*/*/$1 2>/dev/null || echo "Project not found"
    else
        cd ~/dev/$1/$2 2>/dev/null || echo "Project not found"
    fi
}

# List all projects
alias projects="find ~/dev -mindepth 3 -maxdepth 3 -type d | sed 's|.*/dev/||' | sort"

# Create new worktree helper
worktree-add() {
    if [ -z "$1" ]; then
        echo "Usage: worktree-add <branch-name>"
        return 1
    fi
    git worktree add ../$1 -b $1
    cd ../$1
}

Example Workflow

  1. Start a New Feature:
    cd ~/dev/sigaostudios/sigao-ai-devkit/main
    worktree-add feature-payment-integration
    # Now in ~/dev/sigaostudios/sigao-ai-devkit/feature-payment-integration
    
  2. Switch Between Branches:
    cd ~/dev/sigaostudios/sigao-ai-devkit/feature-auth
    # Work on auth feature
    
    cd ../main
    # Check something in main branch
    
    cd ../feature-payment-integration
    # Continue payment work
    
  3. Environment Variables Load Automatically:
    cd ~/dev/sigaostudios/sigao-ai-devkit/feature-auth
    # .envrc loads automatically
    echo $PROJECT_NAME  # "sigao-ai-devkit"
    
    cd ~/dev/personal/my-project
    # Previous project's variables unloaded
    # New project's .envrc loads
    

Environment Variables with direnv

Why Use direnv?

direnv is an environment switcher for the shell that automatically loads and unloads environment variables based on your current directory. Here's why it's incredibly helpful for development:

1. Automatic Environment Switching

  • No more manually sourcing .env files or setting variables
  • Environment variables are automatically loaded when you cd into a project
  • Variables are unloaded when you leave the directory, preventing conflicts

2. Project Isolation

  • Each project can have its own set of environment variables
  • No risk of variables from one project affecting another
  • Perfect for working on multiple projects with different configurations

3. Security Benefits

  • Requires explicit approval before loading .envrc files (direnv allow)
  • Prevents accidental execution of untrusted environment configurations
  • Keeps sensitive variables out of your shell history

4. Developer Experience

  • Seamless integration with your workflow
  • Works with any shell (bash, zsh, fish, etc.)
  • Supports complex environment setups including PATH modifications

5. Team Collaboration

  • Share .envrc.example files with your team
  • Each developer creates their own .envrc with their specific values
  • Consistent environment setup across the team

Basic Usage

Installation

If you haven't already installed direnv, it's included in our developer setup:

# Already installed via install-dev-tools.sh
# Manual installation if needed:
curl -sfL https://direnv.net/install.sh | bash

Creating Your First .envrc

  1. Navigate to your project directory:
    cd ~/my-project
    
  2. Create a .envrc file:
    # Basic example
    echo 'export API_KEY="your-secret-key"' > .envrc
    echo 'export DATABASE_URL="postgresql://localhost/mydb"' >> .envrc
    
  3. Allow direnv to load the file:
    direnv allow
    
  4. Test it works:
    echo $API_KEY  # Shows your key
    cd ..
    echo $API_KEY  # Empty - variable unloaded!
    cd my-project
    echo $API_KEY  # Shows your key again
    

Advanced Features

Layout Functions

direnv provides useful layout functions for different programming languages:

# Python virtual environment
echo 'layout python3' > .envrc
direnv allow
# Automatically creates and activates a venv

# Node.js with specific version
echo 'use node 18.17.0' > .envrc
direnv allow

# Ruby with rbenv
echo 'use rbenv' > .envrc
direnv allow

PATH Modifications

Add project-specific directories to your PATH:

# .envrc
export PATH="$PWD/bin:$PATH"
export PATH="$PWD/node_modules/.bin:$PATH"

Loading from .env Files

Keep your .envrc clean by loading from .env files:

# .envrc
dotenv .env
dotenv .env.local  # Local overrides

Conditional Logic

Add logic to your .envrc for different environments:

# .envrc
if [[ "$USER" == "production" ]]; then
    export NODE_ENV="production"
    export API_URL="https://api.production.com"
else
    export NODE_ENV="development"
    export API_URL="http://localhost:3000"
fi

Best Practices

1. Use .envrc.example

Always provide an example file for your team:

# .envrc.example
export API_KEY="your-api-key-here"
export DATABASE_URL="postgresql://user:pass@localhost/dbname"
export REDIS_URL="redis://localhost:6379"
export NODE_ENV="development"

Add to your README:

## Setup
1. Copy `.envrc.example` to `.envrc`
2. Fill in your values
3. Run `direnv allow`

2. Git Configuration

Always gitignore your actual .envrc:

# .gitignore
.envrc
!.envrc.example

3. Organize Complex Configurations

For complex setups, use multiple files:

# .envrc
source_env_if_exists .envrc.private
source_env_if_exists .envrc.local

# Common variables
export APP_NAME="my-app"
export LOG_LEVEL="debug"

4. Document Required Variables

Create a table in your README:

VariableDescriptionExample
API_KEYExternal API authenticationsk-1234567890
DATABASE_URLPostgreSQL connection stringpostgresql://localhost/myapp
REDIS_URLRedis connection stringredis://localhost:6379

.NET Secrets Management

While the Sigao AI DevKit doesn't currently include .NET projects, here's how to manage secrets in .NET applications, which can be integrated with direnv.

Using dotnet user-secrets

The .NET Secret Manager tool stores sensitive data during development, keeping secrets out of your code.

Setup

  1. Initialize user secrets in your project:
    dotnet user-secrets init
    
  2. Set a secret:
    dotnet user-secrets set "ApiKey" "12345"
    dotnet user-secrets set "ConnectionStrings:DefaultConnection" "Server=.;Database=MyDb;..."
    
  3. List secrets:
    dotnet user-secrets list
    
  4. Access in code:
    var apiKey = Configuration["ApiKey"];
    var connString = Configuration.GetConnectionString("DefaultConnection");
    

Integration with direnv

You can combine .NET secrets with direnv for a unified experience:

# .envrc
# Export .NET secrets as environment variables
export ApiKey=$(dotnet user-secrets list --json | jq -r '.ApiKey // empty')
export ConnectionStrings__DefaultConnection=$(dotnet user-secrets list --json | jq -r '."ConnectionStrings:DefaultConnection" // empty')

# Fallback to local development values if secrets not set
export ApiKey=${ApiKey:-"dev-api-key"}
export ConnectionStrings__DefaultConnection=${ConnectionStrings__DefaultConnection:-"Server=localhost;Database=DevDb;..."}

Benefits of This Approach

  1. Single Source of Truth: Manage all environment variables through direnv
  2. Flexibility: Use .NET secrets for sensitive data, direnv for everything else
  3. Team Friendly: Developers can choose between .NET secrets or .envrc files
  4. Production Ready: Same environment variable names work in production

Starship Prompt Configuration

Why Starship?

Starship is a minimal, blazing-fast, and infinitely customizable prompt for any shell. It's particularly valuable for developers because it provides:

  1. Context Awareness: Shows current git branch, Node.js/Python/Rust versions, AWS profile, and more
  2. Performance: Written in Rust for speed - adds minimal latency to your prompt
  3. Cross-Shell Support: Works with Bash, Zsh, Fish, PowerShell, and more
  4. Customizable: Extensive configuration options via starship.toml
  5. Smart Defaults: Looks great out of the box with sensible defaults

Installation and Setup

Starship is already included in our developer setup script, but here's how to install it manually:

# Install via curl (recommended)
curl -sS https://starship.rs/install.sh | sh

# Or install via package manager
brew install starship              # macOS
sudo snap install starship         # Ubuntu
cargo install starship --locked    # Using Rust

Shell Configuration

Add to the end of your shell configuration file:

# ~/.bashrc
eval "$(starship init bash)"

# ~/.zshrc
eval "$(starship init zsh)"

# ~/.config/fish/config.fish
starship init fish | source

Configuration with starship.toml

Starship uses a TOML configuration file located at ~/.config/starship.toml. Here are some powerful configurations for development:

Basic Configuration

# ~/.config/starship.toml

# Don't print a new line at the start of the prompt
add_newline = false

# Wait 10 milliseconds for starship to check files
scan_timeout = 10

# Disable the package module, hiding it from the prompt completely
[package]
disabled = true

Developer-Focused Configuration

# ~/.config/starship.toml

# Format the prompt
format = """
[┌─────────────────────────────────>](bold green)
[│](bold green) $username$hostname$directory$git_branch$git_status$nodejs$python$rust$golang$docker_context
[└─>](bold green) """

# Show command duration for commands that take > 2 seconds
[cmd_duration]
min_time = 2_000
format = "took [$duration](bold yellow) "

# Directory settings
[directory]
truncation_length = 3
truncate_to_repo = true
format = "[$path]($style)[$read_only]($read_only_style) "
style = "bold cyan"

# Git branch configuration
[git_branch]
symbol = " "
format = "[$symbol$branch]($style) "
style = "bold purple"

# Git status symbols
[git_status]
format = '([\[$all_status$ahead_behind\]]($style) )'
conflicted = "🏳"
ahead = "⇡${count}"
behind = "⇣${count}"
diverged = "⇕⇡${ahead_count}⇣${behind_count}"
untracked = "🤷"
stashed = "📦"
modified = "📝"
staged = '[++\($count\)](green)'
renamed = "👅"
deleted = "🗑"

# Show Node.js version for JS/TS projects
[nodejs]
format = "via [⬢ $version](bold green) "
detect_files = ["package.json", ".node-version"]
detect_folders = ["node_modules"]

# Python version display
[python]
format = 'via [${symbol}${pyenv_prefix}(${version} )(\($virtualenv\) )]($style)'
symbol = "🐍 "
style = "yellow bold"

# Show current AWS profile
[aws]
format = 'on [$symbol($profile )(\($region\) )]($style)'
style = "bold orange"
symbol = "☁️  "
[aws.region_aliases]
us-east-1 = "va"
us-west-2 = "or"

# Docker context
[docker_context]
format = "via [🐋 $context](blue bold)"
only_with_files = true

# Kubernetes context - useful for cloud development
[kubernetes]
format = 'on [⛵ $context \($namespace\)](dimmed green) '
disabled = false
[kubernetes.context_aliases]
"dev.local.cluster.k8s" = "dev"

Minimal Configuration

For those who prefer a cleaner look:

# ~/.config/starship.toml

format = "$directory$git_branch$git_status$character"

[directory]
truncation_length = 2
format = "[$path](bold blue) "

[git_branch]
format = "[$symbol$branch](bold yellow) "
symbol = ""

[git_status]
format = '([$all_status$ahead_behind](red) )'
conflicted = "="
ahead = "↑"
behind = "↓"
diverged = "↕"
untracked = "?"
stashed = "$"
modified = "!"
staged = "+"
renamed = "»"
deleted = "✘"

[character]
success_symbol = "[❯](bold green)"
error_symbol = "[❯](bold red)"

Performance-Optimized Configuration

For maximum speed on large repositories:

# ~/.config/starship.toml

command_timeout = 100

[git_status]
disabled = false
ahead = "↑${count}"
behind = "↓${count}"
diverged = "↕↑${ahead_count}↓${behind_count}"
untracked = "[${count}+](bold red)"
stashed = ""
modified = "[${count}~](bold yellow)"
staged = "[${count}✓](bold green)"
renamed = ""
deleted = "[${count}✗](bold red)"

# Disable modules that can be slow
[package]
disabled = true

[nodejs]
disabled = false
detect_files = ["package.json"]
detect_folders = []

[rust]
disabled = false
detect_files = ["Cargo.toml"]
detect_folders = []

Integration with Development Tools

Direnv Integration

Show when direnv is active in your prompt:

[env_var.DIRENV_DIR]
format = "[direnv](bold cyan) "
variable = "DIRENV_DIR"

[custom.direnv]
command = "echo 📁"
when = '[[ -n "$DIRENV_DIR" ]]'
format = "[$output](yellow) "

Git Worktree Indicator

Show which worktree you're in:

[custom.git_worktree]
command = "basename $(git rev-parse --show-toplevel 2>/dev/null) 2>/dev/null || echo ''"
when = "git rev-parse --is-inside-work-tree 2>/dev/null"
format = "[($output)]($style) "
style = "bold blue"

Virtual Environment Detection

Better Python virtual environment display:

[python]
format = 'via [${symbol}${pyenv_prefix}(${version} )(\($virtualenv\) )]($style)'
python_binary = ["./venv/bin/python", "python", "python3"]
detect_extensions = ["py"]
detect_files = [".python-version", "Pipfile", "__pycache__", "pyproject.toml", "requirements.txt", "setup.py", "tox.ini"]

Custom Time Display

Show current time in prompt (useful for long-running commands):

[time]
disabled = false
format = '🕙[\[ $time \]]($style) '
time_format = "%T"
style = "bold dim white"

SSH Indicator

Show when you're in an SSH session:

[custom.ssh]
command = "echo 🌐"
when = '[[ -n "$SSH_CLIENT" || -n "$SSH_TTY" ]]'
format = "[$output ](bold blue)"

Tips and Best Practices

  1. Start Simple: Begin with minimal configuration and add features as needed
  2. Profile Performance: Use starship timings to identify slow modules
  3. Version Control: Keep your starship.toml in your dotfiles repository
  4. Theme Consistency: Match your prompt colors to your terminal theme
  5. Context Awareness: Only show relevant information (e.g., Node.js version in JS projects)

Shell Startup Customization

ANSI Art Welcome Banner

The Sigao AI DevKit includes a custom ANSI art banner that displays when you start a new shell session. This adds a professional touch to your development environment.

Installation

The kitchen-sink installer automatically configures the ANSI art display by:

  1. Downloading sigao.ans from the repository to ~/.config/sigao/
  2. Adding display commands to your shell configuration

Manual Setup

If you want to add the banner manually or customize it:

# Create config directory
mkdir -p ~/.config/sigao

# Download the ANSI art file
curl -fsSL https://raw.githubusercontent.com/sigaostudios/sigao-ai-devkit/main/setup/sigao.ans \
     -o ~/.config/sigao/sigao.ans

# Add to ~/.bashrc or ~/.zshrc
cat >> ~/.bashrc << 'EOF'
# Sigao AI DevKit Welcome Banner
if [ -f "$HOME/.config/sigao/sigao.ans" ]; then
    cat "$HOME/.config/sigao/sigao.ans"
    echo ""  # Add blank line after art
fi
EOF

Alternative: Inline ANSI Art

For environments where downloading isn't possible, you can embed the art directly:

# Add to ~/.bashrc or ~/.zshrc
cat >> ~/.bashrc << 'EOF'
# Sigao AI DevKit Welcome Banner (inline)
sigao_banner() {
    # Download on first use if not present
    if [ ! -f "$HOME/.config/sigao/sigao.ans" ]; then
        mkdir -p ~/.config/sigao
        curl -fsSL https://raw.githubusercontent.com/sigaostudios/sigao-ai-devkit/main/setup/sigao.ans \
             -o ~/.config/sigao/sigao.ans 2>/dev/null
    fi
    
    if [ -f "$HOME/.config/sigao/sigao.ans" ]; then
        cat "$HOME/.config/sigao/sigao.ans"
        echo ""
    fi
}
sigao_banner
EOF

Creating Custom ANSI Art

You can create your own ANSI art using tools like:

  • PabloDraw - Cross-platform ANSI/ASCII art editor
  • Moebius - Modern ANSI art editor
  • Online converters - Convert images to ANSI art

Save your custom art as .ans file and update the path in your shell configuration.

Conditional Display

To show the banner only on interactive shells or specific conditions:

# Only show in interactive shells
if [[ $- == *i* ]] && [ -f "$HOME/.config/sigao/sigao.ans" ]; then
    cat "$HOME/.config/sigao/sigao.ans"
    echo ""
fi

# Show only once per day
LAST_SHOWN_FILE="$HOME/.config/sigao/.last_shown"
TODAY=$(date +%Y%m%d)
if [ -f "$HOME/.config/sigao/sigao.ans" ]; then
    if [ ! -f "$LAST_SHOWN_FILE" ] || [ "$(cat "$LAST_SHOWN_FILE")" != "$TODAY" ]; then
        cat "$HOME/.config/sigao/sigao.ans"
        echo "$TODAY" > "$LAST_SHOWN_FILE"
        echo ""
    fi
fi

# Disable temporarily
export SIGAO_NO_BANNER=1  # Add to .envrc or shell to skip banner

Performance Considerations

ANSI art display is very fast, but if you want to optimize further:

# Cache the processed output
if [ ! -f "$HOME/.cache/sigao_banner" ]; then
    cat "$HOME/.config/sigao/sigao.ans" > "$HOME/.cache/sigao_banner"
fi
cat "$HOME/.cache/sigao_banner"

Example Setup Script

Add this to your dotfiles setup:

# Install starship if not present
if ! command -v starship &> /dev/null; then
    curl -sS https://starship.rs/install.sh | sh
fi

# Create config directory
mkdir -p ~/.config

# Link or copy your starship.toml
ln -sf ~/dotfiles/starship.toml ~/.config/starship.toml

# Add to shell rc file if not already present
if ! grep -q "starship init" ~/.bashrc; then
    echo 'eval "$(starship init bash)"' >> ~/.bashrc
fi

Troubleshooting

  1. Slow Prompt: Run starship timings to identify bottlenecks
  2. Missing Icons: Install a Nerd Font for full icon support
  3. Git Status Slow: Disable git status in large repos or use the performance config above
  4. Module Not Showing: Check detection files/folders and ensure disabled = false

Security Considerations

Do's

  1. Always use direnv allow after reviewing .envrc changes
  2. Keep secrets in .envrc, never commit them
  3. Use descriptive variable names to avoid confusion
  4. Rotate secrets regularly and update your .envrc
  5. Use read-only permissions for .envrc files: chmod 600 .envrc

Don'ts

  1. Never commit .envrc files with real secrets
  2. Don't use production secrets in development
  3. Avoid hardcoding sensitive values in your code
  4. Don't share .envrc files via insecure channels
  5. Never auto-allow direnv without reviewing changes

Additional Security Tools

Consider these complementary tools:

Troubleshooting

Common Issues

  1. direnv: command not found
    # Ensure direnv is in your PATH
    eval "$(direnv hook bash)"  # or zsh
    
  2. Variables not loading
    # Check if .envrc is allowed
    direnv status
    direnv allow
    
  3. Permission denied
    # Fix permissions
    chmod 600 .envrc
    
  4. Syntax errors in .envrc
    # Validate your .envrc
    bash -n .envrc