Files
immich-sdk/AGENTS.md
Joakim Hulthe 2e7db3b35a Add integration testing infrastructure with Podman Compose
- Add docker/podman-compose.yml for Immich server (no ML)
- Add test-data/sample-photos/ with 3 public domain images
- Add scripts/start-immich.sh for container startup + admin/API key creation
- Add scripts/seed-data.sh for uploading test photos and creating albums
- Add scripts/stop-immich.sh for cleanup with volume destruction
- Add scripts/run-example.sh wrapper (fixed env var export)
- Update examples to use IMMICH_URL and IMMICH_API_KEY env vars
- Add .github/workflows/integration-test.yml for CI
- Update assets.list() to use /search/metadata endpoint
- Update AGENTS.md with example running instructions
- Add 5 new examples: search_metadata, album_management, timeline_browsing,
  delete_assets, server_info
2026-04-14 20:13:30 +00:00

149 lines
4.7 KiB
Markdown

# 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 <test_name> # 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 <example_name>
```
**Available examples:**
```bash
./scripts/run-example.sh basic_usage
./scripts/run-example.sh upload_photos
./scripts/run-example.sh download_asset
./scripts/run-example.sh thumbnail
```
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 <name>`
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<T>` 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<ClientInner>`
- 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<String>` 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<ClientInner>
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