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
//! Markdown Configuration Module
//!
//! Provides markdown-based definition of agents, modes, and commands with YAML frontmatter.
//! Enables users to create custom configurations using familiar markdown syntax.
//!
//! # Overview
//!
//! The markdown configuration module enables users to define custom agents, modes, and commands
//! using markdown files with YAML frontmatter. This approach combines the readability of markdown
//! with the structure of YAML, making configuration files both human-friendly and machine-parseable.
//!
//! # Configuration File Format
//!
//! All markdown configuration files follow this structure:
//!
//! ```markdown
//! ---
//! name: example-agent
//! description: Example agent configuration
//! model: gpt-4
//! temperature: 0.7
//! max_tokens: 2000
//! ---
//!
//! # Example Agent
//!
//! This is the markdown content that serves as documentation or prompt.
//! ```
//!
//! # Configuration Types
//!
//! ## Agent Configuration
//!
//! Agents are AI-powered components with specific capabilities and parameters.
//!
//! **File Pattern**: `*.agent.md`
//!
//! **Fields**:
//! - `name` (required): Unique identifier for the agent
//! - `description` (optional): Human-readable description
//! - `model` (optional): LLM model to use (e.g., "gpt-4")
//! - `temperature` (optional): Model temperature (0.0-2.0)
//! - `max_tokens` (optional): Maximum response tokens
//! - `tools` (optional): List of available tools
//!
//! ## Mode Configuration
//!
//! Modes define editor behaviors and keybindings for different workflows.
//!
//! **File Pattern**: `*.mode.md`
//!
//! **Fields**:
//! - `name` (required): Unique identifier for the mode
//! - `description` (optional): Human-readable description
//! - `keybinding` (optional): Keyboard shortcut to activate
//! - `enabled` (optional): Whether the mode is enabled (default: true)
//!
//! ## Command Configuration
//!
//! Commands define custom operations with parameters and templates.
//!
//! **File Pattern**: `*.command.md`
//!
//! **Fields**:
//! - `name` (required): Unique identifier for the command
//! - `description` (optional): Human-readable description
//! - `template` (required): Command template with parameter placeholders
//! - `parameters` (optional): List of parameter definitions
//! - `keybinding` (optional): Keyboard shortcut to invoke
//!
//! # Discovery and Loading
//!
//! Configuration files are discovered in the following locations (in priority order):
//!
//! 1. **Project-level**: `projects/ricecoder/.agent/`
//! 2. **User-level**: `~/.ricecoder/agents/`, `~/.ricecoder/modes/`, `~/.ricecoder/commands/`
//! 3. **System-level**: `/etc/ricecoder/agents/` (Linux/macOS)
//!
//! The [`ConfigurationLoader`] automatically discovers and loads all configuration files
//! from these locations, validating each file and registering valid configurations with
//! the [`ConfigRegistry`].
//!
//! # Hot-Reload Support
//!
//! The [`FileWatcher`] monitors configuration directories for changes. When a file is modified:
//!
//! 1. File is detected within 5 seconds
//! 2. Configuration is re-parsed and validated
//! 3. If valid, configuration is updated in the registry
//! 4. If invalid, error is logged and previous configuration is retained
//!
//! This enables runtime configuration updates without requiring application restart.
//!
//! # Usage Examples
//!
//! ## Loading Configurations
//!
//! ```ignore
//! use ricecoder_storage::markdown_config::{ConfigurationLoader, ConfigRegistry};
//! use std::sync::Arc;
//!
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let registry = Arc::new(ConfigRegistry::new());
//! let loader = ConfigurationLoader::new(registry.clone());
//!
//! // Discover and load configurations
//! let paths = vec![
//! std::path::PathBuf::from("~/.ricecoder/agents"),
//! std::path::PathBuf::from("projects/ricecoder/.agent"),
//! ];
//!
//! loader.load_all(&paths).await?;
//!
//! // Query loaded configurations
//! if let Some(agent) = registry.get_agent("code-review") {
//! println!("Found agent: {}", agent.name);
//! }
//!
//! Ok(())
//! }
//! ```
//!
//! ## Parsing Markdown Configuration
//!
//! ```ignore
//! use ricecoder_storage::markdown_config::{MarkdownParser, YamlParser};
//!
//! let markdown_content = r#"---
//! name: example-agent
//! description: Example agent
//! model: gpt-4
//! ---
//!
//! # Example Agent
//! This is the documentation.
//! "#;
//!
//! let parser = MarkdownParser::new();
//! let parsed = parser.parse(markdown_content)?;
//!
//! println!("Frontmatter: {:?}", parsed.frontmatter);
//! println!("Content: {}", parsed.content);
//! ```
//!
//! ## Validating Configuration
//!
//! ```ignore
//! use ricecoder_storage::markdown_config::{AgentConfig, validate_agent_config};
//!
//! let config = AgentConfig {
//! name: "code-review".to_string(),
//! description: Some("Code review agent".to_string()),
//! model: Some("gpt-4".to_string()),
//! temperature: Some(0.7),
//! max_tokens: Some(2000),
//! tools: vec!["syntax-analyzer".to_string()],
//! };
//!
//! validate_agent_config(&config)?;
//! println!("Configuration is valid!");
//! ```
//!
//! # Error Handling
//!
//! The module provides detailed error information for debugging:
//!
//! - **Parsing Errors**: Include file path and line numbers
//! - **Validation Errors**: List all validation failures with field paths
//! - **Loading Errors**: Indicate which files failed and why
//!
//! Invalid configurations are logged but don't prevent loading of other files,
//! enabling graceful degradation when some configurations are malformed.
//!
//! # Configuration File Locations
//!
//! ## Project-Level Configuration
//!
//! Place configuration files in `projects/ricecoder/.agent/`:
//!
//! ```text
//! projects/ricecoder/
//! └── .agent/
//! ├── examples/
//! │ ├── code-review.agent.md
//! │ ├── focus.mode.md
//! │ └── test.command.md
//! ├── custom-agent.agent.md
//! └── custom-mode.mode.md
//! ```
//!
//! ## User-Level Configuration
//!
//! Place configuration files in `~/.ricecoder/`:
//!
//! ```text
//! ~/.ricecoder/
//! ├── agents/
//! │ ├── my-agent.agent.md
//! │ └── code-review.agent.md
//! ├── modes/
//! │ ├── focus.mode.md
//! │ └── debug.mode.md
//! └── commands/
//! ├── test.command.md
//! └── build.command.md
//! ```
//!
//! # Best Practices
//!
//! 1. **Use Descriptive Names**: Choose names that clearly indicate purpose
//! 2. **Document Configurations**: Include markdown documentation explaining usage
//! 3. **Validate Early**: Use the validation functions to catch errors early
//! 4. **Organize Files**: Group related configurations in directories
//! 5. **Version Control**: Commit project-level configurations to version control
//! 6. **Test Configurations**: Verify configurations work as expected before deploying
//!
//! # See Also
//!
//! - [`ConfigurationLoader`]: Discovers and loads configuration files
//! - [`ConfigRegistry`]: Central registry for loaded configurations
//! - [`FileWatcher`]: Monitors configuration files for changes
//! - [`MarkdownParser`]: Parses markdown files with YAML frontmatter
//! - [`YamlParser`]: Parses and validates YAML frontmatter
// Re-export commonly used types
pub use MarkdownConfigError;
pub use ;
pub use ;
pub use MarkdownParser;
pub use ConfigRegistry;
pub use ;
pub use ;
pub use FileWatcher;
pub use YamlParser;