pub enum ResourceDependency {
Simple(String),
Detailed(Box<DetailedDependency>),
}Expand description
A resource dependency specification supporting multiple formats.
Dependencies can be specified in two main formats to balance simplicity
with flexibility. The enum uses Serde’s untagged attribute to automatically
deserialize the correct variant based on the TOML structure.
§Variants
§Simple Dependencies
For local file dependencies, just specify the path directly:
[agents]
local-helper = "../shared/agents/helper.md"
nearby-agent = "./local/custom-agent.md"§Detailed Dependencies
For remote dependencies or when you need more control:
[agents]
# Remote dependency with version
code-reviewer = { source = "official", path = "agents/reviewer.md", version = "v1.0.0" }
# Remote dependency with git reference
experimental = { source = "community", path = "agents/new.md", git = "develop" }
# Local dependency with explicit path (equivalent to simple form)
local-tool = { path = "../tools/agent.md" }§Validation Rules
- Local dependencies (no source): Cannot have version constraints
- Remote dependencies (with source): Must have either
versionorgitfield - Path field: Required and cannot be empty
- Source field: Must reference an existing source in the
[sources]section
§Type Safety
The enum ensures type safety at compile time while providing runtime
validation through the Manifest::validate method.
§Serialization Behavior
- Simple paths serialize directly as strings
- Detailed specs serialize as TOML inline tables
- Empty optional fields are omitted for cleaner output
- Deserialization is automatic based on TOML structure
§Memory Layout
This enum uses #[serde(untagged)] for automatic variant detection,
which means deserialization tries the Detailed variant first, then
falls back to Simple. This is efficient for the expected usage patterns
where detailed dependencies are more common in larger projects.
§Memory Layout
The Detailed variant is boxed to reduce the size of the enum from 264 bytes
to 24 bytes, improving memory efficiency when many dependencies are stored.
Variants§
Simple(String)
Simple path-only dependency, typically for local files.
This variant represents the simplest dependency format where only a file path is specified. It’s primarily used for local dependencies that exist in the filesystem relative to the project.
§Format
dependency-name = "path/to/file.md"§Examples
[agents]
# Relative paths from manifest directory
helper = "../shared/helper.md"
custom = "./local/custom.md"
# Absolute paths (not recommended)
system = "/usr/local/share/agent.md"§Limitations
- Cannot specify version constraints
- Cannot reference remote Git sources
- Must be a valid filesystem path
- Path must exist at installation time
Detailed(Box<DetailedDependency>)
Detailed dependency specification with full control.
This variant provides complete control over dependency specification, supporting both local and remote dependencies with version constraints, Git references, and explicit source mapping.
See DetailedDependency for field-level documentation.
Note: This variant is boxed to reduce the overall size of the enum.
Implementations§
Source§impl ResourceDependency
impl ResourceDependency
Sourcepub fn get_source(&self) -> Option<&str>
pub fn get_source(&self) -> Option<&str>
Get the source repository name if this is a remote dependency.
Returns the source name for remote dependencies (those that reference
a Git repository), or None for local dependencies (those that reference
local filesystem paths).
§Examples
use agpm_cli::manifest::{ResourceDependency, DetailedDependency};
// Local dependency - no source
let local = ResourceDependency::Simple("../local/file.md".to_string());
assert!(local.get_source().is_none());
// Remote dependency - has source
let remote = ResourceDependency::Detailed(Box::new(DetailedDependency {
source: Some("official".to_string()),
path: "agents/tool.md".to_string(),
version: Some("v1.0.0".to_string()),
branch: None,
rev: None,
command: None,
args: None,
target: None,
filename: None,
dependencies: None,
tool: "claude-code".to_string(),
}));
assert_eq!(remote.get_source(), Some("official"));§Use Cases
This method is commonly used to:
- Determine if dependency resolution should use Git vs filesystem
- Validate that referenced sources exist in the manifest
- Filter dependencies by type (local vs remote)
- Generate dependency graphs and reports
Sourcepub fn get_target(&self) -> Option<&str>
pub fn get_target(&self) -> Option<&str>
Get the custom target directory for this dependency.
Returns the custom target directory if specified, or None if the
dependency should use the default installation location for its resource type.
§Examples
use agpm_cli::manifest::{ResourceDependency, DetailedDependency};
// Dependency with custom target
let custom = ResourceDependency::Detailed(Box::new(DetailedDependency {
source: Some("official".to_string()),
path: "agents/tool.md".to_string(),
version: Some("v1.0.0".to_string()),
target: Some("custom/tools".to_string()),
branch: None,
rev: None,
command: None,
args: None,
filename: None,
dependencies: None,
tool: "claude-code".to_string(),
}));
assert_eq!(custom.get_target(), Some("custom/tools"));
// Dependency without custom target
let default = ResourceDependency::Simple("../local/file.md".to_string());
assert!(default.get_target().is_none());Sourcepub fn get_filename(&self) -> Option<&str>
pub fn get_filename(&self) -> Option<&str>
Get the custom filename for this dependency.
Returns the custom filename if specified, or None if the
dependency should use the default filename based on the dependency key.
§Examples
use agpm_cli::manifest::{ResourceDependency, DetailedDependency};
// Dependency with custom filename
let custom = ResourceDependency::Detailed(Box::new(DetailedDependency {
source: Some("official".to_string()),
path: "agents/tool.md".to_string(),
version: Some("v1.0.0".to_string()),
filename: Some("ai-assistant.md".to_string()),
branch: None,
rev: None,
command: None,
args: None,
target: None,
dependencies: None,
tool: "claude-code".to_string(),
}));
assert_eq!(custom.get_filename(), Some("ai-assistant.md"));
// Dependency without custom filename
let default = ResourceDependency::Simple("../local/file.md".to_string());
assert!(default.get_filename().is_none());Sourcepub fn get_path(&self) -> &str
pub fn get_path(&self) -> &str
Get the path to the resource file.
Returns the path component of the dependency, which is interpreted differently based on whether this is a local or remote dependency:
- Local dependencies: Filesystem path relative to the manifest directory
- Remote dependencies: Path within the Git repository
§Examples
use agpm_cli::manifest::{ResourceDependency, DetailedDependency};
// Local dependency - filesystem path
let local = ResourceDependency::Simple("../shared/helper.md".to_string());
assert_eq!(local.get_path(), "../shared/helper.md");
// Remote dependency - repository path
let remote = ResourceDependency::Detailed(Box::new(DetailedDependency {
source: Some("official".to_string()),
path: "agents/code-reviewer.md".to_string(),
version: Some("v1.0.0".to_string()),
branch: None,
rev: None,
command: None,
args: None,
target: None,
filename: None,
dependencies: None,
tool: "claude-code".to_string(),
}));
assert_eq!(remote.get_path(), "agents/code-reviewer.md");§Path Resolution
The returned path should be processed appropriately based on the dependency type:
- Local paths may need resolution against the manifest directory
- Remote paths are used directly within the cloned repository
- All paths should use forward slashes (/) for cross-platform compatibility
Sourcepub fn is_pattern(&self) -> bool
pub fn is_pattern(&self) -> bool
Check if this is a pattern-based dependency.
Returns true if this dependency uses a glob pattern to match
multiple resources, false if it specifies a single resource path.
Patterns are detected by the presence of glob characters (*, ?, [)
in the path field.
Sourcepub fn get_version(&self) -> Option<&str>
pub fn get_version(&self) -> Option<&str>
Get the version constraint for dependency resolution.
Returns the version constraint that should be used when resolving this
dependency from a Git repository. For local dependencies, always returns None.
§Priority Rules
If both version and git fields are present in a detailed dependency,
the git field takes precedence:
use agpm_cli::manifest::{ResourceDependency, DetailedDependency};
let dep = ResourceDependency::Detailed(Box::new(DetailedDependency {
source: Some("repo".to_string()),
path: "file.md".to_string(),
version: Some("v1.0.0".to_string()), // This is ignored
branch: Some("develop".to_string()), // This takes precedence over version
rev: None,
command: None,
args: None,
target: None,
filename: None,
dependencies: None,
tool: "claude-code".to_string(),
}));
assert_eq!(dep.get_version(), Some("develop"));§Examples
use agpm_cli::manifest::{ResourceDependency, DetailedDependency};
// Local dependency - no version
let local = ResourceDependency::Simple("../local/file.md".to_string());
assert!(local.get_version().is_none());
// Remote dependency with version
let versioned = ResourceDependency::Detailed(Box::new(DetailedDependency {
source: Some("repo".to_string()),
path: "file.md".to_string(),
version: Some("v1.0.0".to_string()),
branch: None,
rev: None,
command: None,
args: None,
target: None,
filename: None,
dependencies: None,
tool: "claude-code".to_string(),
}));
assert_eq!(versioned.get_version(), Some("v1.0.0"));
// Remote dependency with branch reference
let branch_ref = ResourceDependency::Detailed(Box::new(DetailedDependency {
source: Some("repo".to_string()),
path: "file.md".to_string(),
version: None,
branch: Some("main".to_string()),
rev: None,
command: None,
args: None,
target: None,
filename: None,
dependencies: None,
tool: "claude-code".to_string(),
}));
assert_eq!(branch_ref.get_version(), Some("main"));§Version Formats
Supported version constraint formats include:
- Semantic versions:
"v1.0.0","1.2.3" - Semantic version ranges:
"^1.0.0","~2.1.0" - Branch names:
"main","develop","latest","feature/new" - Git tags:
"release-2023","stable" - Commit SHAs:
"a1b2c3d4e5f6..."
Sourcepub fn is_local(&self) -> bool
pub fn is_local(&self) -> bool
Check if this is a local filesystem dependency.
Returns true if this dependency refers to a local file (no Git source),
or false if it’s a remote dependency that will be resolved from a
Git repository.
This is a convenience method equivalent to self.get_source().is_none().
§Examples
use agpm_cli::manifest::{ResourceDependency, DetailedDependency};
// Local dependency
let local = ResourceDependency::Simple("../local/file.md".to_string());
assert!(local.is_local());
// Remote dependency
let remote = ResourceDependency::Detailed(Box::new(DetailedDependency {
source: Some("official".to_string()),
path: "agents/tool.md".to_string(),
version: Some("v1.0.0".to_string()),
branch: None,
rev: None,
command: None,
args: None,
target: None,
filename: None,
dependencies: None,
tool: "claude-code".to_string(),
}));
assert!(!remote.is_local());
// Local detailed dependency (no source specified)
let local_detailed = ResourceDependency::Detailed(Box::new(DetailedDependency {
source: None,
path: "../shared/tool.md".to_string(),
version: None,
branch: None,
rev: None,
command: None,
args: None,
target: None,
filename: None,
dependencies: None,
tool: "claude-code".to_string(),
}));
assert!(local_detailed.is_local());§Use Cases
This method is useful for:
- Choosing between filesystem and Git resolution strategies
- Validation logic (local deps can’t have versions)
- Installation planning (local deps don’t need caching)
- Progress reporting (different steps for local vs remote)
Sourcepub fn get_tool(&self) -> &str
pub fn get_tool(&self) -> &str
Get the tool type for this dependency.
Returns the target AI coding assistant tool for this resource. This determines where
the resource will be installed (e.g., .claude, .opencode, .agpm).
For simple dependencies, defaults to “claude-code”. For detailed dependencies, returns the configured tool type.
§Examples
use agpm_cli::manifest::{ResourceDependency, DetailedDependency};
// Simple dependency - defaults to "claude-code"
let simple = ResourceDependency::Simple("../local/file.md".to_string());
assert_eq!(simple.get_tool(), "claude-code");
// Detailed dependency with explicit tool
let detailed = ResourceDependency::Detailed(Box::new(DetailedDependency {
source: Some("official".to_string()),
path: "agents/tool.md".to_string(),
version: Some("v1.0.0".to_string()),
branch: None,
rev: None,
command: None,
args: None,
target: None,
filename: None,
dependencies: None,
tool: "opencode".to_string(),
}));
assert_eq!(detailed.get_tool(), "opencode");Trait Implementations§
Source§impl Clone for ResourceDependency
impl Clone for ResourceDependency
Source§fn clone(&self) -> ResourceDependency
fn clone(&self) -> ResourceDependency
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more