Configuration 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.
Table of Contents
- Recommended Directory Structure
- Environment Variables with direnv
- .NET Secrets Management
- Starship Prompt Configuration
- Shell Startup Customization
- Security Considerations
Recommended Directory Structure
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
- Clear Organization: Instantly know which organization owns each project
- Multiple Checkouts: Work on different branches simultaneously without stashing
- Isolation: Each project has its own environment configuration
- Consistency: Team members can use the same structure for easy collaboration
- 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
- 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 - Add a New Worktree for a feature branch:
cd ~/dev/sigaostudios/sigao-ai-devkit/main git worktree add ../feature-auth -b feature-auth - Work on Existing Branch:
cd ~/dev/sigaostudios/sigao-ai-devkit/main git worktree add ../bugfix-123 bugfix-123 - List All Worktrees:
git worktree list - 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"
Navigation Helpers
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
- 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 - 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 - 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
.envfiles or setting variables - Environment variables are automatically loaded when you
cdinto 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
.envrcfiles (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.examplefiles with your team - Each developer creates their own
.envrcwith 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
- Navigate to your project directory:
cd ~/my-project - Create a
.envrcfile:# Basic example echo 'export API_KEY="your-secret-key"' > .envrc echo 'export DATABASE_URL="postgresql://localhost/mydb"' >> .envrc - Allow direnv to load the file:
direnv allow - 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:
| Variable | Description | Example |
|---|---|---|
API_KEY | External API authentication | sk-1234567890 |
DATABASE_URL | PostgreSQL connection string | postgresql://localhost/myapp |
REDIS_URL | Redis connection string | redis://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
- Initialize user secrets in your project:
dotnet user-secrets init - Set a secret:
dotnet user-secrets set "ApiKey" "12345" dotnet user-secrets set "ConnectionStrings:DefaultConnection" "Server=.;Database=MyDb;..." - List secrets:
dotnet user-secrets list - 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
- Single Source of Truth: Manage all environment variables through direnv
- Flexibility: Use .NET secrets for sensitive data, direnv for everything else
- Team Friendly: Developers can choose between .NET secrets or
.envrcfiles - 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:
- Context Awareness: Shows current git branch, Node.js/Python/Rust versions, AWS profile, and more
- Performance: Written in Rust for speed - adds minimal latency to your prompt
- Cross-Shell Support: Works with Bash, Zsh, Fish, PowerShell, and more
- Customizable: Extensive configuration options via
starship.toml - 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
- Start Simple: Begin with minimal configuration and add features as needed
- Profile Performance: Use
starship timingsto identify slow modules - Version Control: Keep your
starship.tomlin your dotfiles repository - Theme Consistency: Match your prompt colors to your terminal theme
- 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:
- Downloading
sigao.ansfrom the repository to~/.config/sigao/ - 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
- Slow Prompt: Run
starship timingsto identify bottlenecks - Missing Icons: Install a Nerd Font for full icon support
- Git Status Slow: Disable git status in large repos or use the performance config above
- Module Not Showing: Check detection files/folders and ensure
disabled = false
Security Considerations
Do's
- Always use
direnv allowafter reviewing.envrcchanges - Keep secrets in
.envrc, never commit them - Use descriptive variable names to avoid confusion
- Rotate secrets regularly and update your
.envrc - Use read-only permissions for
.envrcfiles:chmod 600 .envrc
Don'ts
- Never commit
.envrcfiles with real secrets - Don't use production secrets in development
- Avoid hardcoding sensitive values in your code
- Don't share
.envrcfiles via insecure channels - Never auto-allow direnv without reviewing changes
Additional Security Tools
Consider these complementary tools:
- git-secrets: Prevents committing secrets
- detect-secrets: Pre-commit hook for secret detection
- SOPS: Encrypt secrets in git
- Vault: Enterprise secret management
Troubleshooting
Common Issues
- direnv: command not found
# Ensure direnv is in your PATH eval "$(direnv hook bash)" # or zsh - Variables not loading
# Check if .envrc is allowed direnv status direnv allow - Permission denied
# Fix permissions chmod 600 .envrc - Syntax errors in .envrc
# Validate your .envrc bash -n .envrc