first pass of merging in warp (doesn't build)

This commit is contained in:
Ryan Ward
2026-07-01 16:08:58 -05:00
parent 2f64909469
commit 4770ac06b5
3662 changed files with 414574 additions and 89772 deletions
+225
View File
@@ -0,0 +1,225 @@
use repo_metadata::repositories::DetectedRepositories;
use repo_metadata::{DirectoryWatcher, RepoMetadataModel};
use warpui::App;
use watcher::HomeDirectoryWatcher;
use super::*;
use crate::settings::AISettings;
use crate::warp_managed_paths_watcher::WarpManagedPathsWatcher;
fn bundled_skill(
id: &str,
path: &str,
content: &str,
requires_mcp: Option<&str>,
) -> RemoteSkillProto {
RemoteSkillProto {
path: path.to_string(),
content: content.to_string(),
source: Some(remote_skill_proto::Source::Bundled(
remote_server::proto::BundledSkillMetadata {
id: id.to_string(),
requires_mcp: requires_mcp.map(str::to_string),
},
)),
}
}
fn home_skill(path: &str, content: &str) -> RemoteSkillProto {
RemoteSkillProto {
path: path.to_string(),
content: content.to_string(),
source: Some(remote_skill_proto::Source::Home(
remote_server::proto::HomeSkillMetadata {},
)),
}
}
fn rule(path: &str, content: &str) -> RemoteContextFileProto {
RemoteContextFileProto {
path: path.to_string(),
content: content.to_string(),
}
}
fn snapshot() -> RemoteAgentContextSnapshot {
RemoteAgentContextSnapshot {
revision: 7,
home_dir: "/home/user".to_string(),
skills: vec![
bundled_skill(
"bundled",
"/bundled/skills/bundled/SKILL.md",
"---\nname: bundled\ndescription: Bundled skill\n---\nbody",
None,
),
bundled_skill(
"unknown-mcp",
"/bundled/skills/unknown/SKILL.md",
"# unknown",
Some("unknown"),
),
home_skill(
"/home/user/.agents/skills/deploy/SKILL.md",
"---\nname: deploy\ndescription: Deploy things\n---\nbody",
),
home_skill("/repo/.agents/skills/project/SKILL.md", "outside home"),
home_skill("/home/user/not-a-skill.md", "unknown provider"),
],
global_rules: vec![
rule("/home/user/.agents/AGENTS.md", "global rule"),
rule("/repo/AGENTS.md", "outside home"),
],
}
}
fn setup_context_models(app: &mut App) {
app.add_singleton_model(DirectoryWatcher::new);
app.add_singleton_model(AISettings::new_with_defaults);
app.add_singleton_model(|_| DetectedRepositories::default());
app.add_singleton_model(RepoMetadataModel::new);
app.add_singleton_model(HomeDirectoryWatcher::new_for_test);
app.add_singleton_model(WarpManagedPathsWatcher::new_for_testing);
app.add_singleton_model(SkillManager::new);
app.add_singleton_model(|_| ProjectContextModel::default());
}
#[test]
fn snapshot_decoding_keeps_valid_context_from_each_source() {
let _bundled_skills = FeatureFlag::BundledSkills.override_enabled(true);
let host_id = HostId::new("remote-host".to_string());
let state = parse_snapshot(&host_id, snapshot());
let bundled = state.bundled_skills.unwrap();
let home = state.home_skills.unwrap();
assert_eq!(bundled.skill("bundled").unwrap().name, "bundled");
assert!(bundled.skill("unknown-mcp").is_none());
assert_eq!(home.home_dir, remote_path(&host_id, "/home/user").unwrap());
assert_eq!(home.skills.len(), 1);
assert_eq!(home.skills[0].name, "deploy");
assert_eq!(home.skills[0].provider, SkillProvider::Agents);
assert_eq!(home.skills[0].scope, SkillScope::Home);
assert_eq!(state.global_rules.len(), 1);
assert_eq!(state.global_rules[0].content, "global rule");
for path in home
.skills
.iter()
.map(|skill| &skill.path)
.chain(state.global_rules.iter().map(|rule| &rule.path))
{
assert_eq!(path.as_remote().unwrap().host_id, host_id);
assert!(path.starts_with(&home.home_dir));
}
}
#[test]
fn invalid_home_directory_drops_only_home_context() {
let _bundled_skills = FeatureFlag::BundledSkills.override_enabled(true);
let host_id = HostId::new("remote-host".to_string());
let mut snapshot = snapshot();
snapshot.home_dir = "relative/home".to_string();
let state = parse_snapshot(&host_id, snapshot);
assert!(state.bundled_skills.unwrap().skill("bundled").is_some());
assert!(state.home_skills.is_none());
assert!(state.global_rules.is_empty());
}
#[test]
fn reconcile_snapshot_fully_replaces_all_host_context() {
let _bundled_skills = FeatureFlag::BundledSkills.override_enabled(true);
let host_id = HostId::new("remote-host".to_string());
let bundled_path = remote_path(&host_id, "/bundled/skills/bundled/SKILL.md").unwrap();
let home_path = remote_path(&host_id, "/home/user/.agents/skills/deploy/SKILL.md").unwrap();
App::test((), |mut app| async move {
setup_context_models(&mut app);
let skills = SkillManager::handle(&app);
let rules = ProjectContextModel::handle(&app);
let context = app.add_singleton_model(|_| RemoteAgentContext);
context.update(&mut app, |context, ctx| {
context.reconcile_snapshot(host_id.clone(), snapshot(), ctx);
});
skills.read(&app, |manager, _| {
assert!(manager.skill_by_path(&bundled_path).is_some());
assert!(manager.skill_by_path(&home_path).is_some());
});
rules.read(&app, |model, _| {
assert_eq!(
model
.find_applicable_rules(&remote_path(&host_id, "/repo").unwrap())
.unwrap()
.active_rules[0]
.content,
"global rule"
);
});
context.update(&mut app, |context, ctx| {
context.reconcile_snapshot(
host_id.clone(),
RemoteAgentContextSnapshot {
revision: 8,
home_dir: "/home/user".to_string(),
skills: Vec::new(),
global_rules: Vec::new(),
},
ctx,
);
});
skills.read(&app, |manager, _| {
assert!(manager.skill_by_path(&bundled_path).is_none());
assert!(manager.skill_by_path(&home_path).is_none());
});
rules.read(&app, |model, _| {
assert!(model
.find_applicable_rules(&remote_path(&host_id, "/repo").unwrap())
.is_none());
});
});
}
#[test]
fn remove_host_context_clears_only_the_matching_host() {
let _bundled_skills = FeatureFlag::BundledSkills.override_enabled(true);
let first_host = HostId::new("first-host".to_string());
let second_host = HostId::new("second-host".to_string());
let first_bundled_path = remote_path(&first_host, "/bundled/skills/bundled/SKILL.md").unwrap();
let second_bundled_path =
remote_path(&second_host, "/bundled/skills/bundled/SKILL.md").unwrap();
App::test((), |mut app| async move {
setup_context_models(&mut app);
let skills = SkillManager::handle(&app);
let rules = ProjectContextModel::handle(&app);
let context = app.add_singleton_model(|_| RemoteAgentContext);
for host_id in [&first_host, &second_host] {
context.update(&mut app, |context, ctx| {
context.reconcile_snapshot(host_id.clone(), snapshot(), ctx);
});
}
context.update(&mut app, |context, ctx| {
context.remove_host_context(&first_host, ctx);
});
skills.read(&app, |manager, _| {
assert!(manager.skill_by_path(&first_bundled_path).is_none());
assert!(manager.skill_by_path(&second_bundled_path).is_some());
});
rules.read(&app, |model, _| {
assert!(model
.find_applicable_rules(&remote_path(&first_host, "/repo").unwrap())
.is_none());
assert_eq!(
model
.find_applicable_rules(&remote_path(&second_host, "/repo").unwrap())
.unwrap()
.active_rules[0]
.content,
"global rule"
);
});
});
}