The panel
The panel lives at /__vkma/ on your dev server (the URL prints at startup) or opens from the FAB right on the app page. It is the same SPA: light and dark themes follow the system, with a toggle in the header. Three sections — Timeline, Execute, Clients.
Timeline
Section titled “Timeline”A ledger of all bridge traffic, modeled as request / response / event:
- Request — a row with the send’s name and a payload preview; nested inside the group is the paired response with the round-trip duration and an ok/error mark.
- Event — unsolicited VK events (e.g.
VKWebAppUpdateConfig) stand as their own rows.
A row expands into a collapsible JSON tree with type highlighting, collapsed-node previews and copy. Internal transport chatter (vk-connect) never reaches the ledger.
Above the ledger sits the filter row:
- search by event name;
- an All / Requests / Events segmented control;
- a client switcher (appears once more than one client is connected);
- pause — the view freezes at the pause point while new events buffer, shown as a counter;
- clear — the ledger empties, new events keep arriving.
A separate mechanism is ignored events: platform noise stays out of the ledger by default (VKWebAppScrollTop, VKWebAppResizeWindow, SetSupportedHandlers, VKWebAppUpdateInsets, VKWebAppUpdateConfig, VKWebAppUpdateInfo). Every row has an “Ignore
History lives on the dev server — the last 500 events. Open the panel long after the app started and it replays the buffer. Reloading the app page starts a new session — that client’s history is purged on every surface.
Execute
Section titled “Execute”Send any bridge event into the running app without leaving the panel:
- Pick the target client (in the standalone panel; in the embedded one it is pinned).
- Start typing the event name — autocomplete offers the bridge catalogue plus names already seen in the session. Picking a catalogue event prefills a params stub.
- Params are JSON with live validation; send stays disabled while the JSON is invalid.
The result lands right there: Response (ok) or Error response — as a payload, Timeout — if nothing answered within 60 seconds, No such client — if the target disconnected. Result payloads expand through the same JSON tree.
Clients
Section titled “Clients”Every connected page script — a desktop tab, a phone on LAN, an iframe, a standalone run — gets a card:
- platform, a colored short id and the page URL (sensitive query params are masked);
- User-Agent and the connection time (“connected 5m ago”);
- an online/offline status — an offline client is dimmed, and refocusing its tab brings it back online;
- launch params as a key-value grid; sensitive values (
sign,access_token,auth_key,sid,secret) are blurred and hinted nowhere.
Offline clients are removable one by one or via the Remove offline button — the server never removes live ones; they re-register on their own.
Embedded scope (FAB)
Section titled “Embedded scope (FAB)”The panel opened from the FAB shows only its own page’s traffic: a colored client badge in the header, the Clients tab hidden, execute pinned to that client. Other clients’ traffic never reaches such a panel at all, and an execute aimed at a foreign client returns forbidden. The standalone /__vkma/ tab sees everything and switches between clients with the filter.
The button’s own placement changes right from the panel (the DevTools position control): the pick is stored on the dev server origin and survives restarts; the initial value comes from the plugin’s fabPosition option.
- Vite plugin and Rsbuild adapter — setup.
- MCP — the same data and execute for coding agents.