Sno Station
Sno Station is your agents' workstation: open-source software that turns the AI agents you already run into one squad on your own machine. Two heads are better than one, and they get better with every
See your website on every screen at once. Multi-device responsive testing wall with synchronized navigation and scroll.
PluginsJavaScript · CSSGitHub @JacobTheJacobsOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Chrome extension that shows one website on every screen at once: phones, foldables, tablets, laptops, watches and TVs in a single tab, with navigation, scrolling and clicks in sync.
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Chrome extension: see one website on many viewports at once, with synchronized navigation and scroll.
Add to Chrome from the Chrome Web Store
1. chrome://extensions → enable Developer mode → Load unpacked → select this folder.
2. Open any page (or localhost:3000) and click the toolbar icon. The wall opens with that URL; clicking the icon again reuses the open wall and sends it the new page.Read the full README ↗Chrome extension: see one website on many viewports at once, with synchronized navigation and scroll.
| For | Install | |
|---|---|---|
| Viewport Wall (this extension) | A person looking at devices | Chrome Web Store |
| viewport-wall-mcp (mcp/) | An AI agent checking pages | one file, no package manager, see below |
Both read the same device library, so the agent tests exactly what you see.
Add to Chrome from the Chrome Web Store
chrome://extensions → enable Developer mode → Load unpacked → select this folder.localhost:3000) and click the toolbar icon. The wall opens with that URL; clicking the icon again reuses the open wall and sends it the new page.chrome.debugger API. No extra windows are opened.localhost / 127.0.0.1 / *.localhost when the server sends no X-Frame-Options or restrictive frame-ancestors): the page runs in a live <iframe> inside the wall. Real-time and directly interactive, no capture pipeline, but only width/height emulation (no DPR, touch or user-agent) and no screenshots. The wall's host permission for localhost lets the agent script run inside these frames for scroll/navigation sync and issue checks, and gives them access to the site's normal cookies (Chrome's storage-partitioning exemption for extension pages with host permission). Sites that block framing fall back to Full emulation automatically.
Emulation.setDeviceMetricsOverride applies width/height/DPR/mobile/touch/user-agent, so CSS media queries see the real emulated viewport.
This works on sites that block iframes (X-Frame-Options, frame-ancestors) and on localhost/staging with your existing cookies.Page.startScreencast runs on every tab at the resolution the panel is displayed at (JPEG, maxWidth/maxHeight = panel size), so a phone shown at 40% costs a fraction of a full frame. Chrome pushes a frame only when the compositor produced one, which is the "pixels changed" signal: a still page sends nothing, a scrolling one streams at the compositor's full rate for the active device and 20/15 fps for the others (everyNthFrame). An inactive device that keeps streaming for 3 s (an animation) drops to 10 fps until it is touched or navigates. The screencast also keeps hidden tabs painting. Page.captureScreenshot (clipped to the visual viewport in document coordinates) is only a fallback for the first paint and for a device whose agent reported a change without a frame following, plus full-resolution downloads.captureScreenshot's clip.scale multiplies the emulated DPR, startScreencast's maxWidth does not), and every frame is decoded before it is swapped into the panel. Otherwise panels visibly pulse between two resolutions while scrolling.Input.*.scrollTop / (scrollHeight - viewportHeight)).chrome.storage.local for custom devices, sets, preferences, and recent URLs. Nothing is uploaded.Chrome shows an "is debugging this browser" bar while the wall is open; that is expected and cannot be removed by an extension. Closing the wall tab closes the device tabs.
One header bar: brand, pill URL bar with back/forward/reload, View menu (layout, zoom, frame style incl. none, browser UI, rotate all, presentation), Sync switch (on: navigation, scroll, clicks and typing in one device happen on every device; off: only the device you touch reacts), Screenshot menu, Record (WebM of the wall), Add Device, Settings (theme, mobile user agent, auto reload, QA report, about). Everything about adding devices lives in the Add Device modal: sets, simple tags (Phone, Fold, Tablet, PC, Watch, TV, Widths, Favorites, Custom), search, and every preset drawn with a tiny silhouette. Footer: a Devices hub (list, sets, save set, breakpoints, save session, sessions, clear all), performance. Compare two devices from a device's menu ("Compare with active"). Focus a device by double-clicking it or from its menu; Escape returns to the wall. "Pause live updates" in Settings freezes every device. Each device label has rotate, close and one actions menu (reload, rotate, fold/unfold on foldables, pause, focus, capture, compare, note, edit, duplicate, network, CPU, remove); double-click a device to focus it. Inter font bundled locally; dark and light themes.
Realistic frames are data-driven (frames.js): iPhone modern (Dynamic Island, iOS status bar, Safari bar, home indicator), iPhone classic (bezels + home button), Pixel / Galaxy (punch-hole, Android status bar, Chrome bar, gesture bar), iPad, desktop browser window, and a minimal rounded frame for raw breakpoints. All bars sit outside the emulated viewport, so CSS media queries always see the exact device width.
Headless Chromium 151 on a 24-core Linux box, bench2.py in the test harness. CPU is the sum over all Chrome processes (100% = one core); RSS is the whole browser including the wall page. "Static" is a plain page, "animated" is a worst case that rewrites text at 60 fps in every device.
| Devices | Mode | Idle CPU static / animated | Scrolling CPU static / animated | RSS static / animated | Frames sent, animated | All devices ready after navigation |
|---|---|---|---|---|---|---|
| 1 | Full emulation | 0% / 70% | 11% / 66% | 1.08 / 1.42 GB | 60 fps | 0.3 s |
| 4 | Full emulation | 2% / 193% | 30% / 149% | 1.52 / 2.11 GB | 90 fps total | 0.3 s |
| 8 | Full emulation | 1% / 240% | 105% / 241% | 2.07 / 2.67 GB | 98 fps total | 0.3 s |
| 12 | Full emulation | 1% / 247% | 112% / 254% | 2.59 / 3.21 GB | 118 fps total | 0.3 s |
| 4 | Interactive (iframe) | 0% / 20% | 14% / 24% | 1.11 / 1.14 GB | native | 0.3 s |
| 12 | Interactive (iframe) | 1% / 30% | 21% / 35% | 1.16 / 1.21 GB | native | 0.3 s |
What this says: a still wall costs nothing in either mode (no frames are sent). Scrolling on the active device streams real frames to every panel, so a 12-device scroll costs about one core. Each emulated tab costs roughly 130 MB and, on a page that animates continuously, most of the cost is the renderers themselves (about 20% of a core each), so an animated 12-device wall is heavy; the Snapshots pause in Settings or Interactive mode for local work brings it down. Real sites (YouTube watch page, react.dev, nextjs.org, github.com, threejs.org, MDN, Wikipedia) render and scroll in sync on four devices in the sites.py check.
mcp/ is a companion that gives an agent the same devices: it loads a page at every viewport, reports what
breaks with the element that caused it, finds the real breakpoints, and returns screenshots on request. It has
no dependencies and drives the Chrome already on the machine, so there is no server, no npm install and no
browser download. Node 22 or newer.
curl -fsSL https://raw.githubusercontent.com/JacobTheJacobs/ViewportWall/master/mcp/dist/viewport-wall-mcp.mjs -o ~/.local/bin/viewport-wall-mcp.mjs
{ "mcpServers": { "viewport-wall": { "command": "node", "args": ["/home/you/.local/bin/viewport-wall-mcp.mjs"] } } }
In the extension: Settings → Connect your AI agent copies both snippets. Details, the CLI form, and how to audit pages behind a login are in mcp/README.md.
A add device · R reload all · Shift+R rotate all · F presentation · 1–9 activate device · +/- zoom · Esc exit · double-click a panel to focus it.
manifest.json MV3 manifest (debugger, tabs, storage, activeTab)
background.js opens the wall from the toolbar icon; closes the device tab group when the wall tab closes
agent.js in-page agent: scroll/navigation reports, responsive checks (CDP-injected or content script)
core.js target manager, rendering modes, CDP emulation, screencast stream + capture fallback, sync, screenshots, sessions (no DOM)
wall.js UI: toolbars, menus, canvas layout, picker, focus/compare/presentation
wall.html/css structure + design tokens (dark/light)
frames.js data-driven device shells, status bars, browser bars, cutouts
icons.js inline SVG icon set
devices.js device library + built-in sets (data only; add a device = add a line)