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

nordisk/dwarves

.nornir/jobs-pane.md

dwarves — the Jobs pane (fleet-consistent, agent-aware)

Transfers nornir's job list surface into dwarves, closing the dwarves-parity-spec.md §4b scaffold item "Jobs tab (facett-jobview) — now agent-aware". Mirrors, doesn't fork: the tree/sort/fold/filter/motion live once in the shared facett-jobview component; dwarves only supplies a fixture + the host seam.

What it is

A task-manager-style job/task list — the 4th pane of the dwarves-gui tabbed shell (Forge | Funnel | Claude | Jobs). It renders the forge's work the way a JetBrains-family app shows background jobs: one parent row per pipeline run, one child row per dispatched step, foldable, sortable, kind-filterable, with a live counts header.

Agent-aware (the dwarves-specific bit). dwarves runs forge steps as jera jobs dispatched to worker-group agents (055da45 jera Scheduler wiring, 0aa5920 drain-through-scheduler). Each child step carries the agent and worker group that ran it in its meta — so the Jobs pane is the natural task-manager view of which machine ran what.

Reuse-first (Law #1 / #2) — no twin

Concern Where it lives dwarves' part
tree / sort / fold / kind-filter / counts / motion facett-jobview::JobList (shared) mount it
the rows a dwarves-shaped fixture (jera jobs) JobsView::from_fixture()
the robot/CLI seam host update_json → typed Msg JobsView::update_json

JobsView (dwarves-gui/src/jobs.rs) is a thin host wrapper, exactly like ForgeView wraps facett-brokkrview and ClaudeTab wraps facett-claude: it delegates the whole Facet contract to the inner JobList and adds only the JSON→Msg control vocabulary the shared widget leaves to its host (the widget publishes a rich state_json but takes the no-op update_json default). Pure facett — no backend, no network, no filesystem — so it drives identically native + wasm (browser-safe).

The robot/CLI seam (state_json out / update_json in)

The same channel the tabbed shell, a nornir-robotui scenario, and a thin gRPC client all use:

update_json effect
{"sort":"elapsed"} sort by a column (same key re-sent flips direction)
{"fold":"#1042"} collapse/expand a parent by its stable id
{"select":"#1042.1"} select a row (null clears)
{"kind_filter":"release"} scope to a kind (null = all)

state_json exposes count / parents / children / running / done / failed / selected / sort and the fold-aware jobs[] display tree.

Tests IN CODE (Law #3 — every UI atom robot-tested)

dwarves-gui/src/jobs.rs:

Follow-ups (tracked, not blocking)