claude_agent/context/
level.rs1use std::path::PathBuf;
7
8use async_trait::async_trait;
9
10use super::{ContextResult, MemoryContent, MemoryProvider, RuleIndex};
11
12#[derive(Debug, Default)]
18pub struct LeveledMemoryProvider {
19 contents: Vec<MemoryContent>,
20}
21
22impl LeveledMemoryProvider {
23 pub fn new() -> Self {
24 Self::default()
25 }
26
27 pub fn add_content(&mut self, content: impl Into<String>) {
29 let mut mc = MemoryContent::default();
30 mc.claude_md.push(content.into());
31 self.contents.push(mc);
32 }
33
34 pub fn add_local_content(&mut self, content: impl Into<String>) {
36 let mut mc = MemoryContent::default();
37 mc.local_md.push(content.into());
38 self.contents.push(mc);
39 }
40
41 pub fn add_rule(&mut self, rule: RuleIndex) {
43 let mut mc = MemoryContent::default();
44 mc.rule_indices.push(rule);
45 self.contents.push(mc);
46 }
47
48 pub fn add_memory_content(&mut self, content: MemoryContent) {
50 self.contents.push(content);
51 }
52}
53
54#[async_trait]
55impl MemoryProvider for LeveledMemoryProvider {
56 fn name(&self) -> &str {
57 "leveled"
58 }
59
60 async fn load(&self) -> ContextResult<MemoryContent> {
61 let mut combined = MemoryContent::default();
62 for content in &self.contents {
63 combined.merge(content.clone());
64 }
65 Ok(combined)
66 }
67
68 fn priority(&self) -> i32 {
69 100
70 }
71}
72
73pub fn enterprise_base_path() -> Option<PathBuf> {
74 #[cfg(target_os = "macos")]
75 {
76 let path = PathBuf::from("/Library/Application Support/ClaudeCode");
77 if path.exists() {
78 return Some(path);
79 }
80 }
81 #[cfg(target_os = "linux")]
82 {
83 let path = PathBuf::from("/etc/claude-code");
84 if path.exists() {
85 return Some(path);
86 }
87 }
88 None
89}
90
91pub fn user_base_path() -> Option<PathBuf> {
92 crate::common::home_dir().map(|h| h.join(".claude"))
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 #[tokio::test]
100 async fn test_leveled_memory_provider() {
101 let mut provider = LeveledMemoryProvider::new();
102 provider.add_content("# Enterprise Rules");
103 provider.add_content("# User Preferences");
104 provider.add_content("# Project Guidelines");
105
106 let content = provider.load().await.unwrap();
107 assert_eq!(content.claude_md.len(), 3);
108 }
109
110 #[tokio::test]
111 async fn test_leveled_with_local() {
112 let mut provider = LeveledMemoryProvider::new();
113 provider.add_content("Main content");
114 provider.add_local_content("Local content");
115
116 let content = provider.load().await.unwrap();
117 assert_eq!(content.claude_md.len(), 1);
118 assert_eq!(content.local_md.len(), 1);
119
120 let combined = content.combined_claude_md();
121 assert!(combined.contains("Main content"));
122 assert!(combined.contains("Local content"));
123 }
124}