chrome-devtools-frontend 1.0.1591204 → 1.0.1592362

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 (81) hide show
  1. package/docs/ui_engineering.md +1 -1
  2. package/front_end/core/host/AidaClient.ts +38 -15
  3. package/front_end/core/host/DispatchHttpRequestClient.ts +7 -4
  4. package/front_end/core/host/InspectorFrontendHostAPI.ts +2 -0
  5. package/front_end/core/host/UserMetrics.ts +2 -1
  6. package/front_end/core/protocol_client/InspectorBackend.ts +4 -0
  7. package/front_end/core/root/ExperimentNames.ts +1 -0
  8. package/front_end/core/sdk/CSSMetadata.ts +18 -0
  9. package/front_end/core/sdk/EmulationModel.ts +41 -1
  10. package/front_end/core/sdk/RuntimeModel.ts +2 -1
  11. package/front_end/entrypoints/main/MainImpl.ts +8 -0
  12. package/front_end/generated/InspectorBackendCommands.ts +1 -0
  13. package/front_end/generated/protocol-mapping.d.ts +6 -0
  14. package/front_end/generated/protocol-proxy-api.d.ts +7 -0
  15. package/front_end/generated/protocol.ts +18 -2
  16. package/front_end/models/ai_assistance/AiConversation.ts +9 -0
  17. package/front_end/models/ai_assistance/AiHistoryStorage.ts +1 -0
  18. package/front_end/models/ai_assistance/agents/AiAgent.ts +6 -1
  19. package/front_end/models/ai_assistance/agents/BreakpointDebuggerAgent.ts +1076 -0
  20. package/front_end/models/ai_assistance/agents/BreakpointDebuggerAgentOverlay.ts +87 -0
  21. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.snapshot.txt +8 -8
  22. package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +65 -44
  23. package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +1 -1
  24. package/front_end/models/ai_assistance/ai_assistance.ts +2 -0
  25. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.snapshot.txt +12 -12
  26. package/front_end/models/ai_assistance/data_formatters/PerformanceInsightFormatter.ts +7 -7
  27. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.snapshot.txt +7 -7
  28. package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatter.ts +1 -1
  29. package/front_end/models/computed_style/ComputedStyleModel.ts +40 -6
  30. package/front_end/models/emulation/DeviceModeModel.ts +47 -0
  31. package/front_end/models/greendev/Prototypes.ts +7 -1
  32. package/front_end/models/trace/handlers/NetworkRequestsHandler.ts +3 -3
  33. package/front_end/models/trace/helpers/Network.ts +1 -1
  34. package/front_end/models/trace/insights/NetworkDependencyTree.ts +1 -1
  35. package/front_end/models/trace/insights/RenderBlocking.ts +5 -5
  36. package/front_end/models/trace/lantern/metrics/FirstContentfulPaint.ts +6 -6
  37. package/front_end/panels/ai_assistance/AiAssistancePanel.ts +73 -1
  38. package/front_end/panels/ai_assistance/components/ChatInput.ts +1 -4
  39. package/front_end/panels/ai_assistance/components/MarkdownRendererWithCodeBlock.ts +55 -1
  40. package/front_end/panels/ai_assistance/components/chatInput.css +0 -8
  41. package/front_end/panels/application/CookieItemsView.ts +194 -134
  42. package/front_end/panels/application/DeviceBoundSessionsTreeElement.ts +1 -1
  43. package/front_end/panels/application/StorageItemsToolbar.ts +25 -2
  44. package/front_end/panels/application/cookieItemsView.css +28 -26
  45. package/front_end/panels/common/AiCodeGenerationTeaser.ts +9 -4
  46. package/front_end/panels/console/ConsoleViewMessage.ts +100 -4
  47. package/front_end/panels/elements/ComputedStyleWidget.ts +27 -34
  48. package/front_end/panels/elements/ElementsPanel.ts +28 -5
  49. package/front_end/panels/elements/StyleEditorWidget.ts +10 -2
  50. package/front_end/panels/elements/StylePropertyTreeElement.ts +33 -0
  51. package/front_end/panels/elements/StylesAiCodeCompletionProvider.ts +148 -1
  52. package/front_end/panels/elements/StylesContainer.ts +2 -0
  53. package/front_end/panels/elements/StylesSidebarPane.ts +8 -0
  54. package/front_end/panels/elements/elements-meta.ts +3 -5
  55. package/front_end/panels/elements/stylePropertiesTreeOutline.css +6 -0
  56. package/front_end/panels/emulation/DeviceModeToolbar.ts +25 -0
  57. package/front_end/panels/network/NetworkDataGridNode.ts +1 -1
  58. package/front_end/panels/network/NetworkLogViewColumns.ts +1 -1
  59. package/front_end/panels/network/RequestTimingView.ts +3 -3
  60. package/front_end/panels/settings/SettingsScreen.ts +3 -2
  61. package/front_end/panels/settings/WorkspaceSettingsTab.ts +1 -1
  62. package/front_end/panels/sources/BreakpointsView.ts +1 -1
  63. package/front_end/panels/sources/CallStackSidebarPane.ts +1 -1
  64. package/front_end/panels/timeline/NetworkTrackAppender.ts +1 -1
  65. package/front_end/panels/timeline/components/IgnoreListSetting.ts +0 -1
  66. package/front_end/panels/timeline/components/NetworkRequestDetails.ts +4 -4
  67. package/front_end/panels/timeline/components/NetworkRequestTooltip.ts +2 -2
  68. package/front_end/panels/timeline/components/SidebarAnnotationsTab.ts +4 -4
  69. package/front_end/panels/timeline/components/metricCard.css +0 -4
  70. package/front_end/third_party/chromium/README.chromium +4 -2
  71. package/front_end/third_party/lighthouse/lighthouse-dt-bundle.js +5 -1
  72. package/front_end/third_party/lighthouse/locales/en-GB.json +2 -2
  73. package/front_end/third_party/lighthouse/locales/en-US.json +2 -2
  74. package/front_end/ui/components/text_editor/AiCodeCompletionProvider.ts +13 -2
  75. package/front_end/ui/components/text_editor/AiCodeGenerationProvider.ts +1 -1
  76. package/front_end/ui/legacy/components/cookie_table/CookiesTable.ts +44 -24
  77. package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +31 -8
  78. package/front_end/ui/legacy/components/object_ui/RemoteObjectPreviewFormatter.ts +10 -3
  79. package/front_end/ui/visual_logging/Debugging.ts +4 -0
  80. package/front_end/ui/visual_logging/KnownContextValues.ts +3 -0
  81. package/package.json +1 -1
@@ -611,7 +611,7 @@ export const DEFAULT_VIEW = (input, _output, target) => {
611
611
  <a href="https://www.google.com" data-some-key="some-value" role="some-role">some-text</a>
612
612
  <img src="https://www.google.com/some-image.png" alt="some-alt" draggable="true" height="100"
613
613
  hidden="hidden" href="https://www.google.com" id="some-id" name="some-name" rel="some-rel"
614
- scope="some-scope"></img>
614
+ scope="some-scope">
615
615
  <input type="text" placeholder="some-placeholder" value="some-value"
616
616
  ?disabled=${!this.enabled} checked>
617
617
  </div>`,
@@ -528,8 +528,8 @@ export class AidaClient {
528
528
  async *
529
529
  doConversation(request: DoConversationRequest, options?: {signal?: AbortSignal}):
530
530
  AsyncGenerator<DoConversationResponse, void, void> {
531
- if (!InspectorFrontendHostInstance.doAidaConversation) {
532
- throw new Error('doAidaConversation is not available');
531
+ if (!InspectorFrontendHostInstance.dispatchHttpRequest) {
532
+ throw new Error('dispatchHttpRequest is not available');
533
533
  }
534
534
 
535
535
  // Disable logging for now.
@@ -559,19 +559,42 @@ export class AidaClient {
559
559
  };
560
560
  })();
561
561
  const streamId = bindOutputStream(stream);
562
- InspectorFrontendHostInstance.doAidaConversation(JSON.stringify(request), streamId, result => {
563
- if (result.statusCode === 403) {
564
- stream.fail(new Error('Server responded: permission denied'));
565
- } else if (result.error) {
566
- stream.fail(new Error(`Cannot send request: ${result.error} ${result.detail || ''}`));
567
- } else if (result.netErrorName === 'net::ERR_TIMED_OUT') {
568
- stream.fail(new Error('doAidaConversation timed out'));
569
- } else if (result.statusCode !== 200) {
570
- stream.fail(new Error(`Request failed: ${JSON.stringify(result)}`));
571
- } else {
572
- void stream.close();
573
- }
574
- });
562
+ DispatchHttpRequestClient
563
+ .makeHttpRequest(
564
+ {
565
+ service: SERVICE_NAME,
566
+ path: '/v1/aida:doConversation',
567
+ method: 'POST',
568
+ body: JSON.stringify(request),
569
+ streamId,
570
+ },
571
+ options)
572
+ .then(
573
+ () => {
574
+ void stream.close();
575
+ },
576
+ err => {
577
+ if (err instanceof DispatchHttpRequestClient.DispatchHttpRequestError && err.response) {
578
+ const result = err.response;
579
+ if (result.statusCode === 403) {
580
+ stream.fail(new Error('Server responded: permission denied'));
581
+ return;
582
+ }
583
+ if ('error' in result && result.error) {
584
+ stream.fail(new Error(`Cannot send request: ${result.error} ${result.detail || ''}`));
585
+ return;
586
+ }
587
+ if ('netErrorName' in result && result.netErrorName === 'net::ERR_TIMED_OUT') {
588
+ stream.fail(new Error('doAidaConversation timed out'));
589
+ return;
590
+ }
591
+ if (result.statusCode !== 200) {
592
+ stream.fail(new Error(`Request failed: ${JSON.stringify(result)}`));
593
+ return;
594
+ }
595
+ }
596
+ stream.fail(err);
597
+ });
575
598
  let chunk;
576
599
  const text = [];
577
600
  let inCodeChunk = false;
@@ -12,7 +12,7 @@ export enum ErrorType {
12
12
  }
13
13
 
14
14
  export class DispatchHttpRequestError extends Error {
15
- constructor(readonly type: ErrorType, options?: ErrorOptions) {
15
+ constructor(readonly type: ErrorType, readonly response?: DispatchHttpRequestResult, options?: ErrorOptions) {
16
16
  super(undefined, options);
17
17
  }
18
18
  }
@@ -38,18 +38,21 @@ export async function makeHttpRequest<R>(
38
38
 
39
39
  debugLog({request, response});
40
40
  if (response.statusCode === 404) {
41
- throw new DispatchHttpRequestError(ErrorType.NOT_FOUND);
41
+ throw new DispatchHttpRequestError(ErrorType.NOT_FOUND, response);
42
42
  }
43
43
 
44
44
  if ('response' in response && response.statusCode === 200) {
45
+ if (request.streamId && !response.response) {
46
+ return null as R;
47
+ }
45
48
  try {
46
49
  return JSON.parse(response.response) as R;
47
50
  } catch (err) {
48
- throw new DispatchHttpRequestError(ErrorType.HTTP_RESPONSE_UNAVAILABLE, {cause: err});
51
+ throw new DispatchHttpRequestError(ErrorType.HTTP_RESPONSE_UNAVAILABLE, response, {cause: err});
49
52
  }
50
53
  }
51
54
 
52
- throw new DispatchHttpRequestError(ErrorType.HTTP_RESPONSE_UNAVAILABLE);
55
+ throw new DispatchHttpRequestError(ErrorType.HTTP_RESPONSE_UNAVAILABLE, response);
53
56
  }
54
57
 
55
58
  function isDebugMode(): boolean {
@@ -263,12 +263,14 @@ export type DispatchHttpRequestRequest = {
263
263
  path: string,
264
264
  method: 'GET',
265
265
  queryParams?: Record<string, string|string[]>,
266
+ streamId?: number,
266
267
  body?: never,
267
268
  }|{
268
269
  service: string,
269
270
  path: string,
270
271
  method: 'POST',
271
272
  queryParams?: Record<string, string|string[]>,
273
+ streamId?: number,
272
274
  // A JSON string containing the request body.
273
275
  body?: string,
274
276
  };
@@ -826,10 +826,11 @@ export enum DevtoolsExperiments {
826
826
  'timeline-show-postmessage-events' = 86,
827
827
  'timeline-debug-mode' = 93,
828
828
  'durable-messages' = 110,
829
+ 'jpeg-xl' = 111,
829
830
  /* eslint-enable @typescript-eslint/naming-convention */
830
831
 
831
832
  // Increment this when new experiments are added.
832
- MAX_VALUE = 111,
833
+ MAX_VALUE = 112,
833
834
  }
834
835
 
835
836
  /** Update DevToolsIssuesPanelIssueExpanded from tools/metrics/histograms/enums.xml if new enum is added. **/
@@ -559,6 +559,10 @@ export class TargetBase {
559
559
  this.registerDispatcher('DOMStorage', dispatcher);
560
560
  }
561
561
 
562
+ registerEmulationDispatcher(dispatcher: ProtocolProxyApi.EmulationDispatcher): void {
563
+ this.registerDispatcher('Emulation', dispatcher);
564
+ }
565
+
562
566
  registerFetchDispatcher(dispatcher: ProtocolProxyApi.FetchDispatcher): void {
563
567
  this.registerDispatcher('Fetch', dispatcher);
564
568
  }
@@ -24,6 +24,7 @@ export enum ExperimentName {
24
24
  TIMELINE_SHOW_POST_MESSAGE_EVENTS = 'timeline-show-postmessage-events',
25
25
  TIMELINE_DEBUG_MODE = 'timeline-debug-mode',
26
26
  DURABLE_MESSAGES = 'durable-messages',
27
+ JPEG_XL = 'jpeg-xl',
27
28
  // Adding or removing an entry from this enum?
28
29
  // You will need to update:
29
30
  // 1. DevToolsExperiments enum in host/UserMetrics.ts
@@ -1344,6 +1344,24 @@ const extraPropertyValues = new Map<string, Set<string>>([
1344
1344
  ['-webkit-transform-origin-x', new Set(['left', 'right', 'center'])],
1345
1345
  ['-webkit-transform-origin-y', new Set(['top', 'bottom', 'center'])],
1346
1346
  ['width', new Set(['-webkit-fill-available', 'stretch'])],
1347
+ [
1348
+ 'animation-trigger',
1349
+ new Set([
1350
+ 'play',
1351
+ 'pause',
1352
+ 'play-once',
1353
+ 'play-alternate',
1354
+ 'play-forwards',
1355
+ 'play-backwards',
1356
+ 'play-pause',
1357
+ 'replay',
1358
+ ]),
1359
+ ],
1360
+ ['timeline-trigger-activation-range-start', new Set(['normal'])],
1361
+ ['timeline-trigger-activation-range-end', new Set(['normal'])],
1362
+ ['timeline-trigger-active-range-start', new Set(['normal'])],
1363
+ ['timeline-trigger-active-range-end', new Set(['normal'])],
1364
+
1347
1365
  ['contain-intrinsic-width', new Set(['auto none', 'auto 100px'])],
1348
1366
  ['contain-intrinsic-height', new Set(['auto none', 'auto 100px'])],
1349
1367
  ['contain-intrinsic-size', new Set(['auto none', 'auto 100px'])],
@@ -18,7 +18,7 @@ export const enum DataSaverOverride {
18
18
  DISABLED = 'disabled',
19
19
  }
20
20
 
21
- export class EmulationModel extends SDKModel<void> {
21
+ export class EmulationModel extends SDKModel<EmulationModelEventTypes> implements ProtocolProxyApi.EmulationDispatcher {
22
22
  readonly #emulationAgent: ProtocolProxyApi.EmulationApi;
23
23
  readonly #deviceOrientationAgent: ProtocolProxyApi.DeviceOrientationApi;
24
24
  #cssModel: CSSModel|null;
@@ -33,11 +33,15 @@ export class EmulationModel extends SDKModel<void> {
33
33
  enabled: boolean,
34
34
  configuration: Protocol.Emulation.SetEmitTouchEventsForMouseRequestConfiguration,
35
35
  };
36
+ #screenOrientationLocked: boolean;
37
+ #lockedOrientation: Protocol.Emulation.ScreenOrientation|null;
36
38
 
37
39
  constructor(target: Target) {
38
40
  super(target);
39
41
  this.#emulationAgent = target.emulationAgent();
40
42
  this.#deviceOrientationAgent = target.deviceOrientationAgent();
43
+ this.#screenOrientationLocked = false;
44
+ this.#lockedOrientation = null;
41
45
  this.#cssModel = target.model(CSSModel);
42
46
  this.#overlayModel = target.model(OverlayModel);
43
47
  if (this.#overlayModel) {
@@ -225,6 +229,7 @@ export class EmulationModel extends SDKModel<void> {
225
229
  enabled: false,
226
230
  configuration: Protocol.Emulation.SetEmitTouchEventsForMouseRequestConfiguration.Mobile,
227
231
  };
232
+ target.registerEmulationDispatcher(this);
228
233
  }
229
234
 
230
235
  setTouchEmulationAllowed(touchEmulationAllowed: boolean): void {
@@ -478,6 +483,41 @@ export class EmulationModel extends SDKModel<void> {
478
483
  ];
479
484
  return await this.emulateCSSMedia(type, features);
480
485
  }
486
+
487
+ // ProtocolProxyApi.EmulationDispatcher implementation
488
+
489
+ virtualTimeBudgetExpired(): void {
490
+ // No-op for now; not used by the frontend.
491
+ }
492
+
493
+ screenOrientationLockChanged(event: Protocol.Emulation.ScreenOrientationLockChangedEvent): void {
494
+ this.#screenOrientationLocked = event.locked;
495
+ this.#lockedOrientation = event.orientation ?? null;
496
+ this.dispatchEventToListeners(
497
+ EmulationModelEvents.SCREEN_ORIENTATION_LOCK_CHANGED,
498
+ {locked: event.locked, orientation: event.orientation ?? null});
499
+ }
500
+
501
+ isScreenOrientationLocked(): boolean {
502
+ return this.#screenOrientationLocked;
503
+ }
504
+
505
+ lockedOrientation(): Protocol.Emulation.ScreenOrientation|null {
506
+ return this.#lockedOrientation;
507
+ }
508
+ }
509
+
510
+ export const enum EmulationModelEvents {
511
+ SCREEN_ORIENTATION_LOCK_CHANGED = 'ScreenOrientationLockChanged',
512
+ }
513
+
514
+ export interface ScreenOrientationLockChangedEvent {
515
+ locked: boolean;
516
+ orientation: Protocol.Emulation.ScreenOrientation|null;
517
+ }
518
+
519
+ export interface EmulationModelEventTypes {
520
+ [EmulationModelEvents.SCREEN_ORIENTATION_LOCK_CHANGED]: ScreenOrientationLockChangedEvent;
481
521
  }
482
522
 
483
523
  export class Location {
@@ -262,7 +262,8 @@ export class RuntimeModel extends SDKModel<EventTypes> {
262
262
  }
263
263
 
264
264
  if (object.isNode()) {
265
- void Common.Revealer.reveal(object).then(object.release.bind(object));
265
+ const omitFocus = hints !== null && typeof hints === 'object' && 'omitFocus' in hints && Boolean(hints.omitFocus);
266
+ void Common.Revealer.reveal(object, omitFocus).then(object.release.bind(object));
266
267
  return;
267
268
  }
268
269
 
@@ -431,6 +431,14 @@ export class MainImpl {
431
431
  requiresChromeRestart: false,
432
432
  });
433
433
 
434
+ Root.Runtime.experiments.registerHostExperiment({
435
+ name: Root.ExperimentNames.ExperimentName.JPEG_XL,
436
+ title: 'JPEG XL support',
437
+ aboutFlag: 'enable-jxl-image-format',
438
+ isEnabled: Root.Runtime.hostConfig.devToolsJpegXlImageFormat?.enabled ?? false,
439
+ requiresChromeRestart: true,
440
+ });
441
+
434
442
  Root.Runtime.experiments.enableExperimentsByDefault([
435
443
  Root.ExperimentNames.ExperimentName.FULL_ACCESSIBILITY_TREE,
436
444
  Root.ExperimentNames.ExperimentName.USE_SOURCE_MAP_SCOPES,
@@ -508,6 +508,7 @@ inspectorBackend.registerEnum("Emulation.PressureSource", {Cpu: "cpu"});
508
508
  inspectorBackend.registerEnum("Emulation.PressureState", {Nominal: "nominal", Fair: "fair", Serious: "serious", Critical: "critical"});
509
509
  inspectorBackend.registerEnum("Emulation.DisabledImageType", {Avif: "avif", Jxl: "jxl", Webp: "webp"});
510
510
  inspectorBackend.registerEvent("Emulation.virtualTimeBudgetExpired", []);
511
+ inspectorBackend.registerEvent("Emulation.screenOrientationLockChanged", ["locked", "orientation"]);
511
512
  inspectorBackend.registerCommand("Emulation.canEmulate", [], ["result"], "Tells whether emulation is supported.");
512
513
  inspectorBackend.registerCommand("Emulation.clearDeviceMetricsOverride", [], [], "Clears the overridden device metrics.");
513
514
  inspectorBackend.registerCommand("Emulation.clearGeolocationOverride", [], [], "Clears the overridden Geolocation Position and Error.");
@@ -202,6 +202,12 @@ export namespace ProtocolMapping {
202
202
  * Notification sent after the virtual time budget for the current VirtualTimePolicy has run out.
203
203
  */
204
204
  'Emulation.virtualTimeBudgetExpired': [];
205
+ /**
206
+ * Fired when a page calls screen.orientation.lock() or screen.orientation.unlock()
207
+ * while device emulation is enabled. This allows the DevTools frontend to update the
208
+ * emulated device orientation accordingly.
209
+ */
210
+ 'Emulation.screenOrientationLockChanged': [Protocol.Emulation.ScreenOrientationLockChangedEvent];
205
211
  'FedCm.dialogShown': [Protocol.FedCm.DialogShownEvent];
206
212
  /**
207
213
  * Triggered when a dialog is closed, either by user action, JS abort,
@@ -1867,6 +1867,13 @@ declare namespace ProtocolProxyApi {
1867
1867
  */
1868
1868
  virtualTimeBudgetExpired(): void;
1869
1869
 
1870
+ /**
1871
+ * Fired when a page calls screen.orientation.lock() or screen.orientation.unlock()
1872
+ * while device emulation is enabled. This allows the DevTools frontend to update the
1873
+ * emulated device orientation accordingly.
1874
+ */
1875
+ screenOrientationLockChanged(params: Protocol.Emulation.ScreenOrientationLockChangedEvent): void;
1876
+
1870
1877
  }
1871
1878
 
1872
1879
  export interface EventBreakpointsApi {
@@ -7554,6 +7554,22 @@ export namespace Emulation {
7554
7554
  export interface SetPrimaryScreenRequest {
7555
7555
  screenId: ScreenId;
7556
7556
  }
7557
+
7558
+ /**
7559
+ * Fired when a page calls screen.orientation.lock() or screen.orientation.unlock()
7560
+ * while device emulation is enabled. This allows the DevTools frontend to update the
7561
+ * emulated device orientation accordingly.
7562
+ */
7563
+ export interface ScreenOrientationLockChangedEvent {
7564
+ /**
7565
+ * Whether the screen orientation is currently locked.
7566
+ */
7567
+ locked: boolean;
7568
+ /**
7569
+ * The orientation lock type requested by the page. Only set when locked is true.
7570
+ */
7571
+ orientation?: ScreenOrientation;
7572
+ }
7557
7573
  }
7558
7574
 
7559
7575
  /**
@@ -10157,7 +10173,7 @@ export namespace Network {
10157
10173
  }
10158
10174
 
10159
10175
  /**
10160
- * The render blocking behavior of a resource request.
10176
+ * The render-blocking behavior of a resource request.
10161
10177
  */
10162
10178
  export const enum RenderBlockingBehavior {
10163
10179
  Blocking = 'Blocking',
@@ -12674,7 +12690,7 @@ export namespace Network {
12674
12690
  */
12675
12691
  hasUserGesture?: boolean;
12676
12692
  /**
12677
- * The render blocking behavior of the request.
12693
+ * The render-blocking behavior of the request.
12678
12694
  */
12679
12695
  renderBlockingBehavior?: RenderBlockingBehavior;
12680
12696
  }
@@ -6,6 +6,7 @@ import * as Host from '../../core/host/host.js';
6
6
  import * as Root from '../../core/root/root.js';
7
7
  import * as SDK from '../../core/sdk/sdk.js';
8
8
  import * as Trace from '../../models/trace/trace.js';
9
+ import * as Greendev from '../greendev/greendev.js';
9
10
  import * as NetworkTimeCalculator from '../network_time_calculator/network_time_calculator.js';
10
11
 
11
12
  import {
@@ -17,6 +18,7 @@ import {
17
18
  ResponseType,
18
19
  type UserQuery
19
20
  } from './agents/AiAgent.js';
21
+ import {BreakpointDebuggerAgent} from './agents/BreakpointDebuggerAgent.js';
20
22
  import {ContextSelectionAgent} from './agents/ContextSelectionAgent.js';
21
23
  import {FileAgent, FileContext} from './agents/FileAgent.js';
22
24
  import {NetworkAgent, RequestContext} from './agents/NetworkAgent.js';
@@ -326,6 +328,13 @@ export class AiConversation {
326
328
  this.#agent = new PerformanceAgent(options);
327
329
  break;
328
330
  }
331
+ case ConversationType.BREAKPOINT: {
332
+ const breakpointAgentEnabled = Greendev.Prototypes.instance().isEnabled('breakpointDebuggerAgent');
333
+ if (breakpointAgentEnabled) {
334
+ this.#agent = new BreakpointDebuggerAgent(options);
335
+ }
336
+ break;
337
+ }
329
338
  case ConversationType.NONE: {
330
339
  this.#agent = new ContextSelectionAgent(options);
331
340
  break;
@@ -13,6 +13,7 @@ export const enum ConversationType {
13
13
  FILE = 'drjones-file',
14
14
  NETWORK = 'drjones-network-request',
15
15
  PERFORMANCE = 'drjones-performance-full',
16
+ BREAKPOINT = 'breakpoint',
16
17
  }
17
18
 
18
19
  export interface SerializedConversation {
@@ -5,6 +5,7 @@
5
5
  import * as Host from '../../../core/host/host.js';
6
6
  import * as Root from '../../../core/root/root.js';
7
7
  import type * as SDK from '../../../core/sdk/sdk.js';
8
+ import * as Greendev from '../../greendev/greendev.js';
8
9
  import {debugLog, isStructuredLogEnabled} from '../debug.js';
9
10
 
10
11
  export const enum ResponseType {
@@ -534,7 +535,11 @@ export abstract class AiAgent<T> {
534
535
 
535
536
  yield* this.handleContextDetails(options.selected);
536
537
 
537
- for (let i = 0; i < MAX_STEPS; i++) {
538
+ const breakpointAgentEnabled = Greendev.Prototypes.instance().isEnabled('breakpointDebuggerAgent');
539
+ const isBreakpointDebuggerAgent = this.constructor.name === 'BreakpointDebuggerAgent';
540
+ const finalMaxSteps = (isBreakpointDebuggerAgent && breakpointAgentEnabled) ? 1000 : MAX_STEPS;
541
+
542
+ for (let i = 0; i < finalMaxSteps; i++) {
538
543
  yield {
539
544
  type: ResponseType.QUERYING,
540
545
  };