Live CortexUI Surface

This block renders live CortexUI contract metadata in the docs DOM so AI View can inspect real machine-readable elements instead of only code examples.

AI View can now inspect a live status region, form fields, actions, and table entities on every docs page.
AI-addressable docs entities
ItemState
Search docsReady
Inspect metadataVisible in AI View

Screen Structure

Every page in a CortexUI application should declare its structural identity through a hierarchy of data-ai-* attributes. This hierarchy allows AI agents to understand where they are, what context they are operating in, and how the content is organized — without any visual inference.

The Hierarchy

screen (root)
  └── section (major region)
        └── entity container (optional, data context)
              └── form / table / modal (component)
                    └── field / action (interactive element)

Each level narrows the context. A screen says "this is the user-profile page." A section says "this is the danger-zone region of that page." An entity container says "the actions and data here apply to user-abc." A form says "these fields submit together."

data-ai-screen: Declaring the Screen

data-ai-screen belongs on the outermost element of the page's content area. It is a kebab-case name that identifies the current view.

<!-- Root element of the page content -->
<div data-ai-screen="user-profile">
  <!-- everything inside is part of the user-profile screen -->
</div>

Screen names should be stable, descriptive, and consistent with your application's routing vocabulary. If the route is /users/:id, the screen is user-profile. If the route is /orders/:id, the screen is order-detail.

Screen Naming Examples

RouteScreen Name
/dashboarddashboard
/users/:iduser-profile
/orders/:idorder-detail
/settings/billingsettings-billing
/checkout/step-1checkout-shipping
/checkout/step-2checkout-payment
/productsproduct-list
/products/:idproduct-detail

data-ai-section: Declaring Major Regions

data-ai-section marks the major logical regions within a screen. Sections help agents understand which actions and data belong together.

Sections should represent meaningful organizational units — not every <div> needs a section. Think about how you would describe the page to someone verbally: "there is a profile header, a profile form, an account settings panel, and a danger zone." Those are your sections.

<div data-ai-screen="user-profile">

  <section data-ai-section="profile-header">
    <!-- avatar, name, status badge -->
  </section>

  <section data-ai-section="profile-form">
    <!-- editable fields -->
  </section>

  <section data-ai-section="account-settings">
    <!-- role, permissions, preferences -->
  </section>

  <section data-ai-section="danger-zone">
    <!-- delete, suspend, reset -->
  </section>

</div>
Note

You do not need to use the HTML5 <section> element. Any block element can carry data-ai-section. Use <section> when it makes semantic sense, but do not force it where a <div> is more appropriate.

data-ai-entity and data-ai-entity-id: Declaring Context

When a screen or section operates on a specific record, annotate the container with the entity type and the instance ID.

<!-- The entire screen is about user user-abc -->
<div
  data-ai-screen="user-profile"
  data-ai-entity="user"
  data-ai-entity-id="user-abc"
>
  ...
</div>

<!-- A section about a specific order within an order list -->
<section
  data-ai-section="recent-orders"
>
  <div data-ai-entity="order" data-ai-entity-id="ord-9981">
    <!-- order details -->
  </div>
  <div data-ai-entity="order" data-ai-entity-id="ord-9982">
    <!-- order details -->
  </div>
</section>

Entity context scopes the meaning of actions. A delete-account action inside data-ai-entity-id="user-abc" means: delete user abc. Without the entity context, the action intent is ambiguous.

Full Annotated Example: User Profile Page

<div
  data-ai-screen="user-profile"
  data-ai-entity="user"
  data-ai-entity-id="user-abc"
>

  <!-- Profile Header Section -->
  <section data-ai-section="profile-header">
    <img src="/avatar/user-abc.jpg" alt="Alice Smith" />
    <h1>Alice Smith</h1>
    <span
      data-ai-role="status"
      data-ai-id="account-status-badge"
      data-ai-state="success"
    >
      Active
    </span>
    <button
      data-ai-role="action"
      data-ai-id="update-avatar"
      data-ai-action="update-avatar"
      data-ai-state="idle"
    >
      Update Avatar
    </button>
  </section>

  <!-- Profile Form Section -->
  <section data-ai-section="profile-form">
    <form
      data-ai-role="form"
      data-ai-id="edit-profile-form"
      onSubmit={handleSubmit}
    >
      <input
        data-ai-role="field"
        data-ai-id="name-field"
        data-ai-field-type="text"
        data-ai-required="true"
        name="name"
        defaultValue="Alice Smith"
      />
      <input
        data-ai-role="field"
        data-ai-id="email-field"
        data-ai-field-type="email"
        data-ai-required="true"
        name="email"
        defaultValue="alice@example.com"
      />
      <input
        data-ai-role="field"
        data-ai-id="phone-field"
        data-ai-field-type="tel"
        data-ai-required="false"
        name="phone"
        defaultValue="+1-555-0100"
      />
      <button
        data-ai-role="action"
        data-ai-id="save-profile"
        data-ai-action="save-profile"
        data-ai-state="idle"
        type="submit"
      >
        Save Profile
      </button>
      <button
        data-ai-role="action"
        data-ai-id="cancel-edit"
        data-ai-action="cancel-edit"
        data-ai-state="idle"
        type="button"
        onClick={handleCancel}
      >
        Cancel
      </button>
    </form>
  </section>

  <!-- Account Settings Section -->
  <section data-ai-section="account-settings">
    <select
      data-ai-role="field"
      data-ai-id="role-select"
      data-ai-field-type="select"
      data-ai-required="true"
      name="role"
    >
      <option value="admin">Admin</option>
      <option value="editor">Editor</option>
      <option value="viewer" selected>Viewer</option>
    </select>
    <button
      data-ai-role="action"
      data-ai-id="assign-role"
      data-ai-action="assign-role"
      data-ai-state="idle"
    >
      Assign Role
    </button>
  </section>

  <!-- Danger Zone Section -->
  <section data-ai-section="danger-zone">
    <button
      data-ai-role="action"
      data-ai-id="suspend-account"
      data-ai-action="suspend-account"
      data-ai-state="idle"
    >
      Suspend Account
    </button>
    <button
      data-ai-role="action"
      data-ai-id="delete-account"
      data-ai-action="delete-account"
      data-ai-state="idle"
    >
      Delete Account
    </button>
  </section>

</div>

How getScreenContext() Reads the Structure

The runtime scanner traverses the DOM and collects all structural annotations into a context object:

const ctx = window.__CORTEX_UI__.getScreenContext();

/*
{
  "screen": "user-profile",
  "entity": "user",
  "entityId": "user-abc",
  "sections": ["profile-header", "profile-form", "account-settings", "danger-zone"]
}
*/

An agent typically calls getScreenContext() as its first step — before any other API call — to verify it is on the expected screen and operating on the expected entity.

// Agent verifying context before acting
const ctx = window.__CORTEX_UI__.getScreenContext();

if (ctx.screen !== "user-profile") {
  throw new Error(`Expected user-profile, but on ${ctx.screen}`);
}
if (ctx.entityId !== targetUserId) {
  throw new Error(`Wrong user: expected ${targetUserId}, got ${ctx.entityId}`);
}

// Safe to proceed
const actions = window.__CORTEX_UI__.getAvailableActions();
Important

Always annotate the entity context (data-ai-entity and data-ai-entity-id) on any page that operates on a specific record. Without entity context, an agent cannot safely determine which record an action will affect. This is especially critical for destructive actions like delete or archive.

Comparing Screens

Screen structure makes pages distinguishable. Two screens that look visually similar can be clearly different in the contract:

User Profile screen:

{ "screen": "user-profile", "entity": "user", "entityId": "user-abc" }

Order Detail screen:

{ "screen": "order-detail", "entity": "order", "entityId": "ord-9981" }

Both might have a "Save" button. The contract tells the agent exactly which record that Save button will affect.