Skip to content

Grammar

Every captured page becomes a tree of UINode objects. Each node carries a role (one of 22 primitives) and optional signals that describe its behavior, state, and visual intent.

FieldTypeRequiredPurpose
idstringYesStable ID within capture (content-addressed or path-based)
roleUIRoleYesOne of 22 primitives: PAGE, BUTTON, NAV, CARD, INPUT, MODAL, etc.
bboxBBox01YesViewport-relative bounding box [x, y, w, h] in [0, 1] range
interactivebooleanYesCan the user click/type on this?
visiblebooleanYesIs it actually on screen?
semanticstringNoCoarse hint like "login", "search", "checkout"
name_hashstringNoHash of aria-label/name/id (not the actual value)
textTextSignalNoText shape: hash, length, classification (short, sentence, paragraph)
znumberNoCoarse z-index bucket (0-10)
enabledbooleanNoNot disabled
focusablebooleanNoCan receive keyboard focus
handlersHandlerSignal[]NoEvent-intent mappings: { event: "click", intent: "toggle_menu" }
bindingsBindingSignal[]NoReactive bindings: { property: "value", expression: "state.email" }
stateStateSignal[]NoState tracking: { key: "cart.items", access: "read", scope: "global" }
styleStyleIntentNoVisual intent tokens: primary, destructive, elevated, muted, ghost
patternPatternSignalNoReusable pattern: { kind: "auth_form", variant: "login", slot: "header" }
childrenUINode[]NoNested child nodes (semantic grouping, not DOM children)
flagsUINodeFlagsNoBehavior/state flags (sticky, scrollable, repeated)

Patterns let LLMs recognize higher-level compositions beyond individual roles:

search_bar · auth_form · product_card · nav_menu · data_table · wizard_step · media_player · chat_thread · dashboard_widget · custom

Design-system-level visual markers (not CSS):

primary · secondary · destructive · success · warning · info · muted · elevated · outlined · ghost · inverted · highlight · truncated · monospace · custom

  • Current version: 0.1
  • Forward compatible: unknown fields are silently ignored
  • Version check: isSupportedSchemaVersion("0.1") returns true
  • Unsupported input: throws WS_UNSUPPORTED_VERSION
CodeWhen it happens
WS_INVALID_JSONInput isn’t valid JSON
WS_INVALID_CAPTURECapture fails schema validation
WS_UNSUPPORTED_VERSIONCapture version isn’t supported
WS_LIMIT_EXCEEDEDToo many nodes or too deep
WS_INVALID_ARGSMissing or bad arguments
WS_NOT_FOUNDResource not found
WS_IO_ERRORI/O failure
WS_PERMISSION_DENIEDInsufficient permissions
WS_INTERNALSomething unexpected went wrong
ConstantValueMeaning
MAX_DEPTH8Maximum tree depth
MAX_CHILDREN200Maximum children per node (overflow is summarized)
BBOX_QUANT_STEP0.001Quantization step for bbox hashing (~1px at 1000px viewport)
COLLAPSE_TOLERANCE0.002Nodes within this bbox difference are considered equal (~2px)