DEV Community

Cover image for Managing goose Configurations Across Multiple Projects
Lymah
Lymah

Posted on

Managing goose Configurations Across Multiple Projects

As development teams scale their use of goose across multiple projects, a new challenge emerges: how do you maintain consistent configurations while adapting to each project's unique needs? In my previous post on team environments, we explored shared workflows within a single project. Now, let's tackle the multi-project configuration challenge.

The Multi-Project Configuration Problem

When working with goose across multiple projects, teams often face:

  • Configuration drift between projects leading to inconsistent behavior
  • Duplicated configuration that becomes painful to maintain
  • Context switching overhead when moving between projects
  • Onboarding friction as team members learn different configurations for each project

The goal is to establish a scalable configuration strategy that maintains consistency where needed while allowing project-specific customization.

Configuration Hierarchy Strategy

The most effective approach uses a three-tier configuration hierarchy:

1. Global Base Configuration

Create a shared base configuration that defines organization-wide standards:

# ~/.config/goose/profiles.yaml (global) default: provider: openai processor: gpt-4 accelerator: gpt-4 moderator: truncate organization-standards: provider: openai processor: gpt-4 accelerator: gpt-4 moderator: truncate toolkits: - name: developer - name: github requires: GITHUB_TOKEN: github-token 
Enter fullscreen mode Exit fullscreen mode

This global configuration serves as your baseline, ensuring all projects start with consistent standards.

2. Project-Specific Configuration

Each project maintains its own .goose/profiles.yaml that extends or overrides the base:

# project-a/.goose/profiles.yaml default: provider: openai processor: gpt-4 accelerator: gpt-4 moderator: truncate toolkits: - name: developer - name: github requires: GITHUB_TOKEN: github-token - name: repo_context requires: path: . backend-dev: extends: default toolkits: - name: docker - name: database 
Enter fullscreen mode Exit fullscreen mode

3. Personal Overrides

Individual developers can customize further with local overrides:

# project-a/.goose/profiles.local.yaml (gitignored) default: provider: anthropic # Personal preference processor: claude-sonnet-4.5 
Enter fullscreen mode Exit fullscreen mode
## Practical Implementation Strategies ### Strategy 1: Configuration Templates Repository Create a dedicated repository for configuration templates: goose-configs/ ├── README.md ├── templates/ │ ├── base/ │ │ └── profiles.yaml │ ├── web-app/ │ │ └── profiles.yaml │ ├── api-service/ │ │ └── profiles.yaml │ └── data-pipeline/ │ └── profiles.yaml └── scripts/ ├── init-project.sh └── sync-config.sh 
Enter fullscreen mode Exit fullscreen mode

init-project.sh example:

#!/bin/bash # Initialize goose config for a new project PROJECT_TYPE=$1 TEMPLATE_PATH="templates/${PROJECT_TYPE}/profiles.yaml" if [ ! -f "$TEMPLATE_PATH" ]; then echo "Unknown project type: $PROJECT_TYPE" echo "Available types: base, web-app, api-service, data-pipeline" exit 1 fi mkdir -p .goose cp "$TEMPLATE_PATH" .goose/profiles.yaml echo "✓ goose configuration initialized for $PROJECT_TYPE" echo "Next steps:" echo "1. Review .goose/profiles.yaml" echo "2. Add .goose/profiles.local.yaml to .gitignore" echo "3. Commit .goose/profiles.yaml to version control" 
Enter fullscreen mode Exit fullscreen mode

Strategy 2: Configuration as Code with Validation

Implement configuration validation to catch issues early:

# .goose/profiles.yaml with schema validation default: provider: openai processor: gpt-4 accelerator: gpt-4 moderator: truncate # Validation metadata _metadata: schema_version: "1.0" required_env_vars: - OPENAI_API_KEY - GITHUB_TOKEN team: "platform-team" last_updated: "2025-10-30" 
Enter fullscreen mode Exit fullscreen mode

Create a validation script:

# scripts/validate-goose-config.py import yaml import os import sys def validate_config(config_path): """Validate Goose configuration file""" errors = [] with open(config_path) as f: config = yaml.safe_load(f) # Check required environment variables  metadata = config.get('default', {}).get('_metadata', {}) required_vars = metadata.get('required_env_vars', []) for var in required_vars: if not os.getenv(var): errors.append(f"Missing required environment variable: {var}") # Validate profile structure  for profile_name, profile in config.items(): if profile_name.startswith('_'): continue if 'provider' not in profile: errors.append(f"Profile '{profile_name}' missing required 'provider' field") return errors if __name__ == '__main__': errors = validate_config('.goose/profiles.yaml') if errors: print("❌ Configuration validation failed:") for error in errors: print(f" - {error}") sys.exit(1) else: print("✓ Configuration valid") 
Enter fullscreen mode Exit fullscreen mode

Strategy 3: Environment-Specific Profiles

Structure profiles to handle different environments:

# .goose/profiles.yaml default: provider: openai processor: gpt-4 accelerator: gpt-4 moderator: truncate toolkits: - name: developer development: extends: default toolkits: - name: developer - name: github - name: docker requires: DOCKER_HOST: "unix:///var/run/docker.sock" staging: extends: default toolkits: - name: developer - name: github - name: kubernetes requires: KUBE_CONFIG: staging-config production: extends: default toolkits: - name: developer - name: github - name: kubernetes requires: KUBE_CONFIG: production-config # More restrictive settings for production moderator: conservative 
Enter fullscreen mode Exit fullscreen mode

Syncing Configurations Across Projects

Automated Sync Script

#!/bin/bash # scripts/sync-goose-configs.sh # Sync base configuration across all projects CONFIG_REPO="git@github.com:your-org/goose-configs.git" TEMP_DIR=$(mktemp -d) # Clone config repository git clone "$CONFIG_REPO" "$TEMP_DIR" # Find all projects with goose configs find ~/projects -name ".goose" -type d | while read goose_dir; do project_dir=$(dirname "$goose_dir") project_name=$(basename "$project_dir") echo "Syncing config for $project_name..." # Backup existing config cp "$goose_dir/profiles.yaml" "$goose_dir/profiles.yaml.bak" # Merge base config with project-specific settings python3 "$TEMP_DIR/scripts/merge-configs.py" \ "$TEMP_DIR/templates/base/profiles.yaml" \ "$goose_dir/profiles.yaml" \ > "$goose_dir/profiles.yaml.new" # Replace if merge successful if [ $? -eq 0 ]; then mv "$goose_dir/profiles.yaml.new" "$goose_dir/profiles.yaml" echo "✓ Updated $project_name" else echo "✗ Failed to update $project_name" rm "$goose_dir/profiles.yaml.new" fi done # Cleanup rm -rf "$TEMP_DIR" 
Enter fullscreen mode Exit fullscreen mode

Best Practices for Multi-Project Management

1. Document Your Configuration Strategy

Create a clear README in your configuration repository:

# goose Configuration Standards ## Configuration Hierarchy  1. **Global base** (~/.config/goose/profiles.yaml) 2. **Project-specific** (.goose/profiles.yaml) - Committed to git 3. **Personal overrides** (.goose/profiles.local.yaml) - Gitignored ## Project Types and Templates  - **web-app**: Frontend applications (React, Vue, Angular) - **api-service**: Backend APIs and microservices - **data-pipeline**: ETL and data processing projects - **infrastructure**: Terraform, Kubernetes configurations ## Adding a New Project `./scripts/init-project.sh <project-type>` ## Updating Configurations Run monthly to sync base configurations: `./scripts/sync-goose-configs.sh` 
Enter fullscreen mode Exit fullscreen mode

2. Version Control Strategy

DO commit to git:

.goose/profiles.yaml (project configuration)
.goose/toolkit-configs/ (shared toolkit settings)
Documentation about configuration choices

DO NOT commit to git:

.goose/profiles.local.yaml (personal overrides)
.goose/sessions/ (session history)
API keys or secrets

Add to .gitignore:

# Goose personal configurations and sessions .goose/profiles.local.yaml .goose/sessions/ .goose/**/*.log 
Enter fullscreen mode Exit fullscreen mode

3. Toolkit Management Across Projects

Standardize commonly used toolkits:

# Standard toolkit configurations default: toolkits: # Core toolkits - always included - name: developer # Version control - most projects - name: github requires: GITHUB_TOKEN: github-token # Project-specific toolkits added per project # Examples: docker, kubernetes, database, etc. 
Enter fullscreen mode Exit fullscreen mode

4. Environment Variable Management

Use a consistent approach for environment variables across projects:
Option A: .env files (per project)

# .env.goose (gitignored) GOOSE_PROVIDER=openai OPENAI_API_KEY=sk-... GITHUB_TOKEN=ghp_... 
Enter fullscreen mode Exit fullscreen mode

Option B: Shared secrets manager

# Use tools like 1Password, AWS Secrets Manager, or HashiCorp Vault export OPENAI_API_KEY=$(op read "op://Development/Goose/OPENAI_API_KEY") 
Enter fullscreen mode Exit fullscreen mode

5. Testing Configuration Changes

Before rolling out configuration changes, test in a sandbox:

# Test configuration in a sandbox project mkdir -p /tmp/goose-config-test cd /tmp/goose-config-test cp -r ~/goose-configs/templates/base/.goose . goose session start --profile default # Verify configuration loaded correctly # Test key workflows # Check for errors or warnings ## Advanced Patterns ### Pattern 1: Monorepo Configuration For monorepos with multiple sub-projects: monorepo/ ├── .goose/ │ └── profiles.yaml # Root configuration ├── packages/ │ ├── frontend/ │ │ └── .goose/ │ │ └── profiles.yaml # Frontend-specific │ ├── backend/ │ │ └── .goose/ │ │ └── profiles.yaml # Backend-specific │ └── shared/ │ └── .goose/ │ └── profiles.yaml # Shared library config 
Enter fullscreen mode Exit fullscreen mode

Pattern 2: Dynamic Profile Selection

Use shell aliases to quickly switch contexts:

# ~/.bashrc or ~/.zshrc alias goose-fe='cd ~/projects/myapp/frontend && goose session start --profile frontend' alias goose-be='cd ~/projects/myapp/backend && goose session start --profile backend' alias goose-infra='cd ~/projects/myapp/infra && goose session start --profile infrastructure' 
Enter fullscreen mode Exit fullscreen mode

Pattern 3: Configuration Inheritance Chain

# Complex inheritance for specialized needs base: provider: openai processor: gpt-4 python-base: extends: base toolkits: - name: developer - name: python django-app: extends: python-base toolkits: - name: database - name: docker ml-pipeline: extends: python-base toolkits: - name: jupyter - name: data-science 
Enter fullscreen mode Exit fullscreen mode

Monitoring and Maintenance

Configuration Drift Detection

Create a script to identify configuration drift:

# scripts/detect-config-drift.py import yaml import os from pathlib import Path def compare_configs(base_config, project_config): """Compare project config against base and report differences""" differences = [] # Compare provider settings  if project_config.get('provider') != base_config.get('provider'): differences.append( f"Provider mismatch: {project_config.get('provider')} vs {base_config.get('provider')}" ) # Add more comparison logic  return differences # Scan all projects projects_dir = Path.home() / 'projects' for goose_config in projects_dir.glob('**/.goose/profiles.yaml'): # Load and compare...  pass 
Enter fullscreen mode Exit fullscreen mode

Regular Maintenance Schedule

Establish a maintenance routine:

  • Weekly: Review new toolkit releases and compatibility
  • Monthly: Audit configurations across projects for drift
  • Quarterly: Update base templates and roll out to projects
  • Annually: Review and refactor configuration strategy

Troubleshooting Common Issues

Issue 1: Configuration Not Loading

Problem: Goose not picking up project configuration
Solution: Check configuration precedence

# Debug which config is being used goose config show --verbose # Verify file exists and is valid YAML cat .goose/profiles.yaml | python -m yaml 
Enter fullscreen mode Exit fullscreen mode

Issue 2: Toolkit Conflicts

Problem: Toolkits behaving differently across projects
Solution: Standardize toolkit versions and dependencies

default: toolkits: - name: developer version: "1.0.0" # Pin versions when possible 
Enter fullscreen mode Exit fullscreen mode

Issue 3: Environment Variable Confusion

Problem: Different projects expecting different environment variables
Solution: Use project-specific .env files and document clearly

# Add to project README ## Required Environment Variables - GOOSE_PROVIDER: OpenAI or Anthropic - OPENAI_API_KEY: Your OpenAI API key - GITHUB_TOKEN: GitHub personal access token 
Enter fullscreen mode Exit fullscreen mode

Conclusion

Managing goose configurations across multiple projects requires a thoughtful strategy that balances consistency with flexibility. By implementing a configuration hierarchy, using templates, automating synchronization, and following best practices, you can scale goose across your organization without sacrificing maintainability.

Key takeaways

  • Establish a clear hierarchy: Global base → Project-specific → Personal overrides
  • Use configuration templates: Create reusable templates for common project types
  • Automate where possible: Scripts for initialization, validation, and synchronization
  • Version control strategically: Commit shared configs, ignore personal overrides
  • Document thoroughly: Make it easy for team members to understand and follow standards
  • Monitor for drift: Regularly audit configurations to maintain consistency.

As your team grows and adopts goose more widely, these strategies will help you maintain a scalable, consistent configuration management approach that empowers developers rather than constrains them.


Do you have questions about managing Goose across your projects? Drop a comment below

Top comments (0)