Appearance
Actor detail tabs
Selecting any node in the tree drives a detail.show-actor op into <director-detail>, which projects the introspection result across seven tabs plus a Chat surface. All eight subcomponents are mounted at all times — switching tabs toggles display: none/block, never tear-down/rebuild (per webapp-compliance.md).
The tab list is fixed at the source: TAB_IDS = ['overview', 'interface', 'state', 'cognitive', 'memory', 'children', 'chat'] (DirectorDetail.ts:25).
Overview tab — director-tab-overview
Source: src/components/tabs/TabOverview.ts.
A static field table:
| Field | Source |
|---|---|
mount | IActorIntrospect.mount |
componentClass | componentClass |
description | description (or —) |
purpose | purpose |
regime | badge |
promptable | true/false badge |
continuationType | continuationType (default stateless) |
planScope | planScope (default session) |
This tab does not call any actor ops; it only renders the introspect payload provided by DirectorApp.
Interface tab — director-tab-interface
Renders accepts, emits, tracks, and skills arrays from $introspect. For each accepted op, it renders the params shape from acceptsSchema. Skills come from skillsSchema if present.
State tab — director-tab-state
Reads stateScope, persistState, and stateSchema from introspect. There is no live state.read request in this tab today; the displayed schema is what the actor declares, not the current values. Live state values are surfaced by selecting the underlying actor in the tree or via direct matrix invoke <mount> state.get (when supported).
Cognitive tab — director-tab-cognitive
Reads the cognitive fields populated by Phase-1 introspection: purpose, systemPrompt, memoryScope, regime, promptable, promptTriggers, continuationType, planScope, and contract.interfaces. These are the fields that classify an actor as a "cognitive" actor. For non-cognitive actors most fields are empty.
Memory tab — director-tab-memory
Source: src/components/tabs/TabMemory.ts.
Issues DirectorDataAdapter.searchMemory({ mount, query, limit }) and renders the result rows. The dispatched mount list is ['system.agents.memory', 'system.memory'] — canonical-first, compat-fallback. The result includes a backendMode (canonical/compat) and searchTier for the badge.
Note:
memory.writeandmemory.historyare target ops inDESIGN.md§3.6. Today's tab is read-only; it shows the closest matches but cannot edit the memory store.
Children tab — director-tab-children
Reads IActorIntrospect.children[] and renders mount, componentClass, accepts/emits hints. qualifyChildren() (src/services/DirectorAddressing.ts) resolves child mounts so each row links to a fully qualified target.
Sessions tab — director-tab-sessions
Source: src/components/tabs/TabSessions.ts. Composes:
director-tab-sessions
├── backend-bar (badge: "agents" | "legacy", clickable to open backend)
├── mx-split (vertical, 24% / 76%)
│ ├── director-session-list (session summaries)
│ └── director-session-chat (history + input)
└── not-promptable (shown when the selected actor isn't promptable)Calls into DirectorDataAdapter:
listSessions(context, root, { mount, principalId? })→$sessionListagainstsystem.agents.loadSessionHistory(context, root, { mount, sessionId })→session_state.read({ sessionId, key: 'transcript' }).promptSession(context, root, { mount, text, sessionId })→$promptagainstsystem.agentswith a snapshotTree carrying the target mount.
Chat tab — director-chat-surface-host
Source: src/components/DirectorChatSurfaceHost.ts.
The chat tab is not a child of director-tab-*. It's a peer tab inside director-detail with its own load-state lifecycle:
'idle' → 'loading' → 'ready' | 'unavailable'On first activation it dynamically imports @open-matrix/chat-component/surface. If the import succeeds and <conversation-surface> registers, the tab renders the surface and forwards surface.set-target { mount } events. If the import fails (chat-component not built into Director's bundle, network error in dev), the tab renders an "unavailable" message with rebuild instructions instead of throwing.
This is the M4-003 / HARVEST-005 pattern: the surface ships as a lazy chunk in Director's own dist, so identity of MatrixActorHtmlElement is preserved and there is no bare-specifier resolution failure in the browser. The genuine cross-package plugin loader (HARVEST-040) is target state.
See also
Source:
projects/matrix-3/packages/director/src/components/DirectorDetail.ts(tab manifold), eachcomponents/tabs/*file, andcomponents/DirectorChatSurfaceHost.ts.