diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml
index 8b948acd6..273aa00c3 100644
--- a/.github/ISSUE_TEMPLATE/bug-report.yml
+++ b/.github/ISSUE_TEMPLATE/bug-report.yml
@@ -1,5 +1,5 @@
name: Bug Report
-description: Report a bug building or running Helium
+description: Report a bug building or running Zephyr
labels: ["bug"]
title: "[Bug]: "
body:
@@ -11,12 +11,12 @@ body:
interacting with the entire organization.
If you suspect your bug might be specific to a certain platform (e.g. macOS),
- please submit it to the relevant repository instead of the root "helium" repo.
+ please submit it to the relevant repository instead of the root "zephyr" repo.
- type: dropdown
id: os
attributes:
label: Operating system
- description: The OS you are running Helium on
+ description: The OS you are running Zephyr on
options:
- macOS
- Linux
@@ -36,7 +36,7 @@ body:
options:
- label: I have tried reproducing this issue in Chrome and it could not be reproduced there
- label: I have tried reproducing this issue in ungoogled-chromium and it could not be reproduced there
- - label: I have tried reproducing this issue in Helium with a new and empty profile using `--user-data-dir` command line argument and it could not be reproduced there
+ - label: I have tried reproducing this issue in Zephyr with a new and empty profile using `--user-data-dir` command line argument and it could not be reproduced there
- type: input
id: description
attributes:
diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml
index 05580df31..59018497f 100644
--- a/.github/ISSUE_TEMPLATE/feature-request.yml
+++ b/.github/ISSUE_TEMPLATE/feature-request.yml
@@ -14,7 +14,7 @@ body:
to read that and thus your request will be closed.
If your request is for a platform-specific feature (e.g. for macOS), please
- submit it to the relevant platform repo instead of the generic "helium" repo.
+ submit it to the relevant platform repo instead of the generic "zephyr" repo.
- type: input
id: description
attributes:
diff --git a/.github/actions/bump-platform/action.yml b/.github/actions/bump-platform/action.yml
index 72def126a..23b561eca 100644
--- a/.github/actions/bump-platform/action.yml
+++ b/.github/actions/bump-platform/action.yml
@@ -91,10 +91,10 @@ runs:
popd
# commit, push, make pr
- TITLE="update: helium $version_after"
+ TITLE="update: zephyr $version_after"
- git config user.name "helium-bot"
- git config user.email "helium-bot@imput.net"
+ git config user.name "zephyr-bot"
+ git config user.email "zephyr-bot@users.noreply.github.com"
git add -u patches helium-chromium revision.txt
PLATFORM_HOOK="$PLATFORM_DIR/.github/bump-hook.sh"
diff --git a/patches/helium/core/add-disable-ech-flag.patch b/patches/helium/core/add-disable-ech-flag.patch
index 26898baf3..b01c02974 100644
--- a/patches/helium/core/add-disable-ech-flag.patch
+++ b/patches/helium/core/add-disable-ech-flag.patch
@@ -13,12 +13,12 @@
+++ b/chrome/browser/helium_flag_entries.h
@@ -11,4 +11,9 @@
"Maximum frame rate for Energy Saver",
- "Configures the frame rate the browser is throttled to when Energy Saver is enabled. Helium flag.",
+ "Configures the frame rate the browser is throttled to when Energy Saver is enabled. Zephyr flag.",
kOsDesktop, MULTI_VALUE_TYPE(helium::kEnergySaverFrameRateChoices)},
+ {helium::kDisableEchCommandLine,
+ "Disable ECH (Encrypted Client Hello)",
+ "Disables TLS Encrypted Client Hello. Not recommended unless you live in an area with heavy Internet"
-+ " censorship and ECH prevents websites from loading. Helium flag.",
++ " censorship and ECH prevents websites from loading. Zephyr flag.",
+ kOsAll, SINGLE_VALUE_TYPE(helium::kDisableEchCommandLine)},
#endif /* CHROME_BROWSER_HELIUM_FLAG_ENTRIES_H_ */
--- a/chrome/browser/ssl/ssl_config_service_manager.cc
diff --git a/patches/helium/core/add-low-power-framerate-flag.patch b/patches/helium/core/add-low-power-framerate-flag.patch
index f061cc65b..4ffe8e5ad 100644
--- a/patches/helium/core/add-low-power-framerate-flag.patch
+++ b/patches/helium/core/add-low-power-framerate-flag.patch
@@ -24,7 +24,7 @@
#define CHROME_BROWSER_HELIUM_FLAG_ENTRIES_H_
+ {helium::kEnergySaverFrameRateCommandLine,
+ "Maximum frame rate for Energy Saver",
-+ "Configures the frame rate the browser is throttled to when Energy Saver is enabled. Helium flag.",
++ "Configures the frame rate the browser is throttled to when Energy Saver is enabled. Zephyr flag.",
+ kOsDesktop, MULTI_VALUE_TYPE(helium::kEnergySaverFrameRateChoices)},
#endif /* CHROME_BROWSER_HELIUM_FLAG_ENTRIES_H_ */
--- a/chrome/browser/performance_manager/user_tuning/battery_saver_mode_manager.cc
diff --git a/patches/helium/core/add-middle-click-autoscroll-flag.patch b/patches/helium/core/add-middle-click-autoscroll-flag.patch
index 6153641a5..916066da2 100644
--- a/patches/helium/core/add-middle-click-autoscroll-flag.patch
+++ b/patches/helium/core/add-middle-click-autoscroll-flag.patch
@@ -13,11 +13,11 @@
+++ b/chrome/browser/helium_flag_entries.h
@@ -33,4 +33,8 @@
"Randomizes the number of cores returned by "
- "`navigator.hardwareConcurrency` in a reasonable range. Helium flag.",
+ "`navigator.hardwareConcurrency` in a reasonable range. Zephyr flag.",
kOsAll, FEATURE_VALUE_TYPE(blink::features::kHeliumNoiseCpuCores)},
+ {helium::kMiddleClickAutoscrollCommandLine,
+ "Middle Click Autoscroll",
-+ "Enables autoscroll on middle click. Helium flag, Chromium feature.",
++ "Enables autoscroll on middle click. Zephyr flag, Chromium feature.",
+ kOsDesktop, FEATURE_VALUE_TYPE(blink::features::kHeliumMiddleClickAutoscroll)},
#endif /* CHROME_BROWSER_HELIUM_FLAG_ENTRIES_H_ */
--- a/third_party/blink/public/common/features.h
diff --git a/patches/helium/core/add-native-bangs.patch b/patches/helium/core/add-native-bangs.patch
index d63b1cfee..2e89b989f 100644
--- a/patches/helium/core/add-native-bangs.patch
+++ b/patches/helium/core/add-native-bangs.patch
@@ -738,16 +738,16 @@
+++ b/chrome/app/settings_strings.grdp
@@ -2029,6 +2029,12 @@
- When enabled, Helium will proxy extension downloads and updates to protect your privacy. When disabled, downloading and updating extensions will not work.
+ When enabled, Zephyr will proxy extension downloads and updates to protect your privacy. When disabled, downloading and updating extensions will not work.
+
+ Allow downloading the !bangs list
+
+
-+ Helium will fetch a list of bangs that help you browse the Internet faster, such as !w or !gh. When disabled, bangs will not work.
++ Zephyr will fetch a list of bangs that help you browse the Internet faster, such as !w or !gh. When disabled, bangs will not work.
+
-
- Use your own instance of Helium services
+
+ Use your own instance of Zephyr services
--- a/chrome/browser/resources/settings/privacy_page/services_page.html
+++ b/chrome/browser/resources/settings/privacy_page/services_page.html
diff --git a/patches/helium/core/add-update-channel-flag.patch b/patches/helium/core/add-update-channel-flag.patch
index 11b752f68..e8528caf5 100644
--- a/patches/helium/core/add-update-channel-flag.patch
+++ b/patches/helium/core/add-update-channel-flag.patch
@@ -83,11 +83,11 @@
#ifndef CHROME_BROWSER_HELIUM_FLAG_ENTRIES_H_
#define CHROME_BROWSER_HELIUM_FLAG_ENTRIES_H_
+ {helium::kChannelCommandLine,
-+ "Update channel", "Selects which update channel to use for update checking. Helium flag.",
++ "Update channel", "Selects which update channel to use for update checking. Zephyr flag.",
+ kOsAll, MULTI_VALUE_TYPE(helium::kChannelChoices)},
{helium::kEnergySaverFrameRateCommandLine,
"Maximum frame rate for Energy Saver",
- "Configures the frame rate the browser is throttled to when Energy Saver is enabled. Helium flag.",
+ "Configures the frame rate the browser is throttled to when Energy Saver is enabled. Zephyr flag.",
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -263,6 +263,8 @@ static_library("browser") {
diff --git a/patches/helium/core/add-updater-preference.patch b/patches/helium/core/add-updater-preference.patch
index 935d08f0c..4ffe5f854 100644
--- a/patches/helium/core/add-updater-preference.patch
+++ b/patches/helium/core/add-updater-preference.patch
@@ -126,21 +126,21 @@
+++ b/chrome/app/settings_strings.grdp
@@ -2044,6 +2044,19 @@
- Helium will fetch dictionary files used for spell checking when requested. When disabled, spell checking will not work.
+ Zephyr will fetch dictionary files used for spell checking when requested. When disabled, spell checking will not work.
+
+ Allow automatic browser and component updates
+
+
+
-+ Helium will automatically download and install browser and component updates as they become available. We recommend keeping this setting enabled to ensure you get the latest features and security updates.
++ Zephyr will automatically download and install browser and component updates as they become available. We recommend keeping this setting enabled to ensure you get the latest features and security updates.
+
+
+
+
-+ Helium will automatically download and install browser and component updates as they become available. We recommend keeping this setting enabled to ensure you get the latest features and security updates. Automatic core browser updates are not available on this platform yet, but component updates are. Please use external software to keep Helium up to date.
++ Zephyr will automatically download and install browser and component updates as they become available. We recommend keeping this setting enabled to ensure you get the latest features and security updates. Automatic core browser updates are not available on this platform yet, but component updates are. Please use external software to keep Zephyr up to date.
+
+
-
- Use your own instance of Helium services
+
+ Use your own instance of Zephyr services
diff --git a/patches/helium/core/change-chromium-branding.patch b/patches/helium/core/change-chromium-branding.patch
index aebe80f7e..f500c8a46 100644
--- a/patches/helium/core/change-chromium-branding.patch
+++ b/patches/helium/core/change-chromium-branding.patch
@@ -9,14 +9,14 @@
-PRODUCT_INSTALLER_SHORTNAME=Chromium Installer
-COPYRIGHT=Copyright @LASTCHANGE_YEAR@ The Chromium Authors. All rights reserved.
-MAC_BUNDLE_ID=org.chromium.Chromium
-+COMPANY_FULLNAME=The Helium Authors
-+COMPANY_SHORTNAME=The Helium Authors
-+PRODUCT_FULLNAME=Helium
-+PRODUCT_SHORTNAME=Helium
-+PRODUCT_INSTALLER_FULLNAME=Helium Installer
-+PRODUCT_INSTALLER_SHORTNAME=Helium Installer
-+COPYRIGHT=Copyright @LASTCHANGE_YEAR@ The Helium Authors. All rights reserved.
-+MAC_BUNDLE_ID=net.imput.helium
++COMPANY_FULLNAME=The Zephyr Authors
++COMPANY_SHORTNAME=The Zephyr Authors
++PRODUCT_FULLNAME=Zephyr
++PRODUCT_SHORTNAME=Zephyr
++PRODUCT_INSTALLER_FULLNAME=Zephyr Installer
++PRODUCT_INSTALLER_SHORTNAME=Zephyr Installer
++COPYRIGHT=Copyright @LASTCHANGE_YEAR@ The Zephyr Authors. All rights reserved.
++MAC_BUNDLE_ID=io.github.quanticstudios.zephyr
MAC_CREATOR_CODE=Cr24
-MAC_TEAM_ID=
-+MAC_TEAM_ID=S4Q33XPHB4
++MAC_TEAM_ID=
diff --git a/patches/helium/core/component-updates.patch b/patches/helium/core/component-updates.patch
index 95691da5a..b9b9e037a 100644
--- a/patches/helium/core/component-updates.patch
+++ b/patches/helium/core/component-updates.patch
@@ -167,7 +167,7 @@
Update error
+
-+ Component updates are disabled. See Helium services in settings.
++ Component updates are disabled. See Zephyr services in settings.
+
Unknown
diff --git a/patches/helium/core/exclude-irrelevant-flags.patch b/patches/helium/core/exclude-irrelevant-flags.patch
index 036899d3e..eaaabd6eb 100644
--- a/patches/helium/core/exclude-irrelevant-flags.patch
+++ b/patches/helium/core/exclude-irrelevant-flags.patch
@@ -4,7 +4,7 @@
// AboutFlagsHistogramTest unit test to verify this process).
};
-+// Flags that either break Helium functionality or are not relevant to Helium
++// Flags that either break Zephyr functionality or are not relevant to Zephyr
+constexpr auto kExcludedFlags = base::MakeFixedFlatSet({
+ // Misc UI features
+ "enable-immersive-fullscreen-toolbar",
@@ -15,20 +15,20 @@
+ "top-chrome-touch-ui",
+
+ // Google's broken canvas noising flag,
-+ // replaced by Helium's fingerprinting-canvas-noise
++ // replaced by Zephyr's fingerprinting-canvas-noise
+ "enable-canvas-noise",
+
+ // Google's fingerprinting protection blocklist
-+ // Helium blocks fingerprinting by default, and these don't even work
++ // Zephyr blocks fingerprinting by default, and these don't even work
+ "enable-fingerprinting-protection-blocklist",
+ "enable-fingerprinting-protection-blocklist-incognito",
+
-+ // Google's experimental APIs that don't work in Helium
++ // Google's experimental APIs that don't work in Zephyr
+ // due to missing model binaries
+ "translation-api",
+ "translation-api-streaming-by-sentence",
+
-+ // Misc features not relevant to Helium
++ // Misc features not relevant to Zephyr
+ "extensions-menu-access-control",
+ "extensions-collapse-main-menu",
+
diff --git a/patches/helium/core/fixups-chrome-webstore-script.patch b/patches/helium/core/fixups-chrome-webstore-script.patch
index 4a09cfed1..a265000f4 100644
--- a/patches/helium/core/fixups-chrome-webstore-script.patch
+++ b/patches/helium/core/fixups-chrome-webstore-script.patch
@@ -50,7 +50,7 @@
+ return false;
+ }
+
-+ el.nodeValue = el.nodeValue.replace(/\b(Google\s)?Chrome\b/, 'Helium');
++ el.nodeValue = el.nodeValue.replace(/\b(Google\s)?Chrome\b/, 'Zephyr');
+ return true;
+ } else if (el.childNodes) {
+ for (const node of el.childNodes) {
diff --git a/patches/helium/core/keyboard-shortcuts.patch b/patches/helium/core/keyboard-shortcuts.patch
index 8bc007921..d5aa5c3d6 100644
--- a/patches/helium/core/keyboard-shortcuts.patch
+++ b/patches/helium/core/keyboard-shortcuts.patch
@@ -4,7 +4,7 @@
#define IDC_WEB_APP_MENU_APP_INFO 34063
#define IDC_WEB_APP_UPGRADE_DIALOG 34064
-+// Helium commands
++// Zephyr commands
+#define IDC_COPY_OR_INSPECT_SHORTCUT 34080
+
#if BUILDFLAG(IS_CHROMEOS)
diff --git a/patches/helium/core/noise/audio.patch b/patches/helium/core/noise/audio.patch
index 25e353b71..929d5bda0 100644
--- a/patches/helium/core/noise/audio.patch
+++ b/patches/helium/core/noise/audio.patch
@@ -11,12 +11,12 @@
--- a/chrome/browser/helium_flag_entries.h
+++ b/chrome/browser/helium_flag_entries.h
@@ -24,4 +24,8 @@
- "[Helium Noise] Canvas pixel noising",
- "Adds insignificant noise to canvas pixels during readback to deceive canvas-based fingerprinting. Helium flag.",
+ "[Zephyr Noise] Canvas pixel noising",
+ "Adds insignificant noise to canvas pixels during readback to deceive canvas-based fingerprinting. Zephyr flag.",
kOsAll, FEATURE_VALUE_TYPE(blink::features::kHeliumNoiseCanvas)},
+ {helium::kHeliumNoiseAudioCommandLine,
-+ "[Helium Noise] Jitter audio context data",
-+ "Adds insignificant jitter to audio data to deceive AudioContext-based fingerprinting. Helium flag.",
++ "[Zephyr Noise] Jitter audio context data",
++ "Adds insignificant jitter to audio data to deceive AudioContext-based fingerprinting. Zephyr flag.",
+ kOsAll, FEATURE_VALUE_TYPE(blink::features::kHeliumNoiseAudio)},
#endif /* CHROME_BROWSER_HELIUM_FLAG_ENTRIES_H_ */
--- a/third_party/blink/common/features.cc
diff --git a/patches/helium/core/noise/canvas.patch b/patches/helium/core/noise/canvas.patch
index f8a830116..7cbec6a7f 100644
--- a/patches/helium/core/noise/canvas.patch
+++ b/patches/helium/core/noise/canvas.patch
@@ -1,5 +1,5 @@
# Some files in this patch are sourced from Chromium. They were
-# heavily modified to fit Helium's needs.
+# heavily modified to fit Zephyr's needs.
#
# Chromium's license header is maintained wherever applicable to
# respect the original authorship of code.
@@ -47,12 +47,12 @@
--- a/chrome/browser/helium_flag_entries.h
+++ b/chrome/browser/helium_flag_entries.h
@@ -20,4 +20,8 @@
- "Helium Noise",
- "Helium's anti-fingerprinting functionality. Adds insignificant noise to various features to deceive fingerprinting scripts. Enabled by default, must be enabled for other anti-fingerprinting features to work. Helium flag.",
+ "Zephyr Noise",
+ "Zephyr's anti-fingerprinting functionality. Adds insignificant noise to various features to deceive fingerprinting scripts. Enabled by default, must be enabled for other anti-fingerprinting features to work. Zephyr flag.",
kOsAll, FEATURE_VALUE_TYPE(blink::features::kHeliumNoise)},
+ {helium::kHeliumNoiseCanvasCommandLine,
-+ "[Helium Noise] Canvas pixel noising",
-+ "Adds insignificant noise to canvas pixels during readback to deceive canvas-based fingerprinting. Helium flag.",
++ "[Zephyr Noise] Canvas pixel noising",
++ "Adds insignificant noise to canvas pixels during readback to deceive canvas-based fingerprinting. Zephyr flag.",
+ kOsAll, FEATURE_VALUE_TYPE(blink::features::kHeliumNoiseCanvas)},
#endif /* CHROME_BROWSER_HELIUM_FLAG_ENTRIES_H_ */
--- a/third_party/blink/common/features.cc
diff --git a/patches/helium/core/noise/core.patch b/patches/helium/core/noise/core.patch
index 4ccff4e82..6ac9d130e 100644
--- a/patches/helium/core/noise/core.patch
+++ b/patches/helium/core/noise/core.patch
@@ -1,5 +1,5 @@
# Some files in this patch are sourced from Chromium. They were
-# heavily modified to fit Helium's needs.
+# heavily modified to fit Zephyr's needs.
#
# Chromium's license header is maintained wherever applicable to
# respect the original authorship of code.
@@ -49,11 +49,11 @@
+++ b/chrome/browser/helium_flag_entries.h
@@ -16,4 +16,8 @@
"Disables TLS Encrypted Client Hello. Not recommended unless you live in an area with heavy Internet"
- " censorship and ECH prevents websites from loading. Helium flag.",
+ " censorship and ECH prevents websites from loading. Zephyr flag.",
kOsAll, SINGLE_VALUE_TYPE(helium::kDisableEchCommandLine)},
+ {helium::kHeliumNoiseCommandLine,
-+ "Helium Noise",
-+ "Helium's anti-fingerprinting functionality. Adds insignificant noise to various features to deceive fingerprinting scripts. Enabled by default, must be enabled for other anti-fingerprinting features to work. Helium flag.",
++ "Zephyr Noise",
++ "Zephyr's anti-fingerprinting functionality. Adds insignificant noise to various features to deceive fingerprinting scripts. Enabled by default, must be enabled for other anti-fingerprinting features to work. Zephyr flag.",
+ kOsAll, FEATURE_VALUE_TYPE(blink::features::kHeliumNoise)},
#endif /* CHROME_BROWSER_HELIUM_FLAG_ENTRIES_H_ */
--- a/third_party/blink/common/features.cc
@@ -62,7 +62,7 @@
// `RuntimeEnabledFeatures)`, they should still be ordered in this section based
// on the identifier name of the generated feature.
-+// Helium Noise; required for fingerprinting protection features.
++// Zephyr Noise; required for fingerprinting protection features.
+BASE_FEATURE(kHeliumNoise,
+ base::FEATURE_ENABLED_BY_DEFAULT);
+
diff --git a/patches/helium/core/noise/hardware-concurrency.patch b/patches/helium/core/noise/hardware-concurrency.patch
index 0ed3c85ac..12c2f678b 100644
--- a/patches/helium/core/noise/hardware-concurrency.patch
+++ b/patches/helium/core/noise/hardware-concurrency.patch
@@ -12,13 +12,13 @@
--- a/chrome/browser/helium_flag_entries.h
+++ b/chrome/browser/helium_flag_entries.h
@@ -28,4 +28,9 @@
- "[Helium Noise] Jitter audio context data",
- "Adds insignificant jitter to audio data to deceive AudioContext-based fingerprinting. Helium flag.",
+ "[Zephyr Noise] Jitter audio context data",
+ "Adds insignificant jitter to audio data to deceive AudioContext-based fingerprinting. Zephyr flag.",
kOsAll, FEATURE_VALUE_TYPE(blink::features::kHeliumNoiseAudio)},
+ {helium::kHeliumNoiseCpuCoresCommandLine,
-+ "[Helium Noise] Randomize number of CPU cores",
++ "[Zephyr Noise] Randomize number of CPU cores",
+ "Randomizes the number of cores returned by "
-+ "`navigator.hardwareConcurrency` in a reasonable range. Helium flag.",
++ "`navigator.hardwareConcurrency` in a reasonable range. Zephyr flag.",
+ kOsAll, FEATURE_VALUE_TYPE(blink::features::kHeliumNoiseCpuCores)},
#endif /* CHROME_BROWSER_HELIUM_FLAG_ENTRIES_H_ */
--- a/content/browser/helium_noise/noise_token_data.cc
diff --git a/patches/helium/core/onboarding-page.patch b/patches/helium/core/onboarding-page.patch
index 5f076d7e4..b33bde456 100644
--- a/patches/helium/core/onboarding-page.patch
+++ b/patches/helium/core/onboarding-page.patch
@@ -655,13 +655,13 @@
Don't notify me again
+
-+ Helium services are not available until setup is complete to ensure your privacy and consent.
++ Zephyr services are not available until setup is complete to ensure your privacy and consent.
+
+
+ Complete setup
+
-
- Allow connecting to Helium services
+
+ Allow connecting to Zephyr services
--- a/chrome/browser/extensions/api/settings_private/prefs_util.cc
+++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
diff --git a/patches/helium/core/proxy-extension-downloads.patch b/patches/helium/core/proxy-extension-downloads.patch
index db2e2d8ed..97d54e14b 100644
--- a/patches/helium/core/proxy-extension-downloads.patch
+++ b/patches/helium/core/proxy-extension-downloads.patch
@@ -167,7 +167,7 @@
--- a/chrome/browser/extensions/api/settings_private/prefs_util.cc
+++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -363,6 +363,8 @@ const PrefsUtil::TypedPrefMap& PrefsUtil
- // Helium services page
+ // Zephyr services page
(*s_allowlist)[::prefs::kHeliumServicesEnabled] =
settings_api::PrefType::kBoolean;
+ (*s_allowlist)[::prefs::kHeliumExtProxyEnabled] =
@@ -215,17 +215,17 @@
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -2023,6 +2023,12 @@
-
- When enabled, Helium will be able to connect to anonymous web services to provide additional functionality. When disabled, additional features will not work.
+
+ When enabled, Zephyr will be able to connect to anonymous web services to provide additional functionality. When disabled, additional features will not work.
+
+ Proxy extension downloads and updates
+
+
-+ When enabled, Helium will proxy extension downloads and updates to protect your privacy. When disabled, downloading and updating extensions will not work.
++ When enabled, Zephyr will proxy extension downloads and updates to protect your privacy. When disabled, downloading and updating extensions will not work.
+
-
- Use your own instance of Helium services
+
+ Use your own instance of Zephyr services
--- a/components/helium_services/pref_names.h
+++ b/components/helium_services/pref_names.h
diff --git a/patches/helium/core/reenable-spellcheck-downloads.patch b/patches/helium/core/reenable-spellcheck-downloads.patch
index 175db9c67..de2049470 100644
--- a/patches/helium/core/reenable-spellcheck-downloads.patch
+++ b/patches/helium/core/reenable-spellcheck-downloads.patch
@@ -149,23 +149,23 @@
Please check with your network administrator to make sure that the firewall is not blocking downloads from Google servers.
+
-+ Please check that Helium services are enabled (including spell check downloads) and make sure that the firewall is not blocking downloads from Helium servers.
++ Please check that Zephyr services are enabled (including spell check downloads) and make sure that the firewall is not blocking downloads from Zephyr servers.
+
@@ -2035,6 +2038,12 @@
- Helium will fetch a list of bangs that help you browse the Internet faster, such as !w or !gh. When disabled, bangs will not work.
+ Zephyr will fetch a list of bangs that help you browse the Internet faster, such as !w or !gh. When disabled, bangs will not work.
+
+ Allow downloading dictionary files for spell checking
+
+
-+ Helium will fetch dictionary files used for spell checking when requested. When disabled, spell checking will not work.
++ Zephyr will fetch dictionary files used for spell checking when requested. When disabled, spell checking will not work.
+
-
- Use your own instance of Helium services
+
+ Use your own instance of Zephyr services
--- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
diff --git a/patches/helium/core/services-prefs.patch b/patches/helium/core/services-prefs.patch
index 4660c70ea..333f38e0e 100644
--- a/patches/helium/core/services-prefs.patch
+++ b/patches/helium/core/services-prefs.patch
@@ -4,38 +4,38 @@
Safe Browsing (protection from dangerous sites) and other security settings
-+
-+ Helium services
++
++ Zephyr services
+
-+
-+ Manage what Helium services are allowed in your browser
++
++ Manage what Zephyr services are allowed in your browser
+
-+
-+ Updates to Helium services:
++
++ Updates to Zephyr services:
+
-+
++
+ These changes are not active until you dismiss this notice.
+
+
+ Don't notify me again
+
-+
-+ Allow connecting to Helium services
++
++ Allow connecting to Zephyr services
+
-+
-+ When enabled, Helium will be able to connect to anonymous web services to provide additional functionality. When disabled, additional features will not work.
++
++ When enabled, Zephyr will be able to connect to anonymous web services to provide additional functionality. When disabled, additional features will not work.
+
-+
-+ Use your own instance of Helium services
++
++ Use your own instance of Zephyr services
+
-+
-+ You can host your own instance of Helium services and use it in your browser instead of the default one. HTTPS only.
++
++ You can host your own instance of Zephyr services and use it in your browser instead of the default one. HTTPS only.
+
-+
++
+ Do not use this field unless you know exactly what you are doing. Never paste URLs from other people here, they are trying to steal your data. We are not responsible for any damages caused by using a custom server and will not be able to help you.
+
-+
-+ Custom origin URL for Helium services
++
++ Custom origin URL for Zephyr services
+
+
;
+ acknowledgeChanges(ignoreAllChangelogs: boolean): void;
@@ -710,7 +710,7 @@
+ {
+ 1,
+ "Automatic component updates are now available. They're managed by the same toggle that enables automatic browser updates.\n"
-+ "From now on, you'll be notified about major changes to Helium services. Even though these notifications are extremely rare, you can choose to ignore them and accept all future changes automatically."
++ "From now on, you'll be notified about major changes to Zephyr services. Even though these notifications are extremely rare, you can choose to ignore them and accept all future changes automatically."
+ }
+ });
+
diff --git a/patches/helium/core/services-schema-nag.patch b/patches/helium/core/services-schema-nag.patch
index 3c07df3e7..0baf4b7e6 100644
--- a/patches/helium/core/services-schema-nag.patch
+++ b/patches/helium/core/services-schema-nag.patch
@@ -4,8 +4,8 @@
Customize and control Chromium. Update is available.
-+
-+ Helium services have been updated. Please review the changes.
++
++ Zephyr services have been updated. Please review the changes.
+
+
@@ -15,9 +15,9 @@
Chromium couldn't update to the latest version, so you're missing out on new features and security fixes.
-+
-+
-+ Review Helium services updates
++
++
++ Review Zephyr services updates
+
+
@@ -29,7 +29,7 @@
Update
-+
++
+ Services updated
+
@@ -95,7 +95,7 @@
// boolean indicating whether any menu items were added.
bool AddDefaultBrowserMenuItems();
-+ // Adds a nag to review Helium services permission changes
++ // Adds a nag to review Zephyr services permission changes
+ bool AddHeliumSchemaItem();
+
// Adds the Safety Hub menu notifications to the menu. Returns a boolean
diff --git a/patches/helium/core/ublock-helium-services.patch b/patches/helium/core/ublock-helium-services.patch
index ae57cf277..d7719bdb2 100644
--- a/patches/helium/core/ublock-helium-services.patch
+++ b/patches/helium/core/ublock-helium-services.patch
@@ -218,17 +218,17 @@
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -2057,6 +2057,12 @@
- Helium will automatically download and install browser and component updates as they become available. We recommend keeping this setting enabled to ensure you get the latest features and security updates. Automatic core browser updates are not available on this platform yet, but component updates are. Please use external software to keep Helium up to date.
+ Zephyr will automatically download and install browser and component updates as they become available. We recommend keeping this setting enabled to ensure you get the latest features and security updates. Automatic core browser updates are not available on this platform yet, but component updates are. Please use external software to keep Zephyr up to date.
+
+ Allow downloading filter lists for uBlock Origin
+
+
-+ Helium will fetch fresh filter lists for uBlock Origin. All requests to lists are proxied to protect your privacy. When disabled, default filter lists will be loaded from local storage, which are only updated along with Helium. Optional filter lists will be requested without proxying.
++ Zephyr will fetch fresh filter lists for uBlock Origin. All requests to lists are proxied to protect your privacy. When disabled, default filter lists will be loaded from local storage, which are only updated along with Zephyr. Optional filter lists will be requested without proxying.
+
-
- Use your own instance of Helium services
+
+ Use your own instance of Zephyr services
--- a/chrome/browser/resources/settings/privacy_page/services_page.html
+++ b/chrome/browser/resources/settings/privacy_page/services_page.html
diff --git a/patches/helium/core/ublock-setup-sources.patch b/patches/helium/core/ublock-setup-sources.patch
index 75c3f52ae..bf19315f2 100644
--- a/patches/helium/core/ublock-setup-sources.patch
+++ b/patches/helium/core/ublock-setup-sources.patch
@@ -189,7 +189,7 @@
"https://ublockorigin.pages.dev/filters/badlists.txt",
"https://cdn.jsdelivr.net/gh/uBlockOrigin/uAssetsCDN@main/filters/badlists.txt",
@@ -36,7 +33,6 @@
- "title": "Helium filters – Annoyances",
+ "title": "Zephyr filters – Annoyances",
"tags": "annoyances",
"contentURL": [
- "https://raw.githubusercontent.com/imputnet/helium-services/main/filters/helium-annoyances.txt",
@@ -197,8 +197,8 @@
]
},
@@ -46,7 +42,6 @@
- "parent": "Helium filters",
- "title": "Helium filters – Unbreak",
+ "parent": "Zephyr filters",
+ "title": "Zephyr filters – Unbreak",
"contentURL": [
- "https://raw.githubusercontent.com/imputnet/helium-services/main/filters/helium-unbreak.txt",
"assets/helium/unbreak.txt"
diff --git a/patches/helium/core/update-credits.patch b/patches/helium/core/update-credits.patch
index c702031c6..1236490f8 100644
--- a/patches/helium/core/update-credits.patch
+++ b/patches/helium/core/update-credits.patch
@@ -6,8 +6,8 @@
reciprocal_contents = EvaluateTemplate(reciprocal_template, {
- 'opensource_project': 'ungoogled-chromium',
- 'opensource_link': 'https://github.com/ungoogled-software/ungoogled-chromium'
-+ 'opensource_project': 'Helium',
-+ 'opensource_link': 'https://github.com/imputnet/helium'
++ 'opensource_project': 'Zephyr',
++ 'opensource_link': 'https://github.com/quanticstudios/zephyr'
},
escape=False)
diff --git a/patches/helium/hop/setup.patch b/patches/helium/hop/setup.patch
index cddc3d8f3..97ef60f71 100644
--- a/patches/helium/hop/setup.patch
+++ b/patches/helium/hop/setup.patch
@@ -147,7 +147,7 @@
// policy. This source should be kept as highest priority source.
POLICY_SOURCE_RESTRICTED_MANAGED_GUEST_SESSION_OVERRIDE,
-+ // Helium opinionated policies
++ // Zephyr opinionated policies
+ POLICY_SOURCE_HOP,
+
// Number of source types. Has to be the last element.
@@ -211,8 +211,8 @@
Restricted managed guest session override
-+
-+ Helium defaults
++
++ Zephyr defaults
+ Local Server
diff --git a/patches/helium/settings/fix-text-on-cookies-page.patch b/patches/helium/settings/fix-text-on-cookies-page.patch
index fa7c9bd0e..3e97d627d 100644
--- a/patches/helium/settings/fix-text-on-cookies-page.patch
+++ b/patches/helium/settings/fix-text-on-cookies-page.patch
@@ -5,7 +5,7 @@
Enabling "Do Not Track" means that a request will be included with your browsing traffic. Any effect depends on whether a website responds to the request, and how the request is interpreted. For example, some websites may respond to this request by showing you ads that aren't based on other websites you've visited. Many websites will still collect and use your browsing data - for example to improve security, to provide content, services, ads and recommendations on their websites, and to generate reporting statistics.
+
-+ Enabling "Do Not Track" means that Helium will include a request not to be tracked with your browsing traffic. Whether this request is honored depends on whether a website responds to it and on how it is interpreted. For example, some websites may respond by showing you ads that aren't personalized using your previous browsing data. Many websites may still track you regardless of the request.
++ Enabling "Do Not Track" means that Zephyr will include a request not to be tracked with your browsing traffic. Whether this request is honored depends on whether a website responds to it and on how it is interpreted. For example, some websites may respond by showing you ads that aren't personalized using your previous browsing data. Many websites may still track you regardless of the request.
+
Learn more about Do Not Track
diff --git a/patches/helium/settings/update-search-suggest-text.patch b/patches/helium/settings/update-search-suggest-text.patch
index 4c6c201c2..9f95e3413 100644
--- a/patches/helium/settings/update-search-suggest-text.patch
+++ b/patches/helium/settings/update-search-suggest-text.patch
@@ -5,7 +5,7 @@
When you type in the address bar or search box, Chromium sends what you type to your default search engine to get better suggestions. This is off in Incognito.
+
-+ When you type in the address bar, Helium sends what you type to your default search engine to get suggestions. This is off in Incognito.
++ When you type in the address bar, Zephyr sends what you type to your default search engine to get suggestions. This is off in Incognito.
+
When you type in the address bar or search box, Chromium sends what you type to your organization's search, AI, and agent tools to get suggestions.
diff --git a/patches/helium/ui/add-specific-error-for-disabled-extension-downloads.patch b/patches/helium/ui/add-specific-error-for-disabled-extension-downloads.patch
index 54e47e827..7a1f272fe 100644
--- a/patches/helium/ui/add-specific-error-for-disabled-extension-downloads.patch
+++ b/patches/helium/ui/add-specific-error-for-disabled-extension-downloads.patch
@@ -95,8 +95,8 @@
File name or location is too long
+
-+ Extension downloads are disabled. Enable this feature in Helium services settings and try again.
++ desc="Subpage summary text for a extension download item that was interrupted because Zephyr services are disabled.">
++ Extension downloads are disabled. Enable this feature in Zephyr services settings and try again.
+
@@ -106,7 +106,7 @@
Something went wrong
+
++ desc="Status text for when Zephyr services extension downloading is disabled.">
+ Extension downloads are disabled
+
+
-+ Helium will not save anything about your browsing in Incognito, but downloads and bookmarks will stick around. Your browsing won't leave any traces on this device, and other users won't be able to see your activity.
++ Zephyr will not save anything about your browsing in Incognito, but downloads and bookmarks will stick around. Your browsing won't leave any traces on this device, and other users won't be able to see your activity.
+
Others who use this device won’t see your activity, so you can browse more privately. This won't change how data is collected by websites you visit and the services they use, including Google. Downloads, bookmarks and reading list items will be saved.
diff --git a/patches/helium/ui/layout-constants.patch b/patches/helium/ui/layout-constants.patch
index f491eca17..56a281212 100644
--- a/patches/helium/ui/layout-constants.patch
+++ b/patches/helium/ui/layout-constants.patch
@@ -162,7 +162,7 @@
#include "ui/gfx/geometry/size.h"
enum class LayoutConstant {
-+ // The base padding used in Helium UI.
++ // The base padding used in Zephyr UI.
+ kHeliumBasePadding,
+
// The size of the avatar icon in the profile row of the app menu.
diff --git a/patches/helium/ui/layout/compact.patch b/patches/helium/ui/layout/compact.patch
index e7a1d28f6..4db944516 100644
--- a/patches/helium/ui/layout/compact.patch
+++ b/patches/helium/ui/layout/compact.patch
@@ -13,11 +13,11 @@
+++ b/chrome/browser/helium_flag_entries.h
@@ -37,4 +37,8 @@
"Middle Click Autoscroll",
- "Enables autoscroll on middle click. Helium flag, Chromium feature.",
+ "Enables autoscroll on middle click. Zephyr flag, Chromium feature.",
kOsDesktop, FEATURE_VALUE_TYPE(blink::features::kHeliumMiddleClickAutoscroll)},
+ {helium::kHeliumCompactLocationWidthCommandLine,
+ "Automatic address bar width in compact layout",
-+ "Allows the location bar to automatically reduce its width in the compact browser layout. The omnibox may be uncomfortable to use. Helium flag.",
++ "Allows the location bar to automatically reduce its width in the compact browser layout. The omnibox may be uncomfortable to use. Zephyr flag.",
+ kOsDesktop, FEATURE_VALUE_TYPE(features::kHeliumCompactLocationWidth)},
#endif /* CHROME_BROWSER_HELIUM_FLAG_ENTRIES_H_ */
--- a/chrome/browser/ui/ui_features.cc
diff --git a/patches/helium/ui/layout/context-menu.patch b/patches/helium/ui/layout/context-menu.patch
index 44225a71f..cf75456bf 100644
--- a/patches/helium/ui/layout/context-menu.patch
+++ b/patches/helium/ui/layout/context-menu.patch
@@ -2,7 +2,7 @@
+++ b/chrome/app/chrome_command_ids.h
@@ -94,15 +94,11 @@
- // Helium commands
+ // Zephyr commands
#define IDC_COPY_OR_INSPECT_SHORTCUT 34080
-
-#if BUILDFLAG(IS_CHROMEOS)
@@ -27,7 +27,7 @@
Create split view
-+
++
+
+
+
@@ -64,7 +64,7 @@
+
+
+
-+
++
+
@@ -148,7 +148,7 @@
command_updater_.UpdateCommandEnabled(IDC_DECLUTTER_TABS, true);
command_updater_.UpdateCommandEnabled(IDC_TOGGLE_VERTICAL_TABS, true);
+
-+ // Helium layout menu
++ // Zephyr layout menu
+ command_updater_.UpdateCommandEnabled(IDC_BROWSER_LAYOUT_MENU, true);
+ command_updater_.UpdateCommandEnabled(IDC_BROWSER_LAYOUT_HORIZONTAL, true);
+ command_updater_.UpdateCommandEnabled(IDC_BROWSER_LAYOUT_COMPACT, true);
diff --git a/patches/helium/ui/layout/settings.patch b/patches/helium/ui/layout/settings.patch
index cb87ce7e1..bc4083120 100644
--- a/patches/helium/ui/layout/settings.patch
+++ b/patches/helium/ui/layout/settings.patch
@@ -4,7 +4,7 @@
}
s_allowlist = new PrefsUtil::TypedPrefMap();
-+ // Helium layout
++ // Zephyr layout
+ (*s_allowlist)[::prefs::kHeliumLayout] =
+ settings_api::PrefType::kNumber;
+ (*s_allowlist)[::prefs::kHeliumVerticalRightAligned] =
diff --git a/patches/helium/ui/layout/vertical-collapse-command.patch b/patches/helium/ui/layout/vertical-collapse-command.patch
new file mode 100644
index 000000000..ed8123aff
--- /dev/null
+++ b/patches/helium/ui/layout/vertical-collapse-command.patch
@@ -0,0 +1,120 @@
+--- a/chrome/app/chrome_command_ids.h
++++ b/chrome/app/chrome_command_ids.h
+@@ -99,6 +99,7 @@
+ #define IDC_BROWSER_LAYOUT_COMPACT 34083
+ #define IDC_BROWSER_LAYOUT_VERTICAL 34084
+ #define IDC_BROWSER_LAYOUT_VERTICAL_RIGHT 34085
++#define IDC_TOGGLE_VERTICAL_TAB_STRIP_COLLAPSED 34086
+
+ // Tab group Commands
+ #define IDC_ADD_NEW_TAB_TO_GROUP 34100
+--- a/chrome/browser/ui/browser_commands.h
++++ b/chrome/browser/ui/browser_commands.h
+@@ -263,6 +263,7 @@
+ void ToggleVerticalTabs(Browser* browser);
+ void SetBrowserLayout(Browser* browser, HeliumLayoutType layout);
+ void ToggleVerticalTabStripRightAligned(Browser* browser);
++void ToggleVerticalTabStripCollapsed(Browser* browser);
+ void ShowTabDeclutter(Browser* browser);
+ bool CanCloseFind(Browser* browser);
+ void CloseFind(Browser* browser);
+--- a/chrome/browser/ui/browser_commands.cc
++++ b/chrome/browser/ui/browser_commands.cc
+@@ -2243,6 +2243,14 @@
+ }
+ }
+
++void ToggleVerticalTabStripCollapsed(Browser* browser) {
++ auto* controller = tabs::VerticalTabStripStateController::From(browser);
++ if (!controller || !controller->ShouldDisplayVerticalTabs()) {
++ return;
++ }
++ controller->SetCollapsed(!controller->IsCollapsed());
++}
++
+ void ShowTabDeclutter(Browser* browser) {
+ browser->window()->CreateTabSearchBubble(
+ tab_search::mojom::TabSearchSection::kOrganize,
+--- a/chrome/browser/ui/browser_command_controller.h
++++ b/chrome/browser/ui/browser_command_controller.h
+@@ -224,6 +224,9 @@
+ // Updates commands that depend on the state of the tab strip model.
+ void UpdateCommandsForTabStripStateChanged();
+
++ // Updates commands that depend on Zephyr layout mode.
++ void UpdateCommandsForHeliumLayoutMode();
++
+ // Updates commands that depend on the enabled state of glic.
+ void UpdateCommandsForEnableGlicChanged();
+
+--- a/chrome/browser/ui/browser_command_controller.cc
++++ b/chrome/browser/ui/browser_command_controller.cc
+@@ -266,6 +266,11 @@
+ &BrowserCommandController::UpdateCommandsForBookmarkBar,
+ base::Unretained(this)));
+ profile_pref_registrar_.Add(
++ prefs::kHeliumLayout,
++ base::BindRepeating(
++ &BrowserCommandController::UpdateCommandsForHeliumLayoutMode,
++ base::Unretained(this)));
++ profile_pref_registrar_.Add(
+ policy::policy_prefs::kIncognitoModeAvailability,
+ base::BindRepeating(
+ &BrowserCommandController::UpdateCommandsForIncognitoAvailability,
+@@ -600,6 +605,9 @@
+ case IDC_BROWSER_LAYOUT_VERTICAL_RIGHT:
+ ToggleVerticalTabStripRightAligned(browser_);
+ break;
++ case IDC_TOGGLE_VERTICAL_TAB_STRIP_COLLAPSED:
++ ToggleVerticalTabStripCollapsed(browser_);
++ break;
+
+ // Window management commands
+ case IDC_NEW_WINDOW:
+@@ -1518,6 +1526,9 @@
+ command_updater_.UpdateCommandEnabled(IDC_BROWSER_LAYOUT_VERTICAL, true);
+ command_updater_.UpdateCommandEnabled(IDC_BROWSER_LAYOUT_VERTICAL_RIGHT,
+ true);
++ command_updater_.UpdateCommandEnabled(IDC_TOGGLE_VERTICAL_TAB_STRIP_COLLAPSED,
++ false);
++ UpdateCommandsForHeliumLayoutMode();
+ #if BUILDFLAG(IS_CHROMEOS)
+ command_updater_.UpdateCommandEnabled(IDC_TOGGLE_MULTITASK_MENU, true);
+ command_updater_.UpdateCommandEnabled(IDC_MINIMIZE_WINDOW, true);
+@@ -2399,6 +2410,14 @@
+ UpdateCommandsForBookmarkEditing();
+ }
+
++void BrowserCommandController::UpdateCommandsForHeliumLayoutMode() {
++ const bool is_vertical_layout =
++ profile()->GetPrefs()->GetInteger(prefs::kHeliumLayout) ==
++ std::to_underlying(HeliumLayoutType::kVertical);
++ command_updater_.UpdateCommandEnabled(IDC_TOGGLE_VERTICAL_TAB_STRIP_COLLAPSED,
++ is_vertical_layout);
++}
++
+ actions::ActionItem* BrowserCommandController::FindAction(
+ actions::ActionId action_id) {
+ actions::ActionItem* const root_action_item =
+--- a/chrome/browser/ui/accelerator_table.cc
++++ b/chrome/browser/ui/accelerator_table.cc
+@@ -61,6 +61,8 @@
+ {ui::VKEY_F, ui::EF_PLATFORM_ACCELERATOR, IDC_FIND},
+ {ui::VKEY_A, ui::EF_SHIFT_DOWN | ui::EF_PLATFORM_ACCELERATOR,
+ IDC_TAB_SEARCH},
++ {ui::VKEY_V, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
++ IDC_TOGGLE_VERTICAL_TAB_STRIP_COLLAPSED},
+ {ui::VKEY_G, ui::EF_PLATFORM_ACCELERATOR, IDC_FIND_NEXT},
+ {ui::VKEY_G, ui::EF_SHIFT_DOWN | ui::EF_PLATFORM_ACCELERATOR,
+ IDC_FIND_PREVIOUS},
+--- a/chrome/browser/ui/cocoa/accelerators_cocoa.mm
++++ b/chrome/browser/ui/cocoa/accelerators_cocoa.mm
+@@ -40,6 +40,8 @@
+ {IDC_DEV_TOOLS_INSPECT, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::VKEY_E},
+ {IDC_COPY_OR_INSPECT_SHORTCUT, ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN, ui::VKEY_C},
+ {IDC_NEW_SPLIT_TAB, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::VKEY_N},
++ {IDC_TOGGLE_VERTICAL_TAB_STRIP_COLLAPSED,
++ ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN, ui::VKEY_V},
+ {IDC_FIND, ui::EF_COMMAND_DOWN, ui::VKEY_F},
+ {IDC_NEW_INCOGNITO_WINDOW, ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN,
+ ui::VKEY_N},
diff --git a/patches/helium/ui/layout/vertical-command-launcher.patch b/patches/helium/ui/layout/vertical-command-launcher.patch
new file mode 100644
index 000000000..e80fb1258
--- /dev/null
+++ b/patches/helium/ui/layout/vertical-command-launcher.patch
@@ -0,0 +1,893 @@
+--- a/chrome/app/chrome_command_ids.h
++++ b/chrome/app/chrome_command_ids.h
+@@ -100,6 +100,7 @@
+ #define IDC_BROWSER_LAYOUT_VERTICAL 34084
+ #define IDC_BROWSER_LAYOUT_VERTICAL_RIGHT 34085
+ #define IDC_TOGGLE_VERTICAL_TAB_STRIP_COLLAPSED 34086
++#define IDC_HELIUM_COMMAND_LAUNCHER 34087
+
+ // Tab group Commands
+ #define IDC_ADD_NEW_TAB_TO_GROUP 34100
+--- a/chrome/browser/ui/browser_commands.h
++++ b/chrome/browser/ui/browser_commands.h
+@@ -258,6 +258,7 @@
+ void FindPrevious(Browser* browser);
+ void FindInPage(Browser* browser, bool find_next, bool forward_direction);
+ void ShowTabSearch(BrowserWindowInterface* bwi);
++void ShowCommandLauncher(BrowserWindowInterface* bwi);
+ void CloseTabSearch(Browser* browser);
+ void ToggleContextualTasksSidePanel(BrowserWindowInterface* browser);
+ void ToggleVerticalTabs(Browser* browser);
+--- a/chrome/browser/ui/browser_commands.cc
++++ b/chrome/browser/ui/browser_commands.cc
+@@ -2199,6 +2199,12 @@
+ tab_search::mojom::TabOrganizationFeature::kNone);
+ }
+
++void ShowCommandLauncher(BrowserWindowInterface* bwi) {
++ bwi->GetBrowserForMigrationOnly()->window()->CreateTabSearchBubble(
++ tab_search::mojom::TabSearchSection::kCommand,
++ tab_search::mojom::TabOrganizationFeature::kNone);
++}
++
+ void CloseTabSearch(Browser* browser) {
+ browser->window()->CloseTabSearchBubble();
+ }
+--- a/chrome/browser/ui/browser_command_controller.cc
++++ b/chrome/browser/ui/browser_command_controller.cc
+@@ -415,7 +415,8 @@
+ command_id == IDC_SELECT_NEXT_TAB ||
+ command_id == IDC_SELECT_PREVIOUS_TAB || command_id == IDC_EXIT ||
+ command_id == IDC_COPY_OR_INSPECT_SHORTCUT || command_id == IDC_DEV_TOOLS ||
+- command_id == IDC_DEV_TOOLS_TOGGLE || command_id == IDC_TAB_SEARCH;
++ command_id == IDC_DEV_TOOLS_TOGGLE || command_id == IDC_TAB_SEARCH ||
++ command_id == IDC_HELIUM_COMMAND_LAUNCHER;
+ }
+
+ void BrowserCommandController::TabStateChanged() {
+@@ -587,6 +588,9 @@
+ case IDC_TAB_SEARCH:
+ ShowTabSearch(browser_);
+ break;
++ case IDC_HELIUM_COMMAND_LAUNCHER:
++ ShowCommandLauncher(browser_);
++ break;
+ case IDC_TAB_SEARCH_CLOSE:
+ CloseTabSearch(browser_);
+ break;
+@@ -1747,6 +1751,8 @@
+ const bool enable_tab_search_commands = browser_->is_type_normal();
+ command_updater_.UpdateCommandEnabled(IDC_TAB_SEARCH,
+ enable_tab_search_commands);
++ command_updater_.UpdateCommandEnabled(IDC_HELIUM_COMMAND_LAUNCHER,
++ enable_tab_search_commands);
+ command_updater_.UpdateCommandEnabled(IDC_TAB_SEARCH_CLOSE,
+ enable_tab_search_commands);
+
+--- a/chrome/browser/ui/accelerator_table.cc
++++ b/chrome/browser/ui/accelerator_table.cc
+@@ -61,6 +61,8 @@
+ {ui::VKEY_F, ui::EF_PLATFORM_ACCELERATOR, IDC_FIND},
+ {ui::VKEY_A, ui::EF_SHIFT_DOWN | ui::EF_PLATFORM_ACCELERATOR,
+ IDC_TAB_SEARCH},
++ {ui::VKEY_K, ui::EF_SHIFT_DOWN | ui::EF_PLATFORM_ACCELERATOR,
++ IDC_HELIUM_COMMAND_LAUNCHER},
+ {ui::VKEY_V, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN,
+ IDC_TOGGLE_VERTICAL_TAB_STRIP_COLLAPSED},
+ {ui::VKEY_G, ui::EF_PLATFORM_ACCELERATOR, IDC_FIND_NEXT},
+--- a/chrome/browser/ui/cocoa/accelerators_cocoa.mm
++++ b/chrome/browser/ui/cocoa/accelerators_cocoa.mm
+@@ -40,6 +40,8 @@
+ {IDC_DEV_TOOLS_INSPECT, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::VKEY_E},
+ {IDC_COPY_OR_INSPECT_SHORTCUT, ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN, ui::VKEY_C},
+ {IDC_NEW_SPLIT_TAB, ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN, ui::VKEY_N},
++ {IDC_HELIUM_COMMAND_LAUNCHER, ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN,
++ ui::VKEY_K},
+ {IDC_TOGGLE_VERTICAL_TAB_STRIP_COLLAPSED,
+ ui::EF_COMMAND_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN, ui::VKEY_V},
+ {IDC_FIND, ui::EF_COMMAND_DOWN, ui::VKEY_F},
+--- a/chrome/browser/ui/webui/tab_search/tab_search.mojom
++++ b/chrome/browser/ui/webui/tab_search/tab_search.mojom
+@@ -46,6 +46,7 @@
+ [Default] kNone = 0,
+ kSearch = 1,
+ kOrganize = 2,
++ kCommand = 3,
+ };
+
+ //TODO(b/311697865) move this to a common location.
+@@ -197,6 +198,12 @@
+ int32 tab_id;
+ };
+
++struct LauncherCommand {
++ int32 command_id;
++ string title;
++ bool enabled;
++};
++
+ struct TabOrganization {
+ int32 organization_id;
+ array tabs;
+@@ -281,6 +288,12 @@
+ // Get window and tab data for the current profile.
+ GetProfileData() => (ProfileData profile_data);
+
++ // Get command launcher actions available in the current browser context.
++ GetLauncherCommands() => (array commands);
++
++ // Execute a command launcher action by command id.
++ ExecuteLauncherCommand(int32 command_id) => (bool executed);
++
+ // Get all tabs that are considered stale based on their last active time,
+ // and tabs that are duplicates of other tabs based on partial URL match
+ // (excludes fragments).
+--- a/chrome/browser/ui/webui/tab_search/tab_search_page_handler.h
++++ b/chrome/browser/ui/webui/tab_search/tab_search_page_handler.h
+@@ -108,6 +108,9 @@
+ void ExcludeFromStaleTabs(int32_t tab_id) override;
+ void ExcludeFromDuplicateTabs(const GURL& url) override;
+ void GetProfileData(GetProfileDataCallback callback) override;
++ void GetLauncherCommands(GetLauncherCommandsCallback callback) override;
++ void ExecuteLauncherCommand(int32_t command_id,
++ ExecuteLauncherCommandCallback callback) override;
+ void GetUnusedTabs(GetUnusedTabsCallback callback) override;
+ void GetTabSearchSection(GetTabSearchSectionCallback callback) override;
+ void GetTabOrganizationFeature(
+--- a/chrome/browser/ui/webui/tab_search/tab_search_page_handler.cc
++++ b/chrome/browser/ui/webui/tab_search/tab_search_page_handler.cc
+@@ -15,6 +15,7 @@
+ #include
+
+ #include "base/base64.h"
++#include "base/containers/contains.h"
+ #include "base/feature_list.h"
+ #include "base/functional/bind.h"
+ #include "base/metrics/histogram_functions.h"
+@@ -23,6 +24,7 @@
+ #include "base/timer/timer.h"
+ #include "base/trace_event/trace_event.h"
+ #include "base/values.h"
++#include "chrome/app/chrome_command_ids.h"
+ #include "chrome/browser/favicon/favicon_utils.h"
+ #include "chrome/browser/feedback/show_feedback_page.h"
+ #include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h"
+@@ -33,6 +35,7 @@
+ #include "chrome/browser/signin/signin_error_controller_factory.h"
+ #include "chrome/browser/signin/signin_ui_util.h"
+ #include "chrome/browser/ui/browser.h"
++#include "chrome/browser/ui/browser_commands.h"
+ #include "chrome/browser/ui/browser_live_tab_context.h"
+ #include "chrome/browser/ui/browser_navigator.h"
+ #include "chrome/browser/ui/browser_window.h"
+@@ -77,6 +80,49 @@
+
+ namespace {
+ constexpr base::TimeDelta kTabsChangeDelay = base::Milliseconds(50);
++constexpr int kLauncherCommandIds[] = {
++ IDC_NEW_TAB,
++ IDC_NEW_WINDOW,
++ IDC_NEW_INCOGNITO_WINDOW,
++ IDC_RESTORE_TAB,
++ IDC_DUPLICATE_TAB,
++ IDC_BOOKMARK_THIS_TAB,
++ IDC_SHOW_HISTORY,
++ IDC_SHOW_DOWNLOADS,
++ IDC_OPTIONS,
++ IDC_TOGGLE_VERTICAL_TAB_STRIP_COLLAPSED,
++};
++
++bool IsSupportedLauncherCommand(int command_id) {
++ return base::Contains(kLauncherCommandIds, command_id);
++}
++
++std::string GetLauncherCommandTitle(int command_id) {
++ switch (command_id) {
++ case IDC_NEW_TAB:
++ return l10n_util::GetStringUTF8(IDS_NEW_TAB);
++ case IDC_NEW_WINDOW:
++ return l10n_util::GetStringUTF8(IDS_NEW_WINDOW);
++ case IDC_NEW_INCOGNITO_WINDOW:
++ return l10n_util::GetStringUTF8(IDS_NEW_INCOGNITO_WINDOW);
++ case IDC_RESTORE_TAB:
++ return l10n_util::GetStringUTF8(IDS_RESTORE_TAB);
++ case IDC_DUPLICATE_TAB:
++ return l10n_util::GetStringUTF8(IDS_TAB_CXMENU_DUPLICATE);
++ case IDC_BOOKMARK_THIS_TAB:
++ return l10n_util::GetStringUTF8(IDS_BOOKMARK_THIS_TAB);
++ case IDC_SHOW_HISTORY:
++ return l10n_util::GetStringUTF8(IDS_HISTORY_SHOW_HISTORY);
++ case IDC_SHOW_DOWNLOADS:
++ return l10n_util::GetStringUTF8(IDS_SHOW_DOWNLOADS);
++ case IDC_OPTIONS:
++ return l10n_util::GetStringUTF8(IDS_SETTINGS);
++ case IDC_TOGGLE_VERTICAL_TAB_STRIP_COLLAPSED:
++ return "Toggle Sidebar";
++ default:
++ return "";
++ }
++}
+
+ std::string GetLastActiveElapsedText(
+ const base::TimeTicks& last_active_time_ticks) {
+@@ -687,6 +733,37 @@
+ std::move(callback).Run(std::move(profile_tabs));
+ }
+
++void TabSearchPageHandler::GetLauncherCommands(
++ GetLauncherCommandsCallback callback) {
++ std::vector commands;
++ if (!browser_) {
++ std::move(callback).Run(std::move(commands));
++ return;
++ }
++
++ for (const int command_id : kLauncherCommandIds) {
++ if (!chrome::SupportsCommand(browser_, command_id)) {
++ continue;
++ }
++ auto command = tab_search::mojom::LauncherCommand::New();
++ command->command_id = command_id;
++ command->title = GetLauncherCommandTitle(command_id);
++ command->enabled = chrome::IsCommandEnabled(browser_, command_id);
++ commands.push_back(std::move(command));
++ }
++
++ std::move(callback).Run(std::move(commands));
++}
++
++void TabSearchPageHandler::ExecuteLauncherCommand(
++ int32_t command_id,
++ ExecuteLauncherCommandCallback callback) {
++ const bool executed = browser_ && IsSupportedLauncherCommand(command_id) &&
++ chrome::SupportsCommand(browser_, command_id) &&
++ chrome::ExecuteCommand(browser_, command_id);
++ std::move(callback).Run(executed);
++}
++
+ void TabSearchPageHandler::GetUnusedTabs(GetUnusedTabsCallback callback) {
+ UpdateUnusedTabs();
+ std::move(callback).Run(GetMojoUnusedTabs());
+--- a/chrome/browser/ui/webui/tab_search/tab_search_ui.cc
++++ b/chrome/browser/ui/webui/tab_search/tab_search_ui.cc
+@@ -227,6 +227,15 @@
+ ui::Accelerator accelerator(ui::VKEY_A,
+ ui::EF_SHIFT_DOWN | ui::EF_PLATFORM_ACCELERATOR);
+ source->AddString("shortcutText", accelerator.GetShortcutText());
++ ui::Accelerator command_launcher_accelerator(
++ ui::VKEY_K, ui::EF_SHIFT_DOWN | ui::EF_PLATFORM_ACCELERATOR);
++ source->AddString("commandLauncherShortcutText",
++ command_launcher_accelerator.GetShortcutText());
++ source->AddString("commandLauncherSearchPlaceholder",
++ "Search commands and tabs");
++ source->AddString("commandLauncherCommandsTitle", "Commands");
++ source->AddString("commandLauncherTabsTitle", "Tabs");
++ source->AddString("commandLauncherActionSubtitle", "Action");
+ // TODO(b/362269642): Once the stale threshold duration is Finch-
+ // configurable, replace the hardcoded 7 below with the value of that
+ // parameter.
+--- a/chrome/browser/resources/tab_search/BUILD.gn
++++ b/chrome/browser/resources/tab_search/BUILD.gn
+@@ -45,6 +45,8 @@
+ "auto_tab_groups/auto_tab_groups_results.ts",
+ "auto_tab_groups/auto_tab_groups_results_actions.html.ts",
+ "auto_tab_groups/auto_tab_groups_results_actions.ts",
++ "command_launcher_page.html.ts",
++ "command_launcher_page.ts",
+ "declutter/declutter_page.html.ts",
+ "declutter/declutter_page.ts",
+ "lazy_list.ts",
+@@ -84,6 +86,7 @@
+ "auto_tab_groups/auto_tab_groups_results.css",
+ "auto_tab_groups/auto_tab_groups_results_actions.css",
+ "auto_tab_groups/auto_tab_groups_shared_style.css",
++ "command_launcher_page.css",
+ "declutter/declutter_page.css",
+ "lazy_list.css",
+ "selectable_lazy_list.css",
+--- a/chrome/browser/resources/tab_search/app.ts
++++ b/chrome/browser/resources/tab_search/app.ts
+@@ -3,6 +3,7 @@
+ // found in the LICENSE file.
+
+ import './auto_tab_groups/auto_tab_groups_page.js';
++import './command_launcher_page.js';
+ import './declutter/declutter_page.js';
+ import './tab_organization_selector.js';
+ import './tab_search_page.js';
+@@ -113,9 +114,14 @@
+ this.tabOrganizationEnabled_ = enabled;
+ }
+
++ protected isCommandLauncherMode_(): boolean {
++ return this.selectedTabSection_ === TabSearchSection.kCommand;
++ }
++
+ protected sectionToIndex_(section: TabSearchSection): number {
+ switch (section) {
+ case TabSearchSection.kNone:
++ case TabSearchSection.kCommand:
+ return -1;
+ case TabSearchSection.kSearch:
+ return 0;
+--- a/chrome/browser/resources/tab_search/app.html.ts
++++ b/chrome/browser/resources/tab_search/app.html.ts
+@@ -9,7 +9,10 @@
+ export function getHtml(this: TabSearchAppElement) {
+ // clang-format off
+ return html`
+-${(this.tabOrganizationEnabled_ || this.declutterEnabled_) ? html`
++${this.isCommandLauncherMode_() ? html`
++
++
++` : (this.tabOrganizationEnabled_ || this.declutterEnabled_) ? html`
+ ;
+
++ getLauncherCommands(): Promise<{commands: LauncherCommand[]}>;
++
++ executeLauncherCommand(commandId: number): Promise<{executed: boolean}>;
++
+ getUnusedTabs(): Promise<{tabs: UnusedTabInfo}>;
+
+ getTabSearchSection(): Promise<{section: TabSearchSection}>;
+@@ -140,6 +144,14 @@
+ return this.handler.getProfileData();
+ }
+
++ getLauncherCommands() {
++ return this.handler.getLauncherCommands();
++ }
++
++ executeLauncherCommand(commandId: number) {
++ return this.handler.executeLauncherCommand(commandId);
++ }
++
+ getUnusedTabs() {
+ return this.handler.getUnusedTabs();
+ }
+--- a/chrome/browser/resources/tab_search/command_launcher_page.ts
++++ b/chrome/browser/resources/tab_search/command_launcher_page.ts
+@@ -0,0 +1,342 @@
++// Copyright 2026 The Chromium Authors
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++import '/strings.m.js';
++import 'chrome://resources/cr_elements/cr_icon/cr_icon.js';
++
++import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
++import {CrLitElement} from 'chrome://resources/lit/v3_0/lit.rollup.js';
++import type {PropertyValues} from 'chrome://resources/lit/v3_0/lit.rollup.js';
++
++import type {LauncherCommand, ProfileData, Tab} from './tab_search.mojom-webui.js';
++import type {TabSearchApiProxy} from './tab_search_api_proxy.js';
++import {TabSearchApiProxyImpl} from './tab_search_api_proxy.js';
++import {getCss} from './command_launcher_page.css.js';
++import {getHtml} from './command_launcher_page.html.js';
++
++type HeadingItem = {
++ kind: 'heading',
++ title: string,
++};
++
++type CommandItem = {
++ kind: 'command',
++ command: LauncherCommand,
++ rank: number,
++ score: number,
++};
++
++type TabItem = {
++ kind: 'tab',
++ tab: Tab,
++ inActiveWindow: boolean,
++ score: number,
++};
++
++type DisplayItem = HeadingItem|CommandItem|TabItem;
++
++type OpenTab = {
++ tab: Tab,
++ inActiveWindow: boolean,
++};
++
++function isSelectable(item: DisplayItem): item is CommandItem|TabItem {
++ return item.kind === 'command' || item.kind === 'tab';
++}
++
++function safeHost(url: string): string {
++ try {
++ return new URL(url).hostname;
++ } catch {
++ return '';
++ }
++}
++
++function scoreText(query: string, value: string): number {
++ if (!query) {
++ return 1;
++ }
++
++ const text = value.toLowerCase();
++ const idx = text.indexOf(query);
++ if (idx === -1) {
++ return 0;
++ }
++
++ if (idx === 0) {
++ return 300 - query.length;
++ }
++
++ const charBefore = text[idx - 1] || '';
++ const isBoundary = /[\s/_.:-]/.test(charBefore);
++ return (isBoundary ? 220 : 120) - idx;
++}
++
++function scoreCommand(
++ query: string, command: LauncherCommand, rank: number): number {
++ if (!query) {
++ return 100 - rank;
++ }
++ return scoreText(query, command.title);
++}
++
++function scoreTab(query: string, tab: Tab, inActiveWindow: boolean): number {
++ if (!query) {
++ return inActiveWindow ? 2 : 1;
++ }
++
++ const titleScore = scoreText(query, tab.title) * 2;
++ const hostScore = scoreText(query, safeHost(tab.url.url));
++ const activeWindowBoost = inActiveWindow ? 15 : 0;
++ return Math.max(titleScore, hostScore) + activeWindowBoost;
++}
++
++function compareTabsByActivity(a: Tab, b: Tab): number {
++ const aValue = Number(a.lastActiveTimeTicks.internalValue);
++ const bValue = Number(b.lastActiveTimeTicks.internalValue);
++ return bValue - aValue;
++}
++
++export class CommandLauncherPageElement extends CrLitElement {
++ static get is() {
++ return 'command-launcher-page';
++ }
++
++ static override get properties() {
++ return {
++ availableHeight: {type: Number},
++ query_: {type: String},
++ displayItems_: {type: Array},
++ selectedDisplayIndex_: {type: Number},
++ shortcut_: {type: String},
++ };
++ }
++
++ accessor availableHeight: number|undefined;
++ protected accessor query_: string = '';
++ protected accessor displayItems_: DisplayItem[] = [];
++ protected accessor selectedDisplayIndex_: number = -1;
++ protected accessor shortcut_: string =
++ loadTimeData.getString('commandLauncherShortcutText');
++
++ private apiProxy_: TabSearchApiProxy = TabSearchApiProxyImpl.getInstance();
++ private commands_: LauncherCommand[] = [];
++ private openTabs_: OpenTab[] = [];
++
++ static override get styles() {
++ return getCss();
++ }
++
++ override render() {
++ return getHtml.bind(this)();
++ }
++
++ override connectedCallback() {
++ super.connectedCallback();
++ this.refreshData_();
++ }
++
++ override updated(changedProperties: PropertyValues) {
++ super.updated(changedProperties);
++
++ if (changedProperties.has('availableHeight')) {
++ this.requestUpdate();
++ }
++ }
++
++ protected getListMaxHeight_(): string {
++ const height = this.availableHeight ?? 440;
++ return `${Math.max(180, height - 78)}px`;
++ }
++
++ protected onQueryInput_(e: Event) {
++ const target = e.target as HTMLInputElement;
++ this.query_ = target.value;
++ this.rebuildDisplayItems_();
++ }
++
++ protected async onSearchKeyDown_(e: KeyboardEvent) {
++ if (e.key === 'ArrowDown') {
++ this.moveSelection_(1);
++ e.preventDefault();
++ return;
++ }
++
++ if (e.key === 'ArrowUp') {
++ this.moveSelection_(-1);
++ e.preventDefault();
++ return;
++ }
++
++ if (e.key === 'Enter') {
++ e.preventDefault();
++ await this.executeSelected_();
++ return;
++ }
++
++ if (e.key === 'Escape') {
++ e.preventDefault();
++ window.close();
++ }
++ }
++
++ protected isSelected_(index: number): boolean {
++ return this.selectedDisplayIndex_ === index;
++ }
++
++ protected onRowMouseEnter_(e: Event) {
++ const target = e.currentTarget as HTMLElement;
++ this.selectedDisplayIndex_ = Number(target.dataset['index']);
++ }
++
++ protected async onRowClick_(e: Event) {
++ const target = e.currentTarget as HTMLElement;
++ const index = Number(target.dataset['index']);
++ this.selectedDisplayIndex_ = index;
++ await this.executeSelected_();
++ }
++
++ protected rowTitle_(item: CommandItem|TabItem): string {
++ return item.kind === 'command' ? item.command.title : item.tab.title;
++ }
++
++ protected rowSubtitle_(item: CommandItem|TabItem): string {
++ if (item.kind === 'command') {
++ return loadTimeData.getString('commandLauncherActionSubtitle');
++ }
++ const url = item.tab.url.url;
++ return safeHost(url) || url;
++ }
++
++ private async refreshData_() {
++ const [{commands}, {profileData}] = await Promise.all([
++ this.apiProxy_.getLauncherCommands(),
++ this.apiProxy_.getProfileData(),
++ ]);
++ this.commands_ = commands.filter(command => command.enabled);
++ this.openTabs_ = this.getOpenTabs_(profileData);
++ this.rebuildDisplayItems_();
++ }
++
++ private getOpenTabs_(profileData: ProfileData): OpenTab[] {
++ return profileData.windows.reduce((acc, window) => {
++ acc.push(...window.tabs.map(tab => ({tab, inActiveWindow: window.active})));
++ return acc;
++ }, [] as OpenTab[]);
++ }
++
++ private rebuildDisplayItems_() {
++ const query = this.query_.trim().toLowerCase();
++
++ const commandItems = this.commands_
++ .map((command, rank) => ({
++ kind: 'command' as const,
++ command,
++ rank,
++ score: scoreCommand(query, command, rank),
++ }))
++ .filter(item => query ? item.score > 0 : true)
++ .sort((a, b) => {
++ if (b.score !== a.score) {
++ return b.score - a.score;
++ }
++ if (a.rank !== b.rank) {
++ return a.rank - b.rank;
++ }
++ return a.command.title.localeCompare(
++ b.command.title);
++ })
++ .slice(0, 8);
++
++ const tabItems = this.openTabs_
++ .map(openTab => ({
++ kind: 'tab' as const,
++ tab: openTab.tab,
++ inActiveWindow: openTab.inActiveWindow,
++ score: scoreTab(
++ query, openTab.tab, openTab.inActiveWindow),
++ }))
++ .filter(item => query ? item.score > 0 : true)
++ .sort((a, b) => {
++ if (b.score !== a.score) {
++ return b.score - a.score;
++ }
++ if (a.inActiveWindow !== b.inActiveWindow) {
++ return a.inActiveWindow ? -1 : 1;
++ }
++ return compareTabsByActivity(a.tab, b.tab);
++ })
++ .slice(0, 8);
++
++ const nextItems: DisplayItem[] = [];
++ if (commandItems.length > 0) {
++ nextItems.push({
++ kind: 'heading',
++ title: loadTimeData.getString('commandLauncherCommandsTitle'),
++ });
++ nextItems.push(...commandItems);
++ }
++ if (tabItems.length > 0) {
++ nextItems.push({
++ kind: 'heading',
++ title: loadTimeData.getString('commandLauncherTabsTitle'),
++ });
++ nextItems.push(...tabItems);
++ }
++
++ this.displayItems_ = nextItems;
++
++ if (!this.isSelectableIndex_(this.selectedDisplayIndex_)) {
++ this.selectedDisplayIndex_ = this.firstSelectableIndex_();
++ }
++ }
++
++ private isSelectableIndex_(index: number): boolean {
++ if (index < 0 || index >= this.displayItems_.length) {
++ return false;
++ }
++ return isSelectable(this.displayItems_[index]!);
++ }
++
++ private firstSelectableIndex_(): number {
++ return this.displayItems_.findIndex(item => isSelectable(item));
++ }
++
++ private moveSelection_(delta: number) {
++ const selectableIndices = this.displayItems_
++ .map((item, index) => ({item, index}))
++ .filter(({item}) => isSelectable(item))
++ .map(({index}) => index);
++ if (selectableIndices.length === 0) {
++ this.selectedDisplayIndex_ = -1;
++ return;
++ }
++
++ const currentPosition = selectableIndices.indexOf(this.selectedDisplayIndex_);
++ if (currentPosition === -1) {
++ this.selectedDisplayIndex_ = selectableIndices[0]!;
++ return;
++ }
++
++ const nextPosition =
++ (currentPosition + delta + selectableIndices.length) % selectableIndices.length;
++ this.selectedDisplayIndex_ = selectableIndices[nextPosition]!;
++ }
++
++ private async executeSelected_() {
++ if (!this.isSelectableIndex_(this.selectedDisplayIndex_)) {
++ return;
++ }
++
++ const selected = this.displayItems_[this.selectedDisplayIndex_]!;
++ if (!isSelectable(selected)) {
++ return;
++ }
++
++ if (selected.kind === 'command') {
++ const {executed} =
++ await this.apiProxy_.executeLauncherCommand(selected.command.commandId);
++ if (!executed) {
++ return;
++ }
++ } else {
++ this.apiProxy_.switchToTab({tabId: selected.tab.tabId});
++ }
++
++ window.close();
++ }
++}
++
++declare global {
++ interface HTMLElementTagNameMap {
++ 'command-launcher-page': CommandLauncherPageElement;
++ }
++}
++
++customElements.define(CommandLauncherPageElement.is, CommandLauncherPageElement);
+--- a/chrome/browser/resources/tab_search/command_launcher_page.html.ts
++++ b/chrome/browser/resources/tab_search/command_launcher_page.html.ts
+@@ -0,0 +1,47 @@
++// Copyright 2026 The Chromium Authors
++// Use of this source code is governed by a BSD-style license that can be
++// found in the LICENSE file.
++
++import {html} from '//resources/lit/v3_0/lit.rollup.js';
++
++import type {CommandLauncherPageElement} from './command_launcher_page.js';
++
++export function getHtml(this: CommandLauncherPageElement) {
++ // clang-format off
++ return html`
++