# reflection/nulib/dashboard.nu — overview, status, health commands. use ./fmt.nu * use ./shared.nu [project-root, load-dimensions, load-gates, adrs-brief] export def run-overview [fmt_resolved: string] { let root = project-root let name = ($root | path basename) let cargo_toml = $"($root)/Cargo.toml" let has_workspace = ($cargo_toml | path exists) and ((open $cargo_toml | get -o workspace | is-not-empty) == true) let crates = if ($cargo_toml | path exists) { let cargo = (open $cargo_toml) let members = ($cargo | get -o workspace.members | default []) if ($members | is-empty) { let pkg_name = ($cargo | get -o package.name | default $name) let deps = ($cargo | get -o dependencies | default {} | columns) let features = ($cargo | get -o features | default {} | columns) [{ name: $pkg_name, deps: ($deps | length), features: $features }] } else { mut result = [] for member in $members { let expanded = (glob $"($root)/($member)/Cargo.toml") for ct in $expanded { let c = (open $ct) let cname = ($c | get -o package.name | default ($ct | path dirname | path basename)) let deps = ($c | get -o dependencies | default {} | columns) let features = ($c | get -o features | default {} | columns) $result = ($result | append { name: $cname, deps: ($deps | length), features: $features }) } } $result } } else { [] } let total_deps = ($crates | get deps | math sum) let systems = [ (if ($"($root)/.ontology/core.ncl" | path exists) { "ontology" } else { null }), (if ((glob $"($root)/adrs/adr-*.ncl" | length) > 0) { "ADRs" } else { null }), (if ($"($root)/reflection" | path exists) { "reflection" } else { null }), (if ($"($root)/.ontology/manifest.ncl" | path exists) { "manifest" } else { null }), (if ($"($root)/.coder" | path exists) { ".coder" } else { null }), (if ($"($root)/.claude/CLAUDE.md" | path exists) { ".claude" } else { null }), (if ($"($root)/justfile" | path exists) { "justfile" } else { null }), ] | compact let report = (sync audit --quick --fmt silent) let health = ($report.health? | default 0.0) let nodes = ($report.nodes? | default {}) let dims = (load-dimensions $root) let reached = ($dims | where reached == true | length) let total_dims = ($dims | length) let brief = adrs-brief let modes_count = ((glob $"($env.ONTOREF_ROOT)/reflection/modes/*.ncl" | length) + (if $root != $env.ONTOREF_ROOT { glob $"($root)/reflection/modes/*.ncl" | length } else { 0 })) let just_count = if ($"($root)/justfiles" | path exists) { glob $"($root)/justfiles/*.just" | length } else { 0 } let overview_data = { project: $name, root: $root, workspace: $has_workspace, crates: ($crates | each { |c| { name: $c.name, deps: $c.deps, features: ($c.features | str join ", ") } }), total_crates: ($crates | length), total_deps: $total_deps, systems: $systems, health: $health, nodes: $nodes, dimensions: { reached: $reached, total: $total_dims }, adrs: $brief, modes: $modes_count, just_modules: $just_count, } match $fmt_resolved { "json" => { print ($overview_data | to json); return }, "yaml" => { print ($overview_data | to yaml); return }, "table" => { print ($overview_data | table --expand); return }, "toml" => { print ($overview_data | to json) return }, _ => {}, } let h_color = if $health >= 90.0 { (ansi green_bold) } else if $health >= 70.0 { (ansi yellow_bold) } else { (ansi red_bold) } let bar_len = (($health / 5.0) | math round | into int) let bar_fill = ("█" | fill -c "█" -w $bar_len) let bar_empty = ("░" | fill -c "░" -w (20 - $bar_len)) print "" fmt-header $name fmt-sep let ws_label = if $has_workspace { $"(ansi cyan)workspace(ansi reset)" } else { $"(ansi dark_gray)single crate(ansi reset)" } print $" ($ws_label) (ansi dark_gray)($systems | str join ' · ')(ansi reset)" print "" print $" ($h_color)($bar_fill)(ansi dark_gray)($bar_empty)(ansi reset) ($h_color)($health)%(ansi reset)" print "" if ($crates | is-not-empty) { let crate_label = $"(ansi white_bold)Crates(ansi reset) ($crates | length) (ansi dark_gray)total deps: ($total_deps)(ansi reset)" print $" ($crate_label)" for c in $crates { let feat_str = if ($c.features | is-not-empty) { $" (ansi dark_gray)features: ($c.features | str join ', ')(ansi reset)" } else { "" } let dep_count = $c.deps print $" (ansi green)($c.name)(ansi reset) (ansi dark_gray)($dep_count) deps(ansi reset)($feat_str)" } print "" } let ok = ($nodes.ok? | default 0) let issues = (($nodes.missing? | default 0) + ($nodes.stale? | default 0) + ($nodes.drift? | default 0)) let issues_str = if $issues > 0 { $"(ansi yellow)($issues)(ansi reset)" } else { $"(ansi dark_gray)0(ansi reset)" } let adr_label = $"($brief.accepted)A/($brief.superseded)S/($brief.proposed)P" let dim_label = if $total_dims > 0 { $"($reached)/($total_dims)" } else { "—" } print $" (ansi white_bold)Nodes(ansi reset) (ansi green)($ok)(ansi reset) ok ($issues_str) issues (ansi white_bold)ADRs(ansi reset) (ansi cyan)($adr_label)(ansi reset) (ansi white_bold)Dims(ansi reset) (ansi cyan)($dim_label)(ansi reset) (ansi white_bold)Modes(ansi reset) ($modes_count) (ansi white_bold)Just(ansi reset) ($just_count)" let active_dims = ($dims | where reached == false) if ($active_dims | is-not-empty) { print "" for d in $active_dims { print $" (ansi dark_gray)($d.id): ($d.current_state) → ($d.desired_state)(ansi reset)" } } print "" } export def run-health [fmt_resolved: string, full: bool] { let report = if $full { sync audit --fmt (if $fmt_resolved == "json" { "json" } else { "silent" }) } else { sync audit --quick --fmt (if $fmt_resolved == "json" { "json" } else { "silent" }) } let health_data = { health: ($report.health? | default 0.0), nodes: ($report.nodes? | default {}), } match $fmt_resolved { "json" => { print ($health_data | to json); return }, "yaml" => { print ($health_data | to yaml); return }, "toml" => { print ($health_data | to toml); return }, "table" => { print ($health_data | table --expand); return }, _ => {}, } let health = $health_data.health let nodes = $health_data.nodes let ok = ($nodes.ok? | default 0) let missing = ($nodes.missing? | default 0) let stale = ($nodes.stale? | default 0) let drift = ($nodes.drift? | default 0) let broken = ($nodes.broken_edges? | default 0) render-health-bar $health print $" (ansi white_bold)Nodes(ansi reset) (ansi green)($ok) OK(ansi reset) (ansi dark_gray)($missing)M ($stale)S ($drift)D ($broken)B(ansi reset)" print "" } export def run-status [fmt_resolved: string] { let root = project-root let name = ($root | path basename) let report = (sync audit --quick --fmt silent) let health = ($report.health? | default 0.0) let dims = (load-dimensions $root) let reached = ($dims | where reached == true | length) let total_dims = ($dims | length) let brief = adrs-brief let adr_label = $"($brief.accepted)A/($brief.superseded)S/($brief.proposed)P" let gates = (load-gates $root) let nodes = ($report.nodes? | default {}) let ok = ($nodes.ok? | default 0) let issues = (($nodes.missing? | default 0) + ($nodes.stale? | default 0) + ($nodes.drift? | default 0)) let recent = (coder log --limit 5) let git_log = do { ^git -C $root log --oneline -3 } | complete let commits = if $git_log.exit_code == 0 { $git_log.stdout | lines | where { $in | is-not-empty } } else { [] } let status_data = { project: $name, root: $root, health: $health, nodes: { ok: $ok, issues: $issues }, dimensions: { reached: $reached, total: $total_dims }, adrs: $brief, gates: ($gates | length), recent_coder: ($recent | each { |r| { title: ($r.title? | default ""), kind: ($r.kind? | default ""), ts: ($r.timestamp? | default "") } }), recent_commits: $commits, } match $fmt_resolved { "json" => { print ($status_data | to json); return }, "yaml" => { print ($status_data | to yaml); return }, "toml" => { print ($status_data | to json) return }, "table" => { print ($status_data | table --expand); return }, _ => {}, } let h_color = if $health >= 90.0 { (ansi green_bold) } else if $health >= 70.0 { (ansi yellow_bold) } else { (ansi red_bold) } let bar_len = (($health / 5.0) | math round | into int) let bar_fill = ("█" | fill -c "█" -w $bar_len) let bar_empty = ("░" | fill -c "░" -w (20 - $bar_len)) print "" fmt-header $"($name) — project status" fmt-sep print $" (ansi white_bold)Health(ansi reset) ($h_color)($bar_fill)(ansi dark_gray)($bar_empty)(ansi reset) ($h_color)($health)%(ansi reset) (ansi dark_gray)\(quick)(ansi reset)" let issues_str = if $issues > 0 { $"(ansi yellow)($issues) issues(ansi reset)" } else { $"(ansi dark_gray)0 issues(ansi reset)" } print $" (ansi white_bold)Nodes(ansi reset) (ansi green)($ok) OK(ansi reset) ($issues_str)" print $" (ansi white_bold)ADRs(ansi reset) (ansi cyan)($adr_label)(ansi reset)" print $" (ansi white_bold)Gates(ansi reset) (ansi cyan)($gates | length) active(ansi reset)" if $total_dims > 0 { print $" (ansi white_bold)State(ansi reset) (ansi green)($reached)(ansi reset)/(ansi cyan)($total_dims)(ansi reset) dimensions reached" let active_dims = ($dims | where reached == false) for d in $active_dims { print $" (ansi dark_gray)($d.id): ($d.current_state) → ($d.desired_state)(ansi reset)" } } if ($commits | is-not-empty) { print "" fmt-section "Recent commits" print "" for c in $commits { print $" (ansi dark_gray)($c)(ansi reset)" } } if ($recent | is-not-empty) { print "" fmt-section "Recent activity (.coder/)" print "" for r in $recent { let kind_color = match ($r.kind? | default "") { "done" => (ansi green), "plan" => (ansi cyan), "review" => (ansi magenta), "audit" => (ansi yellow), _ => (ansi default_dimmed), } let ts = ($r.timestamp? | default "" | str substring 0..9) print $" ($kind_color)($r.kind? | default "?")(ansi reset) (ansi dark_gray)($ts)(ansi reset) ($r.title? | default "")" } } print "" }