Protected_Whether the selected run is paused (from GraphPaused/GraphResumed frames + verbs).
Durable debug state from the parent row — frames are advisory, this is the truth.
Protecteddestroy$What the detail panel is showing.
Edit-input editor (Pending → UpdateTaskInput, Failed → RetryTask).
The engine's recent heartbeat ticks (PassCompleted), newest last. Bounded.
Subclasses can emit anytime an error occurs.
Force-complete confirmation + output editor.
Everything seen this session for the selected run, newest first. Bounded.
The newest frame, bound straight into the run view for sub-second canvas updates.
Children are all terminal — the durable bag can still say paused after the last continue.
Stacked rather than side-by-side when the detail pane is too narrow for both.
Subclasses can emit this event anytime they want to communicate with the container to let it know that something has happened of significance.
Invocation data/context roots from the same parent bag (R3-3).
ReadonlyLayoutPane sizes, panel visibility and the legend toggle — the rules live in workflow-run-layout,
which is pure and therefore testable without standing up Angular.
Preferences go through UserInfoEngine (MJ: User Settings), never localStorage: a pane
width that vanishes when someone opens a different browser is exactly the kind of preference
people notice when it disappears. Reads are a synchronous cache hit; writes are debounced,
because dragging a splitter fires continuously.
ProtectednavigationSubclasses can emit this event anytime they want to open a record within a particular entity. The container should handle this event and open the record.
Tab ID for query param notification scoping. Set by resource wrappers that render child dashboards, so the child knows which tab it belongs to. If not set, falls back to Data.Configuration.tabId.
If specified, this provider will be used for communication and for all metadata purposes. By default, if not provided, the Metadata and RunView classes are used for this and the default GraphQLDataProvider is used which is connected to the same back-end MJAPI instance as the Metadata and RunView classes. If you want to have this component connect to a different MJAPI back-end, create an instance of a ProviderBase sub-class like GraphQLDataProvider/etc, and configure it as appropriate to connect to the MJAPI back-end you want to use, and then pass it in here.
Replay position for a settled run: 0–100 along its wall-clock span, or null for "now".
Dependencies of the selected run's steps, for the what-if preview.
Selected path, when the person clicked an edge rather than a step.
The run whose graph is showing in the detail panel, or null.
The step whose JSON is showing, or null when none is selected.
The selected run's steps, loaded when a run is opened.
Ordering. Newest-first by default, because "what just happened" is the question a run list is usually opened to answer.
Structured stall so a held edge can be answered, not just named.
A one-line diagnosis when the engine reports trouble — a lost worker, a held path.
ReadonlyStatusSubclasses should emit this event anytime their internal state changes in a way that they'd like to persist.
StaticɵdirStaticɵfacWhether the selected run can be scrubbed — it has settled and has a wall-clock span.
Set or change the dashboard configuration. Changing this property will NOT cause the dashboard to reload. Call Refresh() to do that.
True while a control verb round-trips, so the toolbar cannot double-fire.
Returns either the default Metadata provider or the one specified in the Provider property, if it was specified
The scrub position as a timestamp inside the run's span, or null when showing the present.
Returns either the default RunQuery provider or the one specified in the Provider property, if it was specified
Returns either the default RunView provider or the one specified in the Provider property, if it was specified
The whole run as JSON — the graph row and every step under it.
Nested JSON is parsed rather than left as escaped strings, so Configuration and the payloads
read as structure instead of a single unbroken line. That is the difference between a JSON tab
someone can use and one they copy elsewhere to make readable.
The newest claim event seen for the selected step, if any.
The selected step, as formatted JSON for the viewer.
What the selected step's runner last said it was doing.
Latest verdict per path into/out of the selected step — "why did this branch run".
What-if: how many steps would be cut off if the selected step failed — computed with the engine's OWN blocking algorithm over the loaded rows, so the preview cannot disagree with what the dispatcher would actually do.
The rows after the active filter and search, in the chosen order — what the template renders.
Live or paused — the VS Code bar is how you drive it, including a start-paused debug.
ProtectedGetRead current query params from tab configuration. Use in initDashboard() / ngOnInit() to get initial URL state.
Sub-classes can override this to provide a custom icon class
Get this component's tab ID. Checks ParentTabId input first (set by resource wrappers for child dashboards), then falls back to Data.Configuration.tabId.
Subclasses can override this method to perform any initialization they need. This method only runs once when the dashboard is created.
True when this resource holds in-progress user edits that a silent replacement would destroy. Consulted by the shell before consuming a temporary record tab under the preview-tab model (see TabRequest.TempScope): an editing tab is never replaced — the next open lands in its own tab instead, so the edit survives.
Default false: most resources are read-only surfaces with nothing to lose. Resources that host an editable form override it.
Subclasses should override this method to load their data. This method is called when the dashboard is created and when Refresh() is called.
A callback method that is invoked immediately after Angular has completed initialization of a component's view. It is invoked only once when the view is instantiated.
A callback method that performs custom clean-up, invoked immediately before a directive, pipe, or service instance is destroyed.
A callback method that is invoked immediately after the default change detector has checked the directive's data-bound properties for the first time, and before any of the view or content children have been checked. It is invoked only once when the directive is instantiated.
ProtectedNotifyAsk the host shell to close/dismiss this resource (typically: close the tab). Called by subclasses that hosted a form that emitted a 'dismiss' navigation event — most often, a brand-new record where the user clicked Discard. The record was never saved, the form is empty, and leaving it open serves no purpose. The tab-container listens for this and closes the workspace tab.
ProtectedNotifyCall this to notify the tab system that the resource's display name has changed. The tab container will update the tab title and browser title accordingly.
ProtectedNotifyProtectedNotifyA node was clicked on the canvas — show that step's JSON.
The legend was toggled on the canvas toolbar — remember it.
Driven from the toolbar rather than a button of our own: the canvas already has a legend control in the place people look for one, and adding a second in the header would be two controls for one setting, free to disagree.
Opens the agent run that submitted this graph, when there was one.
ProtectedOnCalled by the framework when query params change from an external source (browser back/forward, deep link navigation). Override in subclasses to react to query param changes.
The new query params from the URL
'popstate' for back/forward, 'deeplink' for external URL entry
Sorts by a column, flipping direction when it is already the active one.
Time columns start descending (newest first) and text columns ascending (A→Z), because that is what each is normally wanted in — a first click that produced the least useful order would just mean everyone clicks twice.
ProtectedonHook for a host that instantiates CHILD resource components: re-home them here.
A host stamps its children with its tab id when it creates them, which is a SNAPSHOT. A cache reattach moves the host to a different tab without recreating anything, so a child left holding the birth tab's id would go on reading and — worse — writing that tab's params from inside a tab it no longer belongs to. That is the same cross-tab corruption this class refuses elsewhere, just arriving by a slower route, so the stamp has to move when the host does.
Default is a no-op: a component with no children has nothing to re-home.
Re-evaluates the stacking rule; the detail pane's width follows the window's.
Re-home this component to a different tab (cache reattach across tab ids). Replaces the reactive param subscription with one bound to the new tab and resets the duplicate-delivery key so the new tab's CURRENT params apply as a fresh mount would — the replay-on-subscribe delivers them immediately.
This method will result in the dashboard being reloaded.
NOTE — this promise does NOT reject when the reload fails. A load error is caught, logged via
LogError and surfaced on the Error output (see runGuardedLoad), and the
promise then RESOLVES. That is deliberate: callers invoke Refresh() fire-and-forget (the
container does), so rejecting here would produce an unhandled rejection rather than reaching
anyone. If you need to know whether a refresh succeeded, subscribe to Error — do not
rely on await Refresh() throwing.
ProtectedRefreshMarks this component's view (and its ancestors) as needing change detection and schedules a tick — the reliable way for a resource component to re-render after updating state from async work (RunView/RunQuery continuations, timers, websocket pushes, RxJS subscriptions).
WHY THIS EXISTS: the Explorer shell hosts resource components dynamically — createComponent()
ApplicationRef.attachView() — because tab content mounts into Golden Layout / cached DOM
containers, not into an Angular template. Since Angular 18's change-detection scheduler
rework (Explorer is on Angular 21), ApplicationRef.tick() only refreshes attached views
that are FLAGGED dirty; a root-level attached view whose component mutates plain fields from
an async continuation is never flagged, so the view silently never re-renders — even though
the component uses default (non-OnPush) change detection (issue #3106).The framework calls this automatically from NotifyLoadStarted() / NotifyLoadComplete(), so the standard load lifecycle re-renders without any subclass action. Call it yourself after any LATER async state change that must reach the DOM outside those signals.
ProtectedrehomeRe-homes a child this component created to tabId.
The ParentTabId stamp is cleared FIRST and deliberately: getTabId() prefers it over the
rebound id, so leaving the old stamp in place would make the child's own RebindTabId a
no-op — it early-returns when getTabId() already matches — and the child would keep
answering with the tab it was born in. Clearing it lets the rebind be the authority, and the
child re-delivers the NEW tab's current params exactly as a fresh mount would.
ProtectedResourceThis method can be used by a container to let the dashboard know that it is being opened/closed. Base class just sets a flag.
The sort indicator for a column header: none, ascending, or descending.
ProtectedUpdatePush query param changes to the URL. Creates a browser history entry. Safe to call during OnQueryParamsChanged — auto-suppressed to prevent loops.
The write is ALWAYS scoped to this component's own tab. A component that cannot identify its tab does not write at all — see the guard below.
The Workflows app's Runs surface — every task graph that has run, whoever started it.
This is why the app came back. A workflow's definition already had a home (the AI Agents form, which is the one editor); its runs did not. They were reachable only by opening the agent that happened to submit them, which fails for the case that matters most — a graph outlives the run that submitted it, so a scheduled or MCP-triggered workflow had no owning conversation to find it from. This lists them by the thing a person actually remembers: what ran, when, and how it ended.
Reads parent Task rows because a parent row is a graph — one row per run, no joining required to count them, and the same unit the promotion picker offers.