Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
97343cc
initial refactor
tlongwell-block Sep 6, 2025
5eb5c18
v2 work
tlongwell-block Sep 6, 2025
1a02c18
v3 structure
tlongwell-block Sep 6, 2025
b50ed43
semantic overhaul
tlongwell-block Sep 6, 2025
d610d55
feature complete
tlongwell-block Sep 6, 2025
be636b7
clippy 1
tlongwell-block Sep 6, 2025
0e93597
cleanup + lint
tlongwell-block Sep 6, 2025
0afb0ad
semantic mode fix, pre-focus fix
tlongwell-block Sep 6, 2025
4e1f194
focus
tlongwell-block Sep 6, 2025
f594c5d
focus 2
tlongwell-block Sep 6, 2025
6b9ddf1
focus finish
tlongwell-block Sep 6, 2025
0760588
description with flow
tlongwell-block Sep 7, 2025
d48b210
structure output
tlongwell-block Sep 7, 2025
73aa521
symlink file support
tlongwell-block Sep 7, 2025
b505a91
whoops
tlongwell-block Sep 7, 2025
e1f399c
major refactor
tlongwell-block Sep 7, 2025
fc44115
refactor follow up
tlongwell-block Sep 7, 2025
16f4435
fmt
tlongwell-block Sep 7, 2025
83cd9ef
separate tests
tlongwell-block Sep 7, 2025
35b5e61
test fixes
tlongwell-block Sep 7, 2025
c4ebf65
unrelated
tlongwell-block Sep 7, 2025
dfdaad4
linting
tlongwell-block Sep 7, 2025
17ea82e
less cloning
tlongwell-block Sep 7, 2025
00a4a7b
less async, more paralell
tlongwell-block Sep 7, 2025
cd0bb57
comment cleanup
tlongwell-block Sep 8, 2025
67f1e39
More useful errors
tlongwell-block Sep 8, 2025
31cb6e7
python enhance query
tlongwell-block Sep 8, 2025
6eacf7d
duplicate queries removal
tlongwell-block Sep 8, 2025
3de738f
cache lock poisoning management
tlongwell-block Sep 8, 2025
4c0391c
large output warning and `force` parameter
tlongwell-block Sep 8, 2025
8687383
large output tests
tlongwell-block Sep 8, 2025
dfb8682
Merge remote-tracking branch 'origin/main' into analyze_tool
tlongwell-block Sep 8, 2025
e3ec469
Merge branch 'main' into analyze_tool
michaelneale Sep 9, 2025
c5315fb
Kotlin support
tlongwell-block Sep 9, 2025
e8093a1
Merge origin/main into analyze_tool branch
tlongwell-block Sep 9, 2025
1ea1565
enhanced tool description
tlongwell-block Sep 12, 2025
7600ae3
slim description
tlongwell-block Sep 12, 2025
a8d12d0
feat: Add Swift support to analyze tool and downgrade tree-sitter to …
tlongwell-block Sep 12, 2025
d12723f
swift support
tlongwell-block Sep 12, 2025
4376956
handle binaries more gracefully
tlongwell-block Sep 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 126 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions crates/goose-mcp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,17 @@ hyper = "1"
serde_with = "3"
which = "6.0"
glob = "0.3"
lru = "0.12"
tree-sitter = "0.21"
tree-sitter-python = "0.21"
tree-sitter-rust = "0.21"
tree-sitter-javascript = "0.21"
tree-sitter-go = "0.21"
tree-sitter-java = "0.21"
tree-sitter-kotlin = "0.3.8"
devgen-tree-sitter-swift = "0.21.0"
streaming-iterator = "0.1"
rayon = "1.10"
# TODO: Fork mpatch or replace with a custom implementation using `similar` crate
# for fuzzy patch matching. Current crate has limited maintenance (single maintainer,
# ~1000 downloads). Pinned to exact version to prevent supply chain attacks.
Expand All @@ -70,6 +81,8 @@ mpatch = "=0.2.0"
serial_test = "3.0.0"
sysinfo = "0.32.1"
temp-env = "0.3.6"
clap = { version = "4", features = ["derive"] }
colored = "2"

[features]
utoipa = ["dep:utoipa"]
86 changes: 86 additions & 0 deletions crates/goose-mcp/src/developer/analyze/cache.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
use lru::LruCache;
use std::num::NonZeroUsize;
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use std::time::SystemTime;

use super::lock_or_recover;
use crate::developer::analyze::types::AnalysisResult;

#[derive(Clone)]
pub struct AnalysisCache {
cache: Arc<Mutex<LruCache<CacheKey, Arc<AnalysisResult>>>>,
#[allow(dead_code)]
max_size: usize,
}

#[derive(Hash, Eq, PartialEq, Debug, Clone)]
struct CacheKey {
path: PathBuf,
modified: SystemTime,
}

impl AnalysisCache {
pub fn new(max_size: usize) -> Self {
tracing::info!("Initializing analysis cache with size {}", max_size);

let size = NonZeroUsize::new(max_size).unwrap_or_else(|| {
tracing::warn!("Invalid cache size {}, using default 100", max_size);
NonZeroUsize::new(100).unwrap()
});

Self {
cache: Arc::new(Mutex::new(LruCache::new(size))),
max_size,
}
}

pub fn get(&self, path: &PathBuf, modified: SystemTime) -> Option<AnalysisResult> {
let mut cache = lock_or_recover(&self.cache, |c| c.clear());
let key = CacheKey {
path: path.clone(),
modified,
};

if let Some(result) = cache.get(&key) {
tracing::trace!("Cache hit for {:?}", path);
Some((**result).clone())
} else {
tracing::trace!("Cache miss for {:?}", path);
None
}
}

pub fn put(&self, path: PathBuf, modified: SystemTime, result: AnalysisResult) {
let mut cache = lock_or_recover(&self.cache, |c| c.clear());
let key = CacheKey {
path: path.clone(),
modified,
};

tracing::trace!("Caching result for {:?}", path);
cache.put(key, Arc::new(result));
}

pub fn clear(&self) {
let mut cache = lock_or_recover(&self.cache, |c| c.clear());
cache.clear();
tracing::debug!("Cache cleared");
}

pub fn len(&self) -> usize {
let cache = lock_or_recover(&self.cache, |c| c.clear());
cache.len()
}

pub fn is_empty(&self) -> bool {
let cache = lock_or_recover(&self.cache, |c| c.clear());
cache.is_empty()
}
}

impl Default for AnalysisCache {
fn default() -> Self {
Self::new(100)
}
}
Loading
Loading