# Agent Instructions for immich-sdk ## Build & Test Commands **Quick Checks:** ```bash cargo check # Fast compilation check cargo clippy # Run linter cargo fmt # Format code cargo test # Run all tests cargo test # Run single test (e.g., cargo test test_client_creation) ``` **Full verification before commit:** ```bash cargo check && cargo clippy && cargo test && cargo fmt ``` ## Running Examples All examples should be run using the provided wrapper script: ```bash ./scripts/run-example.sh ``` The wrapper handles everything automatically: - Starts Immich containers (if not running) - Creates admin user and API key - Seeds test data (photos, albums) - Loads credentials - Runs the example **When adding new examples:** 1. Read `IMMICH_URL` and `IMMICH_API_KEY` from environment variables 2. Test with: `./scripts/run-example.sh ` (Important!) 3. Verify it works with the seeded test data (3 photos, 1 album) ## Code Style Guidelines ### Imports - Group by: std, external crates, internal modules (crate::) - Use `use crate::` for internal modules, not relative paths - Example: ```rust use std::path::Path; use std::sync::Arc; use crate::{ Client, error::{ImmichError, Result}, models::AssetId, }; ``` ### Types & Naming - Prefer using newtypes or type aliases instead of Strings or integers For example: `AssetId` (Uuid alias), not `String` for asset IDs - Model types: PascalCase with `Response` or `Request` suffix - Enum variants: Use serde `rename_all` attributes for API compatibility - Builders: `FooBuilder` for constructing `Foo` operations - Type aliases for IDs: `pub type AssetId = uuid::Uuid;` ### Error Handling - Use `crate::error::Result` alias - Use `thiserror` for error enums - Prefer `ImmichError::Validation(String)` for user input errors - Convert external errors: `#[from] reqwest::Error` ### API Design Patterns - **Builder pattern**: All API operations use builders ```rust client.assets().upload().file("path").execute().await?; ``` - Cheap cloning: `Client` wraps data in `Arc` - API modules take `Client` by value - Store `Client` in builders, not references ### OpenAPI Refer to `openapi-spec.yaml` for documentation regarding immich API. Note that some type definitions in this file are incorrect with regards to nullability. The file is big, so prefer to use nushell to query the things you need: ```nu # List all api paths open openapi-spec.yaml | get paths | transpose key val | get key # Read the details about a particular path open openapi-spec.yaml | get paths.'/workflows' | to yaml ``` ### Documentation - All public items must have doc comments - Module-level docs explaining purpose - Example code in docs should compile (use `no_run` or `ignore` if needed) - Include `# Errors` section for fallible methods ### Rust Edition Features - Edition 2024 (use latest idioms) - Minimum Rust version: 1.85 - Use `const fn` where possible - Prefer `impl Into` for string parameters iff the function requires ownership of the String ## Project Structure ``` src/ lib.rs # Re-exports, module declarations client.rs # Client struct with Arc error.rs # Error types with thiserror models/ # Data models, types apis/ # API modules (albums, assets, etc.) examples/ # Usage examples tests/ # Integration tests ``` ## Lint Configuration From Cargo.toml - DO NOT SUPPRESS THESE: - `unused_async = "deny"` - No async fn without await - `wildcard_dependencies = "deny"` - No wildcard deps - `non_ascii_idents = "forbid"` - ASCII only - `rust_2018_idioms = "deny"` - Modern Rust idioms ## Agile agentic workflow - You are responsible for high-level architecture. - You may (and should) read code to understand the architecture. - You should AVOID doing implementation work and testing. Use the `task` tool to spawn subagents for this. - You should also use the `task` tool to spawn subagents to for code review. - Prefer splitting subagent-tasks into small incremental bits of work. - Subagents must NEVER exit with compilation errors, but warnings due to stubbed implementations (`todo!()`) are fine. ## Never Do - Never use `unsafe` without asking first - Never ignore clippy warnings (fix them) - Never suppress warnings with `#[allow(...)]` - Never use `panic!` or `unwrap()` in library code - Never break the builder pattern chain - Never write pointless tests to simply get more code coverage