- 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
149 lines
4.7 KiB
Markdown
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
|