Skip to content

Introspection

phroun edited this page Aug 23, 2026 · 2 revisions

A host can be asked what it understands. describe streams its whole wire vocabulary — every type, every property, every event — as ordinary statements.

describe

It takes no arguments:

describe button
  ->  describe: takes no arguments

Why it exists

A client should not have to be compiled against a particular build of the toolkit. A type may gain a property; a build may carry an Editor with a richer vocabulary than the stock one; a host may be older than the client talking to it.

describe makes that answerable at runtime rather than assumed. The running host is the authority on its own vocabulary — including over this wiki, whose property and event tables are generated from exactly this stream. Where a page and your build disagree, the build is right.

What comes back

One statement per line, ahead of the reply. Five kinds:

Statement One per
propcommon property every non-virtual type accepts
proptype registered type
prop property of a type
event event a type emits
eventfield field of an event

They look like this:

propcommon name="acc_name" kind="string" default="" doc="Accessibility name announced by screen readers." enum=""
proptype name="button" !virtual
prop of="button" name="action" kind="action" default="" doc="Optional command dispatched on click." enum=""
event of="button" name="click" doc="The button was activated, by pointer or by keyboard."
eventfield of="button" event="click" name="trinket" kind="uint" doc="The button's object ID."

Everything is a quoted string, including the numbers, so a decoder needs no type table to read the stream.

of= attaches a statement to its type. propcommon has no of= because it belongs to all of them. eventfield carries both of= and event=, so fields match to their event by name rather than by position — a host may emit them in any order.

proptype marks the trinket/virtual split with a flag: !virtual for a real trinket, bare virtual for a part of another object. Virtual types take none of the common properties, so that flag tells a client whether the propcommon set applies. See Object Model.

enum= is a comma-separated list, empty when the property is not an enum. kind= names the value shape — string, int, flag, word, enum, color, units, action — which is what Properties and Values is about.

It is the wire language describing itself

The stream is not a separate format. Every line is a statement the ordinary parser reads, which has two consequences worth relying on.

A decoder is a parser you already have. Reading the vocabulary needs no JSON, no schema, no second grammar.

Unknown statement kinds are ignored. A newer host can add a sixth kind and an older client keeps working — it decodes what it recognises and skips the rest:

futurething name="x"
  ->  decoded alongside everything else; types = 34, no error

That is the compatibility rule the whole scheme rests on: hosts may add, clients may ignore.

Round-tripping

Encoding a vocabulary, decoding it, and encoding it again produces byte for byte the same stream. Nothing is lost in the crossing.

That is what lets a tool work identically against a live host or a local registry — kittytk-wikidoc generates this wiki's tables from either, and cannot tell them apart, so the two paths cannot drift.

Using it

A client typically calls it once at connection and keeps the result:

v, err := conn.Describe()

What it is worth doing with:

  • Check a property exists before sending it, where a client supports hosts of different ages.
  • Discover a type's events rather than hard-coding names — which matters, because sub does not validate the name you give it and a wrong one fails silently.
  • Build tooling. A UI builder, a documentation generator, a completion list, a protocol linter all need the same answer, and this is it.

Offline

The vocabulary is also readable without a running host, from the registry a binary was linked with. That is how the wiki's tables are generated on a machine with nothing listening:

go run ./cmd/kittytk-wikidoc -wiki ../kittytk.wiki

and how they can be generated against a real host instead:

go run ./cmd/kittytk-wikidoc -wiki ../kittytk.wiki -endpoint ADDR

Both land on the same structure. See wiki-generation.md in the repository.

See also

Protocol Overview — where describe sits among the verbs · Properties and Values — what kind= means · Object Model — the virtual split proptype reports · Events

Clone this wiki locally