The one-command way:
npx skills add 4oko4ow/webview-tunerOr paste this to your coding agent (Claude Code, Cursor, Codex, whatever you run) and let it do everything:
Set up webview-tuner from https://github.com/4oko4ow/webview-tuner:
1. Fetch https://raw.githubusercontent.com/4oko4ow/webview-tuner/main/SKILL.md
and follow its Phase 1 - copy webview-tuner.js into this project's static
assets and load it on the pages we debug (it only activates with ?wvtune=1).
2. Keep SKILL.md available to yourself (as a skill / rule / doc) so that when
I paste a webview-tuner report you turn it into a proper CSS fix.
That's the whole setup. When something looks broken inside a wallet's in-app
browser, you open the page there with ?wvtune=1, nudge the layout with your
finger, hit copy, paste the report to your agent - it fixes the source.
Layout forensics and live element nudging for webviews you can't inspect - wallet in-app browsers (Phantom, Solflare, Jupiter, Backpack), TWAs, release-build WKWebView/Chromium views.
Your dApp looks perfect in Chrome DevTools and broken inside a wallet's in-app browser. Release builds don't allow remote inspection, so you can't see what the webview sees: its viewport height, its safe-area insets, why your CTA floats mid-screen. You end up guessing constants, deploying, asking someone with the device "is it better now?", and repeating.
Built while shipping portfi packs - the buy screen looked
fine on mobile Chrome and broke in three different wallet webviews, each
reporting a different 100dvh.
Add one script. Open your page inside the actual webview with ?wvtune=1.
- Metrics panel: real viewport size,
dvh/svh/lvhas the webview resolves them,safe-area-inset-bottom, horizontal-overflow detector. - Inspect mode: a floating ⌖ badge toggles it. While on, the page is inert and plain taps select elements (dashed ring + floating arrow pad next to the selection). Tap several elements to move them together - nudging a CTA never activates it.
- Drag to move: press an element and drag - it follows your finger and snaps to its neighbours on the way. This is the main gesture; tapping selects.
- Walk the DOM:
parent/childstep up and down the tree, so you tap whatever you can hit and then grab the whole block you actually want to move instead of hunting a 12px target. - Arrows for precision: pad arrows move by exactly 1px (
x8for 8px, hardware arrows + Shift too) with snapping off, so a nudge is never pulled back. Width steppers resize. Overrides use the CSStranslateproperty, so they compose with existing transform animations instead of clobbering them. - Axis lock:
axis free / y / x- lock movement to one direction so a vertical tune never drifts sideways. - Snapping: edges and centers snap to siblings and the parent within 8px, with a guide line - hand-nudged layouts come out symmetrical, not one px off.
- Built for a phone: 44px touch targets, the pad drags anywhere by its grip, the panel starts collapsed and never blocks the page (its shell is transparent to taps - only the buttons take them), and axis/snap/pad position/collapsed persist across reloads (localStorage).
- Copy for AI: one button copies a text report - metrics, a CSS selector path for the element, its box, the offsets you chose, URL and user agent. Paste it to Claude (or any assistant working on your code) and it knows exactly which element to move and by how many pixels.
No dependencies, one file, ~4 KB. Renders nothing unless the query param is present, so it is safe to keep in production.
<script src="webview-tuner.js"></script>
<!-- shows only when the page is opened with ?wvtune=1 -->Or force it on regardless of the query string (for a dev build):
<script src="webview-tuner.js" data-auto></script>- Deploy your page with the script (it stays dormant).
- On the device, open the page inside the wallet browser with
?wvtune=1. - Read the metrics - usually the bug is already visible ("dvh is 850 here, not the 660 I designed for").
- Tap the ⌖ badge, tap the misplaced element (or its parent block via
parent) -> nudge until it looks right. copy-> paste the report into your AI pair programmer -> it turns your on-device pixels into the real CSS fix.
440x746 outer 746 screen 956
vv 746 dvh 746 svh 746 lvh 746
safe-b 0 hscroll none
axis y snap on step 8px
sel[0] div.buyCta > button.primary
box 384x64 @ 28,562
OVERRIDE dx 0 dy -14 dw 16
url https://yourapp.xyz/checkout?wvtune=1
ua ... JupiterBrowser/3.11.0 ...
SKILL.md in this repo is a plain-markdown skill: it teaches an agent the
full loop - wire the script into your project, tell the user what to do on the
device, and turn a pasted report into a real CSS fix (formula-level, not magic
constants). It works with any agent that can read a file.
One command, any agent (via skills.sh - Claude Code, Codex, Cursor, Copilot, Amp and more):
npx skills add 4oko4ow/webview-tunerThen just say "the page looks broken in the wallet browser" or paste a tuner report in any project - the skill picks it up.
Manual, Claude Code:
git clone https://github.com/4oko4ow/webview-tuner ~/.claude/skills/webview-tunerCursor - add it as a project rule:
mkdir -p .cursor/rules && curl -o .cursor/rules/webview-tuner.mdc \
https://raw.githubusercontent.com/4oko4ow/webview-tuner/main/SKILL.mdCodex CLI / agents that read AGENTS.md - vendor the file and point to it:
curl -o docs/webview-tuner-skill.md \
https://raw.githubusercontent.com/4oko4ow/webview-tuner/main/SKILL.md
echo "When debugging webview layouts, follow docs/webview-tuner-skill.md" >> AGENTS.mdAnything else (ChatGPT, a raw API agent, your own harness) - paste the
contents of SKILL.md into the system context together with the user's
report. The report format is stable and documented there.
The version is the first line of webview-tuner.js. Agents following
SKILL.md check it against main once per session and, if there is something
new, tell you what changed and ask before replacing your copy - see
CHANGELOG.md. Nothing auto-updates and nothing phones home: the
check is a plain curl your agent runs, and the script itself never makes a
network request.
Updating by hand:
curl -o path/to/your/webview-tuner.js \
https://raw.githubusercontent.com/4oko4ow/webview-tuner/main/webview-tuner.jsAs with any skill: read what you install. This one is a single ~8 KB file you
can audit in five minutes. It makes no network calls, stores nothing, and does
nothing at all unless the URL contains ?wvtune=1. The clipboard report is
assembled locally and goes only where you paste it.
MIT
