pub async fn install_resource(
entry: &LockedResource,
resource_dir: &str,
context: &InstallContext<'_>,
) -> Result<(bool, String, Option<String>, AppliedPatches, Option<u64>)>Expand description
Install a single resource from a lock entry using worktrees for parallel safety.
This function installs a resource specified by a lockfile entry to the project directory. It uses Git worktrees through the cache layer to enable safe parallel operations without conflicts between concurrent installations.
§Arguments
entry- The locked resource to install containing source and version inforesource_dir- The subdirectory name for this resource type (e.g., “agents”)context- Installation context containing project configuration and cache instance
§Returns
Returns Ok((installed, file_checksum, context_checksum, applied_patches, token_count)) where:
installedistrueif the resource was actually installed (new or updated),falseif the resource already existed and was unchangedfile_checksumis the SHA-256 hash of the installed file content (after rendering)context_checksumis the SHA-256 hash of the template rendering inputs, or None for non-templated resourcesapplied_patchescontains information about any patches that were applied during installationtoken_countis the approximate BPE token count of the content, or None for skills/directories
§Worktree Usage
For remote resources, this function:
- Uses
cache.get_or_clone_source_worktree_with_context()to get a worktree - Each dependency gets its own isolated worktree for parallel safety
- Worktrees are automatically managed and reused by the cache layer
- Context (dependency name) is provided for debugging parallel operations
§Installation Process
- Path resolution: Determines destination based on
installed_ator defaults - Repository access: Gets worktree from cache (for remote) or validates local path
- Content validation: Verifies markdown format and structure
- Atomic write: Installs file atomically to prevent corruption
§Examples
use agpm_cli::installer::{install_resource, InstallContext};
use agpm_cli::lockfile::LockedResourceBuilder;
use agpm_cli::cache::Cache;
use agpm_cli::core::ResourceType;
use std::path::Path;
let cache = Cache::new()?;
let entry = LockedResourceBuilder::new(
"example-agent".to_string(),
"agents/example.md".to_string(),
"sha256:...".to_string(),
".claude/agents/example.md".to_string(),
ResourceType::Agent,
)
.source(Some("community".to_string()))
.url(Some("https://github.com/example/repo.git".to_string()))
.version(Some("v1.0.0".to_string()))
.resolved_commit(Some("abc123".to_string()))
.tool(Some("claude-code".to_string()))
.build();
let context = InstallContext::builder(Path::new("."), &cache).build();
let (installed, checksum, _old_checksum, _patches, _token_count) = install_resource(&entry, "agents", &context).await?;
if installed {
println!("Resource was installed with checksum: {}", checksum);
} else {
println!("Resource already existed and was unchanged");
}§Error Handling
Returns an error if:
- The source repository cannot be accessed or cloned
- The specified file path doesn’t exist in the repository
- The file is not valid markdown format
- File system operations fail (permissions, disk space)
- Worktree creation fails due to Git issues