Expand description
Core types and functionality for AGPM
This module forms the foundation of AGPM’s type system, providing fundamental abstractions for error handling, resource management, and core operations. It defines the contracts and interfaces used throughout the AGPM codebase.
§Architecture Overview
The core module is organized around several key concepts:
§Error Management
AGPM uses a sophisticated error handling system designed for both developer ergonomics and end-user experience:
- Strongly-typed errors (
AgpmError) for precise error handling in code - User-friendly contexts (
ErrorContext) with actionable suggestions for CLI users - Automatic error conversion from common standard library errors
- Contextual suggestions tailored to specific error conditions
§Resource Abstractions
Resources are the core entities managed by AGPM:
- Resource types (
ResourceType) define categories (agents, snippets) - Resource trait provides common interface for all resource types
- Type detection automatically identifies resources
- Extensible design allows future resource types to be added easily
§Operation Context
Operation-scoped state management without global variables:
- Warning deduplication prevents duplicate error messages during operations
- Test isolation each operation gets its own context
- Clean architecture no global state, context flows through call chain
§Modules
§error - Comprehensive Error Handling
The error module provides:
AgpmError- Enumerated error types covering all AGPM failure modesErrorContext- User-friendly error wrapper with suggestions and detailsuser_friendly_error- Convert any error to user-friendly formatIntoAnyhowWithContext- Extension trait for error conversion
§resource - Resource Type System
The resource module provides:
ResourceType- Enumeration of supported resource typesResource- Trait interface for all resource implementations- Type detection functions - Automatic resource type detection
§operation_context - Operation-Scoped State
The operation_context module provides:
OperationContext- Context object for CLI operations- Warning deduplication across module boundaries
- Test-friendly architecture without global state
§Design Principles
§Error First Design
Every operation that can fail returns a Result type with meaningful error information.
Errors are designed to be informative, actionable, and user-friendly.
§Type Safety
Strong typing prevents invalid operations and catches errors at compile time. Resource types, error variants, and operation modes are all statically typed.
§Extensibility
The core abstractions are designed to support future expansion without breaking changes. New resource types and error variants can be added while maintaining compatibility.
§User Experience
All user-facing errors include contextual suggestions and clear guidance for resolution. Terminal colors and formatting enhance readability and highlight important information.
§Examples
§Error Handling Pattern
use agpm_cli::core::{AgpmError, ErrorContext, user_friendly_error};
use anyhow::Result;
fn example_operation() -> Result<String> {
// Simulate an operation that might fail
Err(AgpmError::ManifestNotFound.into())
}
fn handle_operation() {
match example_operation() {
Ok(result) => println!("Success: {}", result),
Err(e) => {
// Convert to user-friendly error and display
let friendly = user_friendly_error(e);
friendly.display(); // Shows colored error with suggestions
}
}
}§Resource Type Detection
use agpm_cli::core::{ResourceType, detect_resource_type};
use std::path::Path;
use tempfile::tempdir;
fn discover_resources() -> anyhow::Result<()> {
let temp_dir = tempdir()?;
let path = temp_dir.path();
// Create a resource manifest
std::fs::write(path.join("agent.toml"), "# Agent configuration")?;
// Detect the resource type
if let Some(resource_type) = detect_resource_type(path) {
match resource_type {
ResourceType::Agent => {
println!("Found agent resource");
println!("Install dir: {}", resource_type.default_directory().unwrap_or("none"));
}
ResourceType::Snippet => {
println!("Found snippet resource");
println!("Install dir: {}", resource_type.default_directory().unwrap_or("none"));
}
ResourceType::Command => {
println!("Found command resource");
println!("Install dir: {}", resource_type.default_directory().unwrap_or("none"));
}
ResourceType::McpServer => {
println!("Found MCP server configuration");
println!("Install dir: {}", resource_type.default_directory().unwrap_or("none"));
}
ResourceType::Script => {
println!("Found script resource");
println!("Install dir: {}", resource_type.default_directory().unwrap_or("none"));
}
ResourceType::Hook => {
println!("Found hook configuration");
println!("Install dir: {}", resource_type.default_directory().unwrap_or("none"));
}
ResourceType::Skill => {
println!("Found skill resource");
println!("Install dir: {}", resource_type.default_directory().unwrap_or("none"));
}
}
} else {
println!("No recognized resource found");
}
Ok(())
}§Resource Trait Usage
use agpm_cli::core::{Resource, ResourceType};
use anyhow::Result;
use std::path::Path;
fn process_any_resource(resource: &dyn Resource) -> Result<()> {
// Get basic information
println!("Processing: {} ({})", resource.name(), resource.resource_type());
if let Some(desc) = resource.description() {
println!("Description: {}", desc);
}
// Validate before processing
resource.validate()?;
// Get metadata for analysis
let metadata = resource.metadata()?;
if let Some(version) = metadata.get("version") {
println!("Version: {}", version);
}
// Install to target location
let target = Path::new("./resources");
let install_path = resource.install_path(target);
println!("Would install to: {}", install_path.display());
Ok(())
}§Error Context Creation
use agpm_cli::core::{AgpmError, ErrorContext};
fn create_helpful_error() -> ErrorContext {
ErrorContext::new(AgpmError::GitNotFound)
.with_suggestion("Install git from https://git-scm.com/ or use your package manager")
.with_details("AGPM requires git to clone and manage source repositories")
}
fn display_error() {
let error = create_helpful_error();
error.display(); // Shows colored output with error, details, and suggestion
}§Integration with Other Modules
The core module provides types used throughout AGPM:
- CLI commands use
AgpmErrorandErrorContextfor user feedback - Git operations return
AgpmErrorvariants for specific failure modes - Manifest parsing uses
Resourcetrait for type-agnostic operations - Installation relies on
ResourceTypefor path generation and validation - Dependency resolution uses error types for constraint violations
§Thread Safety
All core types are designed to be thread-safe where appropriate:
ResourceTypeisCopyand can be shared freelyAgpmErrorimplementsClonefor error propagationResourcetrait is object-safe for dynamic dispatch
Re-exports§
pub use error::AgpmError;pub use error::ErrorContext;pub use error::IntoAnyhowWithContext;pub use error_builders::ErrorContextExt;pub use error_builders::file_error_context;pub use error_builders::git_error_context;pub use error_builders::manifest_error_context;pub use error_formatting::user_friendly_error;pub use error_helpers::FileOperations;pub use error_helpers::FileOps;pub use error_helpers::JsonOperations;pub use error_helpers::JsonOps;pub use error_helpers::LockfileOperations;pub use error_helpers::LockfileOps;pub use error_helpers::ManifestOperations;pub use error_helpers::ManifestOps;pub use error_helpers::MarkdownOperations;pub use error_helpers::MarkdownOps;pub use operation_context::OperationContext;pub use resource_iterator::ResourceIterator;pub use resource_iterator::ResourceTypeExt;
Modules§
- error
- Error handling for AGPM
- error_
builders - Error context builders for consistent error reporting
- error_
formatting - Error formatting utilities for AGPM
- error_
helpers - Error handling helper functions and utilities
- file_
error - Structured file system error handling for AGPM
- operation_
context - Operation-scoped context for cross-module state management.
- resource_
iterator - Resource iteration and collection utilities for parallel installation
Enums§
- Resource
Type - Enumeration of supported resource types in AGPM
Traits§
- Resource
- Base trait defining the interface for all AGPM resources
Functions§
- detect_
resource_ type - Detect the resource type in a directory by examining manifest files