1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
//! Configuration management for AGPM
//!
//! This module provides comprehensive configuration management for the `AGent` Package Manager (AGPM).
//! It handles project manifests, global user configuration, and resource metadata with a focus on
//! security, cross-platform compatibility, and reproducible builds.
//!
//! # Architecture Overview
//!
//! AGPM uses a multi-layered configuration architecture:
//!
//! 1. **Global Configuration** (`~/.agpm/config.toml`) - User-wide settings including authentication
//! 2. **Project Manifest** (`agpm.toml`) - Project dependencies and sources
//! 3. **Lockfile** (`agpm.lock`) - Resolved versions for reproducible builds
//! 4. **Resource Metadata** - Agent and snippet configurations embedded in `.md` files
//!
//! # Modules
//!
//! - `global` - Global configuration management with authentication token support
//! - `parser` - Generic TOML parsing utilities with error context
//!
//! # Configuration Files
//!
//! ## Global Configuration (`~/.agpm/config.toml`)
//!
//! **Location:**
//! - Unix/macOS: `~/.agpm/config.toml`
//! - Windows: `%LOCALAPPDATA%\agpm\config.toml`
//!
//! **Purpose:** Store user-wide settings including private repository access tokens.
//! This file is never committed to version control.
//!
//! ```toml
//! # Global sources with authentication tokens
//! [sources]
//! private = "https://oauth2:ghp_xxxxxxxxxxxx@github.com/company/private-agpm.git"
//! enterprise = "https://token:abc123@gitlab.company.com/ai/resources.git"
//! ```
//!
//! ## Project Manifest (`agpm.toml`)
//!
//! **Purpose:** Define project dependencies and public sources. Safe for version control.
//!
//! ```toml
//! [sources]
//! community = "https://github.com/aig787/agpm-community.git"
//!
//! [agents]
//! code-reviewer = { source = "community", path = "agents/code-reviewer.md", version = "v1.2.0" }
//! local-helper = { path = "../local-agents/helper.md" }
//!
//! [snippets]
//! rust-patterns = { source = "community", path = "snippets/rust.md", version = "^2.0" }
//! ```
//!
//! ## Lockfile (`agpm.lock`)
//!
//! **Purpose:** Pin exact versions for reproducible installations. Auto-generated.
//!
//! ```toml
//! # Auto-generated lockfile - DO NOT EDIT
//! version = 1
//!
//! [[sources]]
//! name = "community"
//! url = "https://github.com/aig787/agpm-community.git"
//! commit = "abc123..."
//!
//! [[agents]]
//! name = "code-reviewer"
//! source = "community"
//! version = "v1.2.0"
//! resolved_commit = "def456..."
//! checksum = "sha256:..."
//! installed_at = "agents/code-reviewer.md"
//! ```
//!
//! # Security Model
//!
//! ## Credential Isolation
//!
//! - **Global Config**: Contains authentication tokens, never committed
//! - **Project Manifest**: Public sources only, safe for version control
//! - **Source Merging**: Global sources loaded first, project sources can override
//!
//! ## Configuration Priority
//!
//! 1. Environment variables (`AGPM_CONFIG_PATH`, `AGPM_CACHE_DIR`)
//! 2. Global configuration (`~/.agpm/config.toml`)
//! 3. Project manifest (`agpm.toml`)
//! 4. Default values
//!
//! # Resource Metadata
//!
//! Agent and snippet files can include TOML frontmatter for metadata:
//!
//! ```markdown
//! +++
//! [metadata]
//! name = "rust-expert"
//! description = "Expert Rust development agent"
//! author = "AGPM Community"
//! license = "MIT"
//! keywords = ["rust", "programming", "expert"]
//!
//! [requirements]
//! agpm_version = ">=0.1.0"
//! claude_version = "latest"
//! platforms = ["windows", "macos", "linux"]
//!
//! [[requirements.dependencies]]
//! name = "code-formatter"
//! version = "^1.0"
//! type = "snippet"
//! +++
//!
//! # Rust Expert Agent
//!
//! You are an expert Rust developer...
//! ```
//!
//! # Platform Support
//!
//! This module handles cross-platform configuration paths:
//!
//! - **Windows**: Uses `%LOCALAPPDATA%` for configuration
//! - **macOS/Linux**: Uses `$HOME/.agpm` directory
//! - **Path Separators**: Normalized automatically
//! - **File Permissions**: Handles Windows vs Unix differences
//!
//! # Examples
//!
//! ## Loading Global Configuration
//!
//! ```rust,no_run
//! use agpm_cli::config::{GlobalConfig, GlobalConfigManager};
//!
//! # async fn example() -> anyhow::Result<()> {
//! // Simple load
//! let global = GlobalConfig::load().await?;
//! println!("Found {} global sources", global.sources.len());
//!
//! // Using manager for caching
//! let mut manager = GlobalConfigManager::new()?;
//! let config = manager.get().await?;
//!
//! // Add authenticated source
//! let config = manager.get_mut().await?;
//! config.add_source(
//! "private".to_string(),
//! "https://oauth2:token@github.com/company/repo.git".to_string()
//! );
//! manager.save().await?;
//! # Ok(())
//! # }
//! ```
//!
//! ## Source Resolution with Authentication
//!
//! ```rust,no_run
//! use agpm_cli::config::GlobalConfig;
//! use std::collections::HashMap;
//!
//! # async fn example() -> anyhow::Result<()> {
//! let global = GlobalConfig::load().await?;
//!
//! // Project manifest sources (public)
//! let mut local_sources = HashMap::new();
//! local_sources.insert(
//! "community".to_string(),
//! "https://github.com/aig787/agpm-community.git".to_string()
//! );
//!
//! // Merge with global sources (may include auth tokens)
//! let merged = global.merge_sources(&local_sources);
//!
//! // Use merged sources for git operations
//! for (name, url) in &merged {
//! println!("Source {}: {}", name,
//! if url.contains("@") { "[authenticated]" } else { url });
//! }
//! # Ok(())
//! # }
//! ```
pub use ;
pub use parse_config;
use crate;
use Result;
use PathBuf;
/// Get the cache directory for AGPM.
///
/// Returns the directory where AGPM stores cached Git repositories and temporary files.
/// The location follows platform conventions and can be overridden with environment variables.
///
/// # Location Priority
///
/// 1. `AGPM_CACHE_DIR` environment variable (if set)
/// 2. Platform-specific cache directory:
/// - Windows: `%LOCALAPPDATA%\agpm\cache`
/// - macOS/Linux: `~/.agpm/cache`
///
/// # Directory Creation
///
/// The directory is automatically created if it doesn't exist.
///
/// # Examples
///
/// ```rust,no_run
/// use agpm_cli::config::get_cache_dir;
///
/// # fn example() -> anyhow::Result<()> {
/// let cache = get_cache_dir()?;
/// println!("Cache directory: {}", cache.display());
/// # Ok(())
/// # }
/// ```
///
/// # Errors
///
/// Returns an error if:
/// - The system cache directory cannot be determined
/// - The cache directory cannot be created
/// - Insufficient permissions for directory creation