diff --git a/packages/browseros/build/config/NXTSCAPE_VERSION b/packages/browseros/build/config/NXTSCAPE_VERSION index 8e14edce..d88e3136 100644 --- a/packages/browseros/build/config/NXTSCAPE_VERSION +++ b/packages/browseros/build/config/NXTSCAPE_VERSION @@ -1 +1 @@ -78 +81 diff --git a/packages/browseros/chromium_patches/chrome/browser/extensions/api/developer_private/extension_info_generator_shared.cc b/packages/browseros/chromium_patches/chrome/browser/extensions/api/developer_private/extension_info_generator_shared.cc index c4fbe1d3..327aee2a 100644 --- a/packages/browseros/chromium_patches/chrome/browser/extensions/api/developer_private/extension_info_generator_shared.cc +++ b/packages/browseros/chromium_patches/chrome/browser/extensions/api/developer_private/extension_info_generator_shared.cc @@ -1,5 +1,5 @@ diff --git a/chrome/browser/extensions/api/developer_private/extension_info_generator_shared.cc b/chrome/browser/extensions/api/developer_private/extension_info_generator_shared.cc -index e6c15e15d3157..c1e2b724f5f8f 100644 +index e6c15e15d3157..38f6be4832650 100644 --- a/chrome/browser/extensions/api/developer_private/extension_info_generator_shared.cc +++ b/chrome/browser/extensions/api/developer_private/extension_info_generator_shared.cc @@ -12,6 +12,7 @@ @@ -26,24 +26,19 @@ index e6c15e15d3157..c1e2b724f5f8f 100644 #include "extensions/grit/extensions_browser_resources.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/base/l10n/l10n_util.h" -@@ -78,6 +81,16 @@ namespace developer = api::developer_private; +@@ -78,6 +81,11 @@ namespace developer = api::developer_private; namespace { -+// Check if an extension is a BrowserOS extension that should be hidden ++// Check if an extension is a BrowserOS extension that should be hidden. +bool IsBrowserOSExtension(const std::string& extension_id) { -+ for (const char* allowed_id : browseros::kAllowedExtensions) { -+ if (extension_id == allowed_id) { -+ return true; -+ } -+ } -+ return false; ++ return browseros::IsBrowserOSExtension(extension_id); +} + // Given a Manifest::Type, converts it into its developer_private // counterpart. developer::ExtensionType GetExtensionType(Manifest::Type manifest_type) { -@@ -447,8 +460,19 @@ void ExtensionInfoGeneratorShared::CreateExtensionInfo( +@@ -447,8 +455,19 @@ void ExtensionInfoGeneratorShared::CreateExtensionInfo( state = developer::ExtensionState::kBlocklisted; } @@ -64,7 +59,7 @@ index e6c15e15d3157..c1e2b724f5f8f 100644 } if (pending_image_loads_ == 0) { -@@ -465,11 +489,22 @@ void ExtensionInfoGeneratorShared::CreateExtensionsInfo( +@@ -465,11 +484,22 @@ void ExtensionInfoGeneratorShared::CreateExtensionsInfo( bool include_disabled, bool include_terminated, ExtensionInfosCallback callback) { diff --git a/packages/browseros/chromium_patches/chrome/browser/extensions/api/settings_private/prefs_util.cc b/packages/browseros/chromium_patches/chrome/browser/extensions/api/settings_private/prefs_util.cc index ec2d8c43..3b6d59b0 100644 --- a/packages/browseros/chromium_patches/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/packages/browseros/chromium_patches/chrome/browser/extensions/api/settings_private/prefs_util.cc @@ -1,46 +1,20 @@ diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc -index 97bb4be60af93..1bff654e3ac42 100644 +index 97bb4be60af93..70bf4e91d6ace 100644 --- a/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc -@@ -580,6 +580,37 @@ const PrefsUtil::TypedPrefMap& PrefsUtil::GetAllowlistedKeys() { +@@ -580,6 +580,11 @@ const PrefsUtil::TypedPrefMap& PrefsUtil::GetAllowlistedKeys() { (*s_allowlist)[::prefs::kCaretBrowsingEnabled] = settings_api::PrefType::kBoolean; -+ // Nxtscape AI provider preferences -+ (*s_allowlist)[prefs::kBrowserOSProviders] = settings_api::PrefType::kString; -+ (*s_allowlist)["nxtscape.default_provider"] = settings_api::PrefType::kString; -+ -+ // Nxtscape provider settings -+ (*s_allowlist)["nxtscape.nxtscape_model"] = settings_api::PrefType::kString; -+ -+ // OpenAI provider settings -+ (*s_allowlist)["nxtscape.openai_api_key"] = settings_api::PrefType::kString; -+ (*s_allowlist)["nxtscape.openai_model"] = settings_api::PrefType::kString; -+ (*s_allowlist)["nxtscape.openai_base_url"] = settings_api::PrefType::kString; -+ -+ // Anthropic provider settings -+ (*s_allowlist)["nxtscape.anthropic_api_key"] = settings_api::PrefType::kString; -+ (*s_allowlist)["nxtscape.anthropic_model"] = settings_api::PrefType::kString; -+ (*s_allowlist)["nxtscape.anthropic_base_url"] = settings_api::PrefType::kString; -+ -+ // Gemini provider settings -+ (*s_allowlist)["nxtscape.gemini_api_key"] = settings_api::PrefType::kString; -+ (*s_allowlist)["nxtscape.gemini_model"] = settings_api::PrefType::kString; -+ (*s_allowlist)["nxtscape.gemini_base_url"] = settings_api::PrefType::kString; -+ -+ // Ollama provider settings -+ (*s_allowlist)["nxtscape.ollama_api_key"] = settings_api::PrefType::kString; -+ (*s_allowlist)["nxtscape.ollama_base_url"] = settings_api::PrefType::kString; -+ (*s_allowlist)["nxtscape.ollama_model"] = settings_api::PrefType::kString; -+ + // BrowserOS preferences ++ (*s_allowlist)[prefs::kBrowserOSProviders] = settings_api::PrefType::kString; + (*s_allowlist)[prefs::kBrowserOSShowToolbarLabels] = settings_api::PrefType::kBoolean; + (*s_allowlist)[prefs::kBrowserOSCustomProviders] = settings_api::PrefType::kString; + #if BUILDFLAG(IS_CHROMEOS) // Accounts / Users / People. (*s_allowlist)[ash::kAccountsPrefAllowGuest] = -@@ -1164,6 +1195,8 @@ const PrefsUtil::TypedPrefMap& PrefsUtil::GetAllowlistedKeys() { +@@ -1164,6 +1169,8 @@ const PrefsUtil::TypedPrefMap& PrefsUtil::GetAllowlistedKeys() { settings_api::PrefType::kBoolean; (*s_allowlist)[::prefs::kImportDialogSearchEngine] = settings_api::PrefType::kBoolean; diff --git a/packages/browseros/chromium_patches/chrome/browser/extensions/browseros_extension_constants.h b/packages/browseros/chromium_patches/chrome/browser/extensions/browseros_extension_constants.h index d9118e79..be2ce1a5 100644 --- a/packages/browseros/chromium_patches/chrome/browser/extensions/browseros_extension_constants.h +++ b/packages/browseros/chromium_patches/chrome/browser/extensions/browseros_extension_constants.h @@ -1,9 +1,9 @@ diff --git a/chrome/browser/extensions/browseros_extension_constants.h b/chrome/browser/extensions/browseros_extension_constants.h new file mode 100644 -index 0000000000000..17b78fbb99a9f +index 0000000000000..e42df6740460c --- /dev/null +++ b/chrome/browser/extensions/browseros_extension_constants.h -@@ -0,0 +1,80 @@ +@@ -0,0 +1,112 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. @@ -11,6 +11,7 @@ index 0000000000000..17b78fbb99a9f +#ifndef CHROME_BROWSER_EXTENSIONS_BROWSEROS_EXTENSION_CONSTANTS_H_ +#define CHROME_BROWSER_EXTENSIONS_BROWSEROS_EXTENSION_CONSTANTS_H_ + ++#include +#include +#include +#include @@ -36,33 +37,67 @@ index 0000000000000..17b78fbb99a9f +inline constexpr char kBrowserOSUpdateUrl[] = + "https://cdn.browseros.com/extensions/update-manifest.xml"; + -+// Allowlist of BrowserOS extension IDs that are permitted to be installed -+// Only extensions with these IDs will be loaded from the config -+constexpr const char* kAllowedExtensions[] = { -+ kAISidePanelExtensionId, // AI Side Panel extension -+ kBugReporterExtensionId, // Bug Reporter extension -+ kControllerExtensionId, // Controller extension ++// BrowserOS extension config URL ++inline constexpr char kBrowserOSConfigUrl[] = ++ "https://cdn.browseros.com/extensions/extensions.json"; ++ ++struct BrowserOSExtensionInfo { ++ const char* id; ++ const char* display_name; ++ bool is_pinned; ++ bool is_labelled; ++}; ++ ++inline constexpr BrowserOSExtensionInfo kBrowserOSExtensions[] = { ++ {kAISidePanelExtensionId, "BrowserOS", true, true}, ++ {kBugReporterExtensionId, "BrowserOS/bug-reporter", true, false}, ++ {kControllerExtensionId, "BrowserOS/controller", false, false}, +}; + ++// Allowlist of BrowserOS extension IDs that are permitted to be installed. ++// Only extensions with these IDs will be loaded from the config. ++inline constexpr const char* kAllowedExtensions[] = { ++ kBrowserOSExtensions[0].id, ++ kBrowserOSExtensions[1].id, ++ kBrowserOSExtensions[2].id, ++}; ++ ++inline constexpr size_t kBrowserOSExtensionsCount = ++ sizeof(kBrowserOSExtensions) / sizeof(kBrowserOSExtensions[0]); ++ ++inline const BrowserOSExtensionInfo* FindBrowserOSExtensionInfo( ++ const std::string& extension_id) { ++ for (const auto& info : kBrowserOSExtensions) { ++ if (extension_id == info.id) ++ return &info; ++ } ++ return nullptr; ++} ++ +// Check if an extension is a BrowserOS extension +inline bool IsBrowserOSExtension(const std::string& extension_id) { -+ return extension_id == kAISidePanelExtensionId || -+ extension_id == kBugReporterExtensionId || -+ extension_id == kControllerExtensionId; ++ return FindBrowserOSExtensionInfo(extension_id) != nullptr; ++} ++ ++inline bool IsBrowserOSPinnedExtension(const std::string& extension_id) { ++ const BrowserOSExtensionInfo* info = ++ FindBrowserOSExtensionInfo(extension_id); ++ return info && info->is_pinned; +} + -+// Check if an extension can be uninstalled (false for BrowserOS extensions) -+inline bool CanUninstallExtension(const std::string& extension_id) { -+ return !IsBrowserOSExtension(extension_id); ++inline bool IsBrowserOSLabelledExtension(const std::string& extension_id) { ++ const BrowserOSExtensionInfo* info = ++ FindBrowserOSExtensionInfo(extension_id); ++ return info && info->is_labelled; +} + +// Get all BrowserOS extension IDs +inline std::vector GetBrowserOSExtensionIds() { -+ return { -+ kAISidePanelExtensionId, -+ kBugReporterExtensionId, -+ kControllerExtensionId -+ }; ++ std::vector ids; ++ ids.reserve(kBrowserOSExtensionsCount); ++ for (const auto& info : kBrowserOSExtensions) ++ ids.push_back(info.id); ++ return ids; +} + +// Get display name for BrowserOS extensions in omnibox @@ -70,12 +105,9 @@ index 0000000000000..17b78fbb99a9f +// otherwise returns std::nullopt +inline std::optional GetExtensionDisplayName( + const std::string& extension_id) { -+ if (extension_id == kAISidePanelExtensionId) { -+ return "BrowserOS"; -+ } else if (extension_id == kBugReporterExtensionId) { -+ return "BrowserOS/bug-reporter"; -+ } else if (extension_id == kControllerExtensionId) { -+ return "BrowserOS/controller"; ++ if (const BrowserOSExtensionInfo* info = ++ FindBrowserOSExtensionInfo(extension_id)) { ++ return info->display_name; + } + return std::nullopt; +} diff --git a/packages/browseros/chromium_patches/chrome/browser/extensions/browseros_external_loader.cc b/packages/browseros/chromium_patches/chrome/browser/extensions/browseros_external_loader.cc index 791ee000..d4e7bec9 100644 --- a/packages/browseros/chromium_patches/chrome/browser/extensions/browseros_external_loader.cc +++ b/packages/browseros/chromium_patches/chrome/browser/extensions/browseros_external_loader.cc @@ -1,9 +1,9 @@ diff --git a/chrome/browser/extensions/browseros_external_loader.cc b/chrome/browser/extensions/browseros_external_loader.cc new file mode 100644 -index 0000000000000..53eeebf1be954 +index 0000000000000..aa11db933c978 --- /dev/null +++ b/chrome/browser/extensions/browseros_external_loader.cc -@@ -0,0 +1,661 @@ +@@ -0,0 +1,645 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. @@ -48,10 +48,6 @@ index 0000000000000..53eeebf1be954 + +namespace { + -+// Default config URL - should be updated to actual BrowserOS server -+// Can be overridden via --browseros-extensions-url command line flag -+constexpr char kBrowserOSConfigUrl[] = "https://cdn.browseros.com/extensions/extensions.json"; -+ +// Interval for periodic maintenance +constexpr base::TimeDelta kPeriodicMaintenanceInterval = base::Minutes(15); + @@ -98,7 +94,7 @@ index 0000000000000..53eeebf1be954 +BrowserOSExternalLoader::BrowserOSExternalLoader(Profile* profile) + : profile_(profile) { + // Default config URL - can be overridden via SetConfigUrl -+ config_url_ = GURL(kBrowserOSConfigUrl); ++ config_url_ = GURL(browseros::kBrowserOSConfigUrl); + + // Add known BrowserOS extension IDs + for (const char* extension_id : browseros::kAllowedExtensions) { @@ -110,6 +106,9 @@ index 0000000000000..53eeebf1be954 + +void BrowserOSExternalLoader::StartLoading() { + LOG(INFO) << "BrowserOS external extension loader starting..."; ++ ++ // Start periodic maintenance immediately, regardless of config state. ++ StartPeriodicCheck(); + + if (!config_file_for_testing_.empty()) { + LoadFromFile(); @@ -148,122 +147,139 @@ index 0000000000000..53eeebf1be954 +void BrowserOSExternalLoader::OnURLFetchComplete( + std::unique_ptr response_body) { + if (!response_body) { -+ LOG(ERROR) << "Failed to fetch BrowserOS extensions config from " ++ LOG(ERROR) << "browseros: Failed to fetch BrowserOS extensions config from " + << config_url_.spec(); -+ LoadFinished(base::Value::Dict()); ++ if (has_successful_config_) { ++ LOG(WARNING) << "browseros: Keeping previously applied configuration."; ++ } + return; + } + -+ ParseConfiguration(*response_body); ++ if (!ParseConfiguration(*response_body)) { ++ LOG(ERROR) << "browseros: Initial configuration parse failed"; ++ } +} + -+void BrowserOSExternalLoader::ParseConfiguration( ++bool BrowserOSExternalLoader::ParseConfiguration( + const std::string& json_content) { + std::optional parsed_json = base::JSONReader::Read(json_content); -+ + if (!parsed_json || !parsed_json->is_dict()) { -+ LOG(ERROR) << "Failed to parse BrowserOS extensions config JSON"; -+ LoadFinished(base::Value::Dict()); -+ return; ++ LOG(ERROR) << "browseros: Failed to parse extensions config JSON"; ++ return false; + } + -+ const base::Value::Dict* extensions_dict = ++ const base::Value::Dict* extensions_dict = + parsed_json->GetDict().FindDict("extensions"); -+ + if (!extensions_dict) { -+ LOG(ERROR) << "No 'extensions' key found in BrowserOS config"; -+ LoadFinished(base::Value::Dict()); -+ return; ++ LOG(ERROR) << "browseros: No 'extensions' key found in BrowserOS config"; ++ return false; + } + -+ // Create the prefs dictionary in the format expected by ExternalProviderImpl ++ base::Value::Dict filtered_config; + base::Value::Dict prefs; -+ ++ size_t dropped_entries = 0u; ++ + for (const auto [extension_id, extension_config] : *extensions_dict) { ++ if (!browseros::IsBrowserOSExtension(extension_id)) { ++ ++dropped_entries; ++ continue; ++ } ++ + if (!extension_config.is_dict()) { -+ LOG(WARNING) << "Invalid config for extension " << extension_id; ++ LOG(WARNING) << "browseros: Invalid config for extension " ++ << extension_id; + continue; + } -+ ++ + const base::Value::Dict& config_dict = extension_config.GetDict(); -+ base::Value::Dict extension_prefs; -+ -+ // Copy supported fields -+ if (const std::string* update_url = -+ config_dict.FindString(ExternalProviderImpl::kExternalUpdateUrl)) { -+ extension_prefs.Set(ExternalProviderImpl::kExternalUpdateUrl, *update_url); ++ ++ base::Value::Dict filtered_entry; ++ if (const std::string* update_url = ++ config_dict.FindString(ExternalProviderImpl::kExternalUpdateUrl)) { ++ filtered_entry.Set(ExternalProviderImpl::kExternalUpdateUrl, *update_url); + } -+ -+ if (const std::string* crx_path = -+ config_dict.FindString(ExternalProviderImpl::kExternalCrx)) { -+ extension_prefs.Set(ExternalProviderImpl::kExternalCrx, *crx_path); ++ if (const std::string* crx_path = ++ config_dict.FindString(ExternalProviderImpl::kExternalCrx)) { ++ filtered_entry.Set(ExternalProviderImpl::kExternalCrx, *crx_path); + } -+ -+ if (const std::string* version = -+ config_dict.FindString(ExternalProviderImpl::kExternalVersion)) { -+ extension_prefs.Set(ExternalProviderImpl::kExternalVersion, *version); ++ if (const std::string* version = ++ config_dict.FindString(ExternalProviderImpl::kExternalVersion)) { ++ filtered_entry.Set(ExternalProviderImpl::kExternalVersion, *version); + } -+ -+ // Add other supported fields as needed -+ std::optional keep_if_present = -+ config_dict.FindBool(ExternalProviderImpl::kKeepIfPresent); -+ if (keep_if_present.has_value()) { -+ extension_prefs.Set(ExternalProviderImpl::kKeepIfPresent, ++ if (std::optional keep_if_present = ++ config_dict.FindBool(ExternalProviderImpl::kKeepIfPresent)) { ++ filtered_entry.Set(ExternalProviderImpl::kKeepIfPresent, + keep_if_present.value()); + } -+ -+ if (!extension_prefs.empty()) { -+ prefs.Set(extension_id, std::move(extension_prefs)); ++ ++ // If update URL is missing, add it ++ if (!filtered_entry.contains(ExternalProviderImpl::kExternalUpdateUrl)) { ++ filtered_entry.Set(ExternalProviderImpl::kExternalUpdateUrl, ++ browseros::kBrowserOSUpdateUrl); + } ++ ++ filtered_config.Set(extension_id, filtered_entry.Clone()); ++ prefs.Set(extension_id, filtered_entry.Clone()); + } -+ -+ LOG(INFO) << "Loaded " << prefs.size() << " extensions from BrowserOS config"; -+ -+ // Track the extension IDs we're managing -+ for (const auto [extension_id, _] : prefs) { -+ browseros_extension_ids_.insert(extension_id); ++ ++ if (dropped_entries > 0) { ++ LOG(WARNING) << "browseros: Ignored " << dropped_entries ++ << " non-allowlisted extensions in config"; + } -+ -+ // Store the initial config for comparison -+ if (!extensions_dict->empty()) { -+ last_config_ = extensions_dict->Clone(); ++ ++ if (prefs.empty()) { ++ LOG(ERROR) << "browseros: Allowlist produced no installable extensions"; ++ return false; + } -+ -+ // Pass the prefs to the external provider system ++ ++ if (filtered_config == last_config_) { ++ LOG(INFO) << "browseros: Config unchanged"; ++ return true; ++ } ++ ++ last_config_ = filtered_config.Clone(); ++ ++ browseros_extension_ids_.clear(); ++ for (const auto [extension_id, _] : filtered_config) { ++ browseros_extension_ids_.insert(extension_id); ++ } ++ ++ LOG(INFO) << "Loaded " << prefs.size() << " extensions from BrowserOS config"; ++ ++ const bool had_previous_config = has_successful_config_; ++ + LoadFinished(std::move(prefs)); -+ -+ // Immediately trigger high-priority installation of all BrowserOS extensions -+ // This ensures they get installed right away instead of waiting for Chrome's -+ // default external extension installation process ++ has_successful_config_ = true; ++ + if (!browseros_extension_ids_.empty()) { -+ LOG(INFO) << "browseros: Triggering immediate high-priority installation for " ++ LOG(INFO) << "browseros: Triggering immediate high-priority installation for " + << browseros_extension_ids_.size() << " BrowserOS extensions"; -+ -+ // Use a delayed task to ensure the extension system is fully initialized ++ + base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask( + FROM_HERE, + base::BindOnce(&BrowserOSExternalLoader::TriggerImmediateInstallation, + weak_ptr_factory_.GetWeakPtr()), -+ base::Seconds(2)); // Small delay to ensure extension system is ready ++ base::Seconds(2)); + } -+ -+ // Start periodic checking after initial load ++ + StartPeriodicCheck(); ++ CheckAndLogExtensionState(had_previous_config ? "config_update" : "startup"); + -+ // Log initial extension state at startup -+ CheckAndLogExtensionState("startup"); ++ return true; +} + +void BrowserOSExternalLoader::StartPeriodicCheck() { -+ LOG(INFO) << "browseros: Starting periodic maintenance (every " ++ if (periodic_timer_.IsRunning()) { ++ return; ++ } ++ ++ LOG(INFO) << "browseros: Starting periodic maintenance (every " + << kPeriodicMaintenanceInterval.InMinutes() << " minutes)"; -+ -+ // Schedule the periodic maintenance -+ base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask( -+ FROM_HERE, -+ base::BindOnce(&BrowserOSExternalLoader::PeriodicMaintenance, -+ weak_ptr_factory_.GetWeakPtr()), -+ kPeriodicMaintenanceInterval); ++ ++ periodic_timer_.Start( ++ FROM_HERE, kPeriodicMaintenanceInterval, ++ base::BindRepeating(&BrowserOSExternalLoader::PeriodicMaintenance, ++ weak_ptr_factory_.GetWeakPtr())); +} + +void BrowserOSExternalLoader::PeriodicMaintenance() { @@ -289,9 +305,6 @@ index 0000000000000..53eeebf1be954 + + // 5. Log extension state after all maintenance attempts + CheckAndLogExtensionState("periodic_maintenance"); -+ -+ // Schedule the next maintenance -+ StartPeriodicCheck(); +} + +void BrowserOSExternalLoader::ReinstallUninstalledExtensions() { @@ -312,6 +325,10 @@ index 0000000000000..53eeebf1be954 + if (registry->GetInstalledExtension(extension_id)) { + continue; // Extension is installed, skip to next + } ++ ++ if (registry->disabled_extensions().Contains(extension_id)) { ++ continue; // Disabled extensions are handled separately ++ } + + LOG(INFO) << "browseros: Extension " << extension_id + << " was uninstalled, attempting to reinstall"; @@ -423,54 +440,9 @@ index 0000000000000..53eeebf1be954 + LOG(WARNING) << "browseros: Failed to fetch config for update check"; + return; + } -+ -+ std::optional parsed_json = base::JSONReader::Read(*response_body); -+ if (!parsed_json || !parsed_json->is_dict()) { -+ LOG(WARNING) << "browseros: Invalid config JSON during update check"; -+ return; -+ } -+ -+ const base::Value::Dict* extensions_dict = -+ parsed_json->GetDict().FindDict("extensions"); -+ if (!extensions_dict) { -+ return; -+ } -+ -+ // Check if config has changed -+ bool config_changed = false; -+ if (last_config_.empty()) { -+ config_changed = true; // First time -+ } else { -+ // Compare with last config -+ for (const auto [extension_id, new_config] : *extensions_dict) { -+ const base::Value::Dict* old_config = last_config_.FindDict(extension_id); -+ if (!old_config || *old_config != new_config.GetDict()) { -+ config_changed = true; -+ LOG(INFO) << "browseros: Config changed for extension " << extension_id; -+ break; -+ } -+ } -+ -+ // Check for removed extensions -+ for (const auto [extension_id, _] : last_config_) { -+ if (!extensions_dict->contains(extension_id)) { -+ config_changed = true; -+ LOG(INFO) << "browseros: Extension " << extension_id << " removed from config"; -+ break; -+ } -+ } -+ } -+ -+ if (config_changed) { -+ LOG(INFO) << "browseros: Config has changed, reloading extensions"; -+ -+ // Store the new config -+ last_config_ = extensions_dict->Clone(); -+ -+ // Parse and reload with new config -+ ParseConfiguration(*response_body); -+ } else { -+ LOG(INFO) << "browseros: Config unchanged"; ++ ++ if (!ParseConfiguration(*response_body)) { ++ LOG(WARNING) << "browseros: Ignoring config update due to parse failure"; + } +} + @@ -574,11 +546,23 @@ index 0000000000000..53eeebf1be954 + return std::string(); + } + return contents; -+ }, config_file_for_testing_), -+ base::BindOnce(&BrowserOSExternalLoader::ParseConfiguration, ++ }, ++ config_file_for_testing_), ++ base::BindOnce(&BrowserOSExternalLoader::OnConfigFileLoaded, + weak_ptr_factory_.GetWeakPtr())); +} + ++void BrowserOSExternalLoader::OnConfigFileLoaded(std::string contents) { ++ if (contents.empty()) { ++ LOG(ERROR) << "browseros: BrowserOS config file is empty"; ++ return; ++ } ++ ++ if (!ParseConfiguration(contents)) { ++ LOG(ERROR) << "browseros: Failed to parse BrowserOS config file"; ++ } ++} ++ +void BrowserOSExternalLoader::CheckAndLogExtensionState( + const std::string& context) { + if (!profile_) { diff --git a/packages/browseros/chromium_patches/chrome/browser/extensions/browseros_external_loader.h b/packages/browseros/chromium_patches/chrome/browser/extensions/browseros_external_loader.h index a0c675e5..335d991a 100644 --- a/packages/browseros/chromium_patches/chrome/browser/extensions/browseros_external_loader.h +++ b/packages/browseros/chromium_patches/chrome/browser/extensions/browseros_external_loader.h @@ -1,9 +1,9 @@ diff --git a/chrome/browser/extensions/browseros_external_loader.h b/chrome/browser/extensions/browseros_external_loader.h new file mode 100644 -index 0000000000000..3d0ba110fe6e1 +index 0000000000000..b313a0ba6fa10 --- /dev/null +++ b/chrome/browser/extensions/browseros_external_loader.h -@@ -0,0 +1,116 @@ +@@ -0,0 +1,126 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. @@ -12,11 +12,13 @@ index 0000000000000..3d0ba110fe6e1 +#define CHROME_BROWSER_EXTENSIONS_BROWSEROS_EXTERNAL_LOADER_H_ + +#include ++#include +#include + +#include "base/files/file_path.h" +#include "base/memory/scoped_refptr.h" +#include "base/memory/weak_ptr.h" ++#include "base/timer/timer.h" +#include "chrome/browser/extensions/external_loader.h" +#include "services/network/public/cpp/simple_url_loader.h" + @@ -47,7 +49,7 @@ index 0000000000000..3d0ba110fe6e1 + config_file_for_testing_ = path; + } + -+ // Starts periodic check to re-enable disabled BrowserOS extensions and check for updates ++ // Starts periodic maintenance loop (no-op if already running). + void StartPeriodicCheck(); + + // Periodic maintenance: re-enables disabled extensions, checks config, and forces updates @@ -70,16 +72,19 @@ index 0000000000000..3d0ba110fe6e1 + + // Called when the URL fetch completes. + void OnURLFetchComplete(std::unique_ptr response_body); -+ ++ + // Called when config check fetch completes + void OnConfigCheckComplete(std::unique_ptr loader, + std::unique_ptr response_body); + + // Parses the fetched JSON configuration and loads extensions. -+ void ParseConfiguration(const std::string& json_content); ++ bool ParseConfiguration(const std::string& json_content); + + // Loads configuration from a local file (for testing). + void LoadFromFile(); ++ ++ // Handles the config contents read from a local file. ++ void OnConfigFileLoaded(std::string contents); + + // Checks for uninstalled BrowserOS extensions and reinstalls them + void ReinstallUninstalledExtensions(); @@ -114,10 +119,14 @@ index 0000000000000..3d0ba110fe6e1 + // Last fetched config for comparison + base::Value::Dict last_config_; + ++ // Tracks whether we have successfully applied a configuration during this session. ++ bool has_successful_config_ = false; ++ ++ base::RepeatingTimer periodic_timer_; ++ + base::WeakPtrFactory weak_ptr_factory_{this}; +}; + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_BROWSEROS_EXTERNAL_LOADER_H_ -\ No newline at end of file diff --git a/packages/browseros/chromium_patches/chrome/browser/extensions/extension_context_menu_model.cc b/packages/browseros/chromium_patches/chrome/browser/extensions/extension_context_menu_model.cc index 5e4344ed..1a544cda 100644 --- a/packages/browseros/chromium_patches/chrome/browser/extensions/extension_context_menu_model.cc +++ b/packages/browseros/chromium_patches/chrome/browser/extensions/extension_context_menu_model.cc @@ -1,5 +1,5 @@ diff --git a/chrome/browser/extensions/extension_context_menu_model.cc b/chrome/browser/extensions/extension_context_menu_model.cc -index d5e3f14b43b44..1a3f546260abb 100644 +index d5e3f14b43b44..350087695ae38 100644 --- a/chrome/browser/extensions/extension_context_menu_model.cc +++ b/chrome/browser/extensions/extension_context_menu_model.cc @@ -7,6 +7,7 @@ @@ -16,7 +16,7 @@ index d5e3f14b43b44..1a3f546260abb 100644 bool has_options_page = OptionsPageInfo::HasOptionsPage(extension); - bool can_uninstall_extension = !is_component_ && !is_required_by_policy; + bool can_uninstall_extension = !is_component_ && !is_required_by_policy && -+ browseros::CanUninstallExtension(extension->id()); ++ !browseros::IsBrowserOSExtension(extension->id()); if (can_show_icon_in_toolbar || has_options_page || can_uninstall_extension) { AddSeparator(ui::NORMAL_SEPARATOR); } diff --git a/packages/browseros/chromium_patches/chrome/browser/extensions/extension_management.cc b/packages/browseros/chromium_patches/chrome/browser/extensions/extension_management.cc index 490fdf12..4e2f4065 100644 --- a/packages/browseros/chromium_patches/chrome/browser/extensions/extension_management.cc +++ b/packages/browseros/chromium_patches/chrome/browser/extensions/extension_management.cc @@ -1,5 +1,5 @@ diff --git a/chrome/browser/extensions/extension_management.cc b/chrome/browser/extensions/extension_management.cc -index ae782891ad341..fa1a80d0265b1 100644 +index ae782891ad341..02e100fd1a934 100644 --- a/chrome/browser/extensions/extension_management.cc +++ b/chrome/browser/extensions/extension_management.cc @@ -14,6 +14,7 @@ @@ -10,38 +10,16 @@ index ae782891ad341..fa1a80d0265b1 100644 #include "base/containers/contains.h" #include "base/feature_list.h" #include "base/functional/bind.h" -@@ -244,7 +245,22 @@ GURL ExtensionManagement::GetEffectiveUpdateURL(const Extension& extension) { - << "Update URL cannot be overridden to be the webstore URL!"; - return update_url; - } -- return ManifestURL::GetUpdateURL(&extension); -+ -+ // Get the update URL from the extension's manifest -+ GURL manifest_update_url = ManifestURL::GetUpdateURL(&extension); -+ -+ // BrowserOS extension fallback: If a BrowserOS extension doesn't have an -+ // force-set the BrowserOS CDN update URL so the extension can receive updates -+ if (manifest_update_url.is_empty() && -+ browseros::IsBrowserOSExtension(extension.id())) { -+ const GURL browseros_update_url(browseros::kBrowserOSUpdateUrl); -+ LOG(INFO) << "browseros: Extension " << extension.id() -+ << " missing update_url in manifest, using BrowserOS CDN: " -+ << browseros_update_url.spec(); -+ return browseros_update_url; -+ } -+ -+ return manifest_update_url; - } - - bool ExtensionManagement::UpdatesFromWebstore(const Extension& extension) { -@@ -593,6 +609,12 @@ ExtensionIdSet ExtensionManagement::GetForcePinnedList() const { +@@ -593,6 +594,14 @@ ExtensionIdSet ExtensionManagement::GetForcePinnedList() const { force_pinned_list.insert(entry.first); } } + -+ // Always force-pin BrowserOS extensions ++ // Always force-pin BrowserOS extensions that are marked pinned. + for (const auto& extension_id : browseros::GetBrowserOSExtensionIds()) { -+ force_pinned_list.insert(extension_id); ++ if (browseros::IsBrowserOSPinnedExtension(extension_id)) { ++ force_pinned_list.insert(extension_id); ++ } + } + return force_pinned_list; diff --git a/packages/browseros/chromium_patches/chrome/browser/prefs/browser_prefs.cc b/packages/browseros/chromium_patches/chrome/browser/prefs/browser_prefs.cc index 8affbbf5..31a6b4f7 100644 --- a/packages/browseros/chromium_patches/chrome/browser/prefs/browser_prefs.cc +++ b/packages/browseros/chromium_patches/chrome/browser/prefs/browser_prefs.cc @@ -1,5 +1,5 @@ diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc -index 9a00400829ae1..ea209084bb09b 100644 +index 9a00400829ae1..265778646348c 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc @@ -21,6 +21,7 @@ @@ -39,47 +39,21 @@ index 9a00400829ae1..ea209084bb09b 100644 regional_capabilities::prefs::RegisterProfilePrefs(registry); RegisterBrowserUserPrefs(registry); RegisterGeminiSettingsPrefs(registry); -+ RegisterNxtscapePrefs(registry); ++ RegisterBrowserOSPrefs(registry); RegisterPrefersDefaultScrollbarStylesPrefs(registry); RegisterSafetyHubProfilePrefs(registry); #if BUILDFLAG(IS_CHROMEOS) -@@ -2322,6 +2328,46 @@ void RegisterGeminiSettingsPrefs(user_prefs::PrefRegistrySyncable* registry) { +@@ -2322,6 +2328,20 @@ void RegisterGeminiSettingsPrefs(user_prefs::PrefRegistrySyncable* registry) { registry->RegisterIntegerPref(prefs::kGeminiSettings, 0); } -+void RegisterNxtscapePrefs(user_prefs::PrefRegistrySyncable* registry) { ++void RegisterBrowserOSPrefs(user_prefs::PrefRegistrySyncable* registry) { + // AI Provider configurations stored as JSON + // This will store the entire provider configuration including: + // - defaultProviderId + // - providers array with all configured providers + registry->RegisterStringPref(prefs::kBrowserOSProviders, ""); + -+ // Legacy preferences (kept for backward compatibility) -+ registry->RegisterStringPref("nxtscape.default_provider", "browseros"); -+ -+ // Nxtscape provider settings -+ registry->RegisterStringPref("nxtscape.nxtscape_model", ""); -+ -+ // OpenAI provider settings -+ registry->RegisterStringPref("nxtscape.openai_api_key", ""); -+ registry->RegisterStringPref("nxtscape.openai_model", "gpt-4o"); -+ registry->RegisterStringPref("nxtscape.openai_base_url", ""); -+ -+ // Anthropic provider settings -+ registry->RegisterStringPref("nxtscape.anthropic_api_key", ""); -+ registry->RegisterStringPref("nxtscape.anthropic_model", "claude-3-5-sonnet-latest"); -+ registry->RegisterStringPref("nxtscape.anthropic_base_url", ""); -+ -+ // Gemini provider settings -+ registry->RegisterStringPref("nxtscape.gemini_api_key", ""); -+ registry->RegisterStringPref("nxtscape.gemini_model", "gemini-1.5-pro"); -+ registry->RegisterStringPref("nxtscape.gemini_base_url", ""); -+ -+ // Ollama provider settings -+ registry->RegisterStringPref("nxtscape.ollama_api_key", ""); -+ registry->RegisterStringPref("nxtscape.ollama_base_url", "http://localhost:11434"); -+ registry->RegisterStringPref("nxtscape.ollama_model", ""); -+ + // BrowserOS toolbar settings + registry->RegisterBooleanPref(prefs::kBrowserOSShowToolbarLabels, true); + diff --git a/packages/browseros/chromium_patches/chrome/browser/prefs/browser_prefs.h b/packages/browseros/chromium_patches/chrome/browser/prefs/browser_prefs.h index 6b727d26..8c00efe3 100644 --- a/packages/browseros/chromium_patches/chrome/browser/prefs/browser_prefs.h +++ b/packages/browseros/chromium_patches/chrome/browser/prefs/browser_prefs.h @@ -1,12 +1,12 @@ diff --git a/chrome/browser/prefs/browser_prefs.h b/chrome/browser/prefs/browser_prefs.h -index 3a1c48b14b37f..5600baa2143e0 100644 +index 3a1c48b14b37f..c9fe51ab1848b 100644 --- a/chrome/browser/prefs/browser_prefs.h +++ b/chrome/browser/prefs/browser_prefs.h @@ -32,6 +32,8 @@ void RegisterScreenshotPrefs(PrefRegistrySimple* registry); void RegisterGeminiSettingsPrefs(user_prefs::PrefRegistrySyncable* registry); -+void RegisterNxtscapePrefs(user_prefs::PrefRegistrySyncable* registry); ++void RegisterBrowserOSPrefs(user_prefs::PrefRegistrySyncable* registry); + // Register all prefs that will be used via a PrefService attached to a user // Profile using the locale of |g_browser_process|. diff --git a/packages/browseros/chromium_patches/chrome/browser/ui/actions/browseros_actions_config.h b/packages/browseros/chromium_patches/chrome/browser/ui/actions/browseros_actions_config.h index a6199917..931ffe91 100644 --- a/packages/browseros/chromium_patches/chrome/browser/ui/actions/browseros_actions_config.h +++ b/packages/browseros/chromium_patches/chrome/browser/ui/actions/browseros_actions_config.h @@ -1,9 +1,9 @@ diff --git a/chrome/browser/ui/actions/browseros_actions_config.h b/chrome/browser/ui/actions/browseros_actions_config.h new file mode 100644 -index 0000000000000..3900759f40883 +index 0000000000000..68985b1490511 --- /dev/null +++ b/chrome/browser/ui/actions/browseros_actions_config.h -@@ -0,0 +1,69 @@ +@@ -0,0 +1,72 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. @@ -43,10 +43,14 @@ index 0000000000000..3900759f40883 + return true; + } + -+ // Check extension actions using the allowed extensions from browseros constants -+ for (const char* ext_id : extensions::browseros::kAllowedExtensions) { ++ // Only labelled extensions are considered for BrowserOS actions ++ for (const auto& ext_id : ++ extensions::browseros::GetBrowserOSExtensionIds()) { ++ if (!extensions::browseros::IsBrowserOSLabelledExtension(ext_id)) { ++ continue; ++ } + auto ext_action_id = actions::ActionIdMap::StringToActionId( -+ SidePanelEntryKey(SidePanelEntryId::kExtension, std::string(ext_id)) ++ SidePanelEntryKey(SidePanelEntryId::kExtension, ext_id) + .ToString()); + if (ext_action_id && id == *ext_action_id) { + return true; @@ -72,4 +76,3 @@ index 0000000000000..3900759f40883 +} // namespace browseros + +#endif // CHROME_BROWSER_UI_ACTIONS_BROWSEROS_ACTIONS_CONFIG_H_ -+ diff --git a/packages/browseros/chromium_patches/chrome/browser/ui/profiles/profile_error_dialog.cc b/packages/browseros/chromium_patches/chrome/browser/ui/profiles/profile_error_dialog.cc new file mode 100644 index 00000000..90dc05e2 --- /dev/null +++ b/packages/browseros/chromium_patches/chrome/browser/ui/profiles/profile_error_dialog.cc @@ -0,0 +1,20 @@ +diff --git a/chrome/browser/ui/profiles/profile_error_dialog.cc b/chrome/browser/ui/profiles/profile_error_dialog.cc +index 1c94ce3fb3dba..a51a43b4f5705 100644 +--- a/chrome/browser/ui/profiles/profile_error_dialog.cc ++++ b/chrome/browser/ui/profiles/profile_error_dialog.cc +@@ -67,10 +67,11 @@ void ShowProfileErrorDialog(ProfileErrorType type, + l10n_util::GetStringUTF16(IDS_PROFILE_ERROR_DIALOG_CHECKBOX), + base::BindOnce(&OnProfileErrorDialogDismissed, diagnostics)); + #else // BUILDFLAG(GOOGLE_CHROME_BRANDING) +- chrome::ShowWarningMessageBox( +- gfx::NativeWindow(), +- l10n_util::GetStringUTF16(IDS_PROFILE_ERROR_DIALOG_TITLE), +- l10n_util::GetStringUTF16(message_id)); ++ // FIXME: nikhil: Handle this warning better ++ // chrome::ShowWarningMessageBox( ++ // gfx::NativeWindow(), ++ // l10n_util::GetStringUTF16(IDS_PROFILE_ERROR_DIALOG_TITLE), ++ // l10n_util::GetStringUTF16(message_id)); + #endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) + + #endif // BUILDFLAG(IS_ANDROID) diff --git a/packages/browseros/chromium_patches/chrome/browser/ui/startup/google_api_keys_infobar_delegate.cc b/packages/browseros/chromium_patches/chrome/browser/ui/startup/google_api_keys_infobar_delegate.cc deleted file mode 100644 index fbd08399..00000000 --- a/packages/browseros/chromium_patches/chrome/browser/ui/startup/google_api_keys_infobar_delegate.cc +++ /dev/null @@ -1,26 +0,0 @@ -diff --git a/chrome/browser/ui/startup/google_api_keys_infobar_delegate.cc b/chrome/browser/ui/startup/google_api_keys_infobar_delegate.cc -index 78ba37b940137..5e11f058c5537 100644 ---- a/chrome/browser/ui/startup/google_api_keys_infobar_delegate.cc -+++ b/chrome/browser/ui/startup/google_api_keys_infobar_delegate.cc -@@ -30,15 +30,18 @@ GoogleApiKeysInfoBarDelegate::GetIdentifier() const { - } - - std::u16string GoogleApiKeysInfoBarDelegate::GetLinkText() const { -- return l10n_util::GetStringUTF16(IDS_LEARN_MORE); -+ // return l10n_util::GetStringUTF16(IDS_LEARN_MORE); -+ return std::u16string(); - } - - GURL GoogleApiKeysInfoBarDelegate::GetLinkURL() const { -- return GURL(google_apis::kAPIKeysDevelopersHowToURL); -+ // return GURL(google_apis::kAPIKeysDevelopersHowToURL); -+ return GURL(); - } - - std::u16string GoogleApiKeysInfoBarDelegate::GetMessageText() const { -- return l10n_util::GetStringUTF16(IDS_MISSING_GOOGLE_API_KEYS); -+ // return l10n_util::GetStringUTF16(IDS_MISSING_GOOGLE_API_KEYS); -+ return std::u16string(); - } - - int GoogleApiKeysInfoBarDelegate::GetButtons() const { diff --git a/packages/browseros/chromium_patches/chrome/browser/ui/startup/infobar_utils.cc b/packages/browseros/chromium_patches/chrome/browser/ui/startup/infobar_utils.cc new file mode 100644 index 00000000..85229ad5 --- /dev/null +++ b/packages/browseros/chromium_patches/chrome/browser/ui/startup/infobar_utils.cc @@ -0,0 +1,15 @@ +diff --git a/chrome/browser/ui/startup/infobar_utils.cc b/chrome/browser/ui/startup/infobar_utils.cc +index d953dc89ed49c..4ce075231da88 100644 +--- a/chrome/browser/ui/startup/infobar_utils.cc ++++ b/chrome/browser/ui/startup/infobar_utils.cc +@@ -163,10 +163,6 @@ void AddInfoBarsIfNecessary(Browser* browser, + infobars::ContentInfoBarManager* infobar_manager = + infobars::ContentInfoBarManager::FromWebContents(web_contents); + +- if (!google_apis::HasAPIKeyConfigured()) { +- GoogleApiKeysInfoBarDelegate::Create(infobar_manager); +- } +- + if (ObsoleteSystem::IsObsoleteNowOrSoon()) { + PrefService* local_state = g_browser_process->local_state(); + if (!local_state || diff --git a/packages/browseros/chromium_patches/chrome/browser/ui/toolbar/toolbar_actions_model.cc b/packages/browseros/chromium_patches/chrome/browser/ui/toolbar/toolbar_actions_model.cc index f5b5af3f..8c31727d 100644 --- a/packages/browseros/chromium_patches/chrome/browser/ui/toolbar/toolbar_actions_model.cc +++ b/packages/browseros/chromium_patches/chrome/browser/ui/toolbar/toolbar_actions_model.cc @@ -1,5 +1,5 @@ diff --git a/chrome/browser/ui/toolbar/toolbar_actions_model.cc b/chrome/browser/ui/toolbar/toolbar_actions_model.cc -index 8c748d7cc5fc1..2019fe0341327 100644 +index 8c748d7cc5fc1..e2649d27ad776 100644 --- a/chrome/browser/ui/toolbar/toolbar_actions_model.cc +++ b/chrome/browser/ui/toolbar/toolbar_actions_model.cc @@ -20,6 +20,7 @@ @@ -15,22 +15,25 @@ index 8c748d7cc5fc1..2019fe0341327 100644 bool ToolbarActionsModel::IsActionForcePinned(const ActionId& action_id) const { + // Check if it's a BrowserOS extension -+ if (extensions::browseros::IsBrowserOSExtension(action_id)) { ++ if (extensions::browseros::IsBrowserOSPinnedExtension(action_id)) { + return true; + } + auto* management = extensions::ExtensionManagementFactory::GetForBrowserContext(profile_); return base::Contains(management->GetForcePinnedList(), action_id); -@@ -533,6 +539,13 @@ ToolbarActionsModel::GetFilteredPinnedActionIds() const { +@@ -533,6 +539,16 @@ ToolbarActionsModel::GetFilteredPinnedActionIds() const { std::ranges::copy_if( management->GetForcePinnedList(), std::back_inserter(pinned), [&pinned](const std::string& id) { return !base::Contains(pinned, id); }); + -+ // Add BrowserOS extensions to the force-pinned list -+ for (const char* ext_id : extensions::browseros::kAllowedExtensions) { -+ if (!base::Contains(pinned, ext_id)) { -+ pinned.push_back(ext_id); ++ // Add BrowserOS extensions that are marked pinned. ++ for (const auto& extension_id : extensions::browseros::GetBrowserOSExtensionIds()) { ++ if (!extensions::browseros::IsBrowserOSPinnedExtension(extension_id)) { ++ continue; ++ } ++ if (!base::Contains(pinned, extension_id)) { ++ pinned.push_back(extension_id); + } + } diff --git a/packages/browseros/resources/binaries/browseros_server/browseros-server-darwin-arm64 b/packages/browseros/resources/binaries/browseros_server/browseros-server-darwin-arm64 index aef94cc4..7c788432 100755 --- a/packages/browseros/resources/binaries/browseros_server/browseros-server-darwin-arm64 +++ b/packages/browseros/resources/binaries/browseros_server/browseros-server-darwin-arm64 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a9cbb68c0cbf2988123a8345429002a9cfa5e6966326f0670474a9fae8e0b89a -size 67383312 +oid sha256:67362257d83a6cf2d2b28477de941dd6178ffeb12c491433a518b79a039012bd +size 67399824 diff --git a/packages/browseros/resources/binaries/browseros_server/browseros-server-darwin-x64 b/packages/browseros/resources/binaries/browseros_server/browseros-server-darwin-x64 index df8956b2..8744ce07 100755 --- a/packages/browseros/resources/binaries/browseros_server/browseros-server-darwin-x64 +++ b/packages/browseros/resources/binaries/browseros_server/browseros-server-darwin-x64 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:09502700bcb72c824df886852a717de908b58ab3eb2634cc0d9e3475f56248c2 -size 73125088 +oid sha256:a175195b1c65107b5492c6fa2faa0b01002708d45fcd8a9503c2bf973c359773 +size 73141472 diff --git a/packages/browseros/resources/binaries/browseros_server/browseros-server-linux-arm64 b/packages/browseros/resources/binaries/browseros_server/browseros-server-linux-arm64 index 0fa6e2e3..ccac00a8 100755 --- a/packages/browseros/resources/binaries/browseros_server/browseros-server-linux-arm64 +++ b/packages/browseros/resources/binaries/browseros_server/browseros-server-linux-arm64 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4842995892d154b53357ed51f231e3fce0c2c5a266638a28ef2a1de52a2e6a84 -size 103911193 +oid sha256:e89e9e689867be49a900dd00fe5ee70456774140d31f50a288d7732cf099b071 +size 103915841 diff --git a/packages/browseros/resources/binaries/browseros_server/browseros-server-linux-x64 b/packages/browseros/resources/binaries/browseros_server/browseros-server-linux-x64 index 88bf88a4..d03150dc 100755 --- a/packages/browseros/resources/binaries/browseros_server/browseros-server-linux-x64 +++ b/packages/browseros/resources/binaries/browseros_server/browseros-server-linux-x64 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5069b7a99937ad596f0c051fcfc25895c9530ee3c7887b036d5456c0e9387349 -size 110599743 +oid sha256:9179bd1420387a090f4f66a2f6b5f444e367ce982f4cdc85f796677b88c32723 +size 110604391 diff --git a/packages/browseros/resources/binaries/browseros_server/browseros-server-windows-x64.exe b/packages/browseros/resources/binaries/browseros_server/browseros-server-windows-x64.exe index 6112dea3..a39a9e89 100755 --- a/packages/browseros/resources/binaries/browseros_server/browseros-server-windows-x64.exe +++ b/packages/browseros/resources/binaries/browseros_server/browseros-server-windows-x64.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d4047a7cad74de8902a457a73ba8d9774e33eaf6827fae3f84a1a2c0e91372c5 -size 125978624 +oid sha256:dd4982e47c19be2a956c1dd29d34fdb797b0552150eb5086478c4a1d52b64866 +size 125983232