@narumitw/pi-chrome-devtools 0.53.0 → 0.53.2

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 (32) hide show
  1. package/README.md +88 -230
  2. package/dist/chunks/{browser-settings-menu-N5O65I7S.js → browser-settings-menu-IMB6HXSU.js} +5 -3
  3. package/dist/chunks/browser-settings-menu-IMB6HXSU.js.map +7 -0
  4. package/dist/chunks/{chunk-RTECHAEZ.js → chunk-GTTYS5GT.js} +20 -9
  5. package/dist/chunks/chunk-GTTYS5GT.js.map +7 -0
  6. package/dist/chunks/{chunk-B7B63PWB.js → chunk-LLXOCRNF.js} +50 -30
  7. package/dist/chunks/chunk-LLXOCRNF.js.map +7 -0
  8. package/dist/chunks/{chunk-GVBXT3FB.js → chunk-SRT3UUIP.js} +117 -73
  9. package/dist/chunks/chunk-SRT3UUIP.js.map +7 -0
  10. package/dist/chunks/{menu-UBHW6UP2.js → menu-UJETYMSB.js} +4 -4
  11. package/dist/chunks/{tools-V7OR5KJ3.js → tools-6P7EUX37.js} +49 -30
  12. package/dist/chunks/tools-6P7EUX37.js.map +7 -0
  13. package/dist/index.ts +21 -18
  14. package/dist/index.ts.map +2 -2
  15. package/docs/browser-setup.md +147 -0
  16. package/package.json +7 -7
  17. package/src/browser-manager.ts +138 -72
  18. package/src/browser-settings-menu.ts +2 -1
  19. package/src/cdp-client.ts +18 -7
  20. package/src/chrome-devtools.ts +8 -1
  21. package/src/display.ts +38 -0
  22. package/src/render.ts +6 -7
  23. package/src/tool-selector.ts +21 -32
  24. package/src/tools.ts +5 -5
  25. package/src/webmcp/policy.ts +14 -7
  26. package/src/webmcp/protocol.ts +33 -21
  27. package/dist/chunks/browser-settings-menu-N5O65I7S.js.map +0 -7
  28. package/dist/chunks/chunk-B7B63PWB.js.map +0 -7
  29. package/dist/chunks/chunk-GVBXT3FB.js.map +0 -7
  30. package/dist/chunks/chunk-RTECHAEZ.js.map +0 -7
  31. package/dist/chunks/tools-V7OR5KJ3.js.map +0 -7
  32. /package/dist/chunks/{menu-UBHW6UP2.js.map → menu-UJETYMSB.js.map} +0 -0
@@ -587,13 +587,34 @@ var DEFAULT_BROWSER_MANAGER_OPERATIONS = {
587
587
  };
588
588
  var browserManagerOperations = DEFAULT_BROWSER_MANAGER_OPERATIONS;
589
589
  var managedBrowserScopes = /* @__PURE__ */ new WeakMap();
590
+ function cloneBrowserSettings(browser) {
591
+ return { ...browser, extensionPaths: [...browser.extensionPaths] };
592
+ }
593
+ function runtimeBrowserSettings() {
594
+ return {
595
+ endpoint: `http://${formatHostForUrl(state.host)}:${state.configuredPort}`,
596
+ host: state.host,
597
+ port: state.configuredPort,
598
+ hostConfigured: state.hostConfigured,
599
+ portConfigured: state.portConfigured,
600
+ autoLaunchEnabled: state.autoLaunchEnabled,
601
+ ...state.browserExecutable ? { executablePath: state.browserExecutable } : {},
602
+ extensionPaths: [...state.extensionPaths],
603
+ endpointSource: state.endpointSource,
604
+ autoLaunchSource: state.autoLaunchSource,
605
+ executablePathSource: state.browserExecutableSource,
606
+ extensionPathsSource: state.extensionPathsSource
607
+ };
608
+ }
590
609
  function managedBrowserScope(owner) {
591
610
  const existing = managedBrowserScopes.get(owner);
592
611
  if (existing) return existing;
612
+ const browser = runtimeBrowserSettings();
593
613
  const created = {
614
+ browser,
594
615
  controller: new AbortController(),
595
616
  generation: 0,
596
- port: state.configuredPort
617
+ port: browser.port
597
618
  };
598
619
  managedBrowserScopes.set(owner, created);
599
620
  return created;
@@ -603,9 +624,19 @@ function startManagedBrowserSession(owner) {
603
624
  scope.controller.abort(new DOMException("Chrome DevTools session replaced", "AbortError"));
604
625
  scope.controller = new AbortController();
605
626
  scope.generation += 1;
606
- scope.port = state.configuredPort;
607
627
  scope.lastLaunchAttempt = void 0;
608
628
  }
629
+ function syncManagedBrowserSettings(owner, browser) {
630
+ const scope = managedBrowserScope(owner);
631
+ scope.browser = cloneBrowserSettings(browser);
632
+ scope.port = browser.port;
633
+ }
634
+ function browserSettingsForOwner(owner) {
635
+ return owner ? managedBrowserScope(owner).browser : runtimeBrowserSettings();
636
+ }
637
+ function managedBrowserExtensionPaths(owner) {
638
+ return browserSettingsForOwner(owner).extensionPaths;
639
+ }
609
640
  function managedBrowserForOwner(owner) {
610
641
  if (!owner) return state.managedBrowser;
611
642
  const scopedBrowser = managedBrowserScope(owner).managedBrowser;
@@ -626,6 +657,12 @@ function setLaunchPromise(owner, launchPromise) {
626
657
  function managedBrowserPort(owner) {
627
658
  return owner ? managedBrowserScope(owner).port : state.port;
628
659
  }
660
+ function managedBrowserConfiguredPort(owner) {
661
+ return browserSettingsForOwner(owner).port;
662
+ }
663
+ function managedBrowserPortConfigured(owner) {
664
+ return browserSettingsForOwner(owner).portConfigured;
665
+ }
629
666
  function setManagedBrowserPort(owner, port) {
630
667
  if (owner) managedBrowserScope(owner).port = port;
631
668
  else state.port = port;
@@ -648,12 +685,12 @@ function normalizePathForComparison(value) {
648
685
  }
649
686
  async function ensureDevToolsEndpoint(waitMs = DEFAULT_ENDPOINT_WAIT_MS, callerSignal, owner) {
650
687
  callerSignal?.throwIfAborted();
651
- if (extensionsConfigured()) {
652
- validateExtensionLaunchMode();
688
+ if (extensionsConfigured(owner)) {
689
+ validateExtensionLaunchMode(owner);
653
690
  await ensureManagedBrowserLaunched(waitMs, callerSignal, owner);
654
691
  return;
655
692
  }
656
- if (canAutoLaunchBrowser()) {
693
+ if (canAutoLaunchBrowser(owner)) {
657
694
  try {
658
695
  await withEndpointRetry(
659
696
  () => fetchDevToolsJson("/json/version", { signal: callerSignal }, owner),
@@ -662,7 +699,7 @@ async function ensureDevToolsEndpoint(waitMs = DEFAULT_ENDPOINT_WAIT_MS, callerS
662
699
  );
663
700
  return;
664
701
  } catch (error) {
665
- if (shouldAutoLaunchAfterEndpointError(error)) {
702
+ if (shouldAutoLaunchAfterEndpointError(error, owner)) {
666
703
  await ensureManagedBrowserLaunched(waitMs, callerSignal, owner);
667
704
  return;
668
705
  }
@@ -676,18 +713,19 @@ async function ensureDevToolsEndpoint(waitMs = DEFAULT_ENDPOINT_WAIT_MS, callerS
676
713
  throw error;
677
714
  }
678
715
  }
679
- function validateExtensionLaunchMode() {
680
- if (!isLocalDevToolsHost(state.host)) {
716
+ function validateExtensionLaunchMode(owner) {
717
+ const browser = browserSettingsForOwner(owner);
718
+ if (!isLocalDevToolsHost(browser.host)) {
681
719
  throw new DevToolsEndpointError(
682
720
  "Unpacked extensions require a local extension-owned managed browser; remote CDP endpoints cannot be modified."
683
721
  );
684
722
  }
685
- if (!state.autoLaunchEnabled) {
723
+ if (!browser.autoLaunchEnabled) {
686
724
  throw new DevToolsEndpointError(
687
725
  "Auto-launch is required for unpacked extensions so Pi can create an isolated managed browser."
688
726
  );
689
727
  }
690
- if (!state.browserExecutable) {
728
+ if (!browser.executablePath) {
691
729
  throw new DevToolsEndpointError(
692
730
  "Unpacked extensions require browser.executablePath for Chrome for Testing or Chromium in pi-chrome-devtools.json."
693
731
  );
@@ -736,9 +774,9 @@ async function prepareManagedBrowserLaunch(waitMs, generation, signal, owner) {
736
774
  await shutdownManagedBrowser(existingBrowser, { awaitLaunch: false, owner });
737
775
  throwIfBrowserLaunchCancelled(generation, signal, owner);
738
776
  }
739
- if (state.portConfigured) {
777
+ if (managedBrowserPortConfigured(owner)) {
740
778
  const available = await browserManagerOperations.isPortAvailable(
741
- state.host,
779
+ browserSettingsForOwner(owner).host,
742
780
  managedBrowserPort(owner)
743
781
  );
744
782
  throwIfBrowserLaunchCancelled(generation, signal, owner);
@@ -752,7 +790,7 @@ async function prepareManagedBrowserLaunch(waitMs, generation, signal, owner) {
752
790
  }
753
791
  async function launchManagedBrowser(waitMs, generation, signal, owner) {
754
792
  throwIfBrowserLaunchCancelled(generation, signal, owner);
755
- const candidateDefinitions = browserCandidateDefinitions();
793
+ const candidateDefinitions = browserCandidateDefinitions(owner);
756
794
  const candidates = await resolveBrowserCandidates(
757
795
  candidateDefinitions,
758
796
  generation,
@@ -762,23 +800,23 @@ async function launchManagedBrowser(waitMs, generation, signal, owner) {
762
800
  throwIfBrowserLaunchCancelled(generation, signal, owner);
763
801
  setLastLaunchAttempt(owner, {
764
802
  candidateLabels: candidateDefinitions.map(formatBrowserCandidateDefinition),
765
- mode: state.portConfigured ? "explicit-port" : "dynamic-port"
803
+ mode: managedBrowserPortConfigured(owner) ? "explicit-port" : "dynamic-port"
766
804
  });
767
805
  if (candidates.length === 0) {
768
- throw new DevToolsEndpointError(noBrowserCandidateMessage(candidateDefinitions));
806
+ throw new DevToolsEndpointError(noBrowserCandidateMessage(candidateDefinitions, owner));
769
807
  }
770
808
  let lastError;
771
809
  for (const candidate of candidates) {
772
810
  throwIfBrowserLaunchCancelled(generation, signal, owner);
773
811
  try {
774
- if (extensionsConfigured())
812
+ if (extensionsConfigured(owner))
775
813
  await requireSupportedExtensionBrowser(candidate, generation, signal, owner);
776
814
  await launchBrowserCandidate(candidate, waitMs, generation, signal, owner);
777
815
  throwIfBrowserLaunchCancelled(generation, signal, owner);
778
816
  setLastLaunchAttempt(owner, {
779
817
  ...lastLaunchAttempt(owner),
780
818
  candidateLabels: candidateDefinitions.map(formatBrowserCandidateDefinition),
781
- mode: state.portConfigured ? "explicit-port" : "dynamic-port",
819
+ mode: managedBrowserPortConfigured(owner) ? "explicit-port" : "dynamic-port",
782
820
  selectedCandidate: formatBrowserCandidate(candidate),
783
821
  userDataDir: managedBrowserForOwner(owner)?.userDataDir
784
822
  });
@@ -790,7 +828,7 @@ async function launchManagedBrowser(waitMs, generation, signal, owner) {
790
828
  setLastLaunchAttempt(owner, {
791
829
  ...lastLaunchAttempt(owner) ?? {
792
830
  candidateLabels: candidateDefinitions.map(formatBrowserCandidateDefinition),
793
- mode: state.portConfigured ? "explicit-port" : "dynamic-port"
831
+ mode: managedBrowserPortConfigured(owner) ? "explicit-port" : "dynamic-port"
794
832
  },
795
833
  lastError: formatError2(cancellation)
796
834
  });
@@ -800,19 +838,19 @@ async function launchManagedBrowser(waitMs, generation, signal, owner) {
800
838
  setLastLaunchAttempt(owner, {
801
839
  ...lastLaunchAttempt(owner) ?? {
802
840
  candidateLabels: candidateDefinitions.map(formatBrowserCandidateDefinition),
803
- mode: state.portConfigured ? "explicit-port" : "dynamic-port"
841
+ mode: managedBrowserPortConfigured(owner) ? "explicit-port" : "dynamic-port"
804
842
  },
805
843
  lastError: formatError2(error)
806
844
  });
807
845
  }
808
846
  }
809
- if (lastError instanceof DevToolsEndpointError && extensionsConfigured()) throw lastError;
847
+ if (lastError instanceof DevToolsEndpointError && extensionsConfigured(owner)) throw lastError;
810
848
  throw new DevToolsEndpointError(
811
849
  [
812
850
  "Unable to auto-launch a Chromium-family browser for Chrome DevTools.",
813
851
  `Tried: ${candidates.map(formatBrowserCandidate).join(", ")}`,
814
852
  lastError ? `Last error: ${formatError2(lastError)}` : void 0,
815
- launchHint(),
853
+ launchHint(owner),
816
854
  endpointConfigHint()
817
855
  ].filter(Boolean).join("\n")
818
856
  );
@@ -851,11 +889,11 @@ async function launchBrowserCandidate(candidate, waitMs, generation, signal, own
851
889
  let managedBrowser;
852
890
  try {
853
891
  throwIfBrowserLaunchCancelled(generation, signal, owner);
854
- const portArgument = state.portConfigured ? String(managedBrowserPort(owner)) : "0";
892
+ const portArgument = managedBrowserPortConfigured(owner) ? String(managedBrowserPort(owner)) : "0";
855
893
  const args = buildManagedBrowserLaunchArguments(
856
894
  userDataDir,
857
895
  portArgument,
858
- state.extensionPaths
896
+ managedBrowserExtensionPaths(owner)
859
897
  );
860
898
  const child = browserManagerOperations.spawn(candidate.resolvedExecutable, args, {
861
899
  shell: false,
@@ -877,13 +915,13 @@ async function launchBrowserCandidate(candidate, waitMs, generation, signal, own
877
915
  }
878
916
  launchedBrowser.exited = true;
879
917
  launchedBrowser.ready = false;
880
- if (!state.portConfigured && launchedBrowser.port === managedBrowserPort(owner)) {
881
- setManagedBrowserPort(owner, state.configuredPort);
918
+ if (!managedBrowserPortConfigured(owner) && launchedBrowser.port === managedBrowserPort(owner)) {
919
+ setManagedBrowserPort(owner, managedBrowserConfiguredPort(owner));
882
920
  }
883
921
  });
884
922
  await waitForBrowserSpawn(child);
885
923
  throwIfBrowserLaunchCancelled(generation, signal, owner);
886
- if (state.portConfigured) {
924
+ if (managedBrowserPortConfigured(owner)) {
887
925
  launchedBrowser.port = managedBrowserPort(owner);
888
926
  } else {
889
927
  launchedBrowser.port = await readManagedBrowserPort(
@@ -958,7 +996,7 @@ async function readManagedBrowserPort(userDataDir, managedBrowser, waitMs, gener
958
996
  [
959
997
  "Timed out waiting for auto-launched browser DevToolsActivePort.",
960
998
  `Expected file: ${activePortFile}`,
961
- launchHint()
999
+ launchHint(owner)
962
1000
  ].join("\n")
963
1001
  );
964
1002
  }
@@ -982,7 +1020,7 @@ async function waitForDevToolsEndpoint(waitMs, managedBrowser, generation, signa
982
1020
  throw new DevToolsEndpointError(
983
1021
  [
984
1022
  `Timed out waiting for auto-launched browser at ${devToolsEndpoint(owner)}.`,
985
- launchHint()
1023
+ launchHint(owner)
986
1024
  ].join("\n")
987
1025
  );
988
1026
  }
@@ -1041,8 +1079,8 @@ async function cleanupManagedBrowser(managedBrowser, owner) {
1041
1079
  });
1042
1080
  }
1043
1081
  await browserManagerOperations.rm(managedBrowser.userDataDir, { recursive: true, force: true }).catch(() => void 0);
1044
- if (!state.portConfigured && managedBrowser.port === managedBrowserPort(owner)) {
1045
- setManagedBrowserPort(owner, state.configuredPort);
1082
+ if (!managedBrowserPortConfigured(owner) && managedBrowser.port === managedBrowserPort(owner)) {
1083
+ setManagedBrowserPort(owner, managedBrowserConfiguredPort(owner));
1046
1084
  }
1047
1085
  }
1048
1086
  function killManagedBrowserProcess(managedBrowser, signal) {
@@ -1132,22 +1170,23 @@ function isRetryableEndpointError(error) {
1132
1170
  function isLaunchableEndpointError(error) {
1133
1171
  return error instanceof DevToolsEndpointError && error.launchable;
1134
1172
  }
1135
- function shouldAutoLaunchAfterEndpointError(error) {
1136
- if (!canAutoLaunchBrowser()) return false;
1173
+ function shouldAutoLaunchAfterEndpointError(error, owner) {
1174
+ if (!canAutoLaunchBrowser(owner)) return false;
1137
1175
  if (isLaunchableEndpointError(error)) return true;
1138
- return !state.portConfigured && error instanceof DevToolsEndpointError;
1176
+ return !managedBrowserPortConfigured(owner) && error instanceof DevToolsEndpointError;
1139
1177
  }
1140
- function canAutoLaunchBrowser() {
1141
- return state.autoLaunchEnabled && isLocalDevToolsHost(state.host);
1178
+ function canAutoLaunchBrowser(owner) {
1179
+ const browser = browserSettingsForOwner(owner);
1180
+ return browser.autoLaunchEnabled && isLocalDevToolsHost(browser.host);
1142
1181
  }
1143
- function extensionsConfigured() {
1144
- return state.extensionPaths.length > 0;
1182
+ function extensionsConfigured(owner) {
1183
+ return managedBrowserExtensionPaths(owner).length > 0;
1145
1184
  }
1146
1185
  function endpointConnectionErrorMessage(error, owner) {
1147
1186
  const reason = isTimeoutError(error) ? "request timed out" : "connection failed";
1148
1187
  return [
1149
1188
  `Cannot connect to Chrome DevTools endpoint at ${devToolsEndpoint(owner)} (${reason}).`,
1150
- launchHint(),
1189
+ launchHint(owner),
1151
1190
  endpointConfigHint()
1152
1191
  ].join("\n");
1153
1192
  }
@@ -1155,14 +1194,14 @@ function isTimeoutError(error) {
1155
1194
  return error instanceof Error && ["AbortError", "TimeoutError"].includes(error.name);
1156
1195
  }
1157
1196
  function devToolsEndpoint(owner) {
1158
- return `http://${formatHostForUrl(state.host)}:${managedBrowserPort(owner)}`;
1197
+ return `http://${formatHostForUrl(browserSettingsForOwner(owner).host)}:${managedBrowserPort(owner)}`;
1159
1198
  }
1160
1199
  function formatHostForUrl(host) {
1161
1200
  if (host.startsWith("[") && host.endsWith("]")) return host;
1162
1201
  return host.includes(":") ? `[${host}]` : host;
1163
1202
  }
1164
- function endpointSourceLabel() {
1165
- return state.endpointSource;
1203
+ function endpointSourceLabel(owner) {
1204
+ return browserSettingsForOwner(owner).endpointSource;
1166
1205
  }
1167
1206
  function browserLifecycleState(owner) {
1168
1207
  if (launchPromiseForOwner(owner)) return "starting";
@@ -1172,21 +1211,22 @@ function browserLifecycleState(owner) {
1172
1211
  return "unobserved";
1173
1212
  }
1174
1213
  function launchModeLabel(owner) {
1214
+ const browser = browserSettingsForOwner(owner);
1175
1215
  const managedBrowser = managedBrowserForOwner(owner);
1176
- if (extensionsConfigured()) {
1177
- if (!isLocalDevToolsHost(state.host)) return "invalid; extensions require a local endpoint";
1178
- if (!state.autoLaunchEnabled) return "invalid; extensions require auto-launch";
1216
+ if (extensionsConfigured(owner)) {
1217
+ if (!isLocalDevToolsHost(browser.host)) return "invalid; extensions require a local endpoint";
1218
+ if (!browser.autoLaunchEnabled) return "invalid; extensions require auto-launch";
1179
1219
  if (managedBrowser && !managedBrowser.exited) {
1180
- return state.portConfigured ? "extension-owned browser on explicit port" : "extension-owned browser on dynamic port";
1220
+ return managedBrowserPortConfigured(owner) ? "extension-owned browser on explicit port" : "extension-owned browser on dynamic port";
1181
1221
  }
1182
- return state.portConfigured ? "force extension-owned launch on explicit port" : "force extension-owned launch on dynamic port";
1222
+ return managedBrowserPortConfigured(owner) ? "force extension-owned launch on explicit port" : "force extension-owned launch on dynamic port";
1183
1223
  }
1184
- if (!isLocalDevToolsHost(state.host)) return "manual remote endpoint";
1185
- if (!state.autoLaunchEnabled) return "manual; auto-launch disabled";
1224
+ if (!isLocalDevToolsHost(browser.host)) return "manual remote endpoint";
1225
+ if (!browser.autoLaunchEnabled) return "manual; auto-launch disabled";
1186
1226
  if (managedBrowser && !managedBrowser.exited) {
1187
- return state.portConfigured ? "auto-launched on explicit port" : "auto-launched on dynamic port";
1227
+ return managedBrowserPortConfigured(owner) ? "auto-launched on explicit port" : "auto-launched on dynamic port";
1188
1228
  }
1189
- return state.portConfigured ? "attach first; auto-launch explicit port" : "attach first; auto-launch dynamic port";
1229
+ return managedBrowserPortConfigured(owner) ? "attach first; auto-launch explicit port" : "attach first; auto-launch dynamic port";
1190
1230
  }
1191
1231
  function launchAttemptLines(owner) {
1192
1232
  const attempt = lastLaunchAttempt(owner);
@@ -1201,29 +1241,30 @@ function launchAttemptLines(owner) {
1201
1241
  if (attempt.lastError) lines.push(`Last launch error: ${attempt.lastError}`);
1202
1242
  return lines;
1203
1243
  }
1204
- function launchHint() {
1205
- if (extensionsConfigured()) {
1244
+ function launchHint(owner) {
1245
+ const browser = browserSettingsForOwner(owner);
1246
+ if (extensionsConfigured(owner)) {
1206
1247
  return "Configured unpacked extensions force an isolated extension-owned launch; existing CDP browsers are never reused, modified, or closed.";
1207
1248
  }
1208
- if (!isLocalDevToolsHost(state.host)) {
1209
- return `Remote/non-local endpoints are not auto-launched. Start a browser with CDP enabled at ${devToolsEndpoint()}.`;
1249
+ if (!isLocalDevToolsHost(browser.host)) {
1250
+ return `Remote/non-local endpoints are not auto-launched. Start a browser with CDP enabled at ${devToolsEndpoint(owner)}.`;
1210
1251
  }
1211
- if (!state.autoLaunchEnabled) {
1212
- return `Auto-launch is disabled. Start a browser manually: ${chromeLaunchCommand()}`;
1252
+ if (!browser.autoLaunchEnabled) {
1253
+ return `Auto-launch is disabled. Start a browser manually: ${chromeLaunchCommand(owner)}`;
1213
1254
  }
1214
- const managedMode = state.portConfigured ? `port ${state.port}` : "a dynamic DevTools port";
1215
- return `If no endpoint is available, Pi will auto-launch a Chromium-family browser with ${managedMode} and an isolated temp profile. Manual command: ${chromeLaunchCommand()}`;
1255
+ const managedMode = managedBrowserPortConfigured(owner) ? `port ${managedBrowserPort(owner)}` : "a dynamic DevTools port";
1256
+ return `If no endpoint is available, Pi will auto-launch a Chromium-family browser with ${managedMode} and an isolated temp profile. Manual command: ${chromeLaunchCommand(owner)}`;
1216
1257
  }
1217
- function browserCandidateHint() {
1218
- if (extensionsConfigured()) {
1258
+ function browserCandidateHint(owner) {
1259
+ if (extensionsConfigured(owner)) {
1219
1260
  return "Extension browser requirement: configure Chrome for Testing or Chromium with browser.executablePath; branded Chrome is rejected because it may ignore unpacked-extension flags.";
1220
1261
  }
1221
- return `Browser candidates: ${browserCandidateDefinitions().map((candidate) => candidate.label).join(", ")}`;
1262
+ return `Browser candidates: ${browserCandidateDefinitions(owner).map((candidate) => candidate.label).join(", ")}`;
1222
1263
  }
1223
- function chromeLaunchCommand() {
1224
- const executable = state.browserExecutable ?? defaultManualBrowserExecutable();
1264
+ function chromeLaunchCommand(owner) {
1265
+ const executable = browserSettingsForOwner(owner).executablePath ?? defaultManualBrowserExecutable();
1225
1266
  const dataDir = process.platform === "win32" ? "%TEMP%\\pi-chrome-devtools" : "/tmp/pi-chrome-devtools";
1226
- return `${quoteCommandPart(executable)} --remote-debugging-port=${state.port} --user-data-dir=${dataDir}`;
1267
+ return `${quoteCommandPart(executable)} --remote-debugging-port=${managedBrowserPort(owner)} --user-data-dir=${dataDir}`;
1227
1268
  }
1228
1269
  function defaultManualBrowserExecutable() {
1229
1270
  return process.platform === "darwin" ? "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" : process.platform === "win32" ? "chrome.exe" : "google-chrome";
@@ -1238,17 +1279,18 @@ function isLocalDevToolsHost(host) {
1238
1279
  const normalizedHost = host.toLowerCase().replace(/^\[(.*)]$/, "$1");
1239
1280
  return ["localhost", "127.0.0.1", "::1", "0:0:0:0:0:0:0:1"].includes(normalizedHost);
1240
1281
  }
1241
- function browserCandidateDefinitions() {
1242
- const explicitCandidate = explicitBrowserCandidateDefinition();
1282
+ function browserCandidateDefinitions(owner) {
1283
+ const explicitCandidate = explicitBrowserCandidateDefinition(owner);
1243
1284
  if (explicitCandidate.length > 0) return explicitCandidate;
1244
1285
  return uniqueBrowserCandidates(platformBrowserCandidateDefinitions());
1245
1286
  }
1246
- function explicitBrowserCandidateDefinition() {
1247
- if (!state.browserExecutable) return [];
1287
+ function explicitBrowserCandidateDefinition(owner) {
1288
+ const browser = browserSettingsForOwner(owner);
1289
+ if (!browser.executablePath) return [];
1248
1290
  return [
1249
1291
  {
1250
- label: state.browserExecutableSource === "environment" ? "PI_CHROME_DEVTOOLS_BROWSER" : "browser.executablePath",
1251
- executable: state.browserExecutable,
1292
+ label: browser.executablePathSource === "environment" ? "PI_CHROME_DEVTOOLS_BROWSER" : "browser.executablePath",
1293
+ executable: browser.executablePath,
1252
1294
  source: "env"
1253
1295
  }
1254
1296
  ];
@@ -1393,8 +1435,8 @@ function formatBrowserCandidate(candidate) {
1393
1435
  function formatBrowserCandidateDefinition(candidate) {
1394
1436
  return `${candidate.label} (${candidate.executable})`;
1395
1437
  }
1396
- function noBrowserCandidateMessage(candidateDefinitions) {
1397
- if (extensionsConfigured()) {
1438
+ function noBrowserCandidateMessage(candidateDefinitions, owner) {
1439
+ if (extensionsConfigured(owner)) {
1398
1440
  return [
1399
1441
  "Cannot launch unpacked extensions because the configured browser executable was not found or is not executable.",
1400
1442
  `Tried: ${candidateDefinitions.map(formatBrowserCandidateDefinition).join(", ")}`,
@@ -1497,6 +1539,8 @@ export {
1497
1539
  webMcpOperationIsCurrent,
1498
1540
  applyRuntimeBrowserSettings,
1499
1541
  startManagedBrowserSession,
1542
+ syncManagedBrowserSettings,
1543
+ browserSettingsForOwner,
1500
1544
  managedBrowserForOwner,
1501
1545
  ensureDevToolsEndpoint,
1502
1546
  shutdownManagedBrowser,
@@ -1512,4 +1556,4 @@ export {
1512
1556
  endpointConfigHint,
1513
1557
  formatPageListItem
1514
1558
  };
1515
- //# sourceMappingURL=chunk-GVBXT3FB.js.map
1559
+ //# sourceMappingURL=chunk-SRT3UUIP.js.map