@aryanduntley/pwa-debug 0.1.5 → 0.1.7

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 (3) hide show
  1. package/README.md +2 -0
  2. package/dist/main.js +43 -14
  3. package/package.json +3 -3
package/README.md CHANGED
@@ -29,6 +29,8 @@ The goal is to eliminate the "user is the AI's eyes and hands" loop. Today, debu
29
29
  > - **PWA Runtime Diagnostics** — service-worker lifecycle + versions, CacheStorage contents + age, installability gaps, a live capability matrix, IndexedDB/web-storage inspection, update-propagation / version-skew analysis, and a one-shot runtime-state snapshot.
30
30
  >
31
31
  > **Verified on Linux** (the full suite live-tested against a real PWA). macOS/Windows code paths are implemented with unit coverage but still need real-machine retest ([help wanted](#help-wanted-macos--windows-verification)). Firefox is not supported (it doesn't speak CDP).
32
+ >
33
+ > ⚠️ **macOS / Windows users, beware:** these platforms have **never been run on real hardware** — only unit-tested with injected fakes. Expect rough edges (browser detection, profile paths, native-messaging registration, system-default resolution). Please [open an issue](../../issues) with the failing command and its output — bug reports from real macOS/Windows machines are the single most useful contribution right now. See [Help wanted](#help-wanted-macos--windows-verification) for the specific things to try.
32
34
 
33
35
  ## How it differs from `chrome-devtools-mcp`
34
36
 
package/dist/main.js CHANGED
@@ -12797,12 +12797,18 @@ const browserUrlFor = (port) => `http://127.0.0.1:${port}`;
12797
12797
  * Chromium flags for a fresh launch — shared by the exec-by-path and flatpak
12798
12798
  * builders so the two command forms differ ONLY in the command prefix, never in
12799
12799
  * the flag set. --no-first-run / --no-default-browser-check keep it non-interactive.
12800
+ *
12801
+ * `extraArgs` are caller-supplied Chromium startup flags (e.g.
12802
+ * --enable-speech-dispatcher) appended AFTER the managed flags so the caller can
12803
+ * override a non-essential default; they only matter on a cold spawn (this path),
12804
+ * never on an attach.
12800
12805
  */
12801
- const freshFlags = (port, userDataDir) => Object.freeze([
12806
+ const freshFlags = (port, userDataDir, extraArgs = []) => Object.freeze([
12802
12807
  `--remote-debugging-port=${port}`,
12803
12808
  `--user-data-dir=${userDataDir}`,
12804
12809
  '--no-first-run',
12805
12810
  '--no-default-browser-check',
12811
+ ...extraArgs,
12806
12812
  ]);
12807
12813
  /**
12808
12814
  * Chromium flags for a sandbox launch (dedicated profile + preloaded extension).
@@ -12818,13 +12824,20 @@ const freshFlags = (port, userDataDir) => Object.freeze([
12818
12824
  * --load-extension, and --disable-extensions-except would additionally block
12819
12825
  * the manual Load-unpack the user is steered to. The profile/port still come
12820
12826
  * up; the extension is provisioned by hand afterward.
12827
+ *
12828
+ * `isolate` (default true) controls --disable-extensions-except, which pins the
12829
+ * profile to ONLY pwa-debug — Chromium disables every other extension, including
12830
+ * ones already in the persistent profile or Load-unpacked/installed after launch.
12831
+ * Pass false to drop it so other extensions coexist: --load-extension still
12832
+ * preloads pwa-debug, while the profile's other extensions stay enabled. No-op
12833
+ * under 'manual-guided' (the flag is already omitted there).
12821
12834
  */
12822
- const sandboxFlags = (port, userDataDir, extensionPath, strategy) => {
12835
+ const sandboxFlags = (port, userDataDir, extensionPath, strategy, isolate, extraArgs = []) => {
12823
12836
  const extensionFlags = strategy === 'manual-guided'
12824
12837
  ? []
12825
12838
  : [
12826
12839
  `--load-extension=${extensionPath}`,
12827
- `--disable-extensions-except=${extensionPath}`,
12840
+ ...(isolate ? [`--disable-extensions-except=${extensionPath}`] : []),
12828
12841
  ...(strategy === 'load-flag-escape-hatch'
12829
12842
  ? ['--disable-features=DisableLoadExtensionCommandLineSwitch']
12830
12843
  : []),
@@ -12837,6 +12850,7 @@ const sandboxFlags = (port, userDataDir, extensionPath, strategy) => {
12837
12850
  '--no-default-browser-check',
12838
12851
  '--disable-session-crashed-bubble',
12839
12852
  '--hide-crash-restore-bubble',
12853
+ ...extraArgs,
12840
12854
  ]);
12841
12855
  };
12842
12856
  /**
@@ -12858,9 +12872,12 @@ const flatpakRun = (appId, browserFlags) => Object.freeze({
12858
12872
  /**
12859
12873
  * Fresh launch (sub-state c): bring up the debug port on the user's profile.
12860
12874
  */
12861
- const buildFreshSpawnArgs = (execPath, port, userDataDir) => Object.freeze({ cmd: execPath, args: freshFlags(port, userDataDir) });
12875
+ const buildFreshSpawnArgs = (execPath, port, userDataDir, extraArgs = []) => Object.freeze({
12876
+ cmd: execPath,
12877
+ args: freshFlags(port, userDataDir, extraArgs),
12878
+ });
12862
12879
  /** Fresh launch for a flatpak browser: `flatpak run <app-id> <fresh flags>`. */
12863
- const buildFreshFlatpakArgs = (appId, port, userDataDir) => flatpakRun(appId, freshFlags(port, userDataDir));
12880
+ const buildFreshFlatpakArgs = (appId, port, userDataDir, extraArgs = []) => flatpakRun(appId, freshFlags(port, userDataDir, extraArgs));
12864
12881
  /**
12865
12882
  * New-window launch (sub-state b): re-invoke the binary so it opens a window
12866
12883
  * in the already-running session via IPC. No debug port — that requires a full
@@ -12872,7 +12889,8 @@ const buildNewWindowFlatpakArgs = (appId) => flatpakRun(appId, Object.freeze(['-
12872
12889
  /**
12873
12890
  * Sandbox launch: dedicated profile + the pwa-debug extension preloaded BEFORE
12874
12891
  * any tab opens (so the content-script injection race cannot occur).
12875
- * --disable-extensions-except pins the profile to only our extension.
12892
+ * --disable-extensions-except pins the profile to only our extension when
12893
+ * `isolate` is true (the default); pass false to let other extensions coexist.
12876
12894
  *
12877
12895
  * --disable-session-crashed-bubble + --hide-crash-restore-bubble suppress the
12878
12896
  * "Brave/Chrome didn't shut down correctly — restore tabs?" prompt on the NEXT
@@ -12883,9 +12901,9 @@ const buildNewWindowFlatpakArgs = (appId) => flatpakRun(appId, Object.freeze(['-
12883
12901
  * Applied to sandbox modes only — an 'existing'-mode launch is the user's real
12884
12902
  * profile, where a genuine restore prompt should be left intact.
12885
12903
  */
12886
- const buildSandboxSpawnArgs = (execPath, port, userDataDir, extensionPath, strategy) => Object.freeze({
12904
+ const buildSandboxSpawnArgs = (execPath, port, userDataDir, extensionPath, strategy, isolate = true, extraArgs = []) => Object.freeze({
12887
12905
  cmd: execPath,
12888
- args: sandboxFlags(port, userDataDir, extensionPath, strategy),
12906
+ args: sandboxFlags(port, userDataDir, extensionPath, strategy, isolate, extraArgs),
12889
12907
  });
12890
12908
  /**
12891
12909
  * Sandbox launch for a flatpak browser: `flatpak run <app-id> <sandbox flags>`.
@@ -12894,7 +12912,7 @@ const buildSandboxSpawnArgs = (execPath, port, userDataDir, extensionPath, strat
12894
12912
  * (`flatpak override --user --filesystem=host <app-id>`) for these to resolve
12895
12913
  * inside the sandbox — the same prerequisite the NMH path documents.
12896
12914
  */
12897
- const buildSandboxFlatpakArgs = (appId, port, userDataDir, extensionPath, strategy) => flatpakRun(appId, sandboxFlags(port, userDataDir, extensionPath, strategy));
12915
+ const buildSandboxFlatpakArgs = (appId, port, userDataDir, extensionPath, strategy, isolate = true, extraArgs = []) => flatpakRun(appId, sandboxFlags(port, userDataDir, extensionPath, strategy, isolate, extraArgs));
12898
12916
 
12899
12917
  /**
12900
12918
  * 'existing'-mode launch: the graceful-degradation triad orchestrated over the
@@ -12940,9 +12958,10 @@ const launchExisting = async (input, deps) => {
12940
12958
  });
12941
12959
  }
12942
12960
  // spawn-fresh
12961
+ const extraArgs = input.extraArgs ?? [];
12943
12962
  const { cmd, args } = input.appId
12944
- ? buildFreshFlatpakArgs(input.appId, input.port, input.userDataDir)
12945
- : buildFreshSpawnArgs(input.execPath, input.port, input.userDataDir);
12963
+ ? buildFreshFlatpakArgs(input.appId, input.port, input.userDataDir, extraArgs)
12964
+ : buildFreshSpawnArgs(input.execPath, input.port, input.userDataDir, extraArgs);
12946
12965
  const { pid } = await deps.spawnBrowser(cmd, args);
12947
12966
  // Chromium 136+ ignores --remote-debugging-port on the default profile: the
12948
12967
  // browser comes up (pwa-debug extension still usable) but the port never
@@ -13002,9 +13021,12 @@ const launchSandbox = async (input, deps) => {
13002
13021
  // refuse the unpacked --load-extension (#318). Seed developer_mode=true into the
13003
13022
  // profile's Preferences before spawn so the extension loads with no manual step.
13004
13023
  await deps.seedDeveloperMode(input.userDataDir);
13024
+ // Default to isolation (clean-room) when unset; false lets other extensions coexist.
13025
+ const isolate = input.isolateExtensions ?? true;
13026
+ const extraArgs = input.extraArgs ?? [];
13005
13027
  const { cmd, args } = input.appId
13006
- ? buildSandboxFlatpakArgs(input.appId, input.port, input.userDataDir, input.extensionPath, input.loadStrategy)
13007
- : buildSandboxSpawnArgs(input.execPath, input.port, input.userDataDir, input.extensionPath, input.loadStrategy);
13028
+ ? buildSandboxFlatpakArgs(input.appId, input.port, input.userDataDir, input.extensionPath, input.loadStrategy, isolate, extraArgs)
13029
+ : buildSandboxSpawnArgs(input.execPath, input.port, input.userDataDir, input.extensionPath, input.loadStrategy, isolate, extraArgs);
13008
13030
  const { pid } = await deps.spawnBrowser(cmd, args);
13009
13031
  if (input.mode === 'sandbox-temp') {
13010
13032
  deps.registerTempProfile(input.userDataDir);
@@ -14009,6 +14031,8 @@ const inputSchema$5 = {
14009
14031
  port: numberType().int().min(1).max(65535).optional(),
14010
14032
  mode: enumType(MODES).optional(),
14011
14033
  packaging: enumType(PACKAGINGS).optional(),
14034
+ isolateExtensions: booleanType().optional(),
14035
+ extraArgs: arrayType(stringType()).optional(),
14012
14036
  };
14013
14037
  const isSandboxMode = (mode) => mode === 'sandbox-persistent' || mode === 'sandbox-temp';
14014
14038
  /**
@@ -14200,6 +14224,10 @@ const launchBrowserCore = async (args, platform, env, deps) => {
14200
14224
  loadStrategy,
14201
14225
  mode,
14202
14226
  refreshExtension: refreshExtensionEnabled(mode, env),
14227
+ ...(args.isolateExtensions !== undefined
14228
+ ? { isolateExtensions: args.isolateExtensions }
14229
+ : {}),
14230
+ ...(args.extraArgs !== undefined ? { extraArgs: args.extraArgs } : {}),
14203
14231
  ...(target.appId !== undefined ? { appId: target.appId } : {}),
14204
14232
  ...(snapPkg ? { snapPackage: snapPkg } : {}),
14205
14233
  });
@@ -14224,6 +14252,7 @@ const launchBrowserCore = async (args, platform, env, deps) => {
14224
14252
  userDataDir,
14225
14253
  debugPortBlockedOnDefaultProfile: portBlocked,
14226
14254
  ...(target.appId !== undefined ? { appId: target.appId } : {}),
14255
+ ...(args.extraArgs !== undefined ? { extraArgs: args.extraArgs } : {}),
14227
14256
  });
14228
14257
  deps.recordLaunch(result, port);
14229
14258
  return launchOk(result, target, alternatives, args.packaging !== undefined);
@@ -14250,7 +14279,7 @@ const launchBrowserHandler = async (args, ctx) => launchBrowserCore(args, proces
14250
14279
  });
14251
14280
  const launchBrowserTool = Object.freeze({
14252
14281
  name: 'pdl_launch_browser',
14253
- description: "Launch or attach to a Chromium-family browser with a live remote-debugging port, for use alongside chrome-devtools-mcp. Modes: mode='existing' (default) targets the user's normal profile and degrades gracefully — (a) port already live → attach; (b) running without a debug port → opens a NEW WINDOW in the existing session (never kills it), attached:false + degradation message; (c) not running → spawns fresh with --remote-debugging-port + --user-data-dir=<your profile>. mode='sandbox-persistent' spawns a dedicated, persistent dev profile at ~/.pwa-debug/profiles/<browser>/ beside your normal browser, with the pwa-debug extension PRELOADED (no reload needed); mode='sandbox-temp' is the same but in a throwaway mkdtemp profile cleaned up on host shutdown. Sandbox modes always work standalone (separate profile → no lock collision) and both pwa-debug + CDP tools are available. Args: browser? (chrome|chromium|edge|brave|vivaldi|opera; defaults to system-default), port? (default 9222), mode?, packaging? (native|snap|flatpak). When the same browser is installed under multiple packagings (e.g. snap AND flatpak chromium), pass packaging to pick one; without it the default preference is native > snap > flatpak and next_steps lists the alternatives so you can re-target. Linux is first-class; macOS/Windows deferred. Follow next_steps[] — it carries the chrome-devtools-mcp registration snippet, the profile location, the flatpak onboarding steps, or the degradation guidance.",
14282
+ description: "Launch or attach to a Chromium-family browser with a live remote-debugging port, for use alongside chrome-devtools-mcp. Modes: mode='existing' (default) targets the user's normal profile and degrades gracefully — (a) port already live → attach; (b) running without a debug port → opens a NEW WINDOW in the existing session (never kills it), attached:false + degradation message; (c) not running → spawns fresh with --remote-debugging-port + --user-data-dir=<your profile>. mode='sandbox-persistent' spawns a dedicated, persistent dev profile at ~/.pwa-debug/profiles/<browser>/ beside your normal browser, with the pwa-debug extension PRELOADED (no reload needed); mode='sandbox-temp' is the same but in a throwaway mkdtemp profile cleaned up on host shutdown. Sandbox modes always work standalone (separate profile → no lock collision) and both pwa-debug + CDP tools are available. Args: browser? (chrome|chromium|edge|brave|vivaldi|opera; defaults to system-default), port? (default 9222), mode?, packaging? (native|snap|flatpak). When the same browser is installed under multiple packagings (e.g. snap AND flatpak chromium), pass packaging to pick one; without it the default preference is native > snap > flatpak and next_steps lists the alternatives so you can re-target. isolateExtensions? (sandbox modes only, default true): true pins the dedicated profile to ONLY the pwa-debug extension (clean room — every other extension is disabled); pass false to let other extensions coexist (pwa-debug still preloads, while extensions already in the persistent profile or Load-unpacked/installed after launch stay enabled) — use this to debug a PWA alongside other extensions or to test your own extension with pwa-debug. existing mode already keeps all your normal-profile extensions. extraArgs? (string[]): extra Chromium startup flags appended after pwa-debug's managed flags — e.g. extraArgs=['--enable-speech-dispatcher'] to enable system TTS/speech-dispatcher, or any other --flag the browser needs at startup. Applied only on a COLD spawn (mode='existing' when the browser isn't already running, or either sandbox mode); they have no effect when attaching to an already-live port or opening a new window in a running session, since startup flags are read once at process start — fully quit the browser (or use a sandbox mode) for them to take effect. Linux is first-class; macOS/Windows deferred. Follow next_steps[] — it carries the chrome-devtools-mcp registration snippet, the profile location, the flatpak onboarding steps, or the degradation guidance.",
14254
14283
  inputSchema: inputSchema$5,
14255
14284
  handler: launchBrowserHandler,
14256
14285
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aryanduntley/pwa-debug",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -63,8 +63,8 @@
63
63
  "@types/winreg": "^1.2.36",
64
64
  "rollup": "^4.27.4",
65
65
  "tslib": "^2.8.1",
66
- "@pwa-debug/extension": "0.1.5",
67
- "@pwa-debug/shared": "0.1.5"
66
+ "@pwa-debug/shared": "0.1.7",
67
+ "@pwa-debug/extension": "0.1.7"
68
68
  },
69
69
  "scripts": {
70
70
  "typecheck": "tsc --noEmit",