# User Configuration Management Module # Manages central user configuration file for workspace switching and preferences # Get path to user config file export def get-user-config-path []: nothing -> string { let user_config_dir = ([$env.HOME "Library" "Application Support" "provisioning"] | path join) if not ($user_config_dir | path exists) { mkdir $user_config_dir } $user_config_dir | path join "user_config.yaml" } # Create default configuration record content def create-default-user-config-content []: nothing -> record { { active_workspace: null, workspaces: [], preferences: { editor: "vim" output_format: "yaml" confirm_delete: true confirm_deploy: true default_log_level: "info" preferred_provider: "local" }, metadata: { created: (date now | format date "%Y-%m-%dT%H:%M:%SZ"), last_updated: (date now | format date "%Y-%m-%dT%H:%M:%SZ"), version: "1.0.0" } } } # Load user configuration export def load-user-config []: nothing -> record { # Build path with explicit string concatenation let config_path_str = $"($env.HOME)/Library/Application Support/provisioning/user_config.yaml" # Check if file exists let file_exists = ($config_path_str | path exists) if not $file_exists { # Create directory if needed let config_dir = $"($env.HOME)/Library/Application Support/provisioning" let dir_exists = ($config_dir | path exists) if not $dir_exists { mkdir $config_dir } # Create and save default config file # Store default content and write via bash let cmd_script = $" mkdir -p \"($config_dir)\" cat > \"($config_path_str)\" <<'YAML' active_workspace: null workspaces: [] preferences: editor: vim output_format: yaml confirm_delete: true confirm_deploy: true default_log_level: info preferred_provider: local metadata: created: null last_updated: null version: \"1.0.0\" YAML " ^bash -c $cmd_script return (create-default-user-config-content) } # Check file type let file_type_result = ($config_path_str | path type) if $file_type_result != "file" { return-default-config "Config path is not a file" } # Load and parse config file let raw_content = (open -r $config_path_str) let config = ($raw_content | from yaml) # Merge with defaults to ensure all fields exist let defaults = (create-default-user-config-content) # Return config with defaults filled in for missing fields return { active_workspace: ($config.active_workspace? | default $defaults.active_workspace) workspaces: ($config.workspaces? | default $defaults.workspaces) preferences: ( ($config.preferences? | default {}) | merge $defaults.preferences ) metadata: ($config.metadata? | default $defaults.metadata) } } # Return default configuration as fallback def return-default-config [reason: string]: nothing -> record { if ($env.PROVISIONING_DEBUG? | default false) { print $"(ansi yellow)⚠ Using default config: ($reason)(ansi reset)" | debug } { active_workspace: null, workspaces: [], preferences: { editor: "vim" output_format: "yaml" confirm_delete: true confirm_deploy: true default_log_level: "info" preferred_provider: "local" }, metadata: { created: (date now | format date "%Y-%m-%dT%H:%M:%SZ"), last_updated: (date now | format date "%Y-%m-%dT%H:%M:%SZ"), version: "1.0.0" } } } # Create default user configuration export def create-default-user-config [] { let config_path = (get-user-config-path) let default_config = { active_workspace: null, workspaces: [], preferences: { editor: "vim", output_format: "yaml", confirm_delete: true, confirm_deploy: true, default_log_level: "info", preferred_provider: "local" }, metadata: { created: (date now | format date "%Y-%m-%dT%H:%M:%SZ"), last_updated: (date now | format date "%Y-%m-%dT%H:%M:%SZ"), version: "1.0.0" } } $default_config | to yaml | save -f $config_path } # Save user configuration export def save-user-config [config: record] { let config_path = (get-user-config-path) # Update last_updated timestamp let updated_config = ( $config | update metadata.last_updated (date now | format date "%Y-%m-%dT%H:%M:%SZ") ) $updated_config | to yaml | save -f $config_path } # Get active workspace name export def get-active-workspace []: nothing -> string { let config = (load-user-config) if ($config.active_workspace == null) { return null } $config.active_workspace } # Get active workspace details export def get-active-workspace-details []: nothing -> record { let config = (load-user-config) if ($config.active_workspace == null) { return null } let workspace_name = $config.active_workspace # Find workspace in list let workspace = ($config.workspaces | where name == $workspace_name | first) if ($workspace | is-empty) { return null } $workspace } # Set active workspace export def set-active-workspace [ workspace_name: string workspace_path: string ] { let config = (load-user-config) # Check if workspace exists in list let workspace_exists = ($config.workspaces | where name == $workspace_name | length) > 0 let updated_config = if $workspace_exists { # Update last_used for existing workspace $config | update workspaces ($config.workspaces | each { |ws| if $ws.name == $workspace_name { $ws | update last_used (date now | format date "%Y-%m-%dT%H:%M:%SZ") } else { $ws } }) | update active_workspace $workspace_name } else { # Add new workspace to list let new_workspace = { name: $workspace_name, path: $workspace_path, last_used: (date now | format date "%Y-%m-%dT%H:%M:%SZ") } $config | update workspaces ($config.workspaces | append $new_workspace) | update active_workspace $workspace_name } save-user-config $updated_config print $"(ansi green)✓(ansi reset) Workspace '($workspace_name)' activated" } # List all known workspaces export def list-workspaces []: nothing -> table { let config = (load-user-config) if ($config.workspaces | is-empty) { return [] } let active_workspace = $config.active_workspace # Build list without piping through each to avoid eval block issues mut workspace_list = [] for ws in $config.workspaces { let is_active = ($ws.name == $active_workspace) let ws_record = { name: $ws.name path: $ws.path active: $is_active last_used: $ws.last_used } $workspace_list = ($workspace_list | append $ws_record) } $workspace_list } # Remove workspace from known list export def remove-workspace [workspace_name: string] { let config = (load-user-config) let updated_workspaces = ($config.workspaces | where name != $workspace_name) let updated_config = $config | update workspaces $updated_workspaces # If removed workspace was active, clear active_workspace let final_config = if $config.active_workspace == $workspace_name { $updated_config | update active_workspace null } else { $updated_config } save-user-config $final_config print $"(ansi green)✓(ansi reset) Workspace '($workspace_name)' removed from known list" } # Add workspace to known list without activating export def register-workspace [ workspace_name: string workspace_path: string ] { let config = (load-user-config) # Check if workspace already exists let workspace_exists = ($config.workspaces | where name == $workspace_name | length) > 0 if $workspace_exists { print $"(ansi yellow)⚠(ansi reset) Workspace '($workspace_name)' already registered" return } let new_workspace = { name: $workspace_name, path: $workspace_path, last_used: (date now | format date "%Y-%m-%dT%H:%M:%SZ") } let updated_config = $config | update workspaces ($config.workspaces | append $new_workspace) save-user-config $updated_config print $"(ansi green)✓(ansi reset) Workspace '($workspace_name)' registered" } # Get user preference export def get-user-preference [preference_key: string]: nothing -> any { let config = (load-user-config) if ($preference_key in $config.preferences) { $config.preferences | get $preference_key } else { null } } # Set user preference export def set-user-preference [ preference_key: string value: any ] { let config = (load-user-config) let updated_config = $config | update preferences { $config.preferences | upsert $preference_key $value } save-user-config $updated_config print $"(ansi green)✓(ansi reset) Preference '($preference_key)' updated to '($value)'" } # Validate workspace exists export def validate-workspace-exists [workspace_name: string]: nothing -> bool { let config = (load-user-config) ($config.workspaces | where name == $workspace_name | length) > 0 } # Get workspace path by name export def get-workspace-path [workspace_name: string]: nothing -> string { let config = (load-user-config) let workspace = ($config.workspaces | where name == $workspace_name | first) if ($workspace | is-empty) { return null } $workspace.path } # Get default infrastructure for workspace export def get-workspace-default-infra [workspace_name: string] { let config = (load-user-config) # Find workspace in config let workspace = ($config.workspaces | where name == $workspace_name | first) if ($workspace | is-empty) { return null } $workspace.default_infra? | default null } # Set default infrastructure for workspace export def set-workspace-default-infra [ workspace_name: string infra_name: string ] { let config = (load-user-config) # Update workspace entry with default_infra mut updated_workspaces = [] for ws in $config.workspaces { if $ws.name == $workspace_name { let updated_ws = { name: $ws.name path: $ws.path last_used: (date now | format date "%Y-%m-%dT%H:%M:%SZ") default_infra: $infra_name } $updated_workspaces = ($updated_workspaces | append $updated_ws) } else { $updated_workspaces = ($updated_workspaces | append $ws) } } # Save updated config let updated_config = { active_workspace: $config.active_workspace workspaces: $updated_workspaces preferences: $config.preferences metadata: $config.metadata } save-user-config $updated_config }