Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T03:59:25.354Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

store.rs

426 lines · 14.9 KB · rust
1use std::any::TypeId;
2use std::sync::Arc;
3
4use collections::HashMap;
5use fs::Fs;
6use gpui::{App, BorrowAppContext, Subscription};
7use settings::{Settings, SettingsStore, update_settings_file};
8
9use crate::{FeatureFlag, FeatureFlagValue, FeatureFlagsSettings, ZED_DISABLE_STAFF};
10
11pub struct FeatureFlagDescriptor {
12    pub name: &'static str,
13    pub variants: fn() -> Vec<FeatureFlagVariant>,
14    pub on_variant_key: fn() -> &'static str,
15    pub default_variant_key: fn() -> &'static str,
16    pub enabled_for_all: fn() -> bool,
17    pub enabled_for_staff: fn() -> bool,
18    pub type_id: fn() -> TypeId,
19}
20
21#[derive(Clone, Debug, PartialEq, Eq)]
22pub struct FeatureFlagVariant {
23    pub override_key: &'static str,
24    pub label: &'static str,
25}
26
27inventory::collect!(FeatureFlagDescriptor);
28
29#[doc(hidden)]
30pub mod __private {
31    pub use inventory;
32}
33
34/// Submits a [`FeatureFlagDescriptor`] for this flag so it shows up in the
35/// configuration UI and in `FeatureFlagStore::known_flags()`.
36#[macro_export]
37macro_rules! register_feature_flag {
38    ($flag:ty) => {
39        $crate::__private::inventory::submit! {
40            $crate::FeatureFlagDescriptor {
41                name: <$flag as $crate::FeatureFlag>::NAME,
42                variants: || {
43                    <<$flag as $crate::FeatureFlag>::Value as $crate::FeatureFlagValue>::all_variants()
44                        .iter()
45                        .map(|v| $crate::FeatureFlagVariant {
46                            override_key: <<$flag as $crate::FeatureFlag>::Value as $crate::FeatureFlagValue>::override_key(v),
47                            label: <<$flag as $crate::FeatureFlag>::Value as $crate::FeatureFlagValue>::label(v),
48                        })
49                        .collect()
50                },
51                on_variant_key: || {
52                    <<$flag as $crate::FeatureFlag>::Value as $crate::FeatureFlagValue>::override_key(
53                        &<<$flag as $crate::FeatureFlag>::Value as $crate::FeatureFlagValue>::on_variant(),
54                    )
55                },
56                default_variant_key: || {
57                    <<$flag as $crate::FeatureFlag>::Value as $crate::FeatureFlagValue>::override_key(
58                        &<<$flag as $crate::FeatureFlag>::Value as ::std::default::Default>::default(),
59                    )
60                },
61                enabled_for_all: <$flag as $crate::FeatureFlag>::enabled_for_all,
62                enabled_for_staff: <$flag as $crate::FeatureFlag>::enabled_for_staff,
63                type_id: || std::any::TypeId::of::<$flag>(),
64            }
65        }
66    };
67}
68
69#[derive(Default)]
70pub struct FeatureFlagStore {
71    staff: bool,
72    server_flags: HashMap<String, String>,
73    server_flags_received: bool,
74
75    _settings_subscription: Option<Subscription>,
76}
77
78impl FeatureFlagStore {
79    pub fn init(cx: &mut App) {
80        let subscription = cx.observe_global::<SettingsStore>(|cx| {
81            // Touch the global so anything observing `FeatureFlagStore` re-runs
82            cx.update_default_global::<FeatureFlagStore, _>(|_, _| {});
83        });
84
85        cx.update_default_global::<FeatureFlagStore, _>(|store, _| {
86            store._settings_subscription = Some(subscription);
87        });
88    }
89
90    pub fn known_flags() -> impl Iterator<Item = &'static FeatureFlagDescriptor> {
91        let mut seen = collections::HashSet::default();
92        inventory::iter::<FeatureFlagDescriptor>().filter(move |d| seen.insert((d.type_id)()))
93    }
94
95    pub fn is_staff(&self) -> bool {
96        self.staff
97    }
98
99    /// Whether feature flag overrides from settings should be honored.
100    ///
101    /// Overrides are a staff-only affordance, so non-staff users in release
102    /// builds can't flip flags through `settings.json` or the settings UI.
103    /// Debug builds are always treated as staff, and `ZED_DISABLE_STAFF`
104    /// forces the user to be treated as non-staff for testing.
105    pub fn overrides_enabled(&self) -> bool {
106        (cfg!(debug_assertions) || self.staff) && !*ZED_DISABLE_STAFF
107    }
108
109    pub fn server_flags_received(&self) -> bool {
110        self.server_flags_received
111    }
112
113    pub fn set_staff(&mut self, staff: bool) {
114        self.staff = staff;
115    }
116
117    pub fn update_server_flags(&mut self, staff: bool, flags: Vec<String>) {
118        self.staff = staff;
119        self.server_flags_received = true;
120        self.server_flags.clear();
121        for flag in flags {
122            self.server_flags.insert(flag.clone(), flag);
123        }
124    }
125
126    /// The user's override key for this flag, read directly from
127    /// [`FeatureFlagsSettings`].
128    pub fn override_for<'a>(flag_name: &str, cx: &'a App) -> Option<&'a str> {
129        FeatureFlagsSettings::get_global(cx)
130            .overrides
131            .get(flag_name)
132            .map(String::as_str)
133    }
134
135    /// Applies an override by writing to `settings.json`. The store's own
136    /// `overrides` field will be updated when the settings-store observer
137    /// fires. Pass the [`FeatureFlagValue::override_key`] of the variant
138    /// you want forced.
139    pub fn set_override(flag_name: &str, override_key: String, fs: Arc<dyn Fs>, cx: &App) {
140        let flag_name = flag_name.to_owned();
141        update_settings_file(fs, cx, move |content, _| {
142            content
143                .feature_flags
144                .get_or_insert_default()
145                .insert(flag_name, override_key);
146        });
147    }
148
149    /// Removes any override for the given flag from `settings.json`. Leaves
150    /// an empty `"feature_flags"` object rather than removing the key
151    /// entirely so the user can see it's still a meaningful settings surface.
152    pub fn clear_override(flag_name: &str, fs: Arc<dyn Fs>, cx: &App) {
153        let flag_name = flag_name.to_owned();
154        update_settings_file(fs, cx, move |content, _| {
155            if let Some(map) = content.feature_flags.as_mut() {
156                map.remove(&flag_name);
157            }
158        });
159    }
160
161    /// The resolved value of the flag for the current user, taking overrides,
162    /// `enabled_for_all`, staff rules, and server flags into account in that
163    /// order of precedence. Overrides are read directly from
164    /// [`FeatureFlagsSettings`].
165    pub fn try_flag_value<T: FeatureFlag>(&self, cx: &App) -> Option<T::Value> {
166        // `enabled_for_all` always wins, including over user overrides.
167        if T::enabled_for_all() {
168            return Some(T::Value::on_variant());
169        }
170
171        // Only apply overrides when they are specifically enabled.
172        if self.overrides_enabled() {
173            if let Some(override_key) = FeatureFlagsSettings::get_global(cx).overrides.get(T::NAME)
174            {
175                return variant_from_key::<T::Value>(override_key);
176            }
177        }
178
179        // Staff default: resolve to the enabled variant.
180        if (cfg!(debug_assertions) || self.staff) && !*ZED_DISABLE_STAFF && T::enabled_for_staff() {
181            return Some(T::Value::on_variant());
182        }
183
184        // Server-delivered flag.
185        if let Some(wire) = self.server_flags.get(T::NAME) {
186            return T::Value::from_wire(wire);
187        }
188
189        None
190    }
191
192    /// Whether the flag resolves to its "on" value. Best for presence-style
193    /// flags. For enum flags with meaningful non-default variants, prefer
194    /// [`crate::FeatureFlagAppExt::flag_value`].
195    pub fn has_flag<T: FeatureFlag>(&self, cx: &App) -> bool {
196        self.try_flag_value::<T>(cx)
197            .is_some_and(|v| v == T::Value::on_variant())
198    }
199
200    /// Mirrors the resolution order of [`Self::try_flag_value`], but falls
201    /// back to the [`Default`] variant when no rule applies so the UI always
202    /// shows *something* selected — matching what
203    /// [`crate::FeatureFlagAppExt::flag_value`] would return.
204    pub fn resolved_key(&self, descriptor: &FeatureFlagDescriptor, cx: &App) -> &'static str {
205        let on_variant_key = (descriptor.on_variant_key)();
206
207        if (descriptor.enabled_for_all)() {
208            return on_variant_key;
209        }
210
211        // Only apply overrides when they are specifically enabled.
212        if self.overrides_enabled() {
213            if let Some(requested) = FeatureFlagsSettings::get_global(cx)
214                .overrides
215                .get(descriptor.name)
216            {
217                if let Some(variant) = (descriptor.variants)()
218                    .into_iter()
219                    .find(|v| v.override_key == requested.as_str())
220                {
221                    return variant.override_key;
222                }
223            }
224        }
225
226        if (cfg!(debug_assertions) || self.staff)
227            && !*ZED_DISABLE_STAFF
228            && (descriptor.enabled_for_staff)()
229        {
230            return on_variant_key;
231        }
232
233        if self.server_flags.contains_key(descriptor.name) {
234            return on_variant_key;
235        }
236
237        (descriptor.default_variant_key)()
238    }
239
240    /// Whether this flag is forced on by `enabled_for_all` and therefore not
241    /// user-overridable. The UI uses this to render the row as disabled.
242    pub fn is_forced_on(descriptor: &FeatureFlagDescriptor) -> bool {
243        (descriptor.enabled_for_all)()
244    }
245
246    /// Fallback used when the store isn't installed as a global yet (e.g. very
247    /// early in startup). Matches the pre-existing default behavior.
248    pub fn has_flag_default<T: FeatureFlag>() -> bool {
249        if T::enabled_for_all() {
250            return true;
251        }
252        cfg!(debug_assertions) && T::enabled_for_staff() && !*ZED_DISABLE_STAFF
253    }
254}
255
256fn variant_from_key<V: FeatureFlagValue>(key: &str) -> Option<V> {
257    V::all_variants()
258        .iter()
259        .find(|v| v.override_key() == key)
260        .cloned()
261}
262
263#[cfg(test)]
264mod tests {
265    use super::*;
266    use crate::{EnumFeatureFlag, FeatureFlag, PresenceFlag};
267    use gpui::UpdateGlobal;
268    use settings::SettingsStore;
269
270    struct DemoFlag;
271    impl FeatureFlag for DemoFlag {
272        const NAME: &'static str = "demo";
273        type Value = PresenceFlag;
274        fn enabled_for_staff() -> bool {
275            false
276        }
277    }
278
279    #[derive(Clone, Copy, PartialEq, Eq, Debug, EnumFeatureFlag)]
280    enum Intensity {
281        #[default]
282        Low,
283        High,
284    }
285
286    struct IntensityFlag;
287    impl FeatureFlag for IntensityFlag {
288        const NAME: &'static str = "intensity";
289        type Value = Intensity;
290        fn enabled_for_all() -> bool {
291            true
292        }
293    }
294
295    fn init_settings_store(cx: &mut App) {
296        let store = SettingsStore::test(cx);
297        cx.set_global(store);
298        SettingsStore::update_global(cx, |store, _| {
299            store.register_setting::<FeatureFlagsSettings>();
300        });
301    }
302
303    fn set_override(name: &str, value: &str, cx: &mut App) {
304        SettingsStore::update_global(cx, |store: &mut SettingsStore, cx| {
305            store.update_user_settings(cx, |content| {
306                content
307                    .feature_flags
308                    .get_or_insert_default()
309                    .insert(name.to_string(), value.to_string());
310            });
311        });
312    }
313
314    #[gpui::test]
315    fn server_flag_enables_presence(cx: &mut App) {
316        init_settings_store(cx);
317        let mut store = FeatureFlagStore::default();
318        assert!(!store.has_flag::<DemoFlag>(cx));
319        store.update_server_flags(false, vec!["demo".to_string()]);
320        assert!(store.has_flag::<DemoFlag>(cx));
321    }
322
323    #[gpui::test]
324    fn off_override_beats_server_flag(cx: &mut App) {
325        init_settings_store(cx);
326        let mut store = FeatureFlagStore::default();
327        store.update_server_flags(false, vec!["demo".to_string()]);
328        set_override(DemoFlag::NAME, "off", cx);
329        assert!(!store.has_flag::<DemoFlag>(cx));
330        assert_eq!(
331            store.try_flag_value::<DemoFlag>(cx),
332            Some(PresenceFlag::Off)
333        );
334    }
335
336    #[gpui::test]
337    fn enabled_for_all_wins_over_override(cx: &mut App) {
338        init_settings_store(cx);
339        let store = FeatureFlagStore::default();
340        set_override(IntensityFlag::NAME, "high", cx);
341        assert_eq!(
342            store.try_flag_value::<IntensityFlag>(cx),
343            Some(Intensity::Low)
344        );
345    }
346
347    #[gpui::test]
348    fn enum_override_selects_specific_variant(cx: &mut App) {
349        init_settings_store(cx);
350        let store = FeatureFlagStore::default();
351        // Staff path would normally resolve to `Low`; the override pushes
352        // us to `High` instead.
353        set_override("enum-demo", "high", cx);
354
355        struct EnumDemo;
356        impl FeatureFlag for EnumDemo {
357            const NAME: &'static str = "enum-demo";
358            type Value = Intensity;
359        }
360
361        assert_eq!(store.try_flag_value::<EnumDemo>(cx), Some(Intensity::High));
362    }
363
364    #[gpui::test]
365    fn unknown_variant_key_resolves_to_none(cx: &mut App) {
366        init_settings_store(cx);
367        let store = FeatureFlagStore::default();
368        set_override("enum-demo", "nonsense", cx);
369
370        struct EnumDemo;
371        impl FeatureFlag for EnumDemo {
372            const NAME: &'static str = "enum-demo";
373            type Value = Intensity;
374        }
375
376        assert_eq!(store.try_flag_value::<EnumDemo>(cx), None);
377    }
378
379    #[gpui::test]
380    fn on_override_enables_without_server_or_staff(cx: &mut App) {
381        init_settings_store(cx);
382        let store = FeatureFlagStore::default();
383        set_override(DemoFlag::NAME, "on", cx);
384        assert!(store.has_flag::<DemoFlag>(cx));
385    }
386
387    /// No rule applies, so the store's `try_flag_value` returns `None`. The
388    /// `FeatureFlagAppExt::flag_value` path (used by most callers) falls
389    /// back to [`Default`], which for `PresenceFlag` is `Off`.
390    #[gpui::test]
391    fn presence_flag_defaults_to_off(cx: &mut App) {
392        init_settings_store(cx);
393        let store = FeatureFlagStore::default();
394        assert_eq!(store.try_flag_value::<DemoFlag>(cx), None);
395        assert_eq!(PresenceFlag::default(), PresenceFlag::Off);
396    }
397
398    #[gpui::test]
399    fn on_flags_ready_waits_for_server_flags(cx: &mut gpui::TestAppContext) {
400        use crate::FeatureFlagAppExt;
401        use std::cell::Cell;
402        use std::rc::Rc;
403
404        cx.update(|cx| {
405            init_settings_store(cx);
406            FeatureFlagStore::init(cx);
407        });
408
409        let fired = Rc::new(Cell::new(false));
410        cx.update({
411            let fired = fired.clone();
412            |cx| cx.on_flags_ready(move |_, _| fired.set(true)).detach()
413        });
414
415        // Settings-triggered no-op touch must not fire on_flags_ready.
416        cx.update(|cx| cx.update_default_global::<FeatureFlagStore, _>(|_, _| {}));
417        cx.run_until_parked();
418        assert!(!fired.get());
419
420        // Server flags arrive — now it should fire.
421        cx.update(|cx| cx.update_flags(true, vec![]));
422        cx.run_until_parked();
423        assert!(fired.get());
424    }
425}
426
Served at tenant.openagents/omega Member data and write actions are omitted.