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(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: Some("claude-code".to_string()),
flatten: None,
install: None,
template_vars: Some(serde_json::Value::Object(serde_json::Map::new())),
}));
assert_eq!(remote.get_source(), Some("official"));
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: Some("claude-code".to_string()),
flatten: None,
install: None,
template_vars: Some(serde_json::Value::Object(serde_json::Map::new())),
}));
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_tool(&self) -> Option<&str>
pub fn get_tool(&self) -> Option<&str>
Get the tool for this dependency.
Returns the tool string if specified, or None if not specified. When None is returned, the caller should apply resource-type-specific defaults.
§Returns
Some(tool)if tool is explicitly specifiedNoneif no tool is configured (use resource-type default)
Sourcepub fn set_tool(&mut self, tool: Option<String>)
pub fn set_tool(&mut self, tool: Option<String>)
Set the tool for this dependency.
Only works for Detailed dependencies. Does nothing for Simple dependencies.
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: Some("claude-code".to_string()),
install: None,
flatten: None,
template_vars: Some(serde_json::Value::Object(serde_json::Map::new())),
}));
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_flatten(&self) -> Option<bool>
pub fn get_flatten(&self) -> Option<bool>
Get the flatten flag for this dependency.
Returns the flatten setting if explicitly specified, or None if the
dependency should use the default flatten behavior based on tool configuration.
When flatten = true: Only the filename is used (e.g., nested/dir/file.md → file.md)
When flatten = false: Full path is preserved (e.g., nested/dir/file.md → nested/dir/file.md)
§Default Behavior (from tool configuration)
- Agents: Default to
true(flatten) - Commands: Default to
true(flatten) - All others: Default to
false(preserve structure)
Sourcepub fn get_install(&self) -> Option<bool>
pub fn get_install(&self) -> Option<bool>
Get the install flag for this dependency.
Returns the install setting if explicitly specified, or None to use the
default behavior (install = true).
When install = false: Dependency is resolved and content made available in
template context, but file is not written to disk.
When install = true (or None): Dependency is installed as a file.
§Returns
Some(false)- Do not install the file, only make content availableSome(true)- Install the file normallyNone- Use default behavior (install = true)
Sourcepub fn get_template_vars(&self) -> Option<&Value>
pub fn get_template_vars(&self) -> Option<&Value>
Get the template variable overrides for this resource.
Returns the resource-specific template variables that override the global
[project] configuration. These variables are used when:
- Rendering the resource file itself
- Resolving the resource’s transitive dependencies
This allows creating specialized variants of generic resources without duplication.
§Examples
use agpm_cli::manifest::{ResourceDependency, DetailedDependency};
use serde_json::json;
// Resource with template variable overrides
let resource = ResourceDependency::Detailed(Box::new(DetailedDependency {
source: Some("community".to_string()),
path: "agents/backend-engineer.md".to_string(),
version: Some("v1.0.0".to_string()),
branch: None,
rev: None,
command: None,
args: None,
target: None,
filename: Some("backend-engineer-golang.md".to_string()),
dependencies: None,
tool: Some("claude-code".to_string()),
flatten: None,
install: None,
template_vars: Some(json!({ "project": { "language": "golang" } })),
}));
assert!(resource.get_template_vars().is_some());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: Some("claude-code".to_string()),
flatten: None,
install: None,
template_vars: Some(serde_json::Value::Object(serde_json::Map::new())),
}));
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: Some("claude-code".to_string()),
flatten: None,
install: None,
template_vars: Some(serde_json::Value::Object(serde_json::Map::new())),
}));
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: Some("claude-code".to_string()),
flatten: None,
install: None,
template_vars: Some(serde_json::Value::Object(serde_json::Map::new())),
}));
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: Some("claude-code".to_string()),
flatten: None,
install: None,
template_vars: Some(serde_json::Value::Object(serde_json::Map::new())),
}));
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: Some("claude-code".to_string()),
flatten: None,
install: None,
template_vars: Some(serde_json::Value::Object(serde_json::Map::new())),
}));
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: Some("claude-code".to_string()),
flatten: None,
install: None,
template_vars: Some(serde_json::Value::Object(serde_json::Map::new())),
}));
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 resolution_mode(&self) -> ResolutionMode
pub fn resolution_mode(&self) -> ResolutionMode
Get the resolution mode for this dependency.
Returns whether this dependency should be resolved using version constraints (semantic versioning with tags) or direct git references (branch/rev).
§Returns
ResolutionMode::Versionif this dependency usesversionfield or has no git referenceResolutionMode::GitRefif this dependency usesbranchorrevfields
§Examples
use agpm_cli::manifest::{ResourceDependency, DetailedDependency};
use agpm_cli::resolver::types::ResolutionMode;
// Version path dependency
let versioned = ResourceDependency::Detailed(Box::new(DetailedDependency {
source: Some("official".to_string()),
path: "agents/tool.md".to_string(),
version: Some("^1.0.0".to_string()),
branch: None,
rev: None,
command: None,
args: None,
target: None,
filename: None,
dependencies: None,
tool: None,
flatten: None,
install: None,
template_vars: None,
}));
assert_eq!(versioned.resolution_mode(), ResolutionMode::Version);
// Git path dependency
let git_ref = ResourceDependency::Detailed(Box::new(DetailedDependency {
source: Some("official".to_string()),
path: "agents/tool.md".to_string(),
version: None,
branch: Some("main".to_string()),
rev: None,
command: None,
args: None,
target: None,
filename: None,
dependencies: None,
tool: None,
flatten: None,
install: None,
template_vars: None,
}));
assert_eq!(git_ref.resolution_mode(), ResolutionMode::GitRef);Sourcepub fn get_version_constraint(&self) -> Option<&str>
pub fn get_version_constraint(&self) -> Option<&str>
Get version constraint (Version path only).
Returns the version constraint only for Version path dependencies. For Git path dependencies, returns None.
§Returns
Some(version)if this is a Version path dependency with a version constraintNonefor Git path dependencies or dependencies without version
§Examples
use agpm_cli::manifest::{ResourceDependency, DetailedDependency};
// Version constraint
let versioned = ResourceDependency::Detailed(Box::new(DetailedDependency {
source: Some("official".to_string()),
path: "agents/tool.md".to_string(),
version: Some("^1.0.0".to_string()),
branch: None,
rev: None,
command: None,
args: None,
target: None,
filename: None,
dependencies: None,
tool: None,
flatten: None,
install: None,
template_vars: None,
}));
assert_eq!(versioned.get_version_constraint(), Some("^1.0.0"));
// Git reference - no version constraint
let git_ref = ResourceDependency::Detailed(Box::new(DetailedDependency {
source: Some("official".to_string()),
path: "agents/tool.md".to_string(),
version: None,
branch: Some("main".to_string()),
rev: None,
command: None,
args: None,
target: None,
filename: None,
dependencies: None,
tool: None,
flatten: None,
install: None,
template_vars: None,
}));
assert_eq!(git_ref.get_version_constraint(), None);Sourcepub fn get_git_ref(&self) -> Option<&str>
pub fn get_git_ref(&self) -> Option<&str>
Get git reference (Git path only).
Returns the git reference (branch or rev) only for Git path dependencies. For Version path dependencies, returns None.
Rev takes precedence over branch if both are specified.
§Returns
Some(git_ref)if this is a Git path dependency with branch or revNonefor Version path dependencies
§Examples
use agpm_cli::manifest::{ResourceDependency, DetailedDependency};
// Branch reference
let branch_ref = ResourceDependency::Detailed(Box::new(DetailedDependency {
source: Some("official".to_string()),
path: "agents/tool.md".to_string(),
version: None,
branch: Some("main".to_string()),
rev: None,
command: None,
args: None,
target: None,
filename: None,
dependencies: None,
tool: None,
flatten: None,
install: None,
template_vars: None,
}));
assert_eq!(branch_ref.get_git_ref(), Some("main"));
// Version constraint - no git reference
let versioned = ResourceDependency::Detailed(Box::new(DetailedDependency {
source: Some("official".to_string()),
path: "agents/tool.md".to_string(),
version: Some("^1.0.0".to_string()),
branch: None,
rev: None,
command: None,
args: None,
target: None,
filename: None,
dependencies: None,
tool: None,
flatten: None,
install: None,
template_vars: None,
}));
assert_eq!(versioned.get_git_ref(), None);Sourcepub fn is_mutable(&self) -> bool
pub fn is_mutable(&self) -> bool
Check if this dependency is mutable (can change without manifest changes).
A dependency is considered mutable if:
- It’s a local dependency (no source, just a filesystem path)
- It uses a branch reference (branches can be updated)
- It uses a version that looks like a branch name (not semver)
A dependency is considered immutable if:
- It uses a
revfield (explicitly pinned to a SHA) - It uses a semver version string (resolved to a specific tag)
Immutable dependencies are safe for fast-path optimization because their content is locked by SHA commit hash after initial resolution.
§Returns
trueif the dependency can change without manifest changesfalseif the dependency is locked to a specific commit
§Examples
use agpm_cli::manifest::{ResourceDependency, DetailedDependency};
// Local dependency - always mutable
let local = ResourceDependency::Simple("../local/file.md".to_string());
assert!(local.is_mutable());
// Branch reference - mutable
let branch = 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: None,
flatten: None,
install: None,
template_vars: None,
}));
assert!(branch.is_mutable());
// Semver version - immutable (tags are stable)
let versioned = ResourceDependency::Detailed(Box::new(DetailedDependency {
source: Some("repo".to_string()),
path: "file.md".to_string(),
version: Some("^1.0.0".to_string()),
branch: None,
rev: None,
command: None,
args: None,
target: None,
filename: None,
dependencies: None,
tool: None,
flatten: None,
install: None,
template_vars: None,
}));
assert!(!versioned.is_mutable());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 moreSource§impl Debug for ResourceDependency
impl Debug for ResourceDependency
Source§impl<'de> Deserialize<'de> for ResourceDependency
impl<'de> Deserialize<'de> for ResourceDependency
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Auto Trait Implementations§
impl Freeze for ResourceDependency
impl RefUnwindSafe for ResourceDependency
impl Send for ResourceDependency
impl Sync for ResourceDependency
impl Unpin for ResourceDependency
impl UnwindSafe for ResourceDependency
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more