
PWA Debug Layer
io.github.aryanduntley由 GitHub 帳號 aryanduntley 發布v1.2.0更新於 Nov 3, 2026
通過 MCP 在真實瀏覽器中除錯 PWA:service-worker、快取、可安裝性及框架狀態。
AI 翻譯由 AI 模型根據下方的原文描述翻譯,可能有誤。
原文描述
Debug PWAs in your real browser via MCP: service-worker, cache, installability & framework state.
概覽
PWA Debug Layer 的本機 MCP 服務;無需登入;STDIO。
暫無 AI 概覽:以下資訊來自註冊中心條目和服務本身。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 PWA Debug Layer,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
pwa-debug-layer
An AI-native debugging layer for PWAs and modern web apps. It lets an AI agent (e.g. Claude Code via MCP) see and act on your live, logged-in browser the way a developer with full DevTools open would — DOM, console, network, framework state, store state, service workers, caches, and direct interaction — as structured data the model consumes natively.
It's built for the questions developers actually search for and that Chrome DevTools makes you assemble by hand: why won't my service worker update? why is my cache stale? why won't my PWA install? why does this component have the wrong state? — answered by an agent reading the runtime directly, against your real browser profile (extensions, auth, and all), not a sterile automated tab.
What it answers
The PWA failures developers actually search for, read straight from your live runtime:
- Why won't my service worker update? Why are some users on old code? — SW lifecycle with waiting-vs-active versions, plus an update-propagation / version-skew analyzer.
- Why is my cache stale? Why are chunks 404ing after a deploy? — CacheStorage contents with age, and a cached-HTML-vs-JS skew check.
- Why won't my PWA install? — structured installability diagnostics with per-gap remediation, not just "manifest invalid."
- What's actually in IndexedDB / localStorage right now? — live storage inspection (inspect IndexedDB live).
- What can this browser actually do? — a live capability matrix (Push / Background Sync / Periodic Sync / Badging / File System Access / Window Controls Overlay).
- Does anything break at 360 px, in Spanish, in dark mode, in this app state? — one
layout_sweepcall checks every page × width × color scheme × state and returns a short list of distinct problems.
All read from your real, logged-in profile — service-worker, cache, and extension state included — which chrome-devtools-mcp's sterile automated Chrome can't see.
The goal is to eliminate the "user is the AI's eyes and hands" loop. Today, debugging a PWA with AI usually means the human copy/pastes DOM snippets, describes console errors, screenshots UI state, and hand-executes clicks. This project replaces that with direct, structured access.
Status: working on Linux. The full MCP→IPC→native-host→service-worker→page-world round-trip is live, and a broad debugging surface is shipped:
- Capture — console / network / error / DOM-mutation / lifecycle, with persistent ring buffers + disk spill.
- Framework introspection — React, Vue, Svelte, and Solid (component/element trees, state, find-by-text/role).
- Store introspection — Redux, Zustand, Pinia, and Jotai (read, subscribe, dispatch).
- Interaction + touch gestures — click, fill, submit, hover, focus/blur, select, key/type, drag, scroll, swipe, tap, double-tap, long-press, pinch.
- Library-popup capture/replay — WalletConnect / SDK modals: record, replay, tail, failure correlation.
- Replay & source maps — rrweb
session_record/session_replay,source_map_resolve.- Browser launcher — one-call
pdl_launch_browserwithchrome-devtools-mcpcoexistence.- Android phones — the same tools drive Android Chrome tabs and installed PWAs over adb (
pdl_android_attach), no desktop browser in the loop.- Responsive layout sweep —
layout_sweepemulates widths and color schemes over CDP, walks app states and languages, measures overflow, off-screen elements, tap targets, pinned bars, cut-off text, edge contact, clipped focus/selection rings and unresolved copy, runs your owncustom_checks, and groups the results into distinct problems.- 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.
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). Firefox is not supported (it doesn't speak CDP).
⚠️ 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 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 for the specific things to try.
How it differs from chrome-devtools-mcp
Google's chrome-devtools-mcp gives an AI Chrome DevTools Protocol access (DOM, console, network, screenshots). That covers a lot.
pwa-debug-layer is complementary — it targets the things CDP can't reach:
- Your real, logged-in browser.
chrome-devtools-mcpspawns a fresh automated Chrome — which shows "controlled by automated test software," blocks extension loading, and has none of your auth/session state, so authenticated apps are hard to debug (the extensions/auth gap, #265). pwa-debug-layer's defaultexistingmode attaches to your normal profile, with its real cookies, extensions, and service-worker state — exactly the real-profile SW/extension visibility people keep asking Google for (#1173, #96). - Framework state. React fiber trees, Vue reactive state, Svelte component graphs, Solid signals — read via the framework's own devtools hooks (
__REACT_DEVTOOLS_GLOBAL_HOOK__,__vue_app__,_vnode, etc.). CDP can't see these. - Store state. Redux / Zustand / Pinia / Jotai — read, subscribe, and dispatch.
- Service-worker, cache & installability state. SW lifecycle + versions, CacheStorage contents + age, manifest installability gaps, IndexedDB/web storage, and an update-propagation / version-skew analyzer — the highest-volume PWA pain (stale cache, "SW won't update," install failures, "why are some users on old code") that DevTools makes you piece together by hand.
- Shadow DOM, iframes, dynamically-injected library widgets. WalletConnect modals, third-party SDK popups, and other widgets that escape standard DOM tooling.
- Page-world reach in general. A MAIN-world script we inject reaches things isolated-world content scripts can't, and reaches them earlier than
initScript-on-next-nav. - Persistent ring buffers + rrweb-style replay across navigations and reloads.
- Configurable filters so the AI receives only the slice it asked for — no full-DOM noise.
The two are designed to coexist: install both, the AI uses each for what it does best, with zero tool-surface duplication.
Architecture
Three components, one installable unit:
- Extension owns the page (DOM, content scripts, page-world hooks).
- Native host owns persistence and the MCP server (long-lived, can hold buffers, can write files).
- MCP owns the AI contract.
Each does what only it can. See docs/PLAN.md for the full design.
Browser support
Chromium-family only, sideloaded. Tested against:
- Chromium (native package)
- Google Chrome (
.deb/.rpm) - Brave Browser
- Microsoft Edge (Linux
.deb) - Vivaldi
- Opera
macOS Application Support paths and Windows HKCU-registry registration are implemented and have unit-test coverage; the manual round-trip retest currently runs on Linux.
Snap browsers are not supported
If you installed your browser via snap (e.g. snap install chromium on Ubuntu), it will not work with pwa-debug-layer.
Why: snap's home interface allows the browser to read files in $HOME but blocks exec of any binary whose resolved path crosses a hidden directory (~/.nvm/..., ~/.config/...). The native messaging host launcher and the node binary it invokes both live under hidden paths in a normal install, so spawn fails with Permission denied and the service worker reports Native host has exited. There is no fix on the extension/host side that doesn't require copying ~125 MB of node into a non-hidden install dir per registration; not worth the install bloat for a setup most distros let you avoid.
What to do: install your Chromium-family browser from a native package source instead:
- Ubuntu/Debian:
apt install chromiumfrom the universe repo if you've enabled the non-snap source, orapt install brave-browser/microsoft-edge-stablefrom their respective.debrepos. The Chromium tarball from chromium.org also works. - Fedora:
dnf install chromiumis non-snap by default. - Arch:
pacman -S chromium.
Flatpak browsers are detected and have a manifest written, but flatpak confinement may also block exec — if it fails, run flatpak override --user --filesystem=host <app-id> and retry.
Installation
Prerequisites
- Node.js ≥ 20.19 (developed on 23.x)
- pnpm
- A Chromium-family browser not installed via snap (see above)
- An MCP-aware client (e.g. Claude Code)
1. Build the host and extension
2. Add the host to your MCP client
For Claude Code, add to your .mcp.json (project-scoped) or ~/.claude/mcp.json (global):
Restart Claude Code so it picks up the server.
3. Load the extension
- Open
chrome://extensions(orbrave://extensions, etc.) in your browser. - Toggle Developer mode on.
- Click Load unpacked and select
packages/extension/dist/. - Note the extension's ID (shown on the card). Or, ask Claude to discover it for you in the next step — the extension service worker logs
[pwa-debug/sw] id=<id>on every boot.
4. Tell Claude to set it up
The host registration is AI-driven. Six MCP tools are exposed for setup; Claude calls them via a guided flow:
Set up pwa-debug. The extension ID is
<your-id>(or omit the ID and Claude can fetch it from the SW console if you also havechrome-devtools-mcpinstalled.)
Claude will:
- Call
host_statusto see what's already registered. - Call
host_register_extension(id)— this writes a per-browser native-messaging manifest into every detected install (Chromium-family native, macOS Application Support, Windows HKCU registry), and drops a launcher script with an absolute node path (so the host spawns under sandboxed PATH environments). - Tell you to reload the extension at
chrome://extensions. - After reload, call
host_statusagain to confirm the manifest is on disk and the SW is connecting.
When the round-trip works you'll see in the SW console (Inspect views: service worker on the extension card):
Launching a browser + chrome-devtools-mcp coexistence
pwa-debug and chrome-devtools-mcp are two separate MCP servers that share one browser. pwa-debug launches (or attaches to) a Chromium browser with a live remote-debugging port; chrome-devtools-mcp attaches to that same port over CDP. No proxying, no version coupling.
Register both with your client. For Claude Code:
Or install pwa-debug as a Claude Code plugin
The repo ships a .claude-plugin/ manifest whose MCP server runs the published npm package (npx -y @aryanduntley/pwa-debug@latest), so the plugin installs with no clone and no build — and picks up updates with /reload-plugins, no full restart:
No build needed. The plugin's MCP entry is
npx -y @aryanduntley/pwa-debug@latest, which fetches the prebuilt host (and its bundled extension) from npm. Working on a local clone instead? Skip the plugin and register your own build directly:claude mcp add pwa-debug --scope user -- node /absolute/path/to/pwa-debug-layer/packages/host/dist/main.js.
chrome-devtools-mcpis still separate. The plugin declares only thepwa-debughost —chrome-devtools-mcpstays the optionalclaude mcp add chrome-devtools …above (no version coupling, no owning its launch). The bundledchrome-devtools-coexistenceskill walks you through registering it; with a plugin install, its "make the tools appear" step is/reload-plugins.
Port must match.
chrome-devtools-mcp's--browserUrlhas to point at the exact portpwa-debugopens — thelaunch.defaultPortsetting (default9222), or the active port from a currentpdl_launch_browser. Rather than hand-write this, let Claude callpdl_register_chrome_devtools, which runs theclaude mcp addabove for you pinned to the right port (andpdl_check_setupflags a registration that is unpinned — no--browserUrl, so it spawns its own isolated browser — or pointed at the wrong port).
Mind the (re)connect. A registration added or changed via
claude mcp addonly takes effect when the server (re)connects. Fastest path: open/mcpand reconnectchrome-devtools— this reloads it from the current registration (verified to pick up a changed--browserUrl) with no full restart and no context loss. If the client won't load it that way, fully restart Claude Code as a fallback. If instead you installchrome-devtools-mcpas a plugin, run/reload-plugins. The bundledchrome-devtools-coexistenceskill walks Claude through all paths and, for the full-restart fallback, hands you a context note to paste back afterward.
The host has no
install/servesubcommand —dist/main.jsauto-detects its mode: launched by Chrome (argv starts withchrome-extension://) it runs as the native-messaging host; launched by your MCP client it runs as the MCP server.
Then let Claude drive setup and launch:
pdl_check_setup— reports{ ok, gaps[], recommendations[] }: whetherchrome-devtools-mcpis registered (read from theclaudeCLI) and pinned with a--browserUrlat the right debug port — it flags both an unpinned registration (which would spawn its own isolated browser instead of attaching to yours) and one pointed at the wrong port; the host manifest is installed (including per active sandbox profile); the extension dist is present; and an extension ID is registered. Follow itsnext_stepsto close any gap.pdl_register_chrome_devtools— writes thechrome-devtools-mcpregistration for you, pinned to the active/launch.defaultPortport (idempotent; re-points it if it's unpinned or on the wrong port). (Mutates your MCP config — Claude will ask first; a restart/reconnect follows, see above.)pdl_install_extension— copies the extension to~/Downloads/pwa-debug-extension(or atargetyou pass) withchrome://extensions"Load unpacked" instructions. (On most browsers a sandbox mode preloads the extension so you can skip this; on branded Google Chrome 142+ preload is impossible — this is the manual install the sandbox launch will point you to.)pdl_launch_browser— launches/attaches a browser with the debug port live and returns thebrowserUrlto hand tochrome-devtools-mcp. Always launch first: call this before anychrome-devtools-mcptool, so the browser + debug port exist for it to attach to. Follow itsnext_steps— they carry the brand/version-specific guidance (preloaded vs. manual Load unpacked, or the modern-Chromium port caveat).pdl_browser_status— shows what's been launched (browser, profile mode, port, pid), re-probes each debug port for liveness, and reports the extension service-worker heartbeat.
The validated one-profile recipe (what these tools converge on, verified live on Brave 148):
Now chrome-devtools-mcp (CDP) and pwa-debug (extension → page-world) drive the same tab simultaneously — independent, non-contending channels (the extension uses page-world injection, not chrome.debugger, so there's no CDP-attacher contention).
Android phones
The extension cannot run in Android Chrome, so pwa-debug reaches phones over adb + the Chrome DevTools Protocol instead. The host injects the same page-world code the extension uses, so once attached every tool works on the phone tab — framework and store introspection, PWA diagnostics, interaction and touch gestures, navigation, and console / network / error capture — and you watch it happen on the phone.
One-time phone setup: Developer options → USB debugging on, connect by USB, accept "Allow USB debugging?", and have Chrome open. You need adb (Android platform-tools) on PATH or in the Android SDK (ANDROID_HOME, ~/Android/Sdk).
Then the AI does the rest in one call:
Pass url_contains instead of open_url to attach to a tab that is already open (add reload: true when a framework or store hook must exist before the app starts), or socket: "webview" / an app package for a debuggable app WebView. pdl_cdp_targets / pdl_cdp_attach / pdl_cdp_detach are the lower-level equivalents for any CDP endpoint (adb forward tcp:9223 localabstract:chrome_devtools_remote, then browser_url: "9223").
pwa-debug only removes the adb forwards and reverses it created, when the host shuts down. Your capture settings (site allow/block lists, read controls, enabled kinds, filters) apply to phone connections exactly as they do to the extension. When something is missing — adb not installed, phone unauthorized or offline, Chrome not running — the tools' next_steps say exactly what to do, and pdl_check_setup reports phone readiness alongside the desktop checks.
Desktop browsers are driven through the extension; the CDP path is for phones.
Profile modes
pdl_launch_browser takes mode (default existing), browser (defaults to your system-default Chromium browser), and port (default 9222).
Extension preload depends on the browser brand + version (the launcher detects it from --version and adapts):
Recommended coexistence setup: sandbox-persistent on a non-Google Chromium (e.g. Brave or Chromium). That single profile gets the extension preloaded and a live debug port, so pwa-debug and chrome-devtools-mcp drive the same browser with zero manual steps.
Browser support matrix
Chromium-family only (Firefox doesn't speak CDP). Linux is first-class. macOS/Windows binary detection, profile/user-data-dir paths, and system-default detection (macOS LaunchServices, Windows UserChoice registry) are all implemented with unit coverage, but live verification on real macOS/Windows machines is still needed — see Help wanted.
- System default: the launcher prefers your system-default browser when you don't pass one — Linux via
xdg-settings get default-web-browser, macOS via LaunchServices (defaults read … LSHandlers), Windows via the HKCUUrlAssociations\http\UserChoiceProgId. The macOS/Windows paths are implemented + unit-tested but not yet exercised on a real machine. - Default debug port is
9222(thechrome-devtools-mcpconvention); override it without passingporteach time via thelaunch.defaultPortsetting (settings.set). - Snap profiles: when launching a snap-packaged browser (
/snap/bin/…) inexistingmode, the launcher now resolves its confined profile (~/snap/<snap>/common/<cfg>) instead of~/.config— but note snap browsers still can't run the native-messaging host (see snap section), so this only matters if/when that confinement is lifted. - Brave Shields can block the content script on a site — set Shields Down for the site if
session_pingreportspage_blocks_scripts. - Snap browsers are unsupported for the native-messaging host (see below); the launcher can still spawn them, but the host round-trip won't connect. Use a native-package browser.
- Flatpak installs get a manifest written, but confinement may block exec — run
flatpak override --user --filesystem=host <app-id>and retry.
Help wanted: macOS / Windows verification
Development happens on Linux, so the macOS and Windows code paths are written and unit-tested with injected fakes, but never run on a real machine. If you're on macOS or Windows, trying these and reporting back (open an issue with the output) is the single most useful contribution right now:
macOS
pdl_check_setup/pdl_install_extension— does the extension resolve and copy, and do thechrome://extensionsinstructions work?- Browser binary detection under
/Applications/*.app/Contents/MacOS/…. - System-default detection:
defaults read com.apple.LaunchServices/com.apple.launchservices.secure LSHandlers— does the parser pick the right browser? (Paste the raw output if it doesn't.) pdl_launch_browsermodeexisting(profile under~/Library/Application Support/…) and both sandbox modes.
Windows
- Browser detection under
%PROGRAMFILES%/%LOCALAPPDATA%. - System-default detection:
reg query "HKCU\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice" /v ProgId— does the ProgId map to the right browser? pdl_launch_browser(profile under%LOCALAPPDATA%\…\User Data) and the HKCU native-messaging registration.
Any OS
pdl_browser_statusafter restarting the host — launches now persist tolaunches.json, so previously-launched browsers should still be listed (with a fresh liveness re-probe). Confirm the list survives a restart and that closed browsers show as not-live.
The launcher never kills your running browser and sandbox modes use throwaway/dedicated profiles, so this is low-risk to try.
Troubleshooting
Verification sequence
When something isn't working, walk this ladder — each step localizes the failure:
pdl_check_setup— are all setup gaps closed? (CDP reachable, manifest installed, extension present, ID registered.)pdl_browser_status— is a browser launched and is its debug port still live? Is the extension service worker connected (recent heartbeat)?host_status— is the native-messaging host registered and is an NMH instance connected?session_ping— does a full MCP → SW → page-world round-trip succeed on the active tab? (See the typedpageWorldErrortable below.)
Common launcher gotchas
- "I launched in
existingmode butchrome-devtools-mcpcan't attach." Two causes. (1) Chrome opens--remote-debugging-portonly at process start — if the browser was already running without it,pdl_launch_browseropens a new window (sub-state b) but can't add the port to the live process (attached:false). (2) On Chromium 136+, the port is refused on the default profile entirely, even on a fresh start. Either way: usemode: sandbox-persistent(a dedicated profile where the port works) forchrome-devtools-mcp. - Brave/Chrome says "Opening in existing browser session." That's sub-state b — the binary handed your request to the already-running process instead of starting a fresh one with the port. Same fix as above.
- Sandbox launch came up but pwa-debug never connects (Google Chrome 142+). Branded Google Chrome 142+ permanently ignores
--load-extension, so the sandbox can't auto-preload the extension — the launch says so and gives you a one-timechrome://extensions→ Developer mode → Load unpacked walkthrough (it persists in that dedicated profile). Or relaunch withbrowser: "brave"/"chromium", where preload works automatically. (chrome-devtools-mcpstill works either way — the debug port is live.) chrome-devtools-mcpopened its own blank browser instead of using yours. Its registration is unpinned (no--browserUrl). Runpdl_register_chrome_devtools(or re-add with--browserUrl http://127.0.0.1:<port>) and restart/reconnect it;pdl_check_setupflags this.- Added the MCP server but the tools don't appear.
.mcp.json/ client MCP config is read at startup — restart your MCP client (or/mcp-reconnect that server) after addingpwa-debugorchrome-devtools. - Tools worked, then stopped after I reloaded the extension. Reloading the extension at
chrome://extensionsdetaches content scripts from already-open tabs. Hard-refresh the page tab (Ctrl+Shift+R); the SW also auto-reinjects on the nextsession_ping(look forpageWorldSelfHealed: true). Sandbox modes avoid this entirely (extension preloaded before tabs open).
session_ping returns pageWorld: null with a typed pageWorldError
session_ping reports failure modes as typed codes in pageWorldError (machine-readable) plus the original chrome-runtime string in pageWorldErrorMessage (for logs). The MCP next_steps[] field carries imperative, code-specific guidance — AI clients should relay it verbatim. Tabs that simply predated the extension reload (the most common dev-loop friction) are auto-recovered by the SW via chrome.scripting.executeScript; when that succeeds, pageWorld is populated and pageWorldSelfHealed: true appears alongside it. The table below is the canonical mapping (single source of truth: NEXT_STEPS_BY_CODE in packages/host/src/mcp/tools/session_ping.ts).
To confirm the content script attached after a successful round-trip, open the page tab's DevTools (F12 on the page itself, not the SW console) and look for [pwa-debug/cs] attached at <url> in the Console.
MCP tool surface
Every tool returns a structured response of the form { ok, data, error?, next_steps[] }. The next_steps array encodes the rules of engagement for the AI — what to call next based on the actual response shape — mirroring the AIMFP return_statements pattern. The canonical list lives in packages/host/src/mcp/tools/index.ts.
The server also sends MCP instructions on connect: a short orientation the client places in the AI's system prompt (you can drive the page yourself, read state as data rather than screenshots, the startup sequence, the phone workflow). For anything deeper the AI calls pdl_help.
Help
Host management & setup
Browser launcher
Capture, evaluate, replay
PWA runtime diagnostics
The namesake suite — read the debugged PWA's service-worker, cache, installability, storage, and update state. All page-world reads against your real profile; CDP / chrome-devtools-mcp can't surface these.
Responsive layout sweep
One call audits a view matrix: pages × viewport widths × color schemes × app states (plus any crossed dimensions such as language). For each view the host emulates the viewport and prefers-color-scheme over CDP on the real top-level page, applies the app state (a hash template or your own apply expression), settles, and measures in the page. The results are grouped into distinct problems, so 150 raw findings that are really two problems come back as two groups, with screenshots on request. Targets: a phone (pdl_android_attach) or a browser started by pdl_launch_browser. A browser you started yourself is refused, because the host needs its debug port.
Hidden content (display: none, closed <details>, collapsed wrappers, screen-reader-only text) is skipped by every check. Your own checks: custom_checks: [{ name, expression }] (up to 20) run in the page after the built-ins for every view. Each one gets view (page, width, scheme, state, dimensions) and a pdl helper object (pdl.elements(selector) for visible elements, plus rect, style, px, name, edges, ink, background). It returns elements, strings or { element, message } items, which become custom:<name> findings, grouped and reported like the built-in ones. pdl_help({ topic: "layout" }) has worked examples.
Verify findings before you fix them. The checks are geometric heuristics over computed styles and rects. They don't see the page the way a person does, so a finding can be a false positive (an intentional full-bleed design, an unusual widget, a state the page never shows a user). Confirm each group before changing code: use
screenshots: "first_per_group", look at the element withevaluate, or check it on the device. Then re-run the sweep on the affected pages. Desktop emulation of a phone width also uses the desktop browser's fonts and scrollbars, so confirm important findings on a real phone.
Framework introspection
Read via each framework's own model — things CDP can't see. Tree/state where the framework persists it; element-level find everywhere.
Store introspection
Interaction & touch gestures
Framework-agnostic native-event sequences dispatched so React/Vue/etc. delegated synthetic-event systems fire. Each targets a unified locator (selector / role / text / framework stable-id).
Android phones (adb + CDP)
Library popups
Roadmap
- Foundation ✅ — pnpm workspace + build pipeline; MV3 extension loads cleanly; native-messaging round-trip; AI-managed host registration; cross-platform install (Linux native + macOS + Windows registry; snap unsupported); MCP↔IPC↔NMH↔SW bridge.
- Capture ✅ — console / network (fetch/XHR/WebSocket) / DOM-mutation / lifecycle producers; host ring buffers with disk spill + archive pruning; filterable, cursor-paginated
console_tail/network_tail. - Framework introspection ✅ — React, Vue, Svelte, Solid (trees/state where the framework persists them, find-by-text/role everywhere); page-world
evaluate. - Store introspection ✅ — Redux (read/subscribe/tail/dispatch) plus a framework-agnostic adapter covering Zustand, Pinia, Jotai.
- Interaction & gestures ✅ — discrete actions (click/fill/submit/hover/focus/blur/select/key/type) + touch gestures (drag/scroll/swipe/tap/double-tap/long-press/pinch) over a unified locator.
- Library popups ✅ —
popup_record/popup_replay/popup_tail/popup_failuresfor WalletConnect & SDK modals (incl. shadow-root + nested). - Replay & source maps ✅ — rrweb
session_record/session_replay;source_map_resolvefor stack frames. - Settings ✅ — typed schema store (allowlist/blocklist, per-kind capture filters, per-site read controls, disk-spill).
- Browser launcher ✅ —
pdl_launch_browser(existing + sandbox-persistent + sandbox-temp),pdl_check_setup,pdl_browser_status,pdl_close_browser,pdl_install_extension,pdl_register_chrome_devtools, andchrome-devtools-mcpcoexistence. - PWA Runtime Diagnostics ✅ — the namesake suite, live-verified against a real PWA. Service-worker introspection (
sw_status+sw_lifecycle_tail: installing/waiting/active versions,updateViaCache, skipWaiting/claim/controllerchange); CacheStorage inspection (cache_list/cache_inspect/cache_matchwith size/age + match-by-URL);pwa_status(display mode, controller, permissions, live capability matrix — Push/Background Sync/Periodic Sync/Badging/File System Access/Window Controls Overlay); installability diagnostics (pwa_installability→ structured{gaps[], fixes[]}); IndexedDB/web-storage inspection (idb_list/idb_query/storage_get); update-propagation / version-skew analysis (pwa_update_analyze); and a one-shot runtime-state snapshot (pwa_snapshot). Closes the stale-cache / "SW won't update" / install-failure / version-skew pain cluster against your real profile. - Android phones ✅ —
pdl_android_devices/pdl_android_attachdrive Android Chrome tabs and installed PWAs over adb + CDP with the full tool surface (onlyrecent_eventsis extension-only); same capture settings; adb mappings cleaned up on shutdown. Live-verified on a Galaxy S24 Ultra (Android 16, Chrome 156). - Responsive layout sweep ✅ —
layout_sweep/layout_sweep_status/layout_sweep_cancelover phones and launched browsers: CDP viewport + color-scheme emulation, app-state and language matrices, ten built-in checks, callercustom_checks, grouping, per-group screenshots and an on-disk report. Live-verified on a Galaxy S24 Ultra and a launched Brave across an 83-page prototype (4812 views). - Later — DevTools panel for human observation of an AI session; multi-tab routing model; event-causality graph (click → action → request → SW → cache → re-render); production-safe diagnostic mode for real-user failure capture.
- Deferred — Firefox port (needs WebDriver BiDi, not CDP); macOS/Windows live verification (help wanted); iOS Safari; hosted/team mode.
- Intentionally not pursued — Chrome Web Store distribution. The extension grants broad page access (DOM, framework state, stores, network) and is only meaningful alongside its MCP host. It ships bundled with the MCP only and is installed via a manual, dev-mode "Load unpacked" (
pdl_install_extensionhands you the path + steps) — so every user knows exactly what they're running and why. Disabling Chrome Developer mode auto-disables it.
Code style
- FP-only: pure functions, immutability, no OOP, no classes-with-methods.
- Side effects (CDP calls, file I/O, native messaging, MCP transport) at the edges; core logic pure.
- OOP library interfaces (Chrome APIs, MCP SDK,
winreg) wrapped in thin functional adapters with injection points for tests.
Repo layout
Contributing
This is a personal project under active redesign. PRs welcome but please open an issue first to discuss scope — the architecture is still settling. The FP / no-OOP discipline applies to all contributions; see CLAUDE.md for the full rules.
License
MIT — see LICENSE.
來源:README.md,提交 935110e
工具
0版本歷史
3- v1.2.0最新Nov 3, 2026
- v1.0.0Nov 1, 2026
- v0.2.0Sep 16, 2026
評分
已滿足適用檢查項的 50%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分