Skip to content

Customizations: consolidate the two independent "disabled" stores #329753

Description

Problem

Whether a chat customization is "disabled" is tracked in two independent, unsynchronised stores:

# Store Storage key Scope / target Serialization Written by
1 IPromptsService.get/setDisabledPromptFiles(type) (promptsServiceImpl.ts) chat.disabledPromptFiles.<PromptsType> PROFILE / USER uri.toJSON() + URI.revive() the Disable/Enable actions in aiCustomizationManagement.contribution.ts
2 AgentCustomizationSyncProvider (ICustomizationSyncProvider) customizationSync.disabled.<harnessId> PROFILE / MACHINE uri.toString() only pluginListWidget.ts (plugins)

Nothing keeps them in agreement, and they differ in storage target (USER vs MACHINE, so one syncs across machines and the other does not) and in URI serialization.

Consumers pick one essentially at random:

  • enumerateLocalCustomizationsForHarness read store 2 only.
  • PureItemProviderItemSource read neither.
  • ItemProviderItemSource reads store 1.
  • The older sessions tree view (aiCustomizationTreeViewViews.ts) reads store 1.

This is the direct cause of #329751, where the Agents window wrote to store 1 and every relevant consumer read store 2. It produced a particularly confusing symptom: the older sessions tree view did reflect the disabled state, so the same skill appeared disabled in one surface and enabled in another, while the agent host kept receiving it either way.

Why this is worth fixing structurally

The immediate fix for #329751 makes the agent-host wire consult both stores (syncProvider.isDisabled(uri) || userDisabled.has(uri)). That resolves the user-visible bug but entrenches the split: every future consumer now has to remember to OR the two together, and every future writer has to pick the right one. The bug is likely to recur in the next surface that ships.

Suggested direction

Consolidate on a single source of truth for "is this customization disabled", most naturally on IPromptsService, with the sync provider's per-harness store either folded into it or kept strictly as a harness-scoped overlay with an explicit, documented precedence rule. Whichever way it goes, there should be exactly one function that answers the question, and the storage target and URI serialization should be consistent.

The two stores and the requirement to consult both are documented for now in src/vs/sessions/AI_CUSTOMIZATIONS.md under Built-in Skills → Enabling and Disabling Built-in Skills.

Found while investigating #329751.

Metadata

Metadata

Labels

chatdebtCode quality issues

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions