# Workspace path/root/state resolution — extracted from cli/components.nu (ADR-026 slice 2a-ii). use platform/user/config.nu [get-active-workspace-details list-workspaces] # Resolve the first server hostname present in the state file for a workspace. # Used by --live to find which host to SSH into when the DAG server is unknown. export def comp-state-server [workspace_path: string]: nothing -> string { let st = (state-read $workspace_path) $st.servers | transpose hostname srv | where {|row| ($row.srv.taskservs? | default {} | is-not-empty) } | get 0? | get -o hostname | default "" } # ─── SSH + k0s kubectl live check infrastructure ───────────────────────────── # Resolve workspace root path (exported for use by component.nu dispatcher). export def comp-ws-path [workspace: string]: nothing -> string { comp-resolve-ws-path $workspace } # Auto-detect infra name from workspace root (exported for use by component.nu dispatcher). export def comp-ws-infra [ws_root: string]: nothing -> string { ls ($ws_root | path join "infra") | where type == dir | get name | each {|p| $p | path basename } | where {|n| ($ws_root | path join "infra" $n "settings.ncl" | path exists) } | get 0? | default "" } # Resolve workspace name: explicit --workspace flag or active workspace. # A path counts as a workspace ONLY if it has real workspace content — not just # any directory that happens to be called "infra/". Otherwise $HOME/infra/ # (or similar incidental dirs) hijack the walk-up and shadow the active workspace. def is-workspace-root [path: string]: nothing -> bool { if (($path | path join ".ontology") | path exists) { return true } if (($path | path join "config" "provisioning.ncl") | path exists) { return true } let infra_dir = ($path | path join "infra") if not ($infra_dir | path exists) { return false } # Require at least one infra/*/settings.ncl to treat this as a workspace root. (ls $infra_dir | where type == dir | get name | any { |p| ($p | path join "settings.ncl" | path exists) }) } def find-workspace-root-up [path: string]: nothing -> string { if ($path | is-empty) or $path == "/" { return "" } if (is-workspace-root $path) { return $path } let parent = ($path | path dirname) if $parent == $path { return "" } find-workspace-root-up $parent } # Walk up from $path looking for a sibling `workspaces//` that qualifies as # a workspace root. Returns the full path to the workspace, or "" if not found. def find-named-workspace-up [path: string, name: string]: nothing -> string { if ($path | is-empty) or $path == "/" { return "" } let candidate = ($path | path join "workspaces" $name) if ($candidate | path exists) and (is-workspace-root $candidate) { return $candidate } let parent = ($path | path dirname) if $parent == $path { return "" } find-named-workspace-up $parent $name } # Derive the project root from $env.PROVISIONING (typically # `/provisioning`). Returns "" if PROVISIONING is unset. def project-root-from-prov []: nothing -> string { let prov = ($env.PROVISIONING? | default "") if ($prov | is-empty) { return "" } $prov | path dirname } # Returns the workspace ROOT PATH (not name) — works for both registered and unregistered workspaces. export def comp-resolve-ws-path [workspace: string]: nothing -> string { # 1. Explicit --workspace → resolve to a path. if ($workspace | is-not-empty) { # 1a. Absolute or CWD-relative path that is itself a workspace root. let as_path = ($workspace | path expand) if ($as_path | path exists) and (is-workspace-root $as_path) { return $as_path } # 1b. Registered in the user config. let registered = ( list-workspaces | where { |ws| $ws.name == $workspace } | get -o 0 ) if ($registered | is-not-empty) { return $registered.path } # 1c. Walk up from CWD looking for a sibling `workspaces//`. let from_cwd = (find-named-workspace-up $env.PWD $workspace) if ($from_cwd | is-not-empty) { return $from_cwd } # 1d. Derive from $env.PROVISIONING — the canonical project-root anchor. let project_root = (project-root-from-prov) if ($project_root | is-not-empty) { let from_prov = ($project_root | path join "workspaces" $workspace) if ($from_prov | path exists) and (is-workspace-root $from_prov) { return $from_prov } } error make {msg: $"Workspace '($workspace)' not found in registry, CWD ancestors, or under ($project_root)/workspaces/"} } # 2. Detect from CWD: registered workspace whose path is prefix of CWD let pwd = $env.PWD let from_registry = ( list-workspaces | where { |ws| ($ws.path | is-not-empty) and ($pwd | str starts-with $ws.path) } | sort-by { |ws| ($ws.path | str length) } | last # longest match wins ) if not ($from_registry | is-empty) { return $from_registry.path } # 3. Unregistered: walk up CWD until workspace markers found let ws_root = (find-workspace-root-up $pwd) if ($ws_root | is-not-empty) { return $ws_root } # 4. Fall back to active workspace let details = (get-active-workspace-details) if ($details == null) or ($details.path? | default "" | is-empty) { error make {msg: "No active workspace — pass --workspace or activate one first"} } $details.path }