The component catalog
The component catalog
Section titled “The component catalog”The palette is not a list somebody maintains. It is read from the images that were actually built.
Why it is derived rather than declared
Section titled “Why it is derived rather than declared”A designer needs to know what components exist, what parameters each takes, and what it can be connected to. Keeping that as a list inside the designer is the obvious approach and the wrong one: it is a second description of software that already exists, and the two drift.
The failure mode is unpleasant, because it is silent. A palette listing a component the deployed image cannot provide looks exactly like a palette listing one it can — right up to the point where a design is applied and something fails to start. Equally, a module that gains a capability does not gain a palette entry until somebody notices.
So each module describes its own components, that description is attached to its container image, and Architect reads it back. The mechanism is documented under capability manifests; this page covers what Architect does with it.
What the catalog does
Section titled “What the catalog does”The catalog service iterates the configured registry providers, lists
repositories and tags, and for each reads the com.phrame.manifest label from
the image config blob over the Docker Registry v2 API. No layers are pulled
and no container is run, so discovering the whole platform’s capabilities costs
a series of metadata requests.
Each manifest is decoded, validated against the shared schema, and its
components[] folded into a matrix keyed by component type. A manifest that
fails to decode or validate is skipped — the catalog degrades to offering
fewer components rather than failing to load. Strictness lives in the build,
where a missing manifest on a required image fails the build outright, and
where somebody is watching.
The default provider is scoped to the phrame group, so any phrame/*
image carrying the label is discovered with no per-module code change in
Architect. Adding a component to the palette is a matter of shipping an image
that declares it. Catalog results are cached in Redis, because the registry
round-trip is the expensive part and the answer changes only when something is
built.
What a component contributes
Section titled “What a component contributes”From the manifest, each component carries:
| Field | Meaning |
|---|---|
type | The component identity the compiler and the canvas both key on |
label | What the palette shows a human |
category | input, process or output — the palette grouping |
params[] | The inspector form: name, type, default, constraints |
inputs[] / outputs[] | The pins, and therefore what may be wired to what |
plugin / note / urlField | Optional hints for components needing them |
Parameter types are flat — string, number, boolean, select — which is
enough for most components and not enough for a few. Where a real capability
exceeds the model (arrays of objects such as WebRTC ICE servers or an HLS ABR
ladder, or per-connection placement on a compositor input) the manifest carries
prose in note and the value is set in the configuration rather than offered as
a generated form field.
Dynamic pins
Section titled “Dynamic pins”Not every pin can be known from a manifest, because not every pin is a property of the component. Some are properties of what got connected to it:
- a demultiplexed source whose sub-streams depend on the transport stream actually arriving,
- an MXL source whose flows exist only once the source is attached.
Those pins are discovered at wiring time and rendered once the component has a source. The practical consequence for anyone using the canvas: if a pin you expect is missing, connect the upstream component first. The canvas is describing what it can currently know, not refusing to offer something.
This is also why the manifest’s inputs[] and outputs[] are the static
pins — the ones true of the component regardless of context — rather than the
complete set.
Pin wiring
Section titled “Pin wiring”Connections are validated on type, direction and arity: an output may only reach a compatible input, and a pin that is already satisfied will not accept a second wire. The canvas resolves a dragged wire to the nearest compatible pin within a snap radius rather than demanding pixel accuracy on a small target, and pins carry a transparent hit area larger than the visible dot — wiring at low zoom was otherwise unreasonably fiddly.
Validation gates what a snapped connection is allowed to be, so a generous snap radius makes valid targets easier to hit without permitting invalid ones.
