Commit 889e0ba2710c

Vincent Demeester <vincent@sbr.pm>
2025-12-05 11:41:23
feat(skills): Add comprehensive Rust skill with modern tooling
- Enable Rust development with Cargo, Clippy, and Criterion - Support error handling patterns with thiserror and anyhow - Provide 8 workflows covering building, testing, and publishing Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Vincent Demeester <vincent@sbr.pm>
1 parent da134e8
dots/.config/claude/skills/Rust/workflows/Bench.md
@@ -0,0 +1,107 @@
+# Benchmark Workflow
+
+Benchmark Rust code with Criterion.
+
+## When to Use
+
+- "benchmark"
+- "cargo bench"
+- "performance test"
+- "criterion"
+
+## Setup
+
+```toml
+[dev-dependencies]
+criterion = { version = "0.7", features = ["html_reports"] }
+
+[[bench]]
+name = "my_benchmark"
+harness = false
+```
+
+## Quick Commands
+
+```bash
+# Run benchmarks
+cargo bench
+
+# Run specific benchmark
+cargo bench my_function
+
+# Save baseline
+cargo bench -- --save-baseline main
+
+# Compare to baseline
+cargo bench -- --baseline main
+```
+
+## Basic Benchmark
+
+```rust
+// benches/my_benchmark.rs
+use criterion::{black_box, criterion_group, criterion_main, Criterion};
+
+fn fibonacci(n: u64) -> u64 {
+    match n {
+        0 => 1,
+        1 => 1,
+        n => fibonacci(n-1) + fibonacci(n-2),
+    }
+}
+
+fn criterion_benchmark(c: &mut Criterion) {
+    c.bench_function("fib 20", |b| b.iter(|| fibonacci(black_box(20))));
+}
+
+criterion_group!(benches, criterion_benchmark);
+criterion_main!(benches);
+```
+
+## Parametrized Benchmarks
+
+```rust
+use criterion::{BenchmarkId, Criterion};
+
+fn bench_sizes(c: &mut Criterion) {
+    let mut group = c.benchmark_group("sizes");
+
+    for size in [10, 100, 1000].iter() {
+        group.bench_with_input(
+            BenchmarkId::from_parameter(size),
+            size,
+            |b, &size| {
+                b.iter(|| process_data(black_box(size)))
+            },
+        );
+    }
+
+    group.finish();
+}
+```
+
+## Comparing Functions
+
+```rust
+fn bench_comparison(c: &mut Criterion) {
+    let mut group = c.benchmark_group("algorithms");
+
+    group.bench_function("algorithm_a", |b| {
+        b.iter(|| algorithm_a(black_box(&data)))
+    });
+
+    group.bench_function("algorithm_b", |b| {
+        b.iter(|| algorithm_b(black_box(&data)))
+    });
+
+    group.finish();
+}
+```
+
+## Best Practices
+
+1. **Use `black_box`**: Prevent compiler optimization
+2. **Warmup iterations**: Let CPU caches warm up
+3. **Save baselines**: Compare against previous runs
+4. **Statistical rigor**: Criterion provides this
+5. **Profile first**: Use profilers before micro-benchmarks
dots/.config/claude/skills/Rust/workflows/Build.md
@@ -0,0 +1,282 @@
+# Build Workflow
+
+Build Rust projects with Cargo using various profiles and configurations.
+
+## When to Use
+
+- "build rust project"
+- "cargo build"
+- "compile rust"
+- "release build"
+
+## Quick Commands
+
+```bash
+# Debug build (fast compilation, with debug symbols)
+cargo build
+
+# Release build (optimized, slower compilation)
+cargo build --release
+
+# Check compilation without building
+cargo check
+
+# Build all targets (bins, libs, tests, benches, examples)
+cargo build --all-targets
+
+# Build with all features enabled
+cargo build --all-features
+
+# Build specific binary
+cargo build --bin mybinary
+
+# Build for specific target
+cargo build --target x86_64-unknown-linux-musl
+
+# Cross-compilation
+cargo build --target aarch64-unknown-linux-gnu
+```
+
+## Build Profiles
+
+### Development Profile
+
+```toml
+# Cargo.toml
+[profile.dev]
+opt-level = 0        # No optimization
+debug = true         # Full debug info
+split-debuginfo = "unpacked"  # Fast debug builds
+incremental = true   # Incremental compilation
+```
+
+### Release Profile
+
+```toml
+[profile.release]
+opt-level = 3        # Maximum optimization
+lto = true           # Link-time optimization
+codegen-units = 1    # Better optimization (slower compile)
+strip = true         # Remove debug symbols
+panic = "abort"      # Smaller binary size
+```
+
+### Custom Profiles
+
+```toml
+# Fast development builds
+[profile.dev-opt]
+inherits = "dev"
+opt-level = 1        # Some optimization
+
+# Smaller release builds
+[profile.release-small]
+inherits = "release"
+opt-level = "z"      # Optimize for size
+lto = true
+strip = true
+```
+
+```bash
+# Use custom profile
+cargo build --profile dev-opt
+```
+
+## Cross-Compilation
+
+### Install Target
+
+```bash
+# List installed targets
+rustup target list --installed
+
+# Add target
+rustup target add x86_64-unknown-linux-musl
+rustup target add aarch64-unknown-linux-gnu
+rustup target add wasm32-unknown-unknown
+```
+
+### Build for Target
+
+```bash
+# Build for target
+cargo build --target x86_64-unknown-linux-musl --release
+
+# Configure target in .cargo/config.toml
+# .cargo/config.toml
+[build]
+target = "x86_64-unknown-linux-musl"
+
+[target.x86_64-unknown-linux-musl]
+linker = "x86_64-linux-musl-gcc"
+```
+
+## Build Features
+
+### Conditional Compilation
+
+```toml
+# Cargo.toml
+[features]
+default = ["std"]
+std = []
+encryption = ["aes", "sha2"]
+network = ["reqwest", "tokio"]
+
+[dependencies]
+aes = { version = "0.8", optional = true }
+reqwest = { version = "0.11", optional = true }
+```
+
+```bash
+# Build with specific features
+cargo build --features encryption
+
+# Build with multiple features
+cargo build --features "encryption,network"
+
+# Build without default features
+cargo build --no-default-features
+
+# Build with all features
+cargo build --all-features
+```
+
+## Build Scripts
+
+### build.rs
+
+```rust
+// build.rs - runs before compilation
+use std::env;
+
+fn main() {
+    // Set environment variables
+    println!("cargo:rustc-env=BUILD_TIME={}", chrono::Utc::now());
+
+    // Link to system library
+    println!("cargo:rustc-link-lib=ssl");
+
+    // Rerun if file changes
+    println!("cargo:rerun-if-changed=src/config.rs");
+
+    // Conditional compilation
+    if cfg!(target_os = "linux") {
+        println!("cargo:rustc-cfg=linux_specific");
+    }
+}
+```
+
+## Optimization Tips
+
+### 1. Use `cargo check` for Development
+
+```bash
+# Faster than build, only checks for errors
+cargo check
+
+# With all features
+cargo check --all-features
+```
+
+### 2. Parallel Builds
+
+```bash
+# Use more CPU cores (default is number of CPUs)
+cargo build -j 8
+```
+
+### 3. Incremental Compilation
+
+```toml
+# Cargo.toml
+[profile.dev]
+incremental = true  # Enabled by default for dev
+```
+
+### 4. Shared Build Cache
+
+```bash
+# Use sccache for caching
+export RUSTC_WRAPPER=sccache
+cargo build
+```
+
+## Build Artifacts
+
+### Location
+
+```
+target/
+├── debug/           # Debug builds
+│   ├── mybinary    # Executable
+│   └── libmylib.rlib
+├── release/         # Release builds
+│   └── mybinary
+└── CACHEDIR.TAG
+```
+
+### Clean Build
+
+```bash
+# Remove all build artifacts
+cargo clean
+
+# Remove only release artifacts
+cargo clean --release
+
+# Remove specific package artifacts
+cargo clean -p mypackage
+```
+
+## Build Times
+
+### Measure Build Times
+
+```bash
+# Time a build
+time cargo build
+
+# Detailed timing info
+cargo build --timings
+
+# Opens HTML report
+cargo build --timings --open
+```
+
+### Speed Up Builds
+
+1. **Use `cargo check` during development**
+2. **Enable incremental compilation**
+3. **Reduce codegen-units in dev profile**
+4. **Use `lld` linker** (faster than default)
+
+```toml
+# .cargo/config.toml
+[target.x86_64-unknown-linux-gnu]
+linker = "clang"
+rustflags = ["-C", "link-arg=-fuse-ld=lld"]
+```
+
+## Workspace Builds
+
+```bash
+# Build all workspace members
+cargo build --workspace
+
+# Build specific package in workspace
+cargo build -p mypackage
+
+# Build all except specific package
+cargo build --workspace --exclude mypackage
+```
+
+## Best Practices
+
+1. **Use `cargo check` frequently** - Faster than build
+2. **Profile appropriately** - Debug for dev, release for production
+3. **Enable LTO for releases** - Smaller, faster binaries
+4. **Strip symbols in release** - Reduce binary size
+5. **Use build features** - Conditional compilation
+6. **Cache dependencies** - Use sccache or similar
+7. **Measure build times** - Use `--timings` to identify bottlenecks
dots/.config/claude/skills/Rust/workflows/Deps.md
@@ -0,0 +1,103 @@
+# Dependencies Workflow
+
+Manage Rust dependencies with Cargo.
+
+## When to Use
+
+- "add dependency"
+- "cargo add"
+- "update dependencies"
+
+## Quick Commands
+
+```bash
+# Add dependency
+cargo add serde
+
+# Add with features
+cargo add tokio --features full
+
+# Add dev dependency
+cargo add --dev proptest
+
+# Add build dependency
+cargo add --build cc
+
+# Remove dependency
+cargo rm serde
+
+# Update dependencies
+cargo update
+
+# Update specific dependency
+cargo update -p serde
+
+# Show dependency tree
+cargo tree
+
+# Check for outdated dependencies
+cargo outdated
+```
+
+## Cargo.toml
+
+```toml
+[dependencies]
+serde = { version = "1.0", features = ["derive"] }
+tokio = { version = "1.0", default-features = false, features = ["rt-multi-thread"] }
+anyhow = "1.0"
+
+# Git dependency
+mylib = { git = "https://github.com/user/mylib" }
+
+# Path dependency
+utils = { path = "../utils" }
+
+# Optional dependency
+encryption = { version = "1.0", optional = true }
+
+[dev-dependencies]
+criterion = "0.7"
+
+[build-dependencies]
+cc = "1.0"
+
+[features]
+default = ["std"]
+std = []
+secure = ["encryption"]
+```
+
+## Workspace Dependencies
+
+```toml
+# Root Cargo.toml
+[workspace.dependencies]
+serde = { version = "1.0", features = ["derive"] }
+tokio = "1.0"
+
+# Member Cargo.toml
+[dependencies]
+serde = { workspace = true }
+tokio = { workspace = true, features = ["full"] }
+```
+
+## Version Requirements
+
+```toml
+[dependencies]
+exact = "=1.2.3"          # Exactly 1.2.3
+caret = "^1.2.3"          # >=1.2.3, <2.0.0 (default)
+tilde = "~1.2.3"          # >=1.2.3, <1.3.0
+wildcard = "1.*"          # >=1.0.0, <2.0.0
+range = ">=1.2, <1.5"     # Range
+```
+
+## Best Practices
+
+1. **Lock files**: Commit for apps, ignore for libraries
+2. **Minimal versions**: Use lowest compatible version
+3. **Feature gates**: Only enable needed features
+4. **Workspace deps**: Share versions across workspace
+5. **Regular updates**: Check for security updates
+6. **Audit dependencies**: `cargo audit`
dots/.config/claude/skills/Rust/workflows/Error.md
@@ -0,0 +1,274 @@
+# Error Handling Workflow
+
+Handle errors idiomatically in Rust using Result, Option, thiserror, and anyhow.
+
+## When to Use
+
+- "error handling"
+- "Result type"
+- "thiserror"
+- "anyhow"
+
+## Core Types
+
+### Result<T, E>
+
+```rust
+fn read_file(path: &str) -> Result<String, std::io::Error> {
+    std::fs::read_to_string(path)
+}
+
+// Usage
+match read_file("config.txt") {
+    Ok(contents) => println!("{}", contents),
+    Err(e) => eprintln!("Error: {}", e),
+}
+
+// With ? operator
+fn process() -> Result<(), std::io::Error> {
+    let contents = read_file("config.txt")?;
+    println!("{}", contents);
+    Ok(())
+}
+```
+
+### Option<T>
+
+```rust
+fn find_user(id: u64) -> Option<User> {
+    DATABASE.get(&id).cloned()
+}
+
+// Usage
+match find_user(42) {
+    Some(user) => println!("Found: {}", user.name),
+    None => println!("Not found"),
+}
+
+// With ? operator (in function returning Option)
+fn get_user_email(id: u64) -> Option<String> {
+    let user = find_user(id)?;
+    Some(user.email)
+}
+```
+
+## Library Errors: thiserror
+
+Use `thiserror` to define custom error types for libraries.
+
+```toml
+[dependencies]
+thiserror = "2.0"
+```
+
+```rust
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+pub enum MyError {
+    #[error("IO error: {0}")]
+    Io(#[from] std::io::Error),
+
+    #[error("Parse error on line {line}: {msg}")]
+    Parse { line: usize, msg: String },
+
+    #[error("User {0} not found")]
+    NotFound(String),
+
+    #[error("Invalid configuration")]
+    InvalidConfig,
+}
+
+// Usage
+fn read_config(path: &str) -> Result<Config, MyError> {
+    let contents = std::fs::read_to_string(path)?; // Auto-converts io::Error
+
+    parse_config(&contents)
+        .map_err(|e| MyError::Parse {
+            line: e.line,
+            msg: e.to_string(),
+        })
+}
+```
+
+### Automatic Conversions
+
+```rust
+#[derive(Error, Debug)]
+pub enum Error {
+    #[error(transparent)]  // Use inner error's Display
+    Io(#[from] std::io::Error),
+
+    #[error(transparent)]
+    Parse(#[from] serde_json::Error),
+}
+
+// Both io::Error and serde_json::Error auto-convert
+fn load_json(path: &str) -> Result<Data, Error> {
+    let contents = std::fs::read_to_string(path)?; // io::Error -> Error
+    let data = serde_json::from_str(&contents)?;   // serde_json::Error -> Error
+    Ok(data)
+}
+```
+
+## Application Errors: anyhow
+
+Use `anyhow` for applications where you want flexible error handling.
+
+```toml
+[dependencies]
+anyhow = "2.0"
+```
+
+```rust
+use anyhow::{Context, Result};
+
+fn process_file(path: &str) -> Result<()> {
+    let contents = std::fs::read_to_string(path)
+        .context("Failed to read configuration file")?;
+
+    let config: Config = serde_json::from_str(&contents)
+        .context("Failed to parse JSON configuration")?;
+
+    apply_config(config)
+        .context("Failed to apply configuration")?;
+
+    Ok(())
+}
+
+// Custom errors with context
+fn validate_user(user: &User) -> Result<()> {
+    anyhow::ensure!(
+        user.age >= 18,
+        "User must be 18 or older, got {}",
+        user.age
+    );
+
+    if user.email.is_empty() {
+        anyhow::bail!("Email cannot be empty");
+    }
+
+    Ok(())
+}
+```
+
+## When to Use What
+
+### thiserror - For Libraries
+
+```rust
+// Define typed errors for library boundaries
+#[derive(Error, Debug)]
+pub enum DatabaseError {
+    #[error("Connection failed: {0}")]
+    Connection(String),
+
+    #[error("Query error: {0}")]
+    Query(#[from] sqlx::Error),
+}
+
+pub fn connect(url: &str) -> Result<Connection, DatabaseError> {
+    // Library code with typed errors
+}
+```
+
+### anyhow - For Applications
+
+```rust
+// Application layer with flexible error handling
+use anyhow::Result;
+
+fn main() -> Result<()> {
+    let config = load_config("config.toml")
+        .context("Failed to load configuration")?;
+
+    let db = connect(&config.database_url)
+        .context("Database connection failed")?;
+
+    run_server(db, config)?;
+    Ok(())
+}
+```
+
+## Error Patterns
+
+### Wrapping Errors
+
+```rust
+#[derive(Error, Debug)]
+pub enum AppError {
+    #[error("Database error")]
+    Database(#[from] DatabaseError),
+
+    #[error("Network error")]
+    Network(#[from] NetworkError),
+}
+```
+
+### Adding Context
+
+```rust
+// With anyhow
+file.read()
+    .context("Reading user data")
+    .with_context(|| format!("File: {}", path))?;
+
+// With Result
+file.read()
+    .map_err(|e| format!("Failed to read {}: {}", path, e))?;
+```
+
+### Recovering from Errors
+
+```rust
+// Using or_else
+let value = risky_operation().unwrap_or_else(|_| default_value());
+
+// Using or
+let value = optional_value.or(Some(default));
+
+// Using ok_or
+let result: Result<T, E> = option.ok_or(error)?;
+```
+
+## Best Practices
+
+1. **Libraries: use thiserror** - Typed errors at API boundaries
+2. **Applications: use anyhow** - Flexible error aggregation
+3. **Never panic in libraries** - Return `Result` instead
+4. **Add context** - Use `.context()` for meaningful errors
+5. **Use ? operator** - Propagate errors ergonomically
+6. **Document errors** - List possible errors in docs
+7. **Don't use `unwrap()`** - Except in tests or when impossible to fail
+
+### Don't Do This
+
+```rust
+// Bad: panic in library
+pub fn get_user(id: u64) -> User {
+    DATABASE.get(&id).unwrap() // DON'T!
+}
+
+// Bad: losing error information
+fn bad() -> Result<(), String> {
+    file.read().map_err(|_| "failed".to_string())?; // Lost error details
+    Ok(())
+}
+```
+
+### Do This
+
+```rust
+// Good: return Result
+pub fn get_user(id: u64) -> Result<User, Error> {
+    DATABASE.get(&id)
+        .ok_or(Error::NotFound(id))
+}
+
+// Good: preserve error information
+fn good() -> Result<()> {
+    file.read()
+        .context("Failed to read user data")?;
+    Ok(())
+}
+```
dots/.config/claude/skills/Rust/workflows/Lint.md
@@ -0,0 +1,182 @@
+# Lint Workflow
+
+Lint and format Rust code with Clippy and rustfmt.
+
+## When to Use
+
+- "lint rust code"
+- "cargo clippy"
+- "cargo fmt"
+- "format rust"
+
+## Quick Commands
+
+### Clippy (Linter)
+
+```bash
+# Run clippy
+cargo clippy
+
+# Fix automatically
+cargo clippy --fix
+
+# Treat warnings as errors
+cargo clippy -- -D warnings
+
+# All targets and features
+cargo clippy --all-targets --all-features -- -D warnings
+
+# Specific lint levels
+cargo clippy -- -W clippy::pedantic
+cargo clippy -- -W clippy::nursery
+```
+
+### rustfmt (Formatter)
+
+```bash
+# Format code
+cargo fmt
+
+# Check if formatted
+cargo fmt -- --check
+
+# Format specific file
+rustfmt src/main.rs
+```
+
+## Configuration
+
+### clippy.toml
+
+```toml
+# .clippy.toml or clippy.toml
+cognitive-complexity-threshold = 30
+type-complexity-threshold = 250
+too-many-arguments-threshold = 8
+```
+
+### rustfmt.toml
+
+```toml
+# rustfmt.toml
+max_width = 100
+hard_tabs = false
+tab_spaces = 4
+newline_style = "Unix"
+use_small_heuristics = "Default"
+reorder_imports = true
+reorder_modules = true
+remove_nested_parens = true
+edition = "2021"
+```
+
+### Cargo.toml Lints
+
+```toml
+[lints.rust]
+unsafe_code = "forbid"
+missing_docs = "warn"
+
+[lints.clippy]
+enum_glob_use = "deny"
+pedantic = "warn"
+nursery = "warn"
+unwrap_used = "deny"
+```
+
+## Common Clippy Lints
+
+### Performance
+
+```rust
+// clippy::unnecessary_clone
+let s = string.clone(); // Unnecessary if string not used after
+
+// clippy::needless_collect
+let v: Vec<_> = iter.collect();
+let len = v.len(); // Better: iter.count()
+
+// clippy::single_char_pattern
+s.split("x") // Better: s.split('x')
+```
+
+### Correctness
+
+```rust
+// clippy::eq_op
+if x == x { } // Always true
+
+// clippy::clone_on_copy
+let x = 5.clone(); // i32 is Copy, not Clone
+
+// clippy::unnecessary_mut_passed
+fn takes_ref(x: &i32) {}
+let mut x = 5;
+takes_ref(&mut x); // &mut not needed
+```
+
+### Style
+
+```rust
+// clippy::needless_return
+fn foo() -> i32 {
+    return 42; // return keyword unnecessary
+}
+
+// clippy::collapsible_if
+if x {
+    if y { }
+}
+// Better: if x && y { }
+```
+
+## Allowing Lints
+
+### File Level
+
+```rust
+#![allow(clippy::module_name_repetitions)]
+```
+
+### Function Level
+
+```rust
+#[allow(clippy::too_many_arguments)]
+fn complex_function(a: i32, b: i32, c: i32, d: i32, e: i32) {}
+```
+
+### Inline
+
+```rust
+#[allow(clippy::cast_possible_truncation)]
+let x = long_value as u32;
+```
+
+## CI Integration
+
+```yaml
+# .github/workflows/ci.yml
+name: CI
+
+on: [push, pull_request]
+
+jobs:
+  lint:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v4
+      - uses: dtolnay/rust-toolchain@stable
+        with:
+          components: clippy, rustfmt
+      - run: cargo fmt -- --check
+      - run: cargo clippy --all-targets --all-features -- -D warnings
+```
+
+## Best Practices
+
+1. **Run before committing** - Fix issues early
+2. **Use `--fix`** - Auto-fix when possible
+3. **Configure in Cargo.toml** - Project-specific lints
+4. **Deny in CI** - `-- -D warnings`
+5. **Allow sparingly** - Document why when needed
+6. **Update regularly** - New lints in new Rust versions
dots/.config/claude/skills/Rust/workflows/Publish.md
@@ -0,0 +1,117 @@
+# Publish Workflow
+
+Publish Rust crates to crates.io.
+
+## When to Use
+
+- "publish crate"
+- "cargo publish"
+- "crates.io"
+
+## Preparation
+
+### 1. Get API Token
+
+```bash
+# Login to crates.io
+cargo login
+
+# Or set token manually
+cargo login <your-api-token>
+```
+
+### 2. Configure Cargo.toml
+
+```toml
+[package]
+name = "my-awesome-crate"
+version = "0.1.0"
+edition = "2021"
+authors = ["Your Name <you@example.com>"]
+description = "A short description of your crate"
+documentation = "https://docs.rs/my-awesome-crate"
+repository = "https://github.com/user/my-awesome-crate"
+license = "MIT OR Apache-2.0"
+keywords = ["cli", "tool", "utility"]  # Max 5
+categories = ["command-line-utilities"]
+readme = "README.md"
+
+# Important: exclude large or unnecessary files
+exclude = [
+    "/.github",
+    "/target",
+    "*.png",
+    "benches/",
+]
+```
+
+## Publishing
+
+```bash
+# Dry run (test package)
+cargo publish --dry-run
+
+# Package and inspect
+cargo package --list
+
+# Publish
+cargo publish
+
+# Publish with custom registry
+cargo publish --registry my-registry
+```
+
+## Version Management
+
+```bash
+# Update version in Cargo.toml
+# Use semantic versioning: MAJOR.MINOR.PATCH
+
+# Tag release
+git tag v0.1.0
+git push --tags
+```
+
+## Semantic Versioning
+
+- **MAJOR**: Breaking changes
+- **MINOR**: New features (backward compatible)
+- **PATCH**: Bug fixes (backward compatible)
+
+```
+0.1.0 -> 0.1.1  (bug fix)
+0.1.1 -> 0.2.0  (new feature)
+0.2.0 -> 1.0.0  (breaking change)
+```
+
+## Yanking Versions
+
+```bash
+# Yank a version (prevent new dependents)
+cargo yank --vers 0.1.0
+
+# Un-yank
+cargo yank --vers 0.1.0 --undo
+```
+
+## Pre-Publish Checklist
+
+- [ ] Update version in Cargo.toml
+- [ ] Update CHANGELOG.md
+- [ ] Run `cargo test --all-features`
+- [ ] Run `cargo clippy --all-targets`
+- [ ] Run `cargo doc --no-deps`
+- [ ] Verify README.md is up to date
+- [ ] Check license files present
+- [ ] Run `cargo publish --dry-run`
+- [ ] Tag release in git
+- [ ] Publish to crates.io
+
+## Best Practices
+
+1. **Follow semver**: Strict semantic versioning
+2. **Good documentation**: README and rustdoc
+3. **Comprehensive tests**: All features tested
+4. **Clear license**: MIT OR Apache-2.0 is common
+5. **Meaningful keywords**: Help discoverability
+6. **Keep it small**: Exclude unnecessary files
dots/.config/claude/skills/Rust/workflows/Test.md
@@ -0,0 +1,208 @@
+# Test Workflow
+
+Run Rust tests with Cargo.
+
+## When to Use
+
+- "run rust tests"
+- "cargo test"
+- "test coverage"
+
+## Quick Commands
+
+```bash
+# Run all tests
+cargo test
+
+# Run tests with output
+cargo test -- --nocapture
+
+# Run specific test
+cargo test test_name
+
+# Run tests in specific module
+cargo test module_name::
+
+# Run doc tests only
+cargo test --doc
+
+# Run tests in release mode
+cargo test --release
+
+# Run ignored tests
+cargo test -- --ignored
+
+# Run tests in parallel (default)
+cargo test
+
+# Run tests single-threaded
+cargo test -- --test-threads=1
+```
+
+## Test Types
+
+### Unit Tests
+
+```rust
+// src/lib.rs
+pub fn add(a: i32, b: i32) -> i32 {
+    a + b
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_add() {
+        assert_eq!(add(2, 2), 4);
+    }
+
+    #[test]
+    fn test_add_negative() {
+        assert_eq!(add(-1, 1), 0);
+    }
+
+    #[test]
+    #[should_panic(expected = "overflow")]
+    fn test_overflow() {
+        let _result = add(i32::MAX, 1);
+    }
+
+    #[test]
+    #[ignore]
+    fn expensive_test() {
+        // Run only with --ignored
+    }
+}
+```
+
+### Integration Tests
+
+```rust
+// tests/integration_test.rs
+use mylib;
+
+#[test]
+fn it_works() {
+    assert_eq!(mylib::add(2, 2), 4);
+}
+
+#[test]
+fn test_full_process() {
+    let result = mylib::process("input");
+    assert!(result.is_ok());
+}
+```
+
+### Doc Tests
+
+```rust
+/// Adds two numbers.
+///
+/// # Examples
+///
+/// ```
+/// use mylib::add;
+/// assert_eq!(add(2, 2), 4);
+/// ```
+pub fn add(a: i32, b: i32) -> i32 {
+    a + b
+}
+```
+
+## Assertions
+
+```rust
+#[test]
+fn test_assertions() {
+    // Equality
+    assert_eq!(2 + 2, 4);
+    assert_ne!(2 + 2, 5);
+
+    // Boolean
+    assert!(true);
+    assert!(!false);
+
+    // Custom message
+    assert_eq!(2 + 2, 4, "Math is broken: {} != {}", 2 + 2, 4);
+
+    // Debug assertion (only in debug builds)
+    debug_assert_eq!(expensive_computation(), expected);
+}
+```
+
+## Test Coverage
+
+### Install tarpaulin
+
+```bash
+cargo install cargo-tarpaulin
+```
+
+### Run Coverage
+
+```bash
+# Generate coverage report
+cargo tarpaulin --out Html --output-dir coverage
+
+# With specific format
+cargo tarpaulin --out Lcov
+cargo tarpaulin --out Xml
+```
+
+## Property-Based Testing
+
+```toml
+[dev-dependencies]
+proptest = "1.0"
+```
+
+```rust
+use proptest::prelude::*;
+
+proptest! {
+    #[test]
+    fn test_reverse_twice(s in ".*") {
+        let rev = reverse(&s);
+        let rev_rev = reverse(&rev);
+        prop_assert_eq!(s, rev_rev);
+    }
+}
+```
+
+## Mocking
+
+```toml
+[dev-dependencies]
+mockall = "0.12"
+```
+
+```rust
+use mockall::{automock, predicate::*};
+
+#[automock]
+trait Database {
+    fn get_user(&self, id: u64) -> Option<User>;
+}
+
+#[test]
+fn test_with_mock() {
+    let mut mock = MockDatabase::new();
+    mock.expect_get_user()
+        .with(eq(1))
+        .returning(|_| Some(User::default()));
+
+    assert!(mock.get_user(1).is_some());
+}
+```
+
+## Best Practices
+
+1. **Test public APIs** - Focus on behavior, not implementation
+2. **Use descriptive names** - `test_user_login_with_invalid_credentials`
+3. **One assertion per test** - When practical
+4. **Use `Result<()>` return type** - For tests that can fail
+5. **Write doc tests** - Examples and tests in one
+6. **Property-based tests** - For invariants
+7. **Run tests in CI** - Catch regressions early
dots/.config/claude/skills/Rust/workflows/Workspace.md
@@ -0,0 +1,112 @@
+# Workspace Workflow
+
+Manage multi-crate projects with Cargo workspaces.
+
+## When to Use
+
+- "cargo workspace"
+- "multi-crate project"
+- "monorepo"
+
+## Structure
+
+```
+myworkspace/
+├── Cargo.toml              # Workspace root
+├── Cargo.lock              # Shared lock file
+├── crates/
+│   ├── core/
+│   │   ├── Cargo.toml
+│   │   └── src/lib.rs
+│   ├── cli/
+│   │   ├── Cargo.toml
+│   │   └── src/main.rs
+│   └── api/
+│       ├── Cargo.toml
+│       └── src/lib.rs
+```
+
+## Root Cargo.toml
+
+```toml
+[workspace]
+members = [
+    "crates/*",
+]
+exclude = ["crates/experimental"]
+
+# Use Rust 2024 resolver
+resolver = "3"
+
+# Shared dependencies
+[workspace.dependencies]
+serde = { version = "1.0", features = ["derive"] }
+tokio = { version = "1.0", features = ["full"] }
+anyhow = "1.0"
+
+# Shared metadata
+[workspace.package]
+version = "0.1.0"
+edition = "2021"
+license = "MIT OR Apache-2.0"
+authors = ["Your Name <you@example.com>"]
+
+# Shared lints
+[workspace.lints.rust]
+unsafe_code = "forbid"
+
+[workspace.lints.clippy]
+pedantic = "warn"
+```
+
+## Member Cargo.toml
+
+```toml
+[package]
+name = "myworkspace-cli"
+version.workspace = true
+edition.workspace = true
+license.workspace = true
+
+[dependencies]
+# Workspace dependencies
+serde.workspace = true
+tokio.workspace = true
+
+# Internal dependencies
+myworkspace-core = { path = "../core" }
+
+# Member-specific dependencies
+clap = "4.0"
+```
+
+## Commands
+
+```bash
+# Build entire workspace
+cargo build --workspace
+
+# Build specific package
+cargo build -p myworkspace-cli
+
+# Test all packages
+cargo test --workspace
+
+# Test specific package
+cargo test -p myworkspace-core
+
+# Run binary from package
+cargo run -p myworkspace-cli
+
+# Check all packages
+cargo check --workspace
+```
+
+## Best Practices
+
+1. **Consistent naming**: `workspace-package` pattern
+2. **Shared dependencies**: Use `workspace.dependencies`
+3. **Version sync**: Use `version.workspace = true`
+4. **One lock file**: Shared across workspace
+5. **Logical separation**: Each crate has clear purpose
+6. **Avoid circular deps**: Keep dependency graph acyclic
dots/.config/claude/skills/Rust/README.md
@@ -0,0 +1,152 @@
+# Rust Skill
+
+Modern Rust development guidance using Cargo, Clippy, and best practices.
+
+## Overview
+
+This skill provides comprehensive guidance for Rust development following 2025 best practices:
+
+- **Cargo**: Build system and package manager
+- **Clippy**: Over 550 lints for catching mistakes
+- **rustfmt**: Official code formatter
+- **Criterion**: Statistical benchmarking
+- **thiserror/anyhow**: Modern error handling
+
+## Workflows
+
+### Building & Testing
+- **[Build](workflows/Build.md)**: Compile projects with various profiles and targets
+- **[Test](workflows/Test.md)**: Unit, integration, and property-based testing
+- **[Bench](workflows/Bench.md)**: Performance benchmarking with Criterion
+
+### Code Quality
+- **[Lint](workflows/Lint.md)**: Lint and format with Clippy and rustfmt
+- **[Error](workflows/Error.md)**: Idiomatic error handling patterns
+
+### Dependencies & Publishing
+- **[Deps](workflows/Deps.md)**: Manage dependencies with Cargo
+- **[Workspace](workflows/Workspace.md)**: Multi-crate monorepos
+- **[Publish](workflows/Publish.md)**: Publish crates to crates.io
+
+## Quick Start
+
+### New Project
+```bash
+# Create binary
+cargo new myapp
+
+# Create library
+cargo new --lib mylib
+
+cd myapp
+cargo build
+cargo run
+```
+
+### Add Dependencies
+```bash
+cargo add serde tokio anyhow
+cargo add --dev proptest criterion
+```
+
+### Quality Checks
+```bash
+# Format code
+cargo fmt
+
+# Lint code
+cargo clippy --all-targets --all-features -- -D warnings
+
+# Run tests
+cargo test
+
+# Run benchmarks
+cargo bench
+```
+
+## Key Concepts
+
+### Ownership & Borrowing
+Rust's ownership system ensures memory safety without garbage collection:
+```rust
+fn main() {
+    let s = String::from("hello"); // s owns the string
+    takes_ownership(s);             // s moved, no longer valid
+    // println!("{}", s);           // Would error!
+
+    let x = 5;
+    makes_copy(x);                  // i32 is Copy, x still valid
+    println!("{}", x);              // OK!
+}
+```
+
+### Error Handling
+Use `Result` and `Option` instead of exceptions:
+```rust
+use anyhow::{Context, Result};
+
+fn process_file(path: &str) -> Result<()> {
+    let contents = std::fs::read_to_string(path)
+        .context("Failed to read file")?;
+
+    // Process contents...
+    Ok(())
+}
+```
+
+### Zero-Cost Abstractions
+High-level code compiles to efficient machine code:
+```rust
+// Iterator chain - as fast as hand-written loop
+let sum: i32 = numbers
+    .iter()
+    .filter(|&&x| x % 2 == 0)
+    .map(|&x| x * 2)
+    .sum();
+```
+
+## Best Practices
+
+1. **Use Clippy**: Run before every commit
+2. **Format with rustfmt**: Consistent style
+3. **Handle errors explicitly**: No `unwrap()` in libraries
+4. **Write tests**: Unit and integration tests
+5. **Document public APIs**: Use `///` doc comments
+6. **Follow API Guidelines**: See Rust API Guidelines
+7. **Use iterators**: Functional and efficient
+8. **Leverage type system**: Make invalid states unrepresentable
+
+## Modern Rust (2024/2025)
+
+### Edition 2021
+- Disjoint capture in closures
+- IntoIterator for arrays
+- Panic macro consistency
+
+### Upcoming Features
+- Async traits (stabilized)
+- Generic associated types (GATs)
+- Let-else statements
+- Edition 2024 (coming soon)
+
+## Resources
+
+### Official Documentation
+- [The Rust Programming Language](https://doc.rust-lang.org/book/)
+- [Rust API Guidelines](https://rust-lang.github.io/api-guidelines/)
+- [The Cargo Book](https://doc.rust-lang.org/cargo/)
+- [Clippy Lints](https://rust-lang.github.io/rust-clippy/)
+
+### Error Handling
+- [thiserror](https://docs.rs/thiserror/)
+- [anyhow](https://docs.rs/anyhow/)
+- [Error Handling Guide 2025](https://markaicode.com/rust-error-handling-2025-guide/)
+
+### Testing & Benchmarking
+- [Criterion.rs](https://github.com/bheisler/criterion.rs)
+- [Rust Benchmarking Guide](https://www.rustfinity.com/blog/rust-benchmarking-with-criterion)
+
+### Community Resources
+- [Rust Users Forum](https://users.rust-lang.org/)
+- [This Week in Rust](https://this-week-in-rust.org/)
+- [Awesome Rust](https://github.com/rust-unofficial/awesome-rust)
dots/.config/claude/skills/Rust/SKILL.md
@@ -0,0 +1,470 @@
+---
+name: Rust
+description: Rust development best practices and patterns. USE WHEN writing Rust code, designing Rust projects, working with Cargo, testing, or Rust package development.
+---
+
+# Rust Development Best Practices
+
+## Purpose
+Guide Rust development following official standards, community best practices, and idiomatic patterns from The Rust Book, Rust API Guidelines, and the Rust team's recommendations.
+
+### Context Detection
+
+**This skill activates when:**
+- Claude is asked to work on Rust code
+- Current directory path or git repository contains `Cargo.toml`
+- User is working with `.rs` files
+- Commands like `cargo`, `rustc`, or `clippy` are mentioned
+
+## Workflow Routing
+
+**When executing a workflow, output this notification directly:**
+
+```
+Running the **WorkflowName** workflow from the **Rust** skill...
+```
+
+| Workflow | Trigger | File |
+|----------|---------|------|
+| **Build** | "build rust project", "cargo build", "compile" | `workflows/Build.md` |
+| **Test** | "run tests", "cargo test", "test coverage" | `workflows/Test.md` |
+| **Bench** | "benchmark", "cargo bench", "performance test" | `workflows/Bench.md` |
+| **Lint** | "lint", "clippy", "cargo fmt", "format" | `workflows/Lint.md` |
+| **Deps** | "dependencies", "cargo add", "update deps" | `workflows/Deps.md` |
+| **Error** | "error handling", "Result", "thiserror", "anyhow" | `workflows/Error.md` |
+| **Workspace** | "workspace", "multi-crate", "monorepo" | `workflows/Workspace.md` |
+| **Publish** | "publish crate", "crates.io", "cargo publish" | `workflows/Publish.md` |
+
+## Core Principles
+
+1. **Safety first**: Leverage Rust's ownership and type system for memory safety
+2. **Zero-cost abstractions**: Write high-level code without runtime overhead
+3. **Fearless concurrency**: Use Rust's guarantees to write concurrent code safely
+4. **Explicit error handling**: Use `Result` and `Option` types, never panic in libraries
+5. **Idiomatic patterns**: Follow Rust API Guidelines and community conventions
+
+## Standard Project Structure
+
+### Binary Application
+```
+myapp/
+├── Cargo.toml              # Project manifest
+├── Cargo.lock              # Dependency lock file (commit for apps)
+├── src/
+│   ├── main.rs            # Entry point
+│   ├── lib.rs             # Optional library code
+│   └── bin/               # Additional binaries
+│       └── helper.rs
+├── tests/                  # Integration tests
+│   └── integration_test.rs
+├── benches/                # Benchmarks
+│   └── my_bench.rs
+├── examples/               # Example code
+│   └── basic.rs
+└── README.md
+```
+
+### Library Crate
+```
+mylib/
+├── Cargo.toml
+├── Cargo.lock              # Don't commit for libraries
+├── src/
+│   ├── lib.rs             # Library root
+│   └── submodule/
+│       └── mod.rs
+├── tests/
+│   └── integration_test.rs
+├── benches/
+│   └── benchmark.rs
+└── examples/
+    └── usage.rs
+```
+
+### Workspace (Multiple Crates)
+```
+myworkspace/
+├── Cargo.toml              # Workspace manifest
+├── Cargo.lock              # Shared lock file
+├── crates/
+│   ├── core/
+│   │   ├── Cargo.toml
+│   │   └── src/lib.rs
+│   ├── cli/
+│   │   ├── Cargo.toml
+│   │   └── src/main.rs
+│   └── api/
+│       ├── Cargo.toml
+│       └── src/lib.rs
+└── README.md
+```
+
+## Writing Idiomatic Rust
+
+### Naming Conventions
+
+```rust
+// Types: UpperCamelCase
+struct MyStruct;
+enum MyEnum { VariantA, VariantB }
+trait MyTrait {}
+
+// Functions, variables, modules: snake_case
+fn my_function() {}
+let my_variable = 42;
+mod my_module {}
+
+// Constants, statics: SCREAMING_SNAKE_CASE
+const MAX_SIZE: usize = 100;
+static GLOBAL_COUNT: AtomicUsize = AtomicUsize::new(0);
+
+// Lifetimes: short lowercase
+fn foo<'a, 'b>(x: &'a str, y: &'b str) -> &'a str { x }
+```
+
+### Error Handling
+
+```rust
+use std::fs::File;
+use std::io::{self, Read};
+
+// Good: Use Result for recoverable errors
+fn read_file(path: &str) -> Result<String, io::Error> {
+    let mut file = File::open(path)?;
+    let mut contents = String::new();
+    file.read_to_string(&mut contents)?;
+    Ok(contents)
+}
+
+// Good: Use Option for values that might not exist
+fn find_user(id: u64) -> Option<User> {
+    DATABASE.get(&id).cloned()
+}
+
+// Bad: Don't use unwrap() in library code
+fn bad_read_file(path: &str) -> String {
+    let mut file = File::open(path).unwrap(); // DON'T DO THIS
+    // ...
+}
+
+// Use thiserror for library errors
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+pub enum MyError {
+    #[error("IO error: {0}")]
+    Io(#[from] io::Error),
+
+    #[error("Parse error: {0}")]
+    Parse(String),
+
+    #[error("Not found: {0}")]
+    NotFound(String),
+}
+
+// Use anyhow for application errors
+use anyhow::{Context, Result};
+
+fn process_file(path: &str) -> Result<()> {
+    let contents = std::fs::read_to_string(path)
+        .context("Failed to read configuration file")?;
+
+    let config: Config = serde_json::from_str(&contents)
+        .context("Failed to parse JSON config")?;
+
+    Ok(())
+}
+```
+
+### Ownership and Borrowing
+
+```rust
+// Good: Use references when you don't need ownership
+fn calculate_length(s: &String) -> usize {
+    s.len()
+}
+
+// Good: Use mutable references for modification
+fn append_world(s: &mut String) {
+    s.push_str(", world!");
+}
+
+// Good: Take ownership when you need it
+fn consume_string(s: String) -> usize {
+    s.len()
+} // s is dropped here
+
+// Good: Use slices for flexibility
+fn first_word(s: &str) -> &str {
+    let bytes = s.as_bytes();
+    for (i, &byte) in bytes.iter().enumerate() {
+        if byte == b' ' {
+            return &s[..i];
+        }
+    }
+    &s[..]
+}
+```
+
+### Iterator Patterns
+
+```rust
+// Good: Use iterators for functional transformations
+let numbers: Vec<i32> = vec![1, 2, 3, 4, 5];
+
+let doubled: Vec<i32> = numbers
+    .iter()
+    .map(|x| x * 2)
+    .collect();
+
+let sum: i32 = numbers
+    .iter()
+    .filter(|&&x| x % 2 == 0)
+    .sum();
+
+// Good: Chain iterator methods
+let result: Vec<String> = input
+    .lines()
+    .map(str::trim)
+    .filter(|line| !line.is_empty())
+    .map(|line| line.to_uppercase())
+    .collect();
+
+// Good: Use iterator adapters
+let pairs: Vec<(usize, &i32)> = numbers
+    .iter()
+    .enumerate()
+    .filter(|(i, _)| i % 2 == 0)
+    .collect();
+```
+
+## Cargo Essentials
+
+### Cargo.toml Configuration
+
+```toml
+[package]
+name = "myproject"
+version = "0.1.0"
+edition = "2021"           # Use latest edition (2024 coming soon)
+rust-version = "1.70"      # Minimum supported Rust version (MSRV)
+authors = ["Your Name <you@example.com>"]
+description = "A short description"
+documentation = "https://docs.rs/myproject"
+repository = "https://github.com/user/myproject"
+license = "MIT OR Apache-2.0"
+keywords = ["cli", "tool"]
+categories = ["command-line-utilities"]
+
+[dependencies]
+serde = { version = "1.0", features = ["derive"] }
+tokio = { version = "1.0", features = ["full"] }
+anyhow = "1.0"
+
+[dev-dependencies]
+criterion = "0.7"
+proptest = "1.0"
+
+[build-dependencies]
+cc = "1.0"
+
+# Profile optimizations
+[profile.release]
+lto = true              # Link-time optimization
+codegen-units = 1       # Better optimization
+strip = true            # Remove debug symbols
+opt-level = 3           # Maximum optimization
+
+[profile.dev]
+opt-level = 0           # Fast compilation
+debug = true
+
+# Workspace dependencies (in workspace root)
+[workspace.dependencies]
+serde = "1.0"
+tokio = "1.0"
+```
+
+### Common Commands
+
+```bash
+# Create new project
+cargo new myproject          # Binary
+cargo new --lib mylib        # Library
+
+# Build
+cargo build                  # Debug build
+cargo build --release        # Release build
+cargo build --all-features   # With all features
+
+# Run
+cargo run                    # Run binary
+cargo run --example basic    # Run example
+
+# Test
+cargo test                   # Run all tests
+cargo test --doc            # Run doc tests
+cargo test integration      # Run tests matching pattern
+
+# Check without building
+cargo check                  # Fast compile check
+cargo clippy                # Lint checks
+
+# Format
+cargo fmt                    # Format code
+
+# Documentation
+cargo doc --open            # Build and open docs
+
+# Dependencies
+cargo add serde             # Add dependency
+cargo update                # Update dependencies
+cargo tree                  # Show dependency tree
+```
+
+## Testing
+
+### Unit Tests
+
+```rust
+// In same file as code being tested
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_addition() {
+        assert_eq!(add(2, 2), 4);
+    }
+
+    #[test]
+    fn test_with_result() -> Result<(), String> {
+        if add(2, 2) == 4 {
+            Ok(())
+        } else {
+            Err(String::from("Addition failed"))
+        }
+    }
+
+    #[test]
+    #[should_panic(expected = "divided by zero")]
+    fn test_panic() {
+        divide(10, 0);
+    }
+
+    #[test]
+    #[ignore]  // Skip unless --ignored flag
+    fn expensive_test() {
+        // ...
+    }
+}
+```
+
+### Integration Tests
+
+```rust
+// tests/integration_test.rs
+use mylib;
+
+#[test]
+fn it_works() {
+    assert_eq!(mylib::add(2, 2), 4);
+}
+
+#[test]
+fn test_full_workflow() {
+    let result = mylib::process_data("input.txt");
+    assert!(result.is_ok());
+}
+```
+
+### Property-Based Testing
+
+```rust
+use proptest::prelude::*;
+
+proptest! {
+    #[test]
+    fn test_reversing_twice_gives_original(s in ".*") {
+        let reversed = reverse(&s);
+        let double_reversed = reverse(&reversed);
+        prop_assert_eq!(s, double_reversed);
+    }
+
+    #[test]
+    fn test_addition_commutative(a in 0..1000i32, b in 0..1000i32) {
+        prop_assert_eq!(a + b, b + a);
+    }
+}
+```
+
+## Async Rust with Tokio
+
+```rust
+use tokio;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn std::error::Error>> {
+    // Spawn concurrent tasks
+    let handle = tokio::spawn(async {
+        // Async work
+        fetch_data().await
+    });
+
+    let result = handle.await?;
+    Ok(())
+}
+
+async fn fetch_data() -> Result<String, reqwest::Error> {
+    let response = reqwest::get("https://api.example.com/data")
+        .await?
+        .text()
+        .await?;
+    Ok(response)
+}
+
+// Concurrent execution
+use tokio::join;
+
+async fn do_stuff_concurrently() {
+    let (result1, result2, result3) = join!(
+        fetch_thing_1(),
+        fetch_thing_2(),
+        fetch_thing_3()
+    );
+}
+```
+
+## Best Practices Checklist
+
+- [ ] Use `cargo fmt` for consistent formatting
+- [ ] Run `cargo clippy` and fix all warnings
+- [ ] Add documentation comments (`///`) for public APIs
+- [ ] Write tests for new functionality
+- [ ] Use `Result` for error handling, not `panic!` in libraries
+- [ ] Specify MSRV in `Cargo.toml`
+- [ ] Use workspace dependencies for consistency
+- [ ] Enable useful Clippy lints in `Cargo.toml`
+- [ ] Profile release builds for performance
+- [ ] Use semantic versioning for releases
+
+## Resources
+
+### Official Documentation
+- [The Rust Programming Language (Book)](https://doc.rust-lang.org/book/)
+- [Rust API Guidelines](https://rust-lang.github.io/api-guidelines/)
+- [The Cargo Book](https://doc.rust-lang.org/cargo/)
+- [Clippy Lints](https://rust-lang.github.io/rust-clippy/)
+
+### Error Handling
+- [thiserror documentation](https://docs.rs/thiserror/)
+- [anyhow documentation](https://docs.rs/anyhow/)
+- [Error Handling Guide 2025](https://markaicode.com/rust-error-handling-2025-guide/)
+
+### Testing & Benchmarking
+- [Criterion.rs](https://github.com/bheisler/criterion.rs)
+- [Rust Benchmarking Guide](https://www.rustfinity.com/blog/rust-benchmarking-with-criterion)
+
+### Best Practices
+- [Rust Project Structure Guide](https://www.djamware.com/post/68b2c7c451ce620c6f5efc56/rust-project-structure-and-best-practices-for-clean-scalable-code)
+- [Large Rust Workspaces](https://matklad.github.io/2021/08/22/large-rust-workspaces.html)
dots/.config/claude/settings.json
@@ -1,8 +1,4 @@
 {
-  "statusLine": {
-    "type": "command",
-    "command": "bash ~/.config/claude/statusline.sh"
-  },
   "hooks": {
     "SessionStart": [
       {
@@ -35,11 +31,9 @@
       }
     ]
   },
-  "skills": {
-    "enabled": true,
-    "directories": [
-      "~/.config/claude/skills"
-    ]
+  "statusLine": {
+    "type": "command",
+    "command": "bash ~/.config/claude/statusline.sh"
   },
   "enabledPlugins": {
     "bug-hunter@chmouel-cc-plugins": true,
@@ -54,5 +48,11 @@
     "hookify@claude-code-plugins": true,
     "gh-tools@vdemeester-claude-code-plugins": true
   },
-  "alwaysThinkingEnabled": false
+  "alwaysThinkingEnabled": true,
+  "skills": {
+    "enabled": true,
+    "directories": [
+      "~/.config/claude/skills"
+    ]
+  }
 }