Complete local-first Rig provider migration

This commit is contained in:
2026-08-06 11:37:28 -05:00
parent f850bae77c
commit 634ce7ba00
38 changed files with 3837 additions and 1616 deletions
+28 -1
View File
@@ -19,6 +19,7 @@ use crate::auth::{AuthStateProvider, UserUid};
use crate::channel::{Channel, ChannelState};
use crate::cloud_object::model::persistence::CloudModel;
use crate::cloud_object::{CloudObjectEventEntrypoint, ObjectType, Owner, Space};
use crate::local_object_repository::local_owner;
use crate::pricing::PricingInfoModel;
use crate::report_error;
use crate::server::experiments::{ServerExperiment, ServerExperiments, ServerExperimentsEvent};
@@ -673,6 +674,12 @@ impl UserWorkspaces {
// Returns a Vec of the user's active spaces, based on their
// team membership. Includes the "Personal Space" by default.
pub fn all_user_spaces(&self, ctx: &AppContext) -> Vec<Space> {
// Galaxy's OSS channel is local-first. It has no authenticated cloud
// identity or shared drive, so never expose the legacy shared space.
if ChannelState::channel().is_local_first() {
return vec![Space::Personal];
}
if AuthStateProvider::as_ref(ctx)
.get()
.is_user_web_anonymous_user()
@@ -695,8 +702,12 @@ impl UserWorkspaces {
}
// Returns the [`Owner`] for the user's personal drive. If the user is not authenticated, this
// returns `None`.
// returns the stable local owner in local-first channels.
pub fn personal_drive(&self, ctx: &AppContext) -> Option<Owner> {
if ChannelState::channel().is_local_first() {
return Some(local_owner());
}
// Return the authenticated user's ID if available, otherwise provide a
// synthetic local owner so cloud objects (rules, etc.) can be created and
// stored locally without requiring Warp authentication.
@@ -724,8 +735,24 @@ impl UserWorkspaces {
// Maps an [`Owner`] into a [`Space`], based on the user's team memberships.
// This is always possible, as unknown owners imply the shared space.
pub fn owner_to_space(&self, owner: Owner, ctx: &AppContext) -> Space {
if ChannelState::channel().is_local_first() {
return if owner == local_owner() {
Space::Personal
} else {
Space::Shared
};
}
match owner {
Owner::User { user_uid } => {
if matches!(
local_owner(),
Owner::User {
user_uid: local_uid
} if local_uid == user_uid
) {
return Space::Personal;
}
if !FeatureFlag::SharedWithMe.is_enabled() {
return Space::Personal;
}
@@ -10,6 +10,7 @@ use crate::ai::llms::LLMModelHost;
use crate::auth::AuthManager;
use crate::cloud_object::model::persistence::CloudModel;
use crate::features::FeatureFlag;
use crate::local_object_repository::local_owner;
use crate::network::NetworkStatus;
use crate::server::cloud_objects::update_manager::UpdateManager;
use crate::server::ids::ClientId;
@@ -96,6 +97,39 @@ fn initialize_app_with_auth(
});
}
#[test]
fn oss_exposes_only_local_personal_space() {
App::test((), |mut app| async move {
app.add_singleton_model(|ctx| {
UserWorkspaces::mock(
Arc::new(MockTeamClient::new()),
Arc::new(MockWorkspaceClient::new()),
vec![],
ctx,
)
});
app.read(|ctx| {
let user_workspaces = UserWorkspaces::as_ref(ctx);
assert_eq!(user_workspaces.all_user_spaces(ctx), vec![Space::Personal]);
assert_eq!(user_workspaces.personal_drive(ctx), Some(local_owner()));
assert_eq!(
user_workspaces.space_to_owner(Space::Personal, ctx),
Some(local_owner())
);
assert_eq!(
user_workspaces.owner_to_space(
Owner::User {
user_uid: UserUid::new("legacy-cloud-user"),
},
ctx,
),
Space::Shared
);
});
})
}
#[test]
fn test_loading_all_spaces_after_switching_from_offline() {
let _flag = FeatureFlag::KnowledgeSidebar.override_enabled(true);