Talos docs

UiNode

Since 0.6

One node of a screen description.

Plain text

This is the frozen wire contract between the TSX compiler and the engine: { format: 1, screen, root }, with a node carrying its role, its identity, its classes, its data attributes, its text and its children. It is deliberately data rather than a builder — a screen an agent can print, diff and post is a screen an agent can debug.

Signature

export interface UiNode {
  role: UiRole
  /**
   * Stable author id, flat within the screen. `GET /ui` reports it qualified: `pause:resume`.
   *
   * May not contain `/` or `:` — those are the id grammar's own separators, so an id using one
   * could forge a sibling's derived id. The engine refuses it and falls back to the derived
   * form rather than letting two nodes answer to one name.
   */
  id?: string
  /** Diffing key. A keyed child keeps its identity across a rebuild even if its position moves. */
  key?: string
  classes?: string[]
  /** Data attributes without the `data-` prefix. Variants are data, not generated class strings. */
  data?: Record<string, string | number | boolean>
  /** A literal string. Mutually exclusive with `textKey`. */
  text?: string
  /** A `meta.strings` key. §2.11 makes this the default and a literal the marked case. */
  textKey?: string
  /**
   * Per-node props. On the **root** these configure the screen itself — `inputContext`,
   * `modal`, `dismissible`, `clickThrough`, `cursor`, `pausesWorld`. On any other node they are accepted,
   * kept and reported as `ui.screen.props-ignored` until the binding table lands; they are
   * never silently dropped.
   */
  props?: Record<string, unknown>
  children?: UiNode[]
}

Import: import type { UiNode } from "@argus/api"

Members

MemberSignatureDescription
rolerole: UiRole
idid?: stringStable author id, flat within the screen. GET /ui reports it qualified: pause:resume. May not contain / or : — those are the id grammar's own separators, so an id using one could forge a sibling's derived id. The engine refuses it and falls back to the derived form rather than letting two nodes answer to one name.
keykey?: stringDiffing key. A keyed child keeps its identity across a rebuild even if its position moves.
classesclasses?: string[]
datadata?: Record<string, string | number | boolean>Data attributes without the data- prefix. Variants are data, not generated class strings.
texttext?: stringA literal string. Mutually exclusive with textKey.
textKeytextKey?: stringA meta.strings key. §2.11 makes this the default and a literal the marked case.
propsprops?: Record<string, unknown>Per-node props. On the root these configure the screen itself — inputContext, modal, dismissible, clickThrough, cursor, pausesWorld. On any other node they are accepted, kept and reported as ui.screen.props-ignored until the binding table lands; they are never silently dropped.
childrenchildren?: UiNode[]

Example

The tested fixture fixtures/app/agent.ts.

import type { Behavior } from "@argus/api"

// Sends a nav agent to `props.target` once, then reports arrival through ctx.state so the
// test can read it without polling the crowd directly.
export default {
  init(ctx) {
    ctx.state.arrived = false
    ctx.nav?.goTo(ctx.props.target as [number, number, number])
  },
  update(ctx) {
    if (ctx.nav?.arrived) ctx.state.arrived = true
  },
} satisfies Behavior