Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T01:50:17.648Z 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

feature_flags.rs

297 lines · 9.7 KB · rust
1// Makes the derive macro's reference to `::feature_flags::FeatureFlagValue`
2// resolve when the macro is invoked inside this crate itself.
3extern crate self as feature_flags;
4
5mod flags;
6mod settings;
7mod store;
8
9use std::cell::RefCell;
10use std::rc::Rc;
11use std::sync::LazyLock;
12
13use gpui::{App, Context, Global, Subscription, Window};
14
15pub use feature_flags_macros::EnumFeatureFlag;
16pub use flags::*;
17pub use settings::{FeatureFlagsSettings, generate_feature_flags_schema};
18pub use store::*;
19
20pub static ZED_DISABLE_STAFF: LazyLock<bool> = LazyLock::new(|| {
21    std::env::var("ZED_DISABLE_STAFF").is_ok_and(|value| !value.is_empty() && value != "0")
22});
23
24impl Global for FeatureFlagStore {}
25
26pub trait FeatureFlagValue:
27    Sized + Clone + Eq + Default + std::fmt::Debug + Send + Sync + 'static
28{
29    /// Every possible value for this flag, in the order the UI should display them.
30    fn all_variants() -> &'static [Self];
31
32    /// A stable identifier for this variant used when persisting overrides.
33    fn override_key(&self) -> &'static str;
34
35    fn from_wire(wire: &str) -> Option<Self>;
36
37    /// Human-readable label for use in the configuration UI.
38    fn label(&self) -> &'static str {
39        self.override_key()
40    }
41
42    /// The variant that represents "on" — what the store resolves to when
43    /// staff rules, `enabled_for_all`, or a server announcement apply.
44    ///
45    /// For enum flags this is usually the same as [`Default::default`] (the
46    /// variant marked `#[default]` in the derive). [`PresenceFlag`] overrides
47    /// this so that `default() == Off` (the "unconfigured" state) but
48    /// `on_variant() == On` (the "enabled" state).
49    fn on_variant() -> Self {
50        Self::default()
51    }
52}
53
54/// Default value type for simple on/off feature flags.
55///
56/// The fallback value is [`PresenceFlag::Off`] so that an absent / unknown
57/// flag reads as disabled; the `on_variant` override pins the "enabled"
58/// state to [`PresenceFlag::On`] so staff / server / `enabled_for_all`
59/// resolution still lights the flag up.
60#[derive(Clone, Copy, Default, PartialEq, Eq, Debug)]
61pub enum PresenceFlag {
62    On,
63    #[default]
64    Off,
65}
66
67/// Presence flags deref to a `bool` so call sites can use `if *flag` without
68/// spelling out the enum variant — or pass them anywhere a `&bool` is wanted.
69impl std::ops::Deref for PresenceFlag {
70    type Target = bool;
71
72    fn deref(&self) -> &bool {
73        match self {
74            PresenceFlag::On => &true,
75            PresenceFlag::Off => &false,
76        }
77    }
78}
79
80impl FeatureFlagValue for PresenceFlag {
81    fn all_variants() -> &'static [Self] {
82        &[PresenceFlag::On, PresenceFlag::Off]
83    }
84
85    fn override_key(&self) -> &'static str {
86        match self {
87            PresenceFlag::On => "on",
88            PresenceFlag::Off => "off",
89        }
90    }
91
92    fn label(&self) -> &'static str {
93        match self {
94            PresenceFlag::On => "On",
95            PresenceFlag::Off => "Off",
96        }
97    }
98
99    fn from_wire(_: &str) -> Option<Self> {
100        Some(PresenceFlag::On)
101    }
102
103    fn on_variant() -> Self {
104        PresenceFlag::On
105    }
106}
107
108/// To create a feature flag, implement this trait on a trivial type and use it as
109/// a generic parameter when called [`FeatureFlagAppExt::has_flag`].
110///
111/// Feature flags are enabled for members of Zed staff by default. To disable this behavior
112/// so you can test flags being disabled, set ZED_DISABLE_STAFF=1 in your environment,
113/// which will force Zed to treat the current user as non-staff.
114pub trait FeatureFlag {
115    const NAME: &'static str;
116
117    /// The type of value this flag can hold. Use [`PresenceFlag`] for simple
118    /// on/off flags.
119    type Value: FeatureFlagValue;
120
121    /// Returns whether this feature flag is enabled for Zed staff.
122    fn enabled_for_staff() -> bool {
123        true
124    }
125
126    /// Returns whether this feature flag is enabled for everyone.
127    ///
128    /// This is generally done on the server, but we provide this as a way to entirely enable a feature flag client-side
129    /// without needing to remove all of the call sites.
130    fn enabled_for_all() -> bool {
131        false
132    }
133
134    /// Subscribes the current view to changes in the feature flag store, so
135    /// that any mutation of flags or overrides will trigger a re-render.
136    ///
137    /// The returned subscription is immediately detached; use [`observe_flag`]
138    /// directly if you need to hold onto the subscription.
139    fn watch<V: 'static>(cx: &mut Context<V>) {
140        cx.observe_global::<FeatureFlagStore>(|_, cx| cx.notify())
141            .detach();
142    }
143}
144
145pub trait FeatureFlagViewExt<V: 'static> {
146    /// Fires the callback whenever the resolved [`T::Value`] transitions.
147    fn observe_flag<T: FeatureFlag, F>(&mut self, window: &Window, callback: F) -> Subscription
148    where
149        F: Fn(T::Value, &mut V, &mut Window, &mut Context<V>) + Send + Sync + 'static;
150
151    fn when_flag_enabled<T: FeatureFlag>(
152        &mut self,
153        window: &mut Window,
154        callback: impl Fn(&mut V, &mut Window, &mut Context<V>) + Send + Sync + 'static,
155    );
156}
157
158impl<V> FeatureFlagViewExt<V> for Context<'_, V>
159where
160    V: 'static,
161{
162    fn observe_flag<T: FeatureFlag, F>(&mut self, window: &Window, callback: F) -> Subscription
163    where
164        F: Fn(T::Value, &mut V, &mut Window, &mut Context<V>) + 'static,
165    {
166        let mut last_value: Option<T::Value> = None;
167        self.observe_global_in::<FeatureFlagStore>(window, move |v, window, cx| {
168            let value = cx.flag_value::<T>();
169            if last_value.as_ref() == Some(&value) {
170                return;
171            }
172            last_value = Some(value.clone());
173            callback(value, v, window, cx);
174        })
175    }
176
177    fn when_flag_enabled<T: FeatureFlag>(
178        &mut self,
179        window: &mut Window,
180        callback: impl Fn(&mut V, &mut Window, &mut Context<V>) + Send + Sync + 'static,
181    ) {
182        if self
183            .try_global::<FeatureFlagStore>()
184            .is_some_and(|f| f.has_flag::<T>(self))
185        {
186            self.defer_in(window, move |view, window, cx| {
187                callback(view, window, cx);
188            });
189            return;
190        }
191        let subscription = Rc::new(RefCell::new(None));
192        let inner = self.observe_global_in::<FeatureFlagStore>(window, {
193            let subscription = subscription.clone();
194            move |v, window, cx| {
195                let has_flag = cx.global::<FeatureFlagStore>().has_flag::<T>(cx);
196                if has_flag {
197                    callback(v, window, cx);
198                    subscription.take();
199                }
200            }
201        });
202        subscription.borrow_mut().replace(inner);
203    }
204}
205
206#[derive(Debug)]
207pub struct OnFlagsReady {
208    pub is_staff: bool,
209}
210
211pub trait FeatureFlagAppExt {
212    fn update_flags(&mut self, staff: bool, flags: Vec<String>);
213    fn set_staff(&mut self, staff: bool);
214    fn has_flag<T: FeatureFlag>(&self) -> bool;
215    fn flag_value<T: FeatureFlag>(&self) -> T::Value;
216    fn is_staff(&self) -> bool;
217
218    /// Whether feature flag overrides from settings are honored for the
219    /// current user. Overrides are a staff-only affordance.
220    fn feature_flag_overrides_enabled(&self) -> bool;
221
222    fn on_flags_ready<F>(&mut self, callback: F) -> Subscription
223    where
224        F: FnMut(OnFlagsReady, &mut App) + 'static;
225
226    fn observe_flag<T: FeatureFlag, F>(&mut self, callback: F) -> Subscription
227    where
228        F: FnMut(T::Value, &mut App) + 'static;
229}
230
231impl FeatureFlagAppExt for App {
232    fn update_flags(&mut self, staff: bool, flags: Vec<String>) {
233        let store = self.default_global::<FeatureFlagStore>();
234        store.update_server_flags(staff, flags);
235    }
236
237    fn set_staff(&mut self, staff: bool) {
238        let store = self.default_global::<FeatureFlagStore>();
239        store.set_staff(staff);
240    }
241
242    fn has_flag<T: FeatureFlag>(&self) -> bool {
243        self.try_global::<FeatureFlagStore>()
244            .map(|store| store.has_flag::<T>(self))
245            .unwrap_or_else(|| FeatureFlagStore::has_flag_default::<T>())
246    }
247
248    fn flag_value<T: FeatureFlag>(&self) -> T::Value {
249        self.try_global::<FeatureFlagStore>()
250            .and_then(|store| store.try_flag_value::<T>(self))
251            .unwrap_or_default()
252    }
253
254    fn is_staff(&self) -> bool {
255        self.try_global::<FeatureFlagStore>()
256            .map(|store| store.is_staff())
257            .unwrap_or(false)
258    }
259
260    fn feature_flag_overrides_enabled(&self) -> bool {
261        self.try_global::<FeatureFlagStore>()
262            .map_or(false, |store| store.overrides_enabled())
263    }
264
265    fn on_flags_ready<F>(&mut self, mut callback: F) -> Subscription
266    where
267        F: FnMut(OnFlagsReady, &mut App) + 'static,
268    {
269        self.observe_global::<FeatureFlagStore>(move |cx| {
270            let store = cx.global::<FeatureFlagStore>();
271            if store.server_flags_received() {
272                callback(
273                    OnFlagsReady {
274                        is_staff: store.is_staff(),
275                    },
276                    cx,
277                );
278            }
279        })
280    }
281
282    fn observe_flag<T: FeatureFlag, F>(&mut self, mut callback: F) -> Subscription
283    where
284        F: FnMut(T::Value, &mut App) + 'static,
285    {
286        let mut last_value: Option<T::Value> = None;
287        self.observe_global::<FeatureFlagStore>(move |cx| {
288            let value = cx.flag_value::<T>();
289            if last_value.as_ref() == Some(&value) {
290                return;
291            }
292            last_value = Some(value.clone());
293            callback(value, cx);
294        })
295    }
296}
297
Served at tenant.openagents/omega Member data and write actions are omitted.