crystal-lang
Use this skill when working with the Crystal programming language. Crystal is a statically-typed, compiled language with Ruby-like syntax. It features type inference, null safety, macros, and compiles to efficient native code. Use for understanding Crystal's standard library, syntax, semantics, concurrency model, and FFI bindings.
What this skill does
# Crystal-Lang Skill
Use this skill when working with the Crystal programming language. a statically-typed, compiled language with Ruby-like syntax that combines Ruby's coding efficiency with C's runtime performance.
## When to Use This Skill
This skill should be triggered when:
- Writing Crystal code and need syntax, semantic, or API guidance
- Debugging Crystal compilation errors or runtime issues
- Understanding Crystal's type system, type inference, or union types
- Working with Crystal's concurrency model (fibers, channels, spawn)
- Using Crystal macros for metaprogramming and compile-time code generation
- Interfacing with C libraries via FFI bindings
- Implementing web services with the Crystal standard library (HTTP, HTTPS, WebSocket)
- Processing data formats (JSON, XML, YAML, CSV)
- Working with Crystal's standard library APIs
## Key Concepts
### Type System
- **Type Inference**: The compiler infers types without explicit annotations in most cases
- **Union Types**: Variables can have multiple possible types at compile time (e.g., `Int32 | String`)
- **Null Safety**: Nilable types (`String?`) must be checked before use
- **Generic Types**: Reusable code with type parameters (e.g., `Array(T)`, `Hash(K, V)`)
### Concurrency Model
- **Fibers**: Lightweight cooperative threads scheduled by the runtime
- **Channels**: Communication primitives for passing data between fibers
- **spawn**: Create a new fiber for concurrent execution
### Macros
- **Compile-time Execution**: Macros run during compilation, not at runtime
- **AST Manipulation**: Modify and generate code programmatically
- **Flag-based Compilation**: Conditional code based on compile-time flags
## Quick Reference
### Basic Syntax
**Hello World**
```crystal
# hello.cr
puts "Hello, World!"
```
**Variables and Types**
```crystal
name = "Crystal" # : String
count = 42 # : Int32
pi = 3.14 # : Float64
enabled = true # : Bool
nothing = nil # : Nil
# Type annotations work too
x : Int32 = 10
```
**String Interpolation**
```crystal
name = "World"
puts "Hello, #{name}!" # => Hello, World!
```
### Methods and Blocks
**Defining Methods**
```crystal
def greet(name : String) : String
"Hello, #{name}!"
end
def add(x : Int32, y : Int32) : Int32
x + y
end
```
**Default Arguments**
```crystal
def greet(name : String, enthusiastic : Bool = false)
message = "Hello, #{name}"
enthusiastic ? "#{message}!" : message
end
```
**Blocks and Procs**
```crystal
# Using a block
[1, 2, 3].map { |x| x * 2 } # => [2, 4, 6]
# Short syntax
[1, 2, 3].map(&.to_s) # => ["1", "2", "3"]
# Storing a block
double = ->(x : Int32) { x * 2 }
double.call(5) # => 10
```
### Control Flow
**If/Else**
```crystal
if count > 0
puts "Positive"
elsif count < 0
puts "Negative"
else
puts "Zero"
end
# Ternary
result = count > 0 ? "positive" : "non-positive"
```
**Case/When**
```crystal
case value
when 1, 2, 3
puts "Small"
when 4..10
puts "Medium"
else
puts "Large"
end
```
**Unless**
```crystal
puts "Access denied" unless user.logged_in?
```
### Classes and Structs
**Class Definition**
```crystal
class Person
property name : String
property age : Int32
def initialize(@name : String, @age : Int32)
end
def greet : String
"Hi, I'm #{@name}, #{@age} years old"
end
end
person = Person.new("Alice", 30)
person.greet # => "Hi, I'm Alice, 30 years old"
```
**Inheritance**
```crystal
class Employee < Person
def initialize(@name : String, @age : Int32, @title : String)
super(@name, @age)
end
end
```
**Structs for Value Types**
```crystal
struct Point
property x : Float64
property y : Float64
def initialize(@x : Float64, @y : Float64)
end
end
```
### Collections
**Arrays**
```crystal
# Literal
numbers = [1, 2, 3, 4, 5]
# Operations
numbers << 6 # append
numbers.first # => 1
numbers.last # => 5
numbers.size # => 5
numbers.includes?(3) # => true
numbers.map { |x| x * 2 } # => [2, 4, 6, 8, 10]
```
**Hashes**
```crystal
# Literal
scores = {"Alice" => 100, "Bob" => 95}
# Access
scores["Alice"] # => 100
scores["Charlie"]? # => nil (safe access)
scores.fetch("Dave", 0) # => 0 (default)
```
**Ranges**
```crystal
1..10 # inclusive range
1...10 # exclusive range
('a'..'z').to_a.first(3) # => ['a', 'b', 'c']
```
### Union Types and Nilable Types
**Union Types**
```crystal
def process(value : Int32 | String)
# Methods must exist for ALL types in the union
value.to_s
end
```
**Nilable Types**
```crystal
def find_user(id : Int32) : User?
# Returns User or nil
users.find { |u| u.id == id }
end
user = find_user(1)
if user
puts user.name # user is guaranteed non-nil here
end
# Safe navigation
name = user&.name || "Unknown"
```
**Type Narrowing**
```crystal
value = rand > 0.5 ? 42 : "hello"
if value.is_a?(Int32)
value.abs # Compiler knows value is Int32 here
else
value.size # Compiler knows value is String here
end
```
### Exception Handling
**Begin/Rescue/Ensure**
```crystal
begin
File.read("nonexistent.txt")
rescue ex : FileNotFoundError
puts "File not found: #{ex.message}"
rescue ex : Exception
puts "Error: #{ex.message}"
ensure
puts "Cleanup code runs here"
end
```
**Custom Exceptions**
```crystal
class MyError < Exception
end
raise MyError.new("Something went wrong")
```
### Concurrency
**Spawning Fibers**
```crystal
spawn do
puts "Running in background"
sleep 1
puts "Done"
end
puts "Main continues"
Fiber.yield # Let other fibers run
```
**Channels**
```crystal
channel = Channel(Int32).new
spawn do
channel.send(42)
end
result = channel.receive # Blocks until value is available
puts result # => 42
```
**Async Operations**
```crystal
def fetch_data : String
"data"
end
# Non-blocking with spawn
spawn { puts fetch_data }
Fiber.yield
```
### Macros
**Compile-time Execution**
```crystal
# Run shell command at compile time
{% `echo "compiled at build time"` %}
# Check compile-time flags
{% if flag?(:x86_64) %}
puts "Running on 64-bit architecture"
{% end %}
```
**Macro Methods**
```crystal
macro define_method(name, content)
def {{name}}
{{content}}
end
end
define_method(:greet, puts "Hello from macro!")
```
**Reading Files at Compile Time**
```crystal
# Embed file contents at compile time
VERSION = {{ read_file("VERSION.txt").strip }}
```
### File I/O
**Reading Files**
```crystal
# Read entire file
content = File.read("file.txt")
# Read line by line
File.each_line("file.txt") do |line|
puts line
end
# Check file exists
if File.exists?("file.txt")
puts "File exists"
end
```
**Writing Files**
```crystal
# Write string to file
File.write("output.txt", "Hello, File!")
# Append to file
File.open("log.txt", "a") do |file|
file.puts "Log entry"
end
```
### JSON Processing
**Parsing JSON**
```crystal
require "json"
data = JSON.parse(%({"name": "Alice", "age": 30}))
data["name"].as_s # => "Alice"
data["age"].as_i # => 30
```
**Generating JSON**
```crystal
require "json"
hash = {"name" => "Bob", "age" => 25}
JSON.build do |json|
json.object do
json.field "name", hash["name"]
json.field "age", hash["age"]
end
end
```
**JSON Mapping**
```crystal
require "json"
class User
include JSON::Serializable
property name : String
property age : Int32
end
user = User.from_json(%({"name": "Charlie", "age": 35}))
user.to_json # => %({"name":"Charlie","age":35})
```
### HTTP Client
**Simple GET Request**
```crystal
require "http"
response = HTTP.get("https://api.example.com/data")
puts response.status_code # => 200
puts response.body
```
**POST with JSON Body**
```crystal
require "http"
response = HTTP.post("https://api.example.com/users",
headers: {"Content-Type" => "application/json"},
body: %({"name": "Dave"}).to_json
)
```
**HTTP Client with Persistent Connection**
```crystal
require "http"
client = HTTP::Client.new("https:/Related 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.