chrome-devtools-frontend 1.0.1667564 → 1.0.1669021

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/.agents/skills/devtools-ci/SKILL.md +65 -0
  2. package/.agents/skills/devtools-setting-migration/SKILL.md +290 -0
  3. package/.agents/skills/gerrit-cli/SKILL.md +59 -0
  4. package/.agents/skills/gerrit-cli/references/commands.md +93 -0
  5. package/.agents/skills/gerrit-cli/references/workflows.md +56 -0
  6. package/.agents/skills/gerrit-cli/scripts/gerrit_client_wrapper.py +47 -0
  7. package/.agents/skills/gerrit-cli/scripts/import_upstream.py +230 -0
  8. package/.agents/skills/ui-eng-vision-widget-promoter/SKILL.md +11 -4
  9. package/.agents/skills/ui-widgets/SKILL.md +25 -1
  10. package/docs/contributing/infrastructure.md +7 -1
  11. package/docs/ui_engineering.md +44 -1
  12. package/front_end/core/common/Settings.ts +11 -4
  13. package/front_end/core/host/AidaClient.ts +66 -47
  14. package/front_end/core/host/GcaClient.ts +4 -6
  15. package/front_end/core/host/ResourceLoader.ts +4 -2
  16. package/front_end/core/root/Runtime.ts +5 -5
  17. package/front_end/core/sdk/CSSModel.test.api.ts +102 -0
  18. package/front_end/core/sdk/CSSModel.ts +3 -2
  19. package/front_end/core/sdk/ConsoleModel.ts +3 -2
  20. package/front_end/core/sdk/DebuggerModel.ts +16 -7
  21. package/front_end/core/sdk/SDKSettings.ts +38 -0
  22. package/front_end/core/sdk/sdk-meta.ts +0 -120
  23. package/front_end/core/sdk/sdk.ts +2 -0
  24. package/front_end/entrypoints/main/MainImpl.ts +10 -3
  25. package/front_end/foundation/Universe.ts +7 -0
  26. package/front_end/generated/InspectorBackendCommands.ts +2 -2
  27. package/front_end/generated/protocol.ts +11 -3
  28. package/front_end/models/ai_assistance/AiAgent2.ts +1 -1
  29. package/front_end/models/ai_assistance/AiUtils.ts +67 -4
  30. package/front_end/models/ai_assistance/BuiltInAi.ts +11 -6
  31. package/front_end/models/ai_assistance/ChangeManager.ts +17 -1
  32. package/front_end/models/ai_assistance/StorageItem.ts +26 -5
  33. package/front_end/models/ai_code_completion/AiCodeCompletion.ts +2 -19
  34. package/front_end/models/ai_code_generation/AiCodeGeneration.ts +2 -3
  35. package/front_end/models/javascript_metadata/NativeFunctions.js +22 -9
  36. package/front_end/models/source_map_scopes/NamesResolver.ts +23 -17
  37. package/front_end/models/trace/handlers/RendererHandler.ts +20 -4
  38. package/front_end/models/trace/types/File.ts +1 -0
  39. package/front_end/models/workspace/UISourceCode.ts +0 -10
  40. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +61 -182
  41. package/front_end/panels/ai_assistance/components/ChatInput.ts +25 -8
  42. package/front_end/panels/ai_assistance/components/ChatMessage.ts +13 -69
  43. package/front_end/panels/ai_assistance/components/ChatView.ts +14 -8
  44. package/front_end/panels/ai_assistance/components/chatMessage.css +2 -20
  45. package/front_end/panels/application/ApplicationPanelSidebar.ts +2 -2
  46. package/front_end/panels/application/ApplicationPanelTreeElement.ts +41 -3
  47. package/front_end/panels/application/ServiceWorkerUpdateCycleView.ts +131 -134
  48. package/front_end/panels/application/ServiceWorkersView.ts +8 -8
  49. package/front_end/panels/application/application.ts +2 -0
  50. package/front_end/panels/application/components/AdsView.ts +10 -6
  51. package/front_end/panels/application/preloading/PreloadingView.ts +53 -45
  52. package/front_end/panels/application/preloading/components/PreloadingDetailsReportView.ts +111 -119
  53. package/front_end/panels/application/preloading/components/preloadingDetailsReportView.css +22 -24
  54. package/front_end/panels/application/serviceWorkerUpdateCycleView.css +105 -102
  55. package/front_end/panels/common/AiCodeCompletionDisclaimer.ts +107 -96
  56. package/front_end/panels/common/AiCodeCompletionSummaryToolbar.ts +17 -19
  57. package/front_end/panels/common/AiCodeCompletionTeaser.ts +6 -6
  58. package/front_end/panels/common/AiCodeGenerationTeaser.ts +28 -26
  59. package/front_end/panels/common/common.ts +1 -1
  60. package/front_end/panels/console/ConsoleInsightTeaser.ts +6 -8
  61. package/front_end/panels/console/ConsoleView.ts +6 -4
  62. package/front_end/panels/console/ConsoleViewMessage.ts +1 -1
  63. package/front_end/panels/console/console-meta.ts +28 -0
  64. package/front_end/panels/elements/StylesAiCodeCompletionProvider.ts +1 -1
  65. package/front_end/panels/elements/StylesSidebarPane.ts +3 -2
  66. package/front_end/panels/emulation/DeviceModeToolbar.ts +2 -2
  67. package/front_end/panels/emulation/DeviceModeView.ts +63 -104
  68. package/front_end/panels/emulation/DeviceModeWrapper.ts +18 -4
  69. package/front_end/panels/explain/components/ConsoleInsight.ts +4 -6
  70. package/front_end/panels/explain/explain-meta.ts +7 -49
  71. package/front_end/panels/network/NetworkDataGridNode.ts +1 -1
  72. package/front_end/panels/network/NetworkLogView.ts +1 -0
  73. package/front_end/panels/network/OriginalResourceChunkView.ts +340 -0
  74. package/front_end/panels/network/ResourceChunkView.ts +72 -46
  75. package/front_end/panels/network/ResourceDirectSocketChunkView.ts +3 -2
  76. package/front_end/panels/network/ResourceWebSocketFrameView.ts +3 -3
  77. package/front_end/panels/network/originalResourceChunkView.css +49 -0
  78. package/front_end/panels/screencast/ScreencastView.ts +401 -260
  79. package/front_end/panels/screencast/screencastView.css +113 -100
  80. package/front_end/panels/sensors/LocationsSettingsTab.ts +329 -135
  81. package/front_end/panels/sensors/locationsSettingsTab.css +78 -4
  82. package/front_end/panels/settings/AISettingsTab.ts +17 -100
  83. package/front_end/panels/snippets/ScriptSnippetFileSystem.ts +2 -2
  84. package/front_end/panels/snippets/SnippetsQuickOpen.ts +4 -4
  85. package/front_end/panels/sources/AddSourceMapURLDialog.ts +3 -3
  86. package/front_end/panels/sources/AiCodeCompletionPlugin.ts +4 -3
  87. package/front_end/panels/sources/BreakpointEditDialog.ts +14 -14
  88. package/front_end/panels/sources/BreakpointsView.ts +14 -14
  89. package/front_end/panels/sources/CallStackSidebarPane.ts +6 -6
  90. package/front_end/panels/sources/CategorizedBreakpointL10n.ts +18 -18
  91. package/front_end/panels/sources/CoveragePlugin.ts +7 -7
  92. package/front_end/panels/sources/DebuggerPausedMessage.ts +23 -23
  93. package/front_end/panels/sources/DebuggerPlugin.ts +31 -31
  94. package/front_end/panels/sources/FilteredUISourceCodeListProvider.ts +2 -2
  95. package/front_end/panels/sources/GoToLineQuickOpen.ts +10 -10
  96. package/front_end/panels/sources/NavigatorView.ts +34 -27
  97. package/front_end/panels/sources/OutlineQuickOpen.ts +3 -3
  98. package/front_end/panels/sources/PersistenceActions.ts +9 -9
  99. package/front_end/panels/sources/ProfilePlugin.ts +1 -1
  100. package/front_end/panels/sources/ScopeChainSidebarPane.ts +5 -5
  101. package/front_end/panels/sources/SnippetsPlugin.ts +2 -2
  102. package/front_end/panels/sources/SourcesNavigator.ts +20 -18
  103. package/front_end/panels/sources/SourcesPanel.ts +26 -25
  104. package/front_end/panels/sources/SourcesView.ts +5 -6
  105. package/front_end/panels/sources/TabbedEditorContainer.ts +3 -3
  106. package/front_end/panels/sources/ThreadsSidebarPane.ts +1 -1
  107. package/front_end/panels/sources/UISourceCodeFrame.ts +0 -2
  108. package/front_end/panels/sources/WatchExpressionsSidebarPane.ts +7 -7
  109. package/front_end/panels/sources/components/HeadersView.ts +2 -2
  110. package/front_end/panels/sources/sources-meta.ts +164 -71
  111. package/front_end/panels/sources/sources.ts +0 -2
  112. package/front_end/panels/timeline/TimelineHistoryManager.ts +14 -3
  113. package/front_end/panels/timeline/TimelineLoader.ts +72 -42
  114. package/front_end/panels/timeline/TimelinePanel.ts +29 -4
  115. package/front_end/panels/timeline/timelineHistoryManager.css +4 -0
  116. package/front_end/third_party/chromium/README.chromium +1 -1
  117. package/front_end/third_party/puppeteer/README.chromium +2 -2
  118. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.d.ts +187 -1
  119. package/front_end/third_party/puppeteer/package/lib/es5-iife/puppeteer-core-browser.js +91 -38
  120. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.d.ts +145 -2
  121. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.d.ts.map +1 -1
  122. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.js +0 -2
  123. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Browser.js.map +1 -1
  124. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/BrowserContext.d.ts +0 -2
  125. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/BrowserContext.d.ts.map +1 -1
  126. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/BrowserContext.js +0 -2
  127. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/BrowserContext.js.map +1 -1
  128. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Dialog.d.ts +3 -2
  129. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Dialog.d.ts.map +1 -1
  130. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Dialog.js +8 -2
  131. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Dialog.js.map +1 -1
  132. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/JSHandle.d.ts +0 -2
  133. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/JSHandle.d.ts.map +1 -1
  134. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/JSHandle.js +0 -2
  135. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/JSHandle.js.map +1 -1
  136. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.d.ts +1 -3
  137. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.d.ts.map +1 -1
  138. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.js +0 -2
  139. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Page.js.map +1 -1
  140. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Realm.d.ts +0 -1
  141. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Realm.d.ts.map +1 -1
  142. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Realm.js +0 -1
  143. package/front_end/third_party/puppeteer/package/lib/puppeteer/api/Realm.js.map +1 -1
  144. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BidiOverCdp.d.ts.map +1 -1
  145. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BidiOverCdp.js +2 -2
  146. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/BidiOverCdp.js.map +1 -1
  147. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Browser.d.ts +5 -1
  148. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Browser.d.ts.map +1 -1
  149. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Browser.js +12 -0
  150. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/Browser.js.map +1 -1
  151. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPResponse.d.ts.map +1 -1
  152. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPResponse.js +4 -1
  153. package/front_end/third_party/puppeteer/package/lib/puppeteer/bidi/HTTPResponse.js.map +1 -1
  154. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.d.ts +5 -1
  155. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.d.ts.map +1 -1
  156. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js +49 -0
  157. package/front_end/third_party/puppeteer/package/lib/puppeteer/cdp/Browser.js.map +1 -1
  158. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/EventEmitter.d.ts +0 -6
  159. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/EventEmitter.d.ts.map +1 -1
  160. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/EventEmitter.js +0 -6
  161. package/front_end/third_party/puppeteer/package/lib/puppeteer/common/EventEmitter.js.map +1 -1
  162. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.d.ts +1 -1
  163. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.d.ts.map +1 -1
  164. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.js +1 -1
  165. package/front_end/third_party/puppeteer/package/lib/puppeteer/generated/injected.js.map +1 -1
  166. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/util.d.ts.map +1 -1
  167. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/util.js +3 -0
  168. package/front_end/third_party/puppeteer/package/lib/puppeteer/injected/util.js.map +1 -1
  169. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ScreenRecorder.d.ts +0 -3
  170. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ScreenRecorder.d.ts.map +1 -1
  171. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ScreenRecorder.js +0 -3
  172. package/front_end/third_party/puppeteer/package/lib/puppeteer/node/ScreenRecorder.js.map +1 -1
  173. package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.d.ts +3 -3
  174. package/front_end/third_party/puppeteer/package/lib/puppeteer/revisions.js +3 -3
  175. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/disposable.d.ts +2 -2
  176. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/disposable.js +2 -2
  177. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.d.ts +1 -1
  178. package/front_end/third_party/puppeteer/package/lib/puppeteer/util/version.js +1 -1
  179. package/front_end/third_party/puppeteer/package/lib/types.d.ts +187 -1
  180. package/front_end/third_party/puppeteer/package/package.json +5 -5
  181. package/front_end/third_party/puppeteer/package/src/api/Browser.ts +155 -2
  182. package/front_end/third_party/puppeteer/package/src/api/BrowserContext.ts +0 -2
  183. package/front_end/third_party/puppeteer/package/src/api/Dialog.ts +10 -2
  184. package/front_end/third_party/puppeteer/package/src/api/JSHandle.ts +0 -2
  185. package/front_end/third_party/puppeteer/package/src/api/Page.ts +1 -3
  186. package/front_end/third_party/puppeteer/package/src/api/Realm.ts +0 -1
  187. package/front_end/third_party/puppeteer/package/src/bidi/BidiOverCdp.ts +4 -2
  188. package/front_end/third_party/puppeteer/package/src/bidi/Browser.ts +17 -0
  189. package/front_end/third_party/puppeteer/package/src/bidi/HTTPResponse.ts +5 -4
  190. package/front_end/third_party/puppeteer/package/src/cdp/Browser.ts +66 -0
  191. package/front_end/third_party/puppeteer/package/src/common/EventEmitter.ts +0 -6
  192. package/front_end/third_party/puppeteer/package/src/generated/injected.ts +1 -1
  193. package/front_end/third_party/puppeteer/package/src/injected/util.ts +4 -1
  194. package/front_end/third_party/puppeteer/package/src/node/ScreenRecorder.ts +0 -3
  195. package/front_end/third_party/puppeteer/package/src/revisions.ts +3 -3
  196. package/front_end/third_party/puppeteer/package/src/util/disposable.ts +2 -2
  197. package/front_end/third_party/puppeteer/package/src/util/version.ts +1 -1
  198. package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +9 -7
  199. package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +7 -8
  200. package/front_end/ui/legacy/Dialog.ts +103 -4
  201. package/front_end/ui/legacy/InspectorView.ts +1 -5
  202. package/front_end/ui/legacy/PopoverHelper.ts +5 -5
  203. package/front_end/ui/legacy/TabbedPane.ts +7 -2
  204. package/front_end/ui/legacy/components/cookie_table/CookiesTable.ts +40 -24
  205. package/front_end/ui/legacy/components/data_grid/DataGrid.ts +1 -0
  206. package/front_end/ui/legacy/components/data_grid/DataGridElement.ts +8 -4
  207. package/front_end/ui/legacy/components/perf_ui/FlameChart.ts +14 -7
  208. package/front_end/ui/legacy/components/quick_open/CommandMenu.ts +11 -1
  209. package/front_end/ui/visual_logging/KnownContextValues.ts +3 -0
  210. package/package.json +1 -1
  211. package/front_end/panels/sources/AiWarningInfobarPlugin.ts +0 -78
@@ -0,0 +1,230 @@
1
+ #!/usr/bin/env python3
2
+ # Copyright 2026 The Chromium Authors
3
+ # Use of this source code is governed by a BSD-style license that can be
4
+ # found in the LICENSE file.
5
+ """Imports the Gerrit CLI skill from upstream and applies DevTools revisions.
6
+
7
+ No external checkouts (like chromium/src) are required. The script downloads
8
+ the skill directly from the public Git repository.
9
+ """
10
+
11
+ import io
12
+ import re
13
+ import sys
14
+ import tarfile
15
+ import urllib.request
16
+ from pathlib import Path
17
+
18
+ UPSTREAM_URL = "https://chromium.googlesource.com/chromium/agents/+archive/refs/heads/main/skills/gerrit-cli.tar.gz"
19
+
20
+ DEVTOOLS_WRAPPER_LOGIC = """ # DevTools specific defaults
21
+ default_args = [
22
+ '--host', 'https://chromium-review.googlesource.com',
23
+ '--project', 'devtools/devtools-frontend',
24
+ ]
25
+
26
+ # gerrit_client.py expects: <command> [options] [args]
27
+ # We need to extract the command from sys.argv and put it first.
28
+ user_args = sys.argv[1:]
29
+ command = []
30
+ other_args = []
31
+ for i, arg in enumerate(user_args):
32
+ if not arg.startswith('-'):
33
+ command = [arg]
34
+ other_args = user_args[:i] + user_args[i + 1:]
35
+ break
36
+ else:
37
+ other_args = user_args
38
+
39
+ full_args = command + default_args + other_args
40
+
41
+ rc = subprocess.call(['vpython3', client] + full_args)"""
42
+
43
+ CAUTION_TEXT = """> [!CAUTION]
44
+ > **NEVER** use this to add patchset comments to an existing comment thread that
45
+ > contains human reviewers in it. Using an agent to reply to a human is a
46
+ > violation of Chromium's code of conduct.
47
+ >
48
+ > If the user requests this or you encounter this scenario as part of your work,
49
+ > inform the user about which comment threads cannot be updated but otherwise
50
+ > continue work.
51
+ """
52
+
53
+
54
+ def fetch_upstream_skill(target_dir: Path):
55
+ print(f"Downloading upstream skill from {UPSTREAM_URL}...")
56
+ try:
57
+ req = urllib.request.Request(UPSTREAM_URL,
58
+ headers={'User-Agent': 'Mozilla/5.0'})
59
+ with urllib.request.urlopen(req) as response:
60
+ tar_data = response.read()
61
+ except Exception as e:
62
+ print(f"Failed to download upstream skill: {e}")
63
+ sys.exit(1)
64
+
65
+ print(f"Extracting to {target_dir}...")
66
+ target_dir.mkdir(parents=True, exist_ok=True)
67
+ with tarfile.open(fileobj=io.BytesIO(tar_data), mode='r:gz') as tar:
68
+ tar.extractall(path=target_dir)
69
+
70
+
71
+ def apply_devtools_revisions(target_dir: Path):
72
+ print("Applying DevTools-specific adaptations...")
73
+
74
+ # 1. Update gerrit_client_wrapper.py
75
+ wrapper_path = target_dir / "scripts" / "gerrit_client_wrapper.py"
76
+ if wrapper_path.exists():
77
+ code = wrapper_path.read_text()
78
+ # Remove ". All rights reserved." from license header to satisfy DevTools presubmit
79
+ code = code.replace(". All rights reserved.", "")
80
+ target_line = " rc = subprocess.call(['vpython3', client] + sys.argv[1:])"
81
+ if target_line in code:
82
+ code = code.replace(target_line, DEVTOOLS_WRAPPER_LOGIC)
83
+ else:
84
+ # Fallback if upstream changed to python3
85
+ fallback_line = " rc = subprocess.call(['python3', client] + sys.argv[1:])"
86
+ code = code.replace(fallback_line, DEVTOOLS_WRAPPER_LOGIC)
87
+ wrapper_path.write_text(code)
88
+ print(" - Adapted gerrit_client_wrapper.py")
89
+
90
+ # 2. Update SKILL.md
91
+ skill_md_path = target_dir / "SKILL.md"
92
+ if skill_md_path.exists():
93
+ content = skill_md_path.read_text()
94
+
95
+ # Re-route wrapper script path & change python3 to vpython3
96
+ content = content.replace(
97
+ "python3 agents/shared/skills/gerrit-cli/scripts/gerrit_client_wrapper.py",
98
+ "vpython3 .agents/skills/gerrit-cli/scripts/gerrit_client_wrapper.py"
99
+ )
100
+
101
+ # Add vpython3 environment warning under Prerequisites
102
+ if "- **Environment**:" not in content:
103
+ prereq_note = "- **Environment**: Always execute the wrapper script using **`vpython3`** instead of `python3` to ensure all internal dependencies are satisfied.\n"
104
+ content = content.replace("## Prerequisites\n",
105
+ f"## Prerequisites\n\n{prereq_note}")
106
+
107
+ # Replace Gotchas section with DevTools defaults info
108
+ global_flags_section = """## Global Flags
109
+
110
+ The wrapper script includes DevTools-specific defaults for `--host` and
111
+ `--project`. You do not need to provide them unless you are targeting a
112
+ different host or project.
113
+
114
+ - **Default Host**: `https://chromium-review.googlesource.com`
115
+ - **Default Project**: `devtools/devtools-frontend`
116
+ - **JSON Output**: Always use the `--json_file=<path>` flag when querying
117
+ changes or fetching metadata to obtain structured, machine-readable output.
118
+ """
119
+ gotchas_pattern = r"## Gotchas & Environment Constraints\n\n(?:[^\n]+\n)+"
120
+ content = re.sub(gotchas_pattern, global_flags_section, content)
121
+
122
+ # Add attribution note at the bottom
123
+ attribution = """
124
+ > [!NOTE]
125
+ > This skill was adapted from the [Chromium Gerrit CLI skill](https://chromium.googlesource.com/chromium/agents/+/main/skills/gerrit-cli/)
126
+ > (automatically rolled in from upstream).
127
+ """
128
+ if "> [!NOTE]" not in content:
129
+ content += "\n" + attribution
130
+
131
+ skill_md_path.write_text(content)
132
+ print(" - Adapted SKILL.md")
133
+
134
+ # 3. Update references/commands.md and references/workflows.md
135
+ for filename in ["commands.md", "workflows.md"]:
136
+ ref_path = target_dir / "references" / filename
137
+ if ref_path.exists():
138
+ c = ref_path.read_text()
139
+
140
+ # Path & executable transformations
141
+ c = c.replace("python3 agents/shared/skills/gerrit-cli/",
142
+ "vpython3 .agents/skills/gerrit-cli/")
143
+
144
+ # Remove redundant host/project flags since our wrapper defaults them
145
+ # This matches the flag and any trailing backslash & newline to keep shell syntax valid
146
+ c = re.sub(r'^[ \t]+--(host|project)[ \t]+\S+[ \t]*(?:\\)?\n',
147
+ '',
148
+ c,
149
+ flags=re.M)
150
+
151
+ # Re-route positional arguments to flags for various commands.
152
+ # TODO(b/40292850): Simplify/remove these once CL lands upstream:
153
+ # https://chromium-review.googlesource.com/c/chromium/agents/+/8146436
154
+
155
+ # content
156
+ c = c.replace(
157
+ "<change_id> <revision> <file_path>",
158
+ "--change <change_id> --revision <revision> --path <file_path>"
159
+ )
160
+ c = c.replace(
161
+ "<change_id> current <file_path>",
162
+ "--change <change_id> --revision current --path <file_path>")
163
+
164
+ # changes (query flag is required)
165
+ c = c.replace('changes \\\n "owner:self status:open"',
166
+ 'changes \\\n --query "owner:self status:open"')
167
+ c = c.replace('changes \\\n "change:<id>"',
168
+ 'changes \\\n --query "change:<id>"')
169
+
170
+ # relatedchanges
171
+ c = c.replace(
172
+ "relatedchanges \\\n <change_id> <revision>",
173
+ "relatedchanges \\\n --change <change_id> --revision <revision>"
174
+ )
175
+ c = c.replace(
176
+ "relatedchanges \\\n <change_id> current",
177
+ "relatedchanges \\\n --change <change_id> --revision current"
178
+ )
179
+
180
+ # addpatchsetcomment
181
+ c = c.replace(
182
+ 'addpatchsetcomment \\\n --message "Review findings: <message>" \\\n <change_id> <revision>',
183
+ 'addpatchsetcomment \\\n --change <change_id> --revision <revision> \\\n --message "Review findings: <message>"'
184
+ )
185
+ c = c.replace(
186
+ 'addpatchsetcomment \\\n --message "Review findings: ..." \\\n <change_id> current',
187
+ 'addpatchsetcomment \\\n --change <change_id> --revision current \\\n --message "Review findings: ..."'
188
+ )
189
+
190
+ # setlabel
191
+ c = c.replace(
192
+ 'setlabel \\\n --label "Code-Review" \\\n --value 1 \\\n <change_id>',
193
+ 'setlabel \\\n --change <change_id> \\\n --label Code-Review 1'
194
+ )
195
+ c = c.replace(
196
+ 'setlabel \\\n --label "Code-Review" \\\n --value 1 \\\n <change_id>',
197
+ 'setlabel \\\n --change <change_id> \\\n --label Code-Review 1'
198
+ )
199
+
200
+ # submitchange
201
+ c = c.replace("submitchange \\\n <change_id>",
202
+ "submitchange \\\n --change <change_id>")
203
+ c = c.replace("submitchange \\\n <change_id>",
204
+ "submitchange \\\n --change <change_id>")
205
+
206
+ # abandon
207
+ c = c.replace(
208
+ 'abandon \\\n --message "<reason>" \\\n <change_id>',
209
+ 'abandon \\\n --change <change_id> \\\n --message "<reason>"'
210
+ )
211
+
212
+ # restore
213
+ c = c.replace(
214
+ 'restore \\\n --message "<reason>" \\\n <change_id>',
215
+ 'restore \\\n --change <change_id> \\\n --message "<reason>"'
216
+ )
217
+
218
+ ref_path.write_text(c)
219
+ print(f" - Adapted references/{filename}")
220
+
221
+
222
+ def main():
223
+ skill_dir = Path(__file__).parent.parent.resolve()
224
+ fetch_upstream_skill(skill_dir)
225
+ apply_devtools_revisions(skill_dir)
226
+ print("Upstream sync completed successfully!")
227
+
228
+
229
+ if __name__ == "__main__":
230
+ main()
@@ -36,13 +36,21 @@ clean `UI.Widget` classes that use native update rendering delegates.
36
36
  };
37
37
  ```
38
38
 
39
- * Make the view injectable in the constructor for testability (as per `docs/ui_engineering.md`):
39
+ * Make the view injectable in the constructor for testability (as per `docs/ui_engineering.md`), and use static `INJECT` if requesting dependencies from `Universe`:
40
40
 
41
41
  ```typescript
42
42
  class MyWidget extends UI.Widget.VBox {
43
+ static override readonly INJECT = [SDK.TargetManager.TargetManager] as const;
44
+
45
+ #targetManager: SDK.TargetManager.TargetManager;
43
46
  #view: View;
44
- constructor(element?: HTMLElement, view: View = DEFAULT_VIEW) {
45
- super(true, element);
47
+ constructor(
48
+ element?: HTMLElement,
49
+ [targetManager]: UI.Widget.WidgetDependencies<typeof MyWidget> = [],
50
+ view: View = DEFAULT_VIEW,
51
+ ) {
52
+ super(element);
53
+ this.#targetManager = targetManager;
46
54
  this.#view = view;
47
55
  }
48
56
  ```
@@ -84,4 +92,3 @@ clean `UI.Widget` classes that use native update rendering delegates.
84
92
  2. ❓ **Inheritance**: Does the class now cleanly inherit from `UI.Widget` or its variants?
85
93
  3. ❓ **Injectability**: Is the view injectable in the constructor?
86
94
  4. ❓ **Build**: Does the code compile and do tests pass?
87
-
@@ -19,6 +19,7 @@ Adhere strictly to the Model-View-Presenter (MVP) architecture.
19
19
  * MUST extend a base `UI.Widget` class (e.g., `UI.Widget.Widget`). Note that `UI.Widget.Widget` is not an `HTMLElement` and must be appended via `.show()` or `UI.Widget.widget`
20
20
  * Constructor MUST assign the injected view function to a private `#view` field.
21
21
  * Constructor MUST call `super()`. If taking `element?: HTMLElement`, pass it to `super(element)`. `super(true)` is forbidden.
22
+ * Dependencies from `Universe` SHOULD be requested via static `INJECT`: `static override readonly INJECT = [...] as const;` and received as constructor parameter #2 (`[dep1, dep2]: UI.Widget.WidgetDependencies<typeof MyWidget>`).
22
23
  * Styling MUST be handled within the View. `this.registerCSSFiles()` is forbidden.
23
24
  * Initial render MUST be triggered in `override wasShown(): void` by calling `this.requestUpdate()`.
24
25
  * MUST hold all UI state as private class fields (e.g., `#counter`).
@@ -109,7 +110,30 @@ render(html`
109
110
  * **Child Widgets:** Use `UI.Widget.widgetRef` to obtain the class instance of a child widget if you need to call methods on it directly (though declarative data flow is preferred).
110
111
 
111
112
  ### Dependencies
112
- The `DEFAULT_VIEW` is typically a module-level function. Ensure all dependencies (enums, constants, other components) are imported at the top of the file so they are available in the function scope.
113
+
114
+ * **View Dependencies:** The `DEFAULT_VIEW` is typically a module-level function. Ensure all dependencies (enums, constants, other components) are imported at the top of the file so they are available in the function scope.
115
+ * **Presenter (`Universe`) Dependencies:** To access dependencies managed by `Universe` (e.g. `SDK.TargetManager.TargetManager`, `Common.Settings.Settings`), declare a static `INJECT` array on the `Widget` subclass:
116
+ ```ts
117
+ export class MyWidget extends UI.Widget.Widget {
118
+ static override readonly INJECT = [SDK.TargetManager.TargetManager, Common.Settings.Settings] as const;
119
+
120
+ #targetManager: SDK.TargetManager.TargetManager;
121
+ #settings: Common.Settings.Settings;
122
+ #view: View;
123
+
124
+ constructor(
125
+ element?: HTMLElement,
126
+ [targetManager, settings]: UI.Widget.WidgetDependencies<typeof MyWidget> = [],
127
+ view: View = DEFAULT_VIEW,
128
+ ) {
129
+ super(element);
130
+ this.#targetManager = targetManager;
131
+ this.#settings = settings;
132
+ this.#view = view;
133
+ }
134
+ }
135
+ ```
136
+ `instantiateWidget` automatically resolves dependencies from `Universe` and passes them as constructor parameter #2. In unit tests using `renderElementIntoDOM`, `TestUniverse` handles injection automatically (override via `setTestUniverseForWidgets`).
113
137
 
114
138
  ## Step-by-Step Implementation Example
115
139
 
@@ -257,7 +257,13 @@ because they picked up the test as it was being touched.
257
257
 
258
258
  You can skip Flake Detection for your tests by adding the `Skip-Flake-Detection`
259
259
  CL footer (see example [CL](https://crrev.com/c/6994031)). Make sure you use the
260
- full path to your test.
260
+ full path to your test. If you need to skip multiple tests, you can repeat the footer:
261
+ ```
262
+ Skip-Flake-Detection: test/e2e/foo.test.ts
263
+ Skip-Flake-Detection: test/e2e/bar.test.ts
264
+ ```
265
+
266
+ You can also skip Flake Detection for multiple tests using a glob pattern by adding the `Skip-Flake-Detection-Pattern` CL footer. For example: `Skip-Flake-Detection-Pattern: test/e2e/performance/*`.
261
267
 
262
268
  ### Common build failures
263
269
 
@@ -38,13 +38,42 @@ Note that `VBox` and `HBox` inherit directly from `Widget`. They fully support v
38
38
 
39
39
  To test the `DEFAULT_VIEW` function itself, we should use screenshot and e2e tests.
40
40
 
41
+ ### Dependency Injection via `INJECT`
42
+
43
+ Subclasses of `UI.Widget.Widget` can declare dependencies from `Universe` to be automatically injected when instantiated (e.g. via `<devtools-widget>` or `UI.Widget.widget()`).
44
+
45
+ To opt into dependency injection, define a static `INJECT` array containing dependency constructors:
46
+
47
+ ```ts
48
+ class MyWidget extends UI.Widget.Widget {
49
+ static override readonly INJECT = [SDK.TargetManager.TargetManager, Common.Settings.Settings] as const;
50
+
51
+ #targetManager: SDK.TargetManager.TargetManager;
52
+ #settings: Common.Settings.Settings;
53
+
54
+ constructor(
55
+ element?: HTMLElement,
56
+ [targetManager, settings]: UI.Widget.WidgetDependencies<typeof MyWidget> = [],
57
+ view: View = DEFAULT_VIEW,
58
+ ) {
59
+ super(element);
60
+ this.#targetManager = targetManager;
61
+ this.#settings = settings;
62
+ }
63
+ }
64
+ ```
65
+
66
+ When `instantiateWidget` creates a widget with a non-empty `INJECT` array, it automatically resolves each requested constructor from the active `Universe` and passes the resolved instances array as parameter #2 to the constructor.
67
+
68
+ Use `UI.Widget.WidgetDependencies<typeof MyWidget>` to type the injected dependencies parameter.
69
+
41
70
  ## Declarative and orchestrated DOM updates
42
71
 
43
72
  We should no longer use imperative API to update DOM. Instead we rely on orchestrated rendering of lit-html templates. The view function described above should be a call to lit-html `render`. The view function should be called from `UI.Widget`’s `performUpdate` method, which by default is scheduled using `requestAnimationFrame`.
44
73
 
45
74
  To embed another presenter (`UI.Widget`) in the lit-html template, use `widget(<class>, {foo: 1, bar: 2})`
46
75
 
47
- This will instantiate a `Widget` class with the web component as its `element` and, optionally, will set the properties provided in the second parameter. The widget won’t be re-instantiated on the subsequent template renders, but the properties would be updated. For this to work, the widget needs to accept `HTMLElement` as a sole constructor parameter and properties need to be public members or setters.
76
+ This will instantiate a `Widget` class with the web component as its `element` and, optionally, will set the properties provided in the second parameter. The widget won’t be re-instantiated on the subsequent template renders, but the properties would be updated. For this to work, the widget needs to accept `HTMLElement` as its first constructor parameter, optional injected dependencies as parameter #2 (if `INJECT` is declared), and properties need to be public members or setters.
48
77
 
49
78
  For backwards compatibility, the first argument to `widget` can also be a factory function: `widget(element => new MyWidget(foo, bar, element))`. Similar to the class constructor version, `element` is the actual `<devtools-widget>` so the following two invocations of `widget` are equivalent: `widget(MyWidget)` and `widget(element => new MyWidget(element))`.
50
79
 
@@ -218,6 +247,20 @@ const presenter = new Presenter();
218
247
  presenter.doSomething();
219
248
  ```
220
249
 
250
+ #### Testing widgets with `INJECT` dependencies
251
+
252
+ When rendering widgets into DOM in unit tests (e.g. via `renderElementIntoDOM`), DOM test helpers automatically supply a default `TestUniverse` for resolving `INJECT` dependencies.
253
+
254
+ If a test requires a custom `TestUniverse` instance, pass it via `setTestUniverseForWidgets`:
255
+
256
+ ```ts
257
+ import {setTestUniverseForWidgets} from '../../testing/DOMHelpers.js';
258
+ import {TestUniverse} from '../../testing/TestUniverse.js';
259
+
260
+ const customUniverse = new TestUniverse();
261
+ setTestUniverseForWidgets(customUniverse);
262
+ ```
263
+
221
264
  # Migrating Widgets and other "legacy" components
222
265
 
223
266
  This section provides a series of examples for migrating from imperative DOM manipulation to a declarative approach using lit-html templates.
@@ -362,6 +362,8 @@ export class Settings {
362
362
  this.createRegExpSetting(name, evaluatedDefaultValue, undefined, storageType) :
363
363
  this.createSetting(name, evaluatedDefaultValue, storageType);
364
364
 
365
+ setting.setSettingType(type);
366
+
365
367
  this.registerModuleSetting(setting);
366
368
  return setting as Setting<T>;
367
369
  }
@@ -511,6 +513,7 @@ export class Deprecation {
511
513
 
512
514
  export class Setting<V> {
513
515
  #registration: SettingRegistration|null = null;
516
+ #type: SettingType|null = null;
514
517
  #requiresUserAction?: boolean;
515
518
  #value?: V;
516
519
  // TODO(crbug.com/1172300) Type cannot be inferred without changes to consumers. See above.
@@ -679,8 +682,15 @@ export class Setting<V> {
679
682
  this.eventSupport.dispatchEventToListeners(this.name, value);
680
683
  }
681
684
 
685
+ setSettingType(type: SettingType): void {
686
+ this.#type = type;
687
+ }
688
+
682
689
  setRegistration(registration: SettingRegistration): void {
683
690
  this.#registration = registration;
691
+ if (registration.settingType) {
692
+ this.#type = registration.settingType;
693
+ }
684
694
  const {deprecationNotice} = registration;
685
695
  if (deprecationNotice?.disabled) {
686
696
  const experiment = deprecationNotice.experiment ?
@@ -694,10 +704,7 @@ export class Setting<V> {
694
704
  }
695
705
 
696
706
  type(): SettingType|null {
697
- if (this.#registration) {
698
- return this.#registration.settingType;
699
- }
700
- return null;
707
+ return this.#type ?? this.#registration?.settingType ?? null;
701
708
  }
702
709
 
703
710
  options(): SimpleSettingOption[] {
@@ -33,7 +33,7 @@ import * as GcaClient from './GcaClient.js';
33
33
  import type {GenerateContentResponse} from './GcaTypes.js';
34
34
  import {InspectorFrontendHostInstance} from './InspectorFrontendHost.js';
35
35
  import type {AidaClientResult, AidaCodeCompleteResult, SyncInformation} from './InspectorFrontendHostAPI.js';
36
- import {bindOutputStream} from './ResourceLoader.js';
36
+ import {bindOutputStream, discardOutputStream} from './ResourceLoader.js';
37
37
 
38
38
  export * from './AidaClientTypes.js';
39
39
 
@@ -159,6 +159,10 @@ export class AidaClient {
159
159
  throw new Error('dispatchHttpRequest is not available');
160
160
  }
161
161
 
162
+ if (options?.signal?.aborted) {
163
+ throw new AidaAbortError();
164
+ }
165
+
162
166
  // Disable logging for now.
163
167
  // For context, see b/454563259#comment35.
164
168
  // We should be able to remove this ~end of April.
@@ -166,51 +170,67 @@ export class AidaClient {
166
170
  request.metadata.disable_user_content_logging = true;
167
171
  }
168
172
 
169
- const stream = (() => {
170
- let {promise, resolve, reject} = Promise.withResolvers<string|null>();
171
- options?.signal?.addEventListener('abort', () => {
172
- reject(new AidaAbortError());
173
- }, {once: true});
174
- return {
175
- write: async(data: string): Promise<void> => {
176
- resolve(data);
177
- ({promise, resolve, reject} = Promise.withResolvers<string|null>());
178
- },
179
- close: async(): Promise<void> => {
180
- resolve(null);
181
- },
182
- read: (): Promise<string|null> => {
183
- return promise;
173
+ let abortListener: (() => void)|undefined;
174
+ let streamId: number|undefined;
175
+ try {
176
+ const stream = (() => {
177
+ let {promise, resolve, reject} = Promise.withResolvers<string|null>();
178
+ // Prevent unhandled promise rejections if stream.fail() is called after
179
+ // doConversation has already exited early (e.g. on recitation block or abort).
180
+ // Active readers calling await stream.read() will still receive the rejection.
181
+ promise.catch(() => {});
182
+ abortListener = () => {
183
+ reject(new AidaAbortError());
184
+ };
185
+ options?.signal?.addEventListener('abort', abortListener, {once: true});
186
+ return {
187
+ write: async(data: string): Promise<void> => {
188
+ resolve(data);
189
+ ({promise, resolve, reject} = Promise.withResolvers<string|null>());
190
+ promise.catch(() => {});
191
+ },
192
+ close: async(): Promise<void> => {
193
+ resolve(null);
194
+ },
195
+ read: (): Promise<string|null> => {
196
+ return promise;
197
+ },
198
+ fail: (e: Error) => reject(e),
199
+ };
200
+ })();
201
+ streamId = bindOutputStream(stream);
202
+
203
+ let response;
204
+ if (this.#gcaClient.enabled()) {
205
+ // Inline and remove the else clause after migration
206
+ response = this.#gcaClient.conversationRequest(request, streamId, options);
207
+ } else {
208
+ response = DispatchHttpRequestClient.makeHttpRequest({
209
+ service: SERVICE_NAME,
210
+ path: '/v1/aida:doConversation',
211
+ method: 'POST',
212
+ body: JSON.stringify(request),
213
+ streamId,
184
214
  },
185
- fail: (e: Error) => reject(e),
186
- };
187
- })();
188
- const streamId = bindOutputStream(stream);
189
-
190
- let response;
191
- if (this.#gcaClient.enabled()) {
192
- // Inline and remove the else clause after migration
193
- response = this.#gcaClient.conversationRequest(request, streamId, options);
194
- } else {
195
- response = DispatchHttpRequestClient.makeHttpRequest(
196
- {
197
- service: SERVICE_NAME,
198
- path: '/v1/aida:doConversation',
199
- method: 'POST',
200
- body: JSON.stringify(request),
201
- streamId,
215
+ options);
216
+ }
217
+ response.then(
218
+ () => {
219
+ void stream.close();
202
220
  },
203
- options);
221
+ err => {
222
+ debugLog('doConversation failed with error:', JSON.stringify(err));
223
+ stream.fail(mapError(err));
224
+ });
225
+ yield* this.#handleResponseStream(stream);
226
+ } finally {
227
+ if (options?.signal && abortListener) {
228
+ options.signal.removeEventListener('abort', abortListener);
229
+ }
230
+ if (streamId !== undefined) {
231
+ discardOutputStream(streamId);
232
+ }
204
233
  }
205
- response.then(
206
- () => {
207
- void stream.close();
208
- },
209
- err => {
210
- debugLog('doConversation failed with error:', JSON.stringify(err));
211
- stream.fail(mapError(err));
212
- });
213
- await (yield* this.#handleResponseStream(stream));
214
234
  }
215
235
 
216
236
  async * #handleResponseStream(stream: AiStream): AsyncGenerator<DoConversationResponse, void, void> {
@@ -397,8 +417,7 @@ export class AidaClient {
397
417
  return {generatedSamples, metadata};
398
418
  }
399
419
 
400
- async generateCode(request: GenerateCodeRequest, options?: {signal?: AbortSignal}):
401
- Promise<GenerateCodeResponse|null> {
420
+ async generateCode(request: GenerateCodeRequest, options?: {signal?: AbortSignal}): Promise<GenerateCodeResponse> {
402
421
  // Disable logging for now.
403
422
  // For context, see b/454563259#comment35.
404
423
  // We should be able to remove this ~end of April.
@@ -495,8 +514,8 @@ export class HostConfigTracker extends Common.ObjectWrapper.ObjectWrapper<EventT
495
514
  return eventDescriptor;
496
515
  }
497
516
 
498
- override removeEventListener(eventType: Events, listener: Common.EventTarget.EventListener<EventTypes, Events>):
499
- void {
517
+ override removeEventListener(eventType: Events,
518
+ listener: Common.EventTarget.EventListener<EventTypes, Events>): void {
500
519
  super.removeEventListener(eventType, listener);
501
520
  if (!this.hasEventListeners(eventType)) {
502
521
  clearTimeout(this.#pollTimer);
@@ -77,18 +77,16 @@ export class GcaClient {
77
77
  });
78
78
  }
79
79
 
80
- async completeCode(request: CompletionRequest): Promise<CompletionResponse|null> {
80
+ async completeCode(request: CompletionRequest): Promise<CompletionResponse> {
81
81
  const gcaRequest = aidaCompletionRequestToGcaRequest(request);
82
82
  const result = await this.#requestContent(gcaRequest);
83
- const aidaResult = result ? gcaResponseToAidaCompletionResponse(result) : null;
84
- return aidaResult;
83
+ return gcaResponseToAidaCompletionResponse(result);
85
84
  }
86
85
 
87
- async generateCode(request: GenerateCodeRequest, options?: {signal?: AbortSignal}):
88
- Promise<GenerateCodeResponse|null> {
86
+ async generateCode(request: GenerateCodeRequest, options?: {signal?: AbortSignal}): Promise<GenerateCodeResponse> {
89
87
  const gcaRequest = aidaGenerateCodeRequestToGcaRequest(request);
90
88
  const result = await this.#requestContent(gcaRequest, options);
91
- return result ? gcaResponseToAidaGenerateCodeResponse(result) : null;
89
+ return gcaResponseToAidaGenerateCodeResponse(result);
92
90
  }
93
91
 
94
92
  async #requestContent(request: GenerateContentRequest,
@@ -80,8 +80,10 @@ export const bindOutputStream = function(stream: Common.StringOutputStream.Outpu
80
80
  };
81
81
 
82
82
  export const discardOutputStream = function(id: number): void {
83
- void _boundStreams[id].close();
84
- delete _boundStreams[id];
83
+ if (_boundStreams[id]) {
84
+ void _boundStreams[id].close();
85
+ delete _boundStreams[id];
86
+ }
85
87
  };
86
88
 
87
89
  export const streamWrite = function(id: number, chunk: string): void {
@@ -560,10 +560,6 @@ export interface HostConfigJpegXlImageFormat {
560
560
  enabled: boolean;
561
561
  }
562
562
 
563
- export interface HostConfigAiAssistanceV2 {
564
- enabled: boolean;
565
- }
566
-
567
563
  interface AiGeneratedTimelineLabels {
568
564
  enabled: boolean;
569
565
  }
@@ -648,6 +644,10 @@ interface DevToolsPlusButton {
648
644
  enabled: boolean;
649
645
  }
650
646
 
647
+ interface DevToolsInstrumentationBreakpoints {
648
+ enabled: boolean;
649
+ }
650
+
651
651
  /**
652
652
  * The host configuration that we expect from the DevTools back-end.
653
653
  *
@@ -673,7 +673,6 @@ export type HostConfig = Platform.TypeScriptUtilities.RecursivePartial<{
673
673
  devToolsAiAssistancePerformanceAgent: HostConfigAiAssistancePerformanceAgent,
674
674
  devToolsAiAssistanceAccessibilityAgent: HostConfigAiAssistanceAccessibilityAgent,
675
675
  devToolsAiAssistanceStorageAgent: HostConfigAiAssistanceStorageAgent,
676
- devToolsAiAssistanceV2: HostConfigAiAssistanceV2,
677
676
  devToolsAiV2Architecture: DevToolsAiV2Architecture,
678
677
  devToolsAiCodeCompletion: HostConfigAiCodeCompletion,
679
678
  devToolsAiCodeGeneration: HostConfigAiCodeGeneration,
@@ -705,6 +704,7 @@ export type HostConfig = Platform.TypeScriptUtilities.RecursivePartial<{
705
704
  devToolsAdsPanel: DevToolsAdsPanel,
706
705
  devToolsUseGcaApi: UseGcaApi,
707
706
  devToolsPlusButton: DevToolsPlusButton,
707
+ devToolsInstrumentationBreakpoints: DevToolsInstrumentationBreakpoints,
708
708
  extensionsOnChromeUrls: ExtensionsOnChromeUrls,
709
709
  }>;
710
710