Skip to repository content
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T00:56:11.710Z Public web read
NIP-34 coordinate
30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omegaMaintainersHidden in public view
References2 branches · 1 tag
Read-only clone
git clone https://openagents.com/git/tenant.openagents/omega.gitRevision diff
24cd026e → 460e04e5diff --git a/crates/settings_ui/src/settings_ui.rs b/crates/settings_ui/src/settings_ui.rs
index 2f577ab7c3..9dc37eacf9 100644
--- a/crates/settings_ui/src/settings_ui.rs
+++ b/crates/settings_ui/src/settings_ui.rs
@@ -2090,6 +2090,16 @@ impl SettingsWindow {
20902090 }));
20912091 }
20922092
2093+ /// Recompute the maintenance rows and wait for nothing.
2094+ ///
2095+ /// The visual test needs the row to be populated at the moment it takes the
2096+ /// picture; production repopulates it on window open, on a settings change,
2097+ /// and after an owner action, none of which a screenshot can wait for.
2098+ #[cfg(any(test, feature = "test-support"))]
2099+ pub fn refresh_harness_maintenance_for_test(&mut self, cx: &mut Context<Self>) {
2100+ self.refresh_harness_maintenance(cx);
2101+ }
2102+
20932103 fn harness_maintenance_target(
20942104 &self,
20952105 id: &project::AgentId,
diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml
index e41a661be9..17355e2c9b 100644
--- a/crates/zed/Cargo.toml
+++ b/crates/zed/Cargo.toml
@@ -51,6 +51,7 @@ visual-tests = [
5151 "fs/test-support",
5252 "recent_projects/test-support",
5353 "title_bar/test-support",
54+ "settings_ui/test-support",
5455 ]
5556
5657 [[bin]]
diff --git a/crates/zed/src/visual_test_runner.rs b/crates/zed/src/visual_test_runner.rs
index 54a4549ec6..d5b89ed8ac 100644
--- a/crates/zed/src/visual_test_runner.rs
+++ b/crates/zed/src/visual_test_runner.rs
@@ -51,6 +51,18 @@ fn main() {
5151 std::env::set_var("ZED_STATELESS", "1");
5252 }
5353
54+ // Redirect every derived data path into a temporary directory. A visual
55+ // test that exercises real on-disk state — omega#81's harness pins and
56+ // receipts do — would otherwise write into the developer's own Omega
57+ // installation. Set before anything can read `data_dir`.
58+ let data_dir = tempfile::tempdir().expect("Failed to create data directory");
59+ paths::set_custom_data_dir(
60+ data_dir
61+ .keep()
62+ .to_str()
63+ .expect("Data directory path is not UTF-8"),
64+ );
65+
5466 env_logger::builder()
5567 .filter_level(log::LevelFilter::Info)
5668 .init();
@@ -625,6 +637,23 @@ fn run_visual_tests(project_path: PathBuf, update_baseline: bool) -> Result<()>
625637 }
626638 }
627639
640+ // Run Test 11: External agent harness maintenance (omega#81)
641+ println!("\n--- Test 11: external_agent_harness_maintenance ---");
642+ match run_external_agent_maintenance_visual_tests(app_state.clone(), &mut cx, update_baseline) {
643+ Ok(TestResult::Passed) => {
644+ println!("\u{2713} external_agent_harness_maintenance: PASSED");
645+ passed += 1;
646+ }
647+ Ok(TestResult::BaselineUpdated(_)) => {
648+ println!("\u{2713} external_agent_harness_maintenance: Baselines updated");
649+ updated += 1;
650+ }
651+ Err(e) => {
652+ eprintln!("\u{2717} external_agent_harness_maintenance: FAILED - {}", e);
653+ failed += 1;
654+ }
655+ }
656+
628657 // Clean up the main workspace's worktree to stop background scanning tasks
629658 // This prevents "root path could not be canonicalized" errors when main() drops temp_dir
630659 workspace_window
@@ -3593,3 +3622,312 @@ fn run_sidebar_duplicate_project_names_visual_tests(
35933622 Ok(TestResult::Passed)
35943623 }
35953624 }
3625+
3626+/// Visual test for harness maintenance on the External Agents settings page.
3627+/// omega#81, `OMEGA-DELTA-0033`.
3628+///
3629+/// The gap omega#81 stayed open for was that every maintenance decision existed
3630+/// and nothing rendered one: a refusal reached the owner only as agent-launch
3631+/// error text, and there was no control to take or remove a pin. So the proof
3632+/// that gap is closed has to be a picture of the row.
3633+///
3634+/// Nothing here is synthetic state handed to a widget. Two registry agents are
3635+/// registered, their installed trees are written to the directories the launch
3636+/// path measures, one is pinned to a different version through the same
3637+/// `pin_installed_harness` the button calls, and the page is then opened and
3638+/// photographed. What the screenshot shows is what the enforcement path
3639+/// decided.
3640+#[cfg(target_os = "macos")]
3641+fn run_external_agent_maintenance_visual_tests(
3642+ app_state: Arc<AppState>,
3643+ cx: &mut VisualTestAppContext,
3644+ update_baseline: bool,
3645+) -> Result<TestResult> {
3646+ use ::collections::HashMap;
3647+ use project::agent_registry_store::{
3648+ AgentRegistryStore, RegistryAgent, RegistryAgentMetadata, RegistryBinaryAgent,
3649+ RegistryTargetConfig,
3650+ };
3651+ use gpui::UpdateGlobal as _;
3652+ use settings::SettingsStore;
3653+
3654+ const HEALTHY: &str = "omega-visual-harness";
3655+ const PINNED: &str = "omega-visual-pinned-harness";
3656+
3657+ let platform_key = format!(
3658+ "{}-{}",
3659+ if cfg!(target_os = "macos") {
3660+ "darwin"
3661+ } else {
3662+ "linux"
3663+ },
3664+ if cfg!(target_arch = "aarch64") {
3665+ "aarch64"
3666+ } else {
3667+ "x86_64"
3668+ }
3669+ );
3670+
3671+ let registry_agent = |id: &str, name: &str, version: &str| {
3672+ let mut targets = HashMap::default();
3673+ targets.insert(
3674+ platform_key.clone(),
3675+ RegistryTargetConfig {
3676+ archive: format!("https://example.invalid/{id}-{version}.tar.gz"),
3677+ cmd: "./harness".to_string(),
3678+ args: vec![],
3679+ sha256: None,
3680+ env: HashMap::default(),
3681+ },
3682+ );
3683+ RegistryAgent::Binary(RegistryBinaryAgent {
3684+ metadata: RegistryAgentMetadata {
3685+ id: AgentId(id.to_string().into()),
3686+ name: name.into(),
3687+ description: "A wrapped ACP harness.".into(),
3688+ version: version.into(),
3689+ repository: None,
3690+ website: None,
3691+ icon_path: None,
3692+ },
3693+ targets,
3694+ supports_current_platform: true,
3695+ })
3696+ };
3697+
3698+ cx.update(|cx| {
3699+ AgentRegistryStore::init_test_global(
3700+ cx,
3701+ vec![
3702+ registry_agent(HEALTHY, "Visual Harness", "1.0.0"),
3703+ // The registry now offers 1.1.0; the pin below freezes 1.0.0,
3704+ // so this row is the refusal an owner has to be able to read.
3705+ registry_agent(PINNED, "Pinned Harness", "1.1.0"),
3706+ ],
3707+ );
3708+ });
3709+
3710+ cx.update(|cx| {
3711+ SettingsStore::update_global(cx, |store: &mut SettingsStore, cx| {
3712+ store.update_user_settings(cx, |content| {
3713+ let agent_servers = content.agent_servers.get_or_insert_default();
3714+ for id in [HEALTHY, PINNED] {
3715+ agent_servers.insert(
3716+ id.to_string(),
3717+ settings::CustomAgentServerSettings::Registry {
3718+ default_mode: None,
3719+ env: Default::default(),
3720+ default_config_options: Default::default(),
3721+ favorite_config_option_values: Default::default(),
3722+ },
3723+ );
3724+ }
3725+ });
3726+ });
3727+ });
3728+
3729+ // `OpenSettingsAt` reuses an open settings window, and an earlier test's
3730+ // window is bound to an earlier test's project — which has no external
3731+ // agents. Close them so the window this test opens is the one it set up.
3732+ let existing: Vec<gpui::AnyWindowHandle> = cx
3733+ .update(|cx| cx.windows())
3734+ .into_iter()
3735+ .filter(|window| window.downcast::<SettingsWindow>().is_some())
3736+ .collect();
3737+ for window in existing {
3738+ cx.update_window(window, |_, window, _cx| {
3739+ window.remove_window();
3740+ })
3741+ .log_err();
3742+ }
3743+ cx.run_until_parked();
3744+
3745+ let window_size = size(px(900.0), px(700.0));
3746+ let bounds = Bounds {
3747+ origin: point(px(0.0), px(0.0)),
3748+ size: window_size,
3749+ };
3750+
3751+ let project = cx.update(|cx| {
3752+ project::Project::local(
3753+ app_state.client.clone(),
3754+ app_state.node_runtime.clone(),
3755+ app_state.user_store.clone(),
3756+ app_state.languages.clone(),
3757+ app_state.fs.clone(),
3758+ None,
3759+ project::LocalProjectFlags {
3760+ init_worktree_trust: false,
3761+ ..Default::default()
3762+ },
3763+ cx,
3764+ )
3765+ });
3766+
3767+ cx.run_until_parked();
3768+
3769+ // The store owns the derivation of the measured tree, so the test asks it
3770+ // rather than re-deriving one. A test that guessed the directory would
3771+ // prove a row about a tree the launch path never looks at.
3772+ let targets: Vec<(String, PathBuf, String)> = cx.update(|cx| {
3773+ let store = project.read(cx).agent_server_store().clone();
3774+ let store = store.read(cx);
3775+ [HEALTHY, PINNED]
3776+ .into_iter()
3777+ .filter_map(|id| {
3778+ let target = store.maintenance_target(&AgentId(id.to_string().into()))?;
3779+ Some((
3780+ id.to_string(),
3781+ target.installed_dir?,
3782+ target.version.to_string(),
3783+ ))
3784+ })
3785+ .collect()
3786+ });
3787+ anyhow::ensure!(
3788+ targets.len() == 2,
3789+ "the store did not offer a maintenance target for both registry agents"
3790+ );
3791+
3792+ for (_, dir, version) in &targets {
3793+ std::fs::create_dir_all(dir)?;
3794+ std::fs::write(dir.join("harness"), format!("harness {version}"))?;
3795+ std::fs::write(dir.join("LICENSE"), b"Apache-2.0")?;
3796+ }
3797+
3798+ // Attest the healthy one and freeze the other, through the production
3799+ // functions the settings buttons call.
3800+ let fs = app_state.fs.clone();
3801+ let healthy = targets[0].clone();
3802+ let pinned = targets[1].clone();
3803+ // Driven on the test executor rather than by blocking this thread: the
3804+ // filesystem work these functions do is scheduled by that executor, so
3805+ // blocking the thread it runs on deadlocks instead of waiting.
3806+ // `RealFs` does its work on real IO threads, so the deterministic scheduler
3807+ // has to be allowed to park while it waits for them. This test runs last.
3808+ cx.executor().allow_parking();
3809+
3810+ let outcome: Arc<std::sync::Mutex<Option<Result<()>>>> =
3811+ Arc::new(std::sync::Mutex::new(None));
3812+ let setup = cx.update(|cx| {
3813+ let outcome = outcome.clone();
3814+ cx.background_spawn(async move {
3815+ let result = async {
3816+ project::harness_maintenance::reprobe_installed_harness(
3817+ fs.clone(),
3818+ &healthy.0,
3819+ &healthy.2,
3820+ &healthy.1,
3821+ 1_784_894_400_000,
3822+ )
3823+ .await?;
3824+ project::harness_maintenance::pin_installed_harness(
3825+ fs.clone(),
3826+ &pinned.0,
3827+ // Frozen at 1.0.0 while the registry advertises 1.1.0.
3828+ "1.0.0",
3829+ &pinned.1,
3830+ 1_784_894_400_001,
3831+ )
3832+ .await?;
3833+ anyhow::Ok(())
3834+ }
3835+ .await;
3836+ *outcome.lock().unwrap() = Some(result);
3837+ })
3838+ });
3839+ for _ in 0..200 {
3840+ cx.run_until_parked();
3841+ if outcome.lock().unwrap().is_some() {
3842+ break;
3843+ }
3844+ std::thread::sleep(Duration::from_millis(20));
3845+ }
3846+ setup.detach();
3847+ match outcome.lock().unwrap().take() {
3848+ Some(Ok(())) => {}
3849+ Some(Err(error)) => return Err(error).context("preparing harness maintenance state"),
3850+ None => anyhow::bail!("harness maintenance setup did not finish"),
3851+ }
3852+
3853+ let workspace_window: WindowHandle<MultiWorkspace> = cx
3854+ .update(|cx| {
3855+ cx.open_window(
3856+ WindowOptions {
3857+ window_bounds: Some(WindowBounds::Windowed(bounds)),
3858+ focus: false,
3859+ show: false,
3860+ ..Default::default()
3861+ },
3862+ |window, cx| {
3863+ let workspace = cx.new(|cx| {
3864+ Workspace::new(None, project.clone(), app_state.clone(), window, cx)
3865+ });
3866+ cx.new(|cx| MultiWorkspace::new(workspace, window, cx))
3867+ },
3868+ )
3869+ })
3870+ .context("Failed to open workspace window for external agents test")?;
3871+
3872+ cx.run_until_parked();
3873+
3874+ workspace_window
3875+ .update(cx, |_workspace, window, cx| {
3876+ window.dispatch_action(
3877+ Box::new(OpenSettingsAt {
3878+ path: "agent_servers".to_string(),
3879+ target: None,
3880+ }),
3881+ cx,
3882+ );
3883+ })
3884+ .context("Failed to dispatch OpenSettingsAt for external agents")?;
3885+
3886+ cx.run_until_parked();
3887+ for _ in 0..10 {
3888+ cx.advance_clock(Duration::from_millis(50));
3889+ cx.run_until_parked();
3890+ }
3891+
3892+ // Earlier tests leave their own settings windows open, so "the newest
3893+ // window" is not reliably this test's. Take the newest one that is a
3894+ // settings window.
3895+ let all_windows = cx.update(|cx| cx.windows());
3896+ let (settings_window, settings_window_handle) = all_windows
3897+ .iter()
3898+ .rev()
3899+ .find_map(|window| Some((*window, window.downcast::<SettingsWindow>()?)))
3900+ .context("No settings window found")?;
3901+
3902+ settings_window_handle
3903+ .update(cx, |settings_window, window, cx| {
3904+ settings_window.navigate_to_sub_page("agent_servers", window, cx);
3905+ settings_window.refresh_harness_maintenance_for_test(cx);
3906+ })
3907+ .context("Failed to navigate to the External Agents sub-page")?;
3908+
3909+ cx.run_until_parked();
3910+ for _ in 0..20 {
3911+ cx.advance_clock(Duration::from_millis(50));
3912+ cx.run_until_parked();
3913+ }
3914+
3915+ let result = run_visual_test(
3916+ "external_agent_harness_maintenance",
3917+ settings_window,
3918+ cx,
3919+ update_baseline,
3920+ )?;
3921+
3922+ cx.update_window(settings_window, |_, window, _cx| {
3923+ window.remove_window();
3924+ })
3925+ .log_err();
3926+ cx.update_window(workspace_window.into(), |_, window, _cx| {
3927+ window.remove_window();
3928+ })
3929+ .log_err();
3930+ cx.run_until_parked();
3931+
3932+ Ok(result)
3933+}