Refactor: Dismantle MemoryState into semantic domain sub-structs

This commit is contained in:
Riz Ashraf committed 2026-09-30 21:13:03 +01:00
1 parent 0e866f2465
commit a34554b7ff
13 files changed
+186 -158

No files matched your search

+15 -15
View File
@@ -20,7 +20,7 @@ impl McpTool for PinFileHandler {
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
let req: PinFileTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
state.pinned_files.modify(|pinned| {
state.project.pinned_files.modify(|pinned| {
pinned.retain(|p| p.namespace != req.namespace || p.file_path != req.file_path);
pinned.push(crate::models::PinnedFile {
namespace: req.namespace,
@@ -47,7 +47,7 @@ impl McpTool for UnpinFileHandler {
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
let req: UnpinFileTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
state.pinned_files.modify(|pinned| {
state.project.pinned_files.modify(|pinned| {
pinned.retain(|p| p.namespace != req.namespace || p.file_path != req.file_path)
});
Ok("File unpinned".to_string())
@@ -71,7 +71,7 @@ impl McpTool for ListPinnedFilesHandler {
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
let req: ListPinnedFilesTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
let data = state.pinned_files.read_with(|pinned| {
let data = state.project.pinned_files.read_with(|pinned| {
let filtered: Vec<_> = pinned
.iter()
.filter(|p| {
@@ -124,7 +124,7 @@ impl McpTool for StoreSnippetHandler {
let idx = state.get_search_index();
drop(idx.index_snippet(&snippet));
state.snippets.modify(|snippets| {
state.code.snippets.modify(|snippets| {
snippets.retain(|s| s.name != req_name);
snippets.push(snippet);
});
@@ -148,7 +148,7 @@ impl McpTool for SearchSnippetsHandler {
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
let req: SearchSnippetsTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
let query = req.query;
let data = state.snippets.read_with(|snippets| {
let data = state.code.snippets.read_with(|snippets| {
let results: Vec<_> = snippets
.iter()
.filter(|s| {
@@ -178,7 +178,7 @@ impl McpTool for DeleteSnippetHandler {
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
let req: DeleteSnippetTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
let mut deleted = false;
state.snippets.modify(|snippets| {
state.code.snippets.modify(|snippets| {
let orig = snippets.len();
snippets.retain(|s| s.name != req.name);
deleted = snippets.len() < orig;
@@ -211,7 +211,7 @@ impl McpTool for SaveContextWorkspaceHandler {
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
let req: SaveContextWorkspaceTool =
serde_json::from_value(args).map_err(|e| e.to_string())?;
state.context_workspaces.modify(|ws| {
state.project.context_workspaces.modify(|ws| {
ws.retain(|w| w.namespace != req.namespace || w.name != req.name);
ws.push(crate::models::ContextWorkspace {
namespace: req.namespace,
@@ -243,7 +243,7 @@ impl McpTool for LoadContextWorkspaceHandler {
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
let req: LoadContextWorkspaceTool =
serde_json::from_value(args).map_err(|e| e.to_string())?;
let data = state.context_workspaces.read_with(|ws| {
let data = state.project.context_workspaces.read_with(|ws| {
let filtered: Vec<_> = ws
.iter()
.filter(|w| w.namespace == req.namespace && w.name == req.name)
@@ -272,7 +272,7 @@ impl McpTool for ListContextWorkspacesHandler {
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
let req: ListContextWorkspacesTool =
serde_json::from_value(args).map_err(|e| e.to_string())?;
let data = state.context_workspaces.read_with(|ws| {
let data = state.project.context_workspaces.read_with(|ws| {
let filtered: Vec<_> = ws
.iter()
.filter(|w| req.namespace.as_ref().is_none_or(|ns| &w.namespace == ns))
@@ -303,7 +303,7 @@ impl McpTool for DeleteContextWorkspaceHandler {
serde_json::from_value(args).map_err(|e| e.to_string())?;
let mut found = false;
state.context_workspaces.modify(|ws| {
state.project.context_workspaces.modify(|ws| {
if let Some(pos) = ws
.iter()
.position(|w| w.namespace == req.namespace && w.name == req.name)
@@ -339,7 +339,7 @@ impl McpTool for AddPrChecklistItemHandler {
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
let req: AddPrChecklistItemTool =
serde_json::from_value(args).map_err(|e| e.to_string())?;
state.pr_checklists.modify(|items| {
state.project.pr_checklists.modify(|items| {
items.push(crate::models::PrChecklistItem {
namespace: req.namespace,
id: uuid::Uuid::new_v4().to_string(),
@@ -364,7 +364,7 @@ impl McpTool for GetPrChecklistHandler {
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
let req: GetPrChecklistTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
let data = state.pr_checklists.read_with(|items| {
let data = state.project.pr_checklists.read_with(|items| {
let filtered: Vec<_> = items
.iter()
.filter(|i| i.namespace == req.namespace)
@@ -393,7 +393,7 @@ impl McpTool for ClearPrChecklistHandler {
async fn execute(&self, args: Value, state: Arc<MemoryState>) -> crate::error::Result<String> {
let req: ClearPrChecklistTool = serde_json::from_value(args).map_err(|e| e.to_string())?;
state
.pr_checklists
.project.pr_checklists
.modify(|items| items.retain(|i| i.namespace != req.namespace));
Ok("PR checklist cleared".to_string())
}
@@ -625,14 +625,14 @@ impl McpTool for SemanticCodeSearchHandler {
let mut texts_to_embed = Vec::new();
let mut metadata = Vec::new();
let snippets = state.snippets.read_with(|snips| snips.clone());
let snippets = state.code.snippets.read_with(|snips| snips.clone());
for snippet in snippets {
let combined = format!("{} {} {}", snippet.name, snippet.description, snippet.code);
texts_to_embed.push(combined);
metadata.push((snippet.name, snippet.description));
}
let sticky = state.sticky.read_with(|s| s.clone());
let sticky = state.code.sticky.read_with(|s| s.clone());
for note in sticky {
texts_to_embed.push(note.content.clone());
metadata.push(("StickyNote".to_string(), note.content.chars().take(200).collect::<String>()));