smithery/majesticlabs-dev

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.

Installation

$ npx skills add smithery/majesticlabs-dev --skill anyway-config-coder

Also in this package

Other skills from smithery/majesticlabs-dev · top by installs.

npx skills add smithery/majesticlabs-dev

Browse all from smithery/majesticlabs-dev

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 4,122 B
  • docs SUMMARY.md 267 B

History

  1. First recorded snapshot · 0 installs

SKILL.md

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 -> GEMINIAPIKEY, GEMINIMODEL, etc. Override prefix with configname :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