Closes #363 (frontend half of milestone #361). Consumes the `ContainerView.parent: Option<String>` field landing in damocles' backend slice — when present, the container list renders depth-first with sibling-position tree glyphs (├─ / └─ joints + │ continuation columns). When absent (pre-#361 state — every container's `parent` is None) the tree collapses to a flat list with no glyphs and no indent — bit-identical to the legacy render. ## Tree shape - Roots: containers whose `parent` is None OR whose parent name isn't in the current container set (orphan tolerance). - Sibling ordering: alphabetical by name within each level (matches damocles' wire spec at #363#issuecomment-3356). - Cycle safety: any container not reached via the root-walk gets emitted as a root at the end — no agent ever silently disappears from the list when the topology is malformed. - Tree glyphs: ancestor at depth d contributes a │ continuation column when that ancestor has more siblings below; otherwise a 3-space gap. The joint is ├─ for non-last siblings, └─ for the last child. - Depth-0 ancestor column is suppressed: roots already separate visually as top-level rows, no need for a column 0 vertical line. ## DOM / CSS - New `buildAgentTree(containers)` + `treePrefix(node)` helpers in app.js. The render loop walks the tree-ordered list instead of the legacy alphabetical containers array. - Each container row gets `data-depth=N` (only when N > 0) and a `<span class="tree-prefix">…</span>` prepended (absolute-positioned into the row's left margin so the existing flex icon/body layout isn't disrupted). - CSS: per-depth `margin-left` step rules for depths 1-6 (hardcoded rather than typed-attr() because CSS Values 5 is Chromium-only as of 2026). 6 depths cover any reasonable hive topology with headroom; deeper agents render at depth 6 indent without further step — visually clamps gracefully. - `.tree-prefix` rendered with `var(--purple-dim)` so the structural lines read as supporting chrome, not as content. ## Validation - `npm run build` clean. Bundle deltas: dashboard app.js +1.8kb (tree builder + treePrefix + render-loop tweak), dashboard.css +0.4kb (tree-prefix + per-depth indent rules). - The render is a no-op until `ContainerView.parent` is populated — validation in production deferred to once damocles' meta-topology field lands. The pre-#361 path (every parent=None) is exercised by every existing dashboard load. - Forward-compatible with damocles' design pivot at #364 (topology source moved from agent.nix to meta/topology.json). The wire shape on ContainerView is unchanged from the frontend's perspective — the field is just sourced from a different backend store. |
||
|---|---|---|
| .. | ||
| agent | ||
| dashboard | ||
| shared | ||