# reflection/nulib/shared.nu — Shared utilities used across multiple nulib modules. use ../modules/store.nu [daemon-export-safe] # Collect mode files from both ONTOREF_ROOT and project-local reflection/modes/. export def all-mode-files []: nothing -> list { let root_modes = (glob $"($env.ONTOREF_ROOT)/reflection/modes/*.ncl") let project_modes = if ($env.ONTOREF_PROJECT_ROOT? | is-not-empty) and ($env.ONTOREF_PROJECT_ROOT? != $env.ONTOREF_ROOT) { glob $"($env.ONTOREF_PROJECT_ROOT)/reflection/modes/*.ncl" } else { [] } $root_modes | append $project_modes | uniq } # Quick ADR status counts (accepted/superseded/proposed). export def adrs-brief []: nothing -> record { let root = ($env.ONTOREF_PROJECT_ROOT? | default $env.ONTOREF_ROOT) let statuses = ( glob $"($root)/adrs/adr-*.ncl" | each { |f| let data = (daemon-export-safe $f) if $data != null { $data.status? | default null } else { null } } | compact ) { accepted: ($statuses | where $it == "Accepted" | length), superseded: ($statuses | where $it == "Superseded" | length), proposed: ($statuses | where $it == "Proposed" | length), } } # Resolve project root: ONTOREF_PROJECT_ROOT if set and different, else ONTOREF_ROOT. export def project-root []: nothing -> string { let pr = ($env.ONTOREF_PROJECT_ROOT? | default "") if ($pr | is-not-empty) and ($pr != $env.ONTOREF_ROOT) { $pr } else { $env.ONTOREF_ROOT } } # Build NICKEL_IMPORT_PATH for a project root. export def nickel-import-path [root: string]: nothing -> string { let entries = [ $"($root)/.ontology" $"($root)/adrs" $"($root)/.ontoref/ontology/schemas" $"($root)/.ontoref/adrs" $"($root)/.onref" $root $"($env.ONTOREF_ROOT)/ontology" $"($env.ONTOREF_ROOT)/ontology/schemas" $"($env.ONTOREF_ROOT)/adrs" $env.ONTOREF_ROOT ] let valid = ($entries | where { |p| $p | path exists } | uniq) let existing = ($env.NICKEL_IMPORT_PATH? | default "") if ($existing | is-not-empty) { ($valid | append $existing) | str join ":" } else { $valid | str join ":" } } # Read state.ncl dimensions from a project root. export def load-dimensions [root: string]: nothing -> list { let state_file = $"($root)/.ontology/state.ncl" if not ($state_file | path exists) { return [] } let ip = (nickel-import-path $root) let state = (daemon-export-safe $state_file --import-path $ip) if $state == null { return [] } $state.dimensions? | default [] | each { |d| { id: $d.id, current_state: $d.current_state, desired_state: $d.desired_state, reached: ($d.current_state == $d.desired_state), }} } # Read active gates from a project root. export def load-gates [root: string]: nothing -> list { let gate_file = $"($root)/.ontology/gate.ncl" if not ($gate_file | path exists) { return [] } let ip = (nickel-import-path $root) let gate = (daemon-export-safe $gate_file --import-path $ip) if $gate == null { return [] } $gate.membranes? | default [] | where { |m| ($m.active? | default false) == true } }