Appearance
Runtime tree
The left pane of Explorer Mode is <director-tree> (src/components/DirectorTree.ts). It renders a recursive tree of IDirectorTreeNode rows and emits director:node-selected, director:node-expand, and director:refresh events upward.
Anatomy of a row
Each row is a flex container with the following pieces (verified against DirectorTree.ts:83-119):
[toggle] [dot] [node-name] [badges...]
▶/▼ color mount.last P P π canonical compat- Toggle —
▶collapsed,▼expanded. Click to expand/collapse. Toggling a node that hasn't loaded children dispatchesdirector:node-expand { mount }soDirectorAppcan lazy-fetch viaDirectorRuntimeAdapter.introspectActorCached. - Dot — color-coded by component class:
| Color | Meaning | Source class regex |
|---|---|---|
Blue (#42a5f5) | Legacy daemon-named mount | matches daemon/Daemon (v1 holdover; new substrate code uses runtime vocabulary, not "daemon") |
Green (#66bb6a) | System actor | matches system/System (or system.* mount) |
Yellow (#ffee58) | Package root | dot-package set on canonical package roots (system.agents, system.observability, system.sqlite) |
Purple (#ab47bc) | Promptable | introspect returned promptable: true |
Grey (#78909c) | Default fallback | none of the above |
- Node name — the last segment of the canonical mount (
system.observability.tracing→tracing). - Badges — small chips:
P(purple) — promptable.regime— text badge (explore,execute, etc.) when introspect returned a regime.canonical/compat— set byinferPackageFamily+isCompatPackageMountso an operator can see at a glance whether they are looking at, e.g.,system.agents.memory(canonical) orsystem.memory(compat alias).
Toolbar
Above the rows, a small toolbar:
- Title — fixed text "ACTORS".
- Refresh button — dispatches
director:refresh, whichDirectorAppreroutes todirector.refresh-surface { surface: 'explorer' }.
Selection and expand contracts
| Inbound op | Effect |
|---|---|
tree.set-data { roots } | Replace the entire roots array. |
tree.set-selected { mount } | Highlight that mount. |
tree.set-status { status } | Update the small status string ("Loading…", "Ready", "Stale"). |
tree.set-children { mount, children } | Replace one node's children (lazy-load result). |
tree.set-runtime-inventory { children } | Splice runtime-only inventory into the runtime branch. |
tree.set-root { root } | Update the implicit authority root used for display. |
| Outbound event | Carries | When |
|---|---|---|
director:node-selected | { mount, componentClass } | Click on a row |
director:node-expand | { mount } | Click toggle on a node with childrenLoaded === false |
director:refresh | {} | Click refresh in the toolbar |
DirectorExplorerShell rebroadcasts these as director:explorer-actor-selected, director:explorer-actor-expand-requested, and director:explorer-refresh-requested to DirectorApp.
Live presence
DirectorApp.subscribes includes system.runtimes/$events filtered to runtimes.added, runtimes.removed, and runtimes.inventory.changed. When events arrive, DirectorApp rebuilds its catalog and pushes the new tree via tree.set-data. There is no per-row websocket; the tree is fully redrawn on each catalog refresh.
Limits and known issues
- Single root only. The tree is rendered for one authority root at a time (the runtime root resolved by
DirectorTopology). Multi-root composition (browser realm + runtime realm side by side) is documented inDESIGN.md§2.1 as a future direction. - Lazy loading is best-effort. If
$introspect.childrenis missing or shaped differently on a custom actor, the node will appear leaf-like. - Synthetic prefix nodes have no actor.
system.observabilitymay be a tree branch even though no actor mounts there directly. Clicking it selects the prefix; the detail panel will show the package status row fromloadPackageStatuses.
See also
Source:
projects/matrix-3/packages/director/src/components/DirectorTree.ts(full component),src/services/DirectorRuntimeAdapter.ts:758-1028(tree construction).