Agent Skills: Anyway Config Coder

Implement type-safe configuration with anyway_config gem. Use when creating configuration classes, replacing ENV access, or managing application settings. Triggers on configuration, environment variables, settings, secrets, or ENV patterns.

UncategorizedID: majesticlabs-dev/majestic-marketplace/anyway-config-coder

Install this agent skill to your local

pnpm dlx add-skill https://github.com/majesticlabs-dev/majestic-marketplace/tree/HEAD/plugins/majestic-rails/skills/anyway-config-coder

Skill Files

Browse the full folder contents for anyway-config-coder.

Download Skill

Loading file tree…

plugins/majestic-rails/skills/anyway-config-coder/SKILL.md

Skill Metadata

Name
anyway-config-coder
Description
Implement type-safe configuration with anyway_config gem. Use when creating configuration classes, replacing ENV access, or managing application settings. Triggers on configuration, environment variables, settings, secrets, or ENV patterns.

Anyway Config Coder

Never use ENV directly or Rails credentials. Wrap all configuration in typed anyway_config classes.

# WRONG
api_key = ENV["GEMINI_API_KEY"]

# RIGHT
class GeminiConfig < Anyway::Config
  attr_config :api_key, timeout: 30
  required :api_key
end
GeminiConfig.new.api_key

Configuration Class Pattern

# config/configs/gemini_config.rb
class GeminiConfig < Anyway::Config
  attr_config :api_key, model: "gemini-pro", timeout: 30, max_retries: 3
  required :api_key

  def configured? = api_key.present?
end

ENV auto-mapping: GeminiConfig -> GEMINI_API_KEY, GEMINI_MODEL, etc. Override prefix with config_name :payment.

Nested config uses hash defaults, accessed via dot notation: AppConfig.new.database.host.

Singleton Pattern (Recommended)

class GeminiConfig < Anyway::Config
  attr_config :api_key, :model

  class << self
    def instance = @instance ||= new
  end
end

GeminiConfig.instance.api_key

Directory Structure

config/
├── configs/          # Ruby config classes
│   ├── gemini_config.rb
│   └── stripe_config.rb
└── settings/         # YAML overrides (optional)
    └── gemini.yml

YAML files use default: &default with environment-specific overrides (development:, test:, production:).

Validation

class StorageConfig < Anyway::Config
  attr_config :bucket, :region, :access_key_id, :secret_access_key
  required :bucket, :region
  required :access_key_id, :secret_access_key, env: :production  # Conditional

  def validate!
    super
    raise_validation_error("Invalid region") unless %w[us-east-1 us-west-2 eu-west-1].include?(region)
  end
end

Type Coercion

class ApiConfig < Anyway::Config
  # Automatic coercion
  attr_config timeout: 30       # Integer
  attr_config enabled: true     # Boolean
  attr_config rate: 1.5         # Float

  # Coerce arrays from comma-separated strings
  coerce_types allowed_origins: {
    type: :string,
    array: true
  }
  # ALLOWED_ORIGINS="example.com,other.com" => ["example.com", "other.com"]
end

Testing Configurations

Test defaults, required validations, and computed methods. Override in tests with with_env:

RSpec.describe GeminiConfig do
  it "requires api_key" do
    expect { described_class.new(api_key: nil) }.to raise_error(Anyway::Config::ValidationError)
  end
end

# spec/support/anyway_config.rb - global override
RSpec.configure do |config|
  config.around(:each) do |example|
    with_env("GEMINI_API_KEY" => "test-key") { example.run }
  end
end

Common Patterns

API Client Config

Add client_options helper to build connection hashes:

class OpenAIConfig < Anyway::Config
  attr_config :api_key, :organization_id, model: "gpt-4", max_tokens: 1000
  required :api_key

  def client_options = { access_token: api_key, organization_id: }.compact
end

Multi-Provider Config

Use predicate methods and case for provider-specific options:

class StorageConfig < Anyway::Config
  attr_config provider: "local", bucket: nil, endpoint: nil

  def s3? = provider == "s3"
  def local? = provider == "local"
  def service_options = case provider when "s3" then s3_options else local_options end
end

Anti-Patterns

| Anti-Pattern | Problem | Solution | |--------------|---------|----------| | Direct ENV["KEY"] | No type safety, scattered | Config class | | ENV.fetch everywhere | Duplication, no validation | Centralized config | | Rails credentials | Complex, hard to test | anyway_config classes | | Hardcoded secrets | Security risk | Environment variables | | Magic strings | Typos, no IDE support | Config constants |

Detailed References

  • references/advanced-patterns.md - Dynamic configs, callbacks, inheritance