# Logging — env-var-only debug flags; no config reads (primitives contract) # Parse PROVISIONING_DEBUG as a numeric level. # Accepts: 0/1/2/3 (int or string), "true" → 1, "false"/"" → 0, bool. # Level semantics: 0=off 1=operational 2=verbose 3=raw/trace export def debug-level []: nothing -> int { let raw = ($env.PROVISIONING_DEBUG? | default 0) let t = ($raw | describe) if ($t | str starts-with "bool") { return (if $raw { 1 } else { 0 }) } if ($t | str starts-with "int") { return (if $raw > 0 { $raw } else { 0 }) } # string path let s = ($raw | into string | str trim) match $s { "true" => 1 "false" => 0 "" => 0 "0" => 0 _ => (try { $s | into int } catch { 0 }) } } # True when PROVISIONING_DEBUG >= 1 (any debug output enabled). export def is-debug-enabled []: nothing -> bool { (debug-level) >= 1 } # True when PROVISIONING_DEBUG >= level. Use to gate verbose/raw output. export def is-debug-level [level: int]: nothing -> bool { (debug-level) >= $level } # Check if debug-check mode is enabled (local task/service simulation). export def is-debug-check-enabled [] { $env.PROVISIONING_DEBUG_CHECK? | default false | into bool } # Check if metadata mode is enabled (detailed error spans). export def is-metadata-enabled [] { $env.PROVISIONING_METADATA? | default false | into bool } export def set-debug-enabled [value: bool] { $env.PROVISIONING_DEBUG = (if $value { 1 } else { 0 }) } export def set-metadata-enabled [value: bool] { $env.PROVISIONING_METADATA = $value } export def log-info [message: string, context?: string] { let ts = (date now | format date '%Y-%m-%d %H:%M:%S') let ctx = if ($context | is-not-empty) { $" [($context)]" } else { "" } print $"ℹ️ ($ts)($ctx) ($message)" } export def log-success [message: string, context?: string] { let ts = (date now | format date '%Y-%m-%d %H:%M:%S') let ctx = if ($context | is-not-empty) { $" [($context)]" } else { "" } print $"✅ ($ts)($ctx) ($message)" } export def log-warning [message: string, context?: string] { let ts = (date now | format date '%Y-%m-%d %H:%M:%S') let ctx = if ($context | is-not-empty) { $" [($context)]" } else { "" } print $"⚠️ ($ts)($ctx) ($message)" } export def log-error [message: string, context?: string, details?: string] { let ts = (date now | format date '%Y-%m-%d %H:%M:%S') let ctx = if ($context | is-not-empty) { $" [($context)]" } else { "" } let det = if ($details | is-not-empty) { $"\n Details: ($details)" } else { "" } print $"🛑 ($ts)($ctx) ($message)($det)" } export def log-debug [ message: string context?: string --level: int = 1 # minimum debug level required to emit this line ] { if (is-debug-level $level) { let ts = (date now | format date '%Y-%m-%d %H:%M:%S') let ctx = if ($context | is-not-empty) { $" [($context)]" } else { "" } print $"🐛 ($ts)($ctx) ($message)" } } export def log-step [step: string, total_steps: int, current_step: int, context?: string] { let ctx = if ($context | is-not-empty) { $" [($context)]" } else { "" } print $"🔄 ($current_step)/($total_steps)($ctx) ($step)" } export def log-progress [message: string, percent: int, context?: string] { let ctx = if ($context | is-not-empty) { $" [($context)]" } else { "" } print $"📊 ($ctx) ($message) ($percent)%" } export def log-section [title: string, context?: string] { let ctx = if ($context | is-not-empty) { $" [($context)]" } else { "" } print "" print $"📋 ($ctx) ($title)" print "─────────────────────────────────────────────────────────────" } export def log-subsection [title: string, context?: string] { let ctx = if ($context | is-not-empty) { $" [($context)]" } else { "" } print $" 📌 ($ctx) ($title)" }