@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.
- package/README.md +2 -0
- package/dist/main.js +43 -14
- 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({
|
|
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.
|
|
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/
|
|
67
|
-
"@pwa-debug/
|
|
66
|
+
"@pwa-debug/shared": "0.1.7",
|
|
67
|
+
"@pwa-debug/extension": "0.1.7"
|
|
68
68
|
},
|
|
69
69
|
"scripts": {
|
|
70
70
|
"typecheck": "tsc --noEmit",
|