Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/nornir

src/viz/dwarves_tab.rs

//! ⚒ The **Dwarves tab** — nornir's build runner.
//!
//! The **Build runner** ([`super::build_tab::BuildTabState`]) reflects a repo's
//! `BuildSurface` into choosable target rows (binary × features × profile ×
//! target), runs `nornir build --attest --seal`, and TEST-BOOTs the result as a
//! job — a *single-target* builder over nornir's own build-thing surface.
//!
//! ## The ⚒ Forge pane that used to live here
//!
//! This tab once carried a second pane, `BrokkrTabState`, which ran **dwarves'
//! brokkr pipeline engine in-process** — the results/tree/DAG/agents/log facets
//! over a hard-coded demo `brokkr.toml`, stepped by `dwarves::runner::DemoRunner`.
//!
//! It was a twin. dwarves-demo's own **Pipeline** tab is that pane, driven by the
//! REAL engine and rendered on the shared `facett-pipeline` viewer — the forge's UI,
//! hosted by the forge. And it was one of the call sites forcing nornir's `dwarves`
//! path-dep, which made `nornir → dwarves → nornir` a cargo dependency cycle and is
//! why the forge could never compile nornir in.
//!
//! Under PRE-PROMPT §L5a a pane may be hosted by either repo but its LOGIC lives
//! with the owner, and running a CI pipeline is as constructive as it gets. So the
//! demo pane is gone (move = delete); the forge UI is dwarves-demo's, and a *running*
//! forge is reachable at `dwarves-server` on `:7900`.

use std::path::PathBuf;

use eframe::egui;

use super::build_tab::BuildTabState;
use super::facett_theme::Theme;

/// ⚒ The Dwarves tab: nornir's single-target build runner.
pub struct DwarvesTabState {
    /// 🔨 the single-target build runner. `pub(crate)` so the app can inject a
    /// test runner + read its `state_json` slice at the top level.
    pub(crate) build: BuildTabState,
}

impl DwarvesTabState {
    /// The tab seeded with the build runner over `workspace_root`.
    pub fn new(workspace_root: PathBuf) -> Self {
        Self {
            build: BuildTabState::new(workspace_root),
        }
    }

    /// Push the active palette into the pane.
    pub fn set_palette(&mut self, p: Theme) {
        self.build.set_palette(p);
    }

    /// The observable state a headless test / operator reads. `pane` stays in the
    /// slice (always `"Build"`) so a matrix row that asserts on it keeps resolving.
    pub fn state_json(&self) -> serde_json::Value {
        serde_json::json!({
            "surface": "dwarves",
            "pane": "Build",
            "build": self.build.state_json(),
        })
    }

    /// Draw the tab.
    pub fn draw(&mut self, ui: &mut egui::Ui) {
        ui.push_id("Dwarves", |ui| {
            ui.heading("⚒ Dwarves — build runner");
            ui.separator();
            self.build.draw(ui);
        });
    }
}