QORMQORM v0.8.4 docs Get started

Interpreting & verifying a QORM app

QORM's goal is to let an AI completely and precisely interpret and verify everything a user expressed in an app — its layout, styles, behavior and translations — using the framework itself, with no external browser.

The mechanism: the running app measures itself in its own runtime (browser or native WebView). A tiny script walks every element with an id, records its getBoundingClientRect and computed styles, and POSTs them to /measure. The framework then joins that real rendered result with the user's intent (each node's type, text, and state binding, from the app JSON). So for every component you get both what the user asked for and what actually rendered.

Everything below works from the CLI (-tags desktop build, which drives a native WebView) and from the live shared session over MCP.

qorm measure — read the real render

qorm measure <app-dir> [-o report.json]

Renders the app, self-measures, and prints one row per component joining intent with result:

{ "id": "wifi", "type": "switchlisttile", "intent": {"label": "Wi-Fi", "binding": "{{state.wifi}}"},
  "x": 32, "y": 499, "w": 336, "h": 47, "visible": true,
  "color": "rgb(0,0,0)", "background": "rgba(0,0,0,0)", "fontSize": "15px",
  "padding": "…", "borderRadius": "…", "overflowX": false }

Fields per component: id, type, intent (text/label/binding), x y w h, visible, tag, text (for leaf nodes), and computed color, background, fontSize, fontWeight, textAlign, padding, margin, borderRadius, border, opacity, zIndex, position, overflowX.

qorm check --checks — verify expectations

qorm check <app-dir> --checks checks.json [-o report.json]

checks.json is an array of {id, <assertion>…}. Each assertion is verified against the real render; the report gives per-check pass/fail with actual values.

assertionmeaning
`visible: true\false`the component is / isn't actually visible
type: "<widget>"rendered from the expected node type
text: "<s>"contains <s> (matched against expressed OR rendered text)
noOverflow: trueno horizontal content overflow
minW / maxW / minH / maxH: <px>size within bounds
x / y: <px>position (±3px tolerance)
within: "<id>"this component's box sits inside that id's box
below: "<id>"starts below that id
backgroundNot / colorNot: "<substr>"that substring is ABSENT (e.g. "255, 255, 255" to assert not-white in dark mode)
role: "<role>"the rendered ARIA role (incl. roles the renderer injects, e.g. root→main, modal→dialog)
hasAriaLabel: truethe element exposes an aria-label
contrastRatio: <n>text/background contrast is at least n (WCAG AA: 4.5 normal, 3.0 large), computed against the effective background

Accessibility assertions read the rendered DOM, so they catch roles and labels the renderer injects implicitly — not just what the JSON declared. focusTrap is intentionally rejected for now: focus containment is a dynamic Tab-order behavior, not a static snapshot, and a verifier must never vouch for a check it cannot actually make.

Checks fail loud: an unrecognised assertion key (e.g. a typo) fails, and a within/below target id that was not measured fails as 'not found' — nothing silently passes.

[
  {"id": "nav",      "type": "appbar", "visible": true, "y": 0, "text": "Today"},
  {"id": "wifi",     "type": "switchlisttile", "visible": true, "within": "settings"},
  {"id": "chart",    "noOverflow": true, "maxW": 370}
]

qorm check step-flow — verify behavior

Pass a {"steps":[…]} object instead of an array to verify interactions: each step applies an action, waits for the re-render + re-measure, then checks.

{ "steps": [
  { "name": "increment", "do": {"dispatch": "increment"}, "checks": [{"id": "number", "text": "1"}] },
  { "name": "go dark",   "do": {"setState": {"path": "theme", "value": "dark"}},
    "checks": [{"id": "card", "backgroundNot": "255, 255, 255"}] }
] }

do is {"dispatch": "<action>", "args": {…}} or {"setState": {"path": …, "value": …}}.

qorm check --audit — one-shot regression

qorm check <app-dir> --audit

No hand-authored checks: verifies generic invariants over every visible component — non-zero size, no horizontal overflow, within the window (horizontal-scroll/paged containers and their descendants are exempt). Returns {ok, visibleComponents, issues, details}.

In the live shared session (MCP)

While a human runs the app, an agent on the same session can call:

per-check pass/fail with actual values.

Both read the live client's self-measurement, so the agent sees exactly what the human sees. The tool descriptions carry the full assertion list.

QORM DevTool activity view of the shared session In a shared session the agent reads the same live render you see; the DevTool interleaves both sides' activity.

Note: the qorm measure and qorm check reports are structured CLI/JSON (shown as code blocks above) — there is no terminal screenshot for them. The image here is the DevTool view of the live shared session, not a captured report.

On-device live debugging

qorm run <app> --lan

Binds to the LAN and prints how a physical phone joins the same live session as the dev machine and agent:

(same network). Real LAN addresses are listed first.

phone opens http://localhost:PORT/.

Once connected, the device is just another client of the live server:

and qorm_check_layout report the real device's rendering — actual screen size, fonts and WebView — not a simulation,

so a device joining the session is visible.

This makes interpret-and-verify work against real hardware, closing the loop from authoring to on-device confirmation.

One command for everything

bash scripts/verify.sh

Runs go test ./... (render markers, actions, i18n formatting, fuzz, determinism) plus a self-measured layout audit of every example, aggregated to a single ALL-GREEN / regressions verdict. No external browser.

Notes

-tags desktop WebView (runs headlessly); the live session uses whatever browser/WebView the human has open.

overlays (modal/dialog/sheet with open:false), and empty conditional text — the audit only flags visible components.