athena-framework
Use this skill when working with Athena Framework for Crystal. Athena is a modular ecosystem of independent, reusable components including: Framework (ATH) for web apps, DependencyInjection (ADI) for IoC containers, Routing (ART) for HTTP routing, Serializer (ASR) for object serialization, Validator (AVD) for validation, Console (ACON) for CLI tools, EventDispatcher (AED) for event-driven architecture, and more. Use for building Crystal web applications, REST APIs, CLI tools, or integrating individual components.
What this skill does
# Athena Framework Skill
Athena Framework is a modular web framework for Crystal, inspired by Symfony. It consists of independent, reusable components that can be used together or à la carte.
## When to Use This Skill
Use this skill when you are:
- **Building web applications** with the Athena Framework (ATH)
- **Creating REST APIs** using Athena's routing and controller system
- **Implementing dependency injection** with ADI (Athena DependencyInjection)
- **Adding HTTP routing** with ART (Athena Routing)
- **Serializing objects** with ASR (Athena Serializer)
- **Validating data** with AVD (Athena Validator)
- **Writing CLI commands** with ACON (Athena Console)
- **Implementing event-driven architecture** with AED (Athena EventDispatcher)
- **Working with individual Athena components** in any Crystal project
- **Debugging Athena applications**
- **Learning Crystal web development patterns**
## Key Concepts
### Component Overview
| Component | Alias | Purpose |
|-----------|-------|---------|
| Framework | `ATH` | Full-stack web framework with controllers, middleware, responses |
| DependencyInjection | `ADI` | IoC container for managing service dependencies |
| Routing | `ART` | HTTP routing with annotations, requirements, and matching |
| Serializer | `ASR` | Object (de)serialization to JSON, YAML, etc. |
| Validator | `AVD` | Declarative object validation with constraints |
| Console | `ACON` | CLI command framework with styled output |
| EventDispatcher | `AED` | Event-driven architecture with listeners/dispatchers |
| Negotiation | `ANEG` | Content negotiation for requests/responses |
| ImageSize | `AIS` | Get image dimensions without processing |
| Clock | `ACLK` | Time abstraction for testing |
## Quick Reference
### HTTP Routing (ART)
**Define a route with requirements:**
```crystal
class ExampleController < ATH::Controller
@[ARTA::Get("/user/{id}")]
def get_user(id : Int64) : Int64
id
end
@[ARTA::Get("/article/{slug}")]
def get_article(slug : String) : String
slug
end
end
```
**Built-in route requirements:**
```crystal
# Only matches digits
ART::Requirement::DIGITS # /[0-9]+/
# Matches URL-safe slugs
ART::Requirement::ASCII_SLUG # /[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*/
# Date format YYYY-MM-DD
ART::Requirement::DATE_YMD # /[0-9]{4}-(?:0[1-9]|1[012])-(?:0[1-9]|[12][0-9]|(?<!02-)3[01])/
# UUID formats
ART::Requirement::UID_BASE32 # /[0-9A-HJKMNP-TV-Z]{26}/
ART::Requirement::UID_BASE58 # /[1-9A-HJ-NP-Za-km-z]{22}/
ART::Requirement::UID_RFC4122 # /[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}/
```
**Route with optional parameters:**
```crystal
# /blog would match with default page=1
# /blog/10 would match with page=10
ART::Route.new "/blog/{page}", {"page" => 1}, {"page" => /\d+/}
```
**Route with custom conditions:**
```crystal
route = ART::Route.new "/contact"
route.condition do |context, request|
request.headers["user-agent"].includes? "Firefox"
end
```
### Dependency Injection (ADI)
**Register and inject services:**
```crystal
# Register a service with constructor injection
@[ADI::Register(public: true)]
class DatabaseService
def initialize(@connection_string : String); end
end
# Use ADI::Inject to specify which constructor to use
@[ADI::Register(_value: 2, public: true)]
class SomeService
@active : Bool = false
# Regular constructor
def initialize(value : String, @active : Bool)
@value = value.to_i
end
# DI-specific constructor
@[ADI::Inject]
def initialize(@value : Int32); end
end
```
### Event Dispatcher (AED)
**Create and dispatch events:**
```crystal
# Define a custom event
class MyEvent < AED::Event
property data : String
def initialize(@data)
end
end
# Register a listener
dispatcher = AED::EventDispatcher.new
dispatcher.listener(MyEvent) do |event|
puts "Event received: #{event.data}"
end
# Dispatch the event
dispatcher.dispatch(MyEvent.new("Hello World"))
```
**Using generic events:**
```crystal
# Generic event with type safety
dispatcher.listener AED::GenericEvent(User, Int32) do |e|
e["counter"] += 1
end
dispatcher.dispatch AED::GenericEvent.new user, data = {"counter" => 0}
```
**Callable listeners with priority:**
```crystal
callable = MyEvent.callable(priority: 10) do |event, dispatcher|
# Handle event
end
dispatcher.listener callable
```
### Serializer (ASR)
**Serialize/deserialize objects:**
```crystal
require "athena-serializer"
record Example, id : Int32, name : String do
include ASR::Serializable
end
# Deserialize from JSON
obj = ASR.serializer.deserialize Example, %({"id":1,"name":"George"}), :json
# Serialize to YAML
ASR.serializer.serialize obj, :yaml
# =>
# ---
# id: 1
# name: George
```
### Console (ACON)
**Create a CLI command:**
```crystal
class GreetCommand < ACON::Command
def configure : Nil
self
.name("greet")
.description("Greets someone")
.argument("name", ACON::Input::Argument::Mode::REQUIRED, "Who to greet")
.option("yell", mode: ACON::Input::Option::Mode::NONE, description: "Yell in uppercase")
end
def execute(input : ACON::Input::Interface, output : ACON::Output::Interface) : ACON::Command::Status
name = input.argument("name", String)
message = "Hello #{name}"
if input.option("yell", Bool)
message = message.upcase
end
output.puts message
ACON::Command::Status::SUCCESS
end
end
```
### Framework Controller (ATH)
**Basic controller with responses:**
```crystal
class ApiController < ATH::Controller
# Returns JSON response
@[ATHA::Get("/api/users")]
@[ATHA::View("user_list.json.ecr")]
def list_users : Iterable(User)
UserRepository.all
end
# Returns plain text
@[ATHA::Get("/health")]
def health_check : String
"OK"
end
# Custom response with headers
@[ATHA::Post("/data")]
def create_data(body : DataRequest) : ATH::Response
ATH::Response.new(
"Created",
status: :created,
headers: HTTP::Headers{"X-Custom" => "value"}
)
end
end
```
**HTTP testing expectations:**
```crystal
# In your specs
include ATH::Spec::Expectations::HTTP
client = ATH::Spec::APIClient.new(APP)
# Test response status
client.get("/health").assert_response_is_successful
# Test response headers
client.get("/api/data").assert_response_has_header("content-type")
# Test response body
client.get("/api/users").assert_json_contains({"users" => [...]})
```
### Testing Utilities (ASPEC)
**Compile-time and runtime assertions:**
```crystal
# Assert code fails to compile with specific message
ASPEC::Methods.assert_compile_time_error "can't instantiate abstract class Foo", <<-CR
abstract class Foo; end
Foo.new
CR
# Assert code compiles successfully
ASPEC::Methods.assert_compiles <<-CR
puts 2 + 2
CR
# Assert code executes without error
ASPEC::Methods.assert_executes <<-CR
puts "Running fine"
CR
# Assert code raises specific runtime error
ASPEC::Methods.assert_runtime_error "Oh noes!", <<-CR
raise "Oh noes!"
CR
```
### CORS Configuration
The framework includes built-in CORS support:
```crystal
# Configure CORS in your application
ATH::Listeners::CORS is enabled by default
# Uses SAFELISTED_HEADERS and SAFELISTED_METHODS for standard browser requests
```
## Reference Files
This skill includes comprehensive documentation in `references/`:
| File | Description | Pages | Source |
|------|-------------|-------|--------|
| **framework.md** | Core framework API documentation | 332 | Official |
| **getting_started.md** | Getting started guides and routing | 44 | Official |
| **index.md** | Documentation index | - | Official |
Use `view` to read specific reference files when detailed information is needed.
## Working with This Skill
### For Beginners
1. Start with **getting_started.md** for foundational routing concepts
2. Review the Quick Reference examples above for common patterns
3. Use the official [Athena Framework documentation](https://athenaframework.org) for tutorials
### For IntermRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.