Agent SkillsChromeDevTools/devtools-frontend › devtools-setting-migration

devtools-setting-migration

GitHub

指导将旧的 SettingRegistration 重构为 SettingDescriptor 和 SettingUIDescriptor,明确分层存储规则以优化模块边界和懒加载。

.agents/skills/devtools-setting-migration/SKILL.md ChromeDevTools/devtools-frontend

Trigger Scenarios

迁移遗留设置注册逻辑 拆分设置描述符与UI描述符

Install

npx skills add ChromeDevTools/devtools-frontend --skill devtools-setting-migration -g -y
More Options

Non-standard path

npx skills add https://github.com/ChromeDevTools/devtools-frontend/tree/main/.agents/skills/devtools-setting-migration -g -y

Use without installing

npx skills use ChromeDevTools/devtools-frontend@devtools-setting-migration

指定 Agent (Claude Code)

npx skills add ChromeDevTools/devtools-frontend --skill devtools-setting-migration -a claude-code -g -y

安装 repo 全部 skill

npx skills add ChromeDevTools/devtools-frontend --all -g -y

预览 repo 内 skill

npx skills add ChromeDevTools/devtools-frontend --list

SKILL.md

Frontmatter
{
    "name": "devtools-setting-migration",
    "description": "Workflow for splitting an existing SettingRegistration into a SettingDescriptor (placed in the lowest layer where used: core\/, models\/, or ui\/settings\/) and SettingUIDescriptor (registered in a higher-level -meta.ts file, outside of core\/ and models\/)."
}

DevTools Setting Migration Guide

This skill guide describes how to migrate an existing legacy SettingRegistration in DevTools by splitting it into a SettingDescriptor (non-UI descriptor) and a SettingUIDescriptor (UI descriptor).


Key Principles & Layer Boundaries

1. SettingDescriptor Location ("Lowest Layer")

  • Lowest Layer Rule: A SettingDescriptor MUST be placed in the lowest architectural layer where the setting is used.
    • Core / Model Settings: If a setting is used by core/sdk (or models/), its SettingDescriptor should be located in core/sdk (or models/).
    • Panel / UI Settings: If a setting is only used by UI components or a specific panel (e.g. panels/console/), its SettingDescriptor MUST GO INTO ui/settings/FooSettings.ts (e.g. ui/settings/ConsoleSettings.ts where Foo is the panel name).
  • CRITICAL RULE — PANEL DESCRIPTORS MUST NOT BE PLACED IN panels/:
    • A SettingDescriptor MUST NOT be placed inside a panels/ directory (e.g. panels/console/ConsoleSettings.ts).
    • Reason: Panel -meta.ts files (e.g. panels/console/console-meta.ts) need to import the SettingDescriptor to call SettingsUI.SettingUIRegistration.register(descriptor, uiDescriptor). -meta.ts files are loaded early and MUST NOT import from panels/ (which would break lazy-loading of panel bundles). Since ui/settings/ is in the ui/ layer below panels/, -meta.ts files can safely import from ui/settings/.
  • CRITICAL RULE — MUST NOT BE IN A -meta.ts FILE:
    • A SettingDescriptor MUST NOT be placed in a -meta.ts file.
    • Reason: Actual runtime code (e.g. models, panels, SDKs) needs to import the descriptor directly to call Settings.instance().resolve(descriptor). Preload -meta.ts files are meant for lazy-loaded extension registrations and must not be imported by runtime code to avoid circular dependencies and module boundary violations.

2. SettingUIDescriptor Location (Higher-Level -meta.ts File)

  • A SettingUIDescriptor defines UI-specific properties (category, title, tags, options, reload requirement, etc.).
  • Higher-Level Meta File Rule: UI registrations MUST BE PLACED IN A -meta.ts FILE ON A HIGHER LEVEL (e.g., entrypoints/main/main-meta.ts, entrypoints/inspector_main/inspector_main-meta.ts, panels/settings/settings-meta.ts, or the specific panel's -meta.ts file).
  • CRITICAL RULE — MUST NOT REMAIN IN core/ OR models/:
    • UI descriptors MUST NOT remain in or be added to -meta.ts files under core/ or models/ (such as core/sdk/sdk-meta.ts or models/*/*-meta.ts).
    • Goal: A major goal of this migration is to completely eliminate -meta.ts files in core/ and models/.

3. Resolving Settings vs moduleSetting(name)

  • Legacy code retrieves settings using string identifiers: Settings.instance().moduleSetting('setting-name').
  • Refactored code should replace moduleSetting('setting-name') with Settings.instance().resolve(settingDescriptor).

Step-by-Step Migration Workflow

Given a setting name (e.g., 'preserve-console-log' or 'network-messages'):

Step 1: Locate Existing Registration & Analyze Use-Sites

  1. Search for the setting name in -meta.ts files to find its Common.Settings.registerSettingExtension block.
  2. Search for all occurrences of 'setting-name' or moduleSetting('setting-name') across the codebase to identify all use-sites.
  3. Determine the lowest layer among all use-sites:
    • If used in core/sdk -> Target directory is core/sdk/.
    • If used in models/ -> Target directory is models/<module>/.
    • If used in a panel (panels/foo) or UI -> Target directory is ui/settings/ (file: ui/settings/FooSettings.ts). NEVER place descriptors in panels/.

Step 2: Extract & Define SettingDescriptor in the Lowest Layer

Decision Strategy: Create vs. Update File

When placing a SettingDescriptor in the target directory, decide whether to create or update a file using these rules:

  1. For Panel / UI Settings (Target is ui/settings/):

    • UPDATE: Check if ui/settings/FooSettings.ts already exists (e.g., ui/settings/ConsoleSettings.ts). If so, add and export the SettingDescriptor there.
    • CREATE: If ui/settings/FooSettings.ts does not exist:
      • Create ui/settings/FooSettings.ts.
      • Add FooSettings.ts to sources in ui/settings/BUILD.gn.
      • Export FooSettings.ts from ui/settings/settings.ts.
  2. For Core / Model Settings (Target is core/ or models/):

    • UPDATE: Check if a module-wide settings file exists in that directory (e.g. core/sdk/SDKSettings.ts, models/workspace/WorkspaceSettings.ts). If so, add and export the SettingDescriptor there.
    • UPDATE: If no module settings file exists and the setting is strictly used inside a single file (e.g., ResourceTreeModel.ts), update that .ts file by exporting the SettingDescriptor at the top.
    • CREATE: Otherwise, create <Module>Settings.ts (e.g., core/sdk/SDKSettings.ts), add it to sources in BUILD.gn, and export it from the module's entrypoint (sdk.ts).

Code Definition Example:

Define and export the SettingDescriptor in the target file:

import type * as Common from '../core/common/common.js';

export const preserveConsoleLogSettingDescriptor: Common.Settings.SettingDescriptor<boolean> = {
  name: 'preserve-console-log',
  type: Common.Settings.SettingType.BOOLEAN,
  defaultValue: false,
  storageType: Common.Settings.SettingStorageType.SYNCED,
};

Note: For conditional settings (dependent on hostConfig), use Common.Settings.ConditionalSettingDescriptor<ValueT, ReasonT> with an isAvailable function.


Step 3: Move UI Registration to a Higher-Level -meta.ts File

If the original registration was in a core/ or models/ -meta.ts file (e.g., core/sdk/sdk-meta.ts), MOVE the UI registration to a higher-level -meta.ts file (e.g., entrypoints/main/main-meta.ts or panels/console/console-meta.ts).

In the higher-level -meta.ts file:

  1. Import SettingsUI from ui/settings/settings.js (e.g., import * as SettingsUI from '../../ui/settings/settings.js';).
  2. Import the SettingDescriptor (from core/sdk/, models/, or ui/settings/).
  3. Register using SettingsUI.SettingUIRegistration.register(...):
import * as SettingsUI from '../../ui/settings/settings.js';
import * as SDK from '../../core/sdk/sdk.js';

SettingsUI.SettingUIRegistration.register(SDK.SDKSettings.preserveConsoleLogSettingDescriptor, {
  category: Common.Settings.SettingCategory.CONSOLE,
  title: i18nLazyString(UIStrings.preserveLogUponNavigation),
  options: [
    {
      value: true,
      title: i18nLazyString(UIStrings.preserveLogUponNavigation),
    },
    {
      value: false,
      title: i18nLazyString(UIStrings.doNotPreserveLogUponNavigation),
    },
  ],
});
  1. Delete the old Common.Settings.registerSettingExtension call from the core/ or models/ -meta.ts file. (If the -meta.ts file becomes empty, delete the file and clean up its build references).

Step 4: Update Call Sites (moduleSetting to resolve)

Find all call sites referencing the setting via moduleSetting:

// BEFORE:
const setting = Common.Settings.Settings.instance().moduleSetting('preserve-console-log');

// AFTER:
import { preserveConsoleLogSettingDescriptor } from './SDKSettings.js';
...
const setting = Common.Settings.Settings.instance().resolve(preserveConsoleLogSettingDescriptor);

For conditional settings, use Common.Settings.Settings.instance().maybeResolve(descriptor) instead of resolve(descriptor).


Step 5: Update BUILD.gn Files and Module Entrypoints

  1. If a new .ts file was created (e.g., SDKSettings.ts or ui/settings/ConsoleSettings.ts):
    • Add the file to sources in its module's BUILD.gn.
    • Export the file from the module's entrypoint (sdk.ts, settings.ts, etc.).
  2. If a core/ or models/ -meta.ts file was deleted, remove it from BUILD.gn and devtools_grd_files.gni.
  3. Verify module imports strictly follow DevTools import rules (refer to devtools-imports skill).

Step 6: Verify Changes

  1. Run autoninja -C out/Default to check GN build.
  2. Run npm run lint to check style and formatting rules.
  3. Run relevant unit tests for the modified module.

Concrete Examples

Example 1: Core/SDK Setting Migration (preserve-console-log)

Before Migration

Setting registered in front_end/core/sdk/sdk-meta.ts (Legacy core meta file):

Common.Settings.registerSettingExtension({
  category: Common.Settings.SettingCategory.CONSOLE,
  storageType: Common.Settings.SettingStorageType.SYNCED,
  title: i18nLazyString(UIStrings.preserveLogUponNavigation),
  settingName: 'preserve-console-log',
  settingType: Common.Settings.SettingType.BOOLEAN,
  defaultValue: false,
  options: [...],
});

Setting used in front_end/core/sdk/ResourceTreeModel.ts:

const setting = Common.Settings.Settings.instance().moduleSetting('preserve-console-log');

After Migration

  1. front_end/core/sdk/SDKSettings.ts (Lowest Layer in Core — NOT a -meta.ts file):
import type * as Common from '../common/common.js';

export const preserveConsoleLogSettingDescriptor: Common.Settings.SettingDescriptor<boolean> = {
  name: 'preserve-console-log',
  type: Common.Settings.SettingType.BOOLEAN,
  defaultValue: false,
  storageType: Common.Settings.SettingStorageType.SYNCED,
};
  1. front_end/entrypoints/main/main-meta.ts (Higher-Level Meta File — NOT in core/ or models/):
import * as SDK from '../../core/sdk/sdk.js';
import * as SettingsUI from '../../ui/settings/settings.js';

SettingsUI.SettingUIRegistration.register(SDK.SDKSettings.preserveConsoleLogSettingDescriptor, {
  category: Common.Settings.SettingCategory.CONSOLE,
  title: i18nLazyString(UIStrings.preserveLogUponNavigation),
  options: [...],
});
  1. front_end/core/sdk/ResourceTreeModel.ts (Call Site in core/sdk):
import { preserveConsoleLogSettingDescriptor } from './SDKSettings.js';

const setting = Common.Settings.Settings.instance().resolve(preserveConsoleLogSettingDescriptor);
  1. front_end/core/sdk/sdk-meta.ts: Registration for 'preserve-console-log' removed.

Example 2: Panel UI Setting Migration (network-messages)

Before Migration

Setting registered in front_end/panels/console/console-meta.ts:

Common.Settings.registerSettingExtension({
  category: Common.Settings.SettingCategory.CONSOLE,
  storageType: Common.Settings.SettingStorageType.SYNCED,
  title: i18nLazyString(UIStrings.networkMessages),
  settingName: 'network-messages',
  settingType: Common.Settings.SettingType.BOOLEAN,
  defaultValue: true,
  options: [...],
});

Setting used in front_end/panels/console/ConsoleView.ts:

const setting = Common.Settings.Settings.instance().moduleSetting('network-messages');

After Migration

  1. front_end/ui/settings/ConsoleSettings.ts (Lowest Layer for UI/Panel Descriptor — NOT in panels/console/!):
import type * as Common from '../../core/common/common.js';

export const networkMessagesSettingDescriptor: Common.Settings.SettingDescriptor<boolean> = {
  name: 'network-messages',
  type: Common.Settings.SettingType.BOOLEAN,
  defaultValue: true,
  storageType: Common.Settings.SettingStorageType.SYNCED,
};
  1. front_end/panels/console/console-meta.ts (Panel Meta File — Imports Descriptor from ui/settings/):
import * as SettingsUI from '../../ui/settings/settings.js';

SettingsUI.SettingUIRegistration.register(SettingsUI.ConsoleSettings.networkMessagesSettingDescriptor, {
  category: Common.Settings.SettingCategory.CONSOLE,
  title: i18nLazyString(UIStrings.networkMessages),
  options: [...],
});
  1. front_end/panels/console/ConsoleView.ts (Call Site in panels/console):
import * as SettingsUI from '../../ui/settings/settings.js';

const setting = Common.Settings.Settings.instance().resolve(SettingsUI.ConsoleSettings.networkMessagesSettingDescriptor);

Interface Reference Summary

SettingDescriptor<T>

Defined in core/common/Settings.ts:

  • name: string: Unique setting name (kebab-case).
  • type: SettingType: BOOLEAN, ENUM, ARRAY, or REGEX.
  • defaultValue: ValueT | ((hostConfig: HostConfig) => ValueT): Default setting value.
  • storageType?: SettingStorageType: SYNCED, LOCAL, GLOBAL, or SESSION.

SettingUIDescriptor

Defined in ui/settings/SettingUIRegistration.ts:

  • category?: SettingCategory: Category under which setting is listed in Settings UI.
  • order?: number: Sorting order.
  • title?: () => LocalizedString: Title string displayed in Settings UI.
  • tags?: Array<() => LocalizedString>: Search tags for Command Menu.
  • options?: SettingExtensionOption[]: Enum / boolean option descriptions.
  • reloadRequired?: boolean: Whether setting change requires DevTools reload.
  • deprecationNotice?: { disabled: boolean, warning: () => LocalizedString, experiment?: string }: Deprecation notice.
  • learnMore?: LearnMore: Help link or tooltip info.

Version History

  • 678d19c Current 2026-08-20 15:20

Same Skill Collection

.agents/skills/devtools-ci/SKILL.md
.agents/skills/devtools-imports/SKILL.md
.agents/skills/devtools-model-management/SKILL.md
.agents/skills/devtools-source-maps/SKILL.md
.agents/skills/devtools-testing-guidance/SKILL.md
.agents/skills/devtools-unicode-escaping/SKILL.md
.agents/skills/devtools-ux-writing-refactor/SKILL.md
.agents/skills/devtools-verification/SKILL.md
.agents/skills/evaluate-ai-css-completion/SKILL.md
.agents/skills/fixing-skipped-tests/SKILL.md
.agents/skills/foundation-test-migration/SKILL.md
.agents/skills/gerrit-cli/SKILL.md
.agents/skills/merging-devtools-module/SKILL.md
.agents/skills/migrate-chromium-test/SKILL.md
.agents/skills/ui-eng-vision-local-lit-renderer/SKILL.md
.agents/skills/ui-eng-vision-logic-consolidator/SKILL.md
.agents/skills/ui-eng-vision-orchestrator/SKILL.md
.agents/skills/ui-eng-vision-test-scaffolder/SKILL.md
.agents/skills/ui-eng-vision-widget-promoter/SKILL.md
.agents/skills/ui-widgets/SKILL.md
.agents/skills/version-control/SKILL.md
.agents/skills/repro-flaky-tests/SKILL.md

Metadata

Files
0
Version
678d19c
Hash
65f19003
Indexed
2026-08-20 15:20

- 위키
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-24 22:32
浙ICP备14020137号-1 $방문자$