core: Make FileWatcher reusable (#15093)

### Summary
Make `FileWatcher` a reusable core component which can be built upon.
Extract skills-related logic into a separate `SkillWatcher`.
Introduce a composable `ThrottledWatchReceiver` to throttle filesystem
events, coalescing affected paths among them.

### Testing
Updated existing unit tests.
This commit is contained in:
Ruslan Nigmatullin
2026-03-24 11:04:47 -07:00
committed by GitHub
parent bb7e9a8171
commit daf5e584c2
10 changed files with 877 additions and 429 deletions

View File

@@ -2524,7 +2524,7 @@ async fn session_new_fails_when_zsh_fork_enabled_without_zsh_path() {
skills_manager,
plugins_manager,
mcp_manager,
Arc::new(FileWatcher::noop()),
Arc::new(SkillsWatcher::noop()),
AgentControl::default(),
)
.await;
@@ -2623,7 +2623,7 @@ pub(crate) async fn make_session_and_context() -> (Session, TurnContext) {
.expect("create environment"),
);
let file_watcher = Arc::new(FileWatcher::noop());
let skills_watcher = Arc::new(SkillsWatcher::noop());
let services = SessionServices {
mcp_connection_manager: Arc::new(RwLock::new(
McpConnectionManager::new_mcp_connection_manager_for_tests(
@@ -2657,7 +2657,7 @@ pub(crate) async fn make_session_and_context() -> (Session, TurnContext) {
skills_manager,
plugins_manager,
mcp_manager,
file_watcher,
skills_watcher,
agent_control,
network_proxy: None,
network_approval: Arc::clone(&network_approval),
@@ -3458,7 +3458,7 @@ pub(crate) async fn make_session_and_context_with_dynamic_tools_and_rx(
.expect("create environment"),
);
let file_watcher = Arc::new(FileWatcher::noop());
let skills_watcher = Arc::new(SkillsWatcher::noop());
let services = SessionServices {
mcp_connection_manager: Arc::new(RwLock::new(
McpConnectionManager::new_mcp_connection_manager_for_tests(
@@ -3492,7 +3492,7 @@ pub(crate) async fn make_session_and_context_with_dynamic_tools_and_rx(
skills_manager,
plugins_manager,
mcp_manager,
file_watcher,
skills_watcher,
agent_control,
network_proxy: None,
network_approval: Arc::clone(&network_approval),