unification improvements

This commit is contained in:
BeniBenj
2025-11-05 13:04:33 +01:00
parent 0bec095988
commit 9ffbee79e0
5 changed files with 15 additions and 17 deletions
@@ -674,7 +674,7 @@ class ConfigurationRegistry extends Disposable implements IConfigurationRegistry
order: configuration.order,
extensionInfo: configuration.extensionInfo
};
if (validate && validateProperty(key, property)) {
if (validate && validateProperty(key, property, extensionInfo?.id)) {
delete properties[key];
continue;
}
@@ -940,14 +940,14 @@ export function getDefaultValue(type: string | string[] | undefined) {
const configurationRegistry = new ConfigurationRegistry();
Registry.add(Extensions.Configuration, configurationRegistry);
export function validateProperty(property: string, schema: IRegisteredConfigurationPropertySchema): string | null {
export function validateProperty(property: string, schema: IRegisteredConfigurationPropertySchema, extensionId?: string): string | null {
if (!property.trim()) {
return nls.localize('config.property.empty', "Cannot register an empty property");
}
if (OVERRIDE_PROPERTY_REGEX.test(property)) {
return nls.localize('config.property.languageDefault', "Cannot register '{0}'. This matches property pattern '\\\\[.*\\\\]$' for describing language specific editor settings. Use 'configurationDefaults' contribution.", property);
}
if (configurationRegistry.getConfigurationProperties()[property] !== undefined && !CODE_UNIFICATION_DUPLICATE_SETTINGS.has(property)) {
if (configurationRegistry.getConfigurationProperties()[property] !== undefined && (!extensionId || !EXTENSION_UNIFICATION_EXTENSION_IDS.has(extensionId.toLowerCase()))) {
return nls.localize('config.property.duplicate', "Cannot register '{0}'. This property is already registered.", property);
}
if (schema.policy?.name && configurationRegistry.getPolicyConfigurations().get(schema.policy?.name) !== undefined) {
@@ -1001,4 +1001,4 @@ export function parseScope(scope: string): ConfigurationScope {
}
// Used for extension unification. Should be removed when complete.
export const CODE_UNIFICATION_DUPLICATE_SETTINGS: Set<string> = new Set([product.defaultChatAgent?.completionsEnablementSetting].filter(Boolean) as string[]);
export const EXTENSION_UNIFICATION_EXTENSION_IDS: Set<string> = new Set(product.defaultChatAgent ? [product.defaultChatAgent.extensionId, product.defaultChatAgent.chatExtensionId].map(id => id.toLowerCase()) : []);
@@ -8,7 +8,7 @@ import * as objects from '../../../base/common/objects.js';
import { Registry } from '../../../platform/registry/common/platform.js';
import { IJSONSchema } from '../../../base/common/jsonSchema.js';
import { ExtensionsRegistry, IExtensionPointUser } from '../../services/extensions/common/extensionsRegistry.js';
import { IConfigurationNode, IConfigurationRegistry, Extensions, validateProperty, ConfigurationScope, OVERRIDE_PROPERTY_REGEX, IConfigurationDefaults, configurationDefaultsSchemaId, IConfigurationDelta, getDefaultValue, getAllConfigurationProperties, parseScope, CODE_UNIFICATION_DUPLICATE_SETTINGS } from '../../../platform/configuration/common/configurationRegistry.js';
import { IConfigurationNode, IConfigurationRegistry, Extensions, validateProperty, ConfigurationScope, OVERRIDE_PROPERTY_REGEX, IConfigurationDefaults, configurationDefaultsSchemaId, IConfigurationDelta, getDefaultValue, getAllConfigurationProperties, parseScope, EXTENSION_UNIFICATION_EXTENSION_IDS } from '../../../platform/configuration/common/configurationRegistry.js';
import { IJSONContributionRegistry, Extensions as JSONExtensions } from '../../../platform/jsonschemas/common/jsonContributionRegistry.js';
import { workspaceSettingsSchemaId, launchSchemaId, tasksSchemaId, mcpSchemaId } from '../../services/configuration/common/configuration.js';
import { isObject, isUndefined } from '../../../base/common/types.js';
@@ -268,13 +268,13 @@ configurationExtPoint.setHandler((extensions, { added, removed }) => {
}
for (const key in properties) {
const propertyConfiguration = properties[key];
const message = validateProperty(key, propertyConfiguration);
const message = validateProperty(key, propertyConfiguration, extension.description.identifier.value);
if (message) {
delete properties[key];
extension.collector.warn(message);
continue;
}
if (seenProperties.has(key) && !CODE_UNIFICATION_DUPLICATE_SETTINGS.has(key)) {
if (seenProperties.has(key) && !EXTENSION_UNIFICATION_EXTENSION_IDS.has(extension.description.identifier.value.toLowerCase())) {
delete properties[key];
extension.collector.warn(nls.localize('config.property.duplicate', "Cannot register '{0}'. This property is already registered.", key));
continue;
@@ -31,6 +31,7 @@ interface IConfiguration extends IWindowsConfiguration {
window: IWindowSettings;
workbench?: { enableExperiments?: boolean };
telemetry?: { feedback?: { enabled?: boolean } };
chat?: { extensionUnification?: { enabled?: boolean } };
_extensionsGallery?: { enablePPE?: boolean };
accessibility?: { verbosity?: { debug?: boolean } };
}
@@ -52,7 +53,8 @@ export class SettingsChangeRelauncher extends Disposable implements IWorkbenchCo
'_extensionsGallery.enablePPE',
'security.restrictUNCAccess',
'accessibility.verbosity.debug',
'telemetry.feedback.enabled'
'telemetry.feedback.enabled',
'chat.extensionUnification.enabled'
];
private readonly titleBarStyle = new ChangeObserver<TitlebarStyle>('string');
@@ -70,6 +72,7 @@ export class SettingsChangeRelauncher extends Disposable implements IWorkbenchCo
private readonly restrictUNCAccess = new ChangeObserver('boolean');
private readonly accessibilityVerbosityDebug = new ChangeObserver('boolean');
private readonly telemetryFeedbackEnabled = new ChangeObserver('boolean');
private readonly extensionUnificationEnabled = new ChangeObserver('boolean');
constructor(
@IHostService private readonly hostService: IHostService,
@@ -165,6 +168,9 @@ export class SettingsChangeRelauncher extends Disposable implements IWorkbenchCo
// Enable Feedback
processChanged(this.telemetryFeedbackEnabled.handleChange(config.telemetry?.feedback?.enabled));
// Extension Unification (only when turning on)
processChanged(this.extensionUnificationEnabled.handleChange(config.chat?.extensionUnification?.enabled) && config.chat?.extensionUnification?.enabled === true);
if (askToRelaunch && changed && this.hostService.hasFocus) {
this.doConfirm(
isNative ?
@@ -37,8 +37,6 @@ export class DefaultConfiguration extends BaseDefaultConfiguration {
private cachedConfigurationDefaultsOverrides: IStringDictionary<any> = {};
private readonly cacheKey: ConfigurationKey = { type: 'defaults', key: 'configurationDefaultsOverrides' };
private updateCache: boolean = false;
constructor(
private readonly configurationCache: IConfigurationCache,
environmentService: IBrowserWorkbenchEnvironmentService,
@@ -60,7 +58,6 @@ export class DefaultConfiguration extends BaseDefaultConfiguration {
}
override reload(): ConfigurationModel {
this.updateCache = true;
this.cachedConfigurationDefaultsOverrides = {};
this.updateCachedConfigurationDefaultsOverrides();
return super.reload();
@@ -97,9 +94,6 @@ export class DefaultConfiguration extends BaseDefaultConfiguration {
}
private async updateCachedConfigurationDefaultsOverrides(): Promise<void> {
if (!this.updateCache) {
return;
}
const cachedConfigurationDefaultsOverrides: IStringDictionary<any> = {};
const configurationDefaultsOverrides = this.configurationRegistry.getConfigurationDefaultsOverrides();
for (const [key, value] of configurationDefaultsOverrides) {
@@ -38,7 +38,6 @@ const SOURCE = 'IWorkbenchExtensionEnablementService';
type WorkspaceType = { readonly virtual: boolean; readonly trusted: boolean };
const EXTENSION_UNIFICATION_SETTING = 'chat.extensionUnification.enabled';
const EXTENSION_UNIFICATION_STORAGE_KEY = 'chat.extensionUnification.enabled';
export class ExtensionEnablementService extends Disposable implements IWorkbenchExtensionEnablementService {
@@ -105,11 +104,10 @@ export class ExtensionEnablementService extends Disposable implements IWorkbench
// Disabling extension unification should immediately disable the unified extension flow
// Enabling extension unification will only take effect after restart
this._extensionUnificationEnabled = storageService.getBoolean(EXTENSION_UNIFICATION_STORAGE_KEY, StorageScope.PROFILE, false);
this._extensionUnificationEnabled = this.configurationService.getValue<boolean>(EXTENSION_UNIFICATION_SETTING);
this._register(this.configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration(EXTENSION_UNIFICATION_SETTING)) {
const extensionUnificationEnabled = this.configurationService.getValue<boolean>(EXTENSION_UNIFICATION_SETTING);
storageService.store(EXTENSION_UNIFICATION_STORAGE_KEY, extensionUnificationEnabled, StorageScope.PROFILE, StorageTarget.MACHINE);
if (!extensionUnificationEnabled) {
this._extensionUnificationEnabled = false;
this._onEnablementChanged.fire(this.extensionsManager.extensions.filter(ext => unificationExtensions.includes(ext.identifier.id.toLowerCase())));