# Three-tier fallback dispatcher for provisioning-core tools. # # Tier 1 — HTTP daemon (daemon running at PROVISIONING_DAEMON_BIND / 9014) # Tier 2 — provisioning-tool binary (spawned as child process) # Tier 3 — Nushell legacy closure (caller-supplied, kept until G3 passes) # # The legacy closure is a required parameter so removal is a one-line diff per # call site when G3 confirms parity. use platform/clients/daemon.nu [daemon-health, daemon-invoke] use platform/clients/provisioning_tool.nu [ptool-available, ptool-invoke] # Invoke a provisioning-core tool through the 3-tier fallback chain. # Returns the *inner* result (unwrapped from HTTP envelope). # # tool_name : snake_case tool name, e.g. "workspace_list" # params : parameter record # legacy : closure { -> any } — Nushell-native fallback, called with no args # jwt : Bearer token for daemon tier (pass "" in solo mode) export def tool-call [ tool_name: string params: record legacy: closure --jwt: string = "" ]: nothing -> any { if (daemon-health) { let resp = (daemon-invoke $tool_name $params --jwt $jwt) # HTTP envelope: {result: } or {error: , code: } if ($resp | get error? | is-not-empty) { error make {msg: $"daemon ($tool_name): ($resp.error)"} } return ($resp.result? | default $resp) } if (ptool-available) { let resp = (ptool-invoke $tool_name $params) # provisioning-tool returns the inner shape directly if ($resp | get error? | is-not-empty) { error make {msg: $"ptool ($tool_name): ($resp.error)"} } return $resp } # Tier 3 — Nushell legacy do $legacy } # Convenience wrapper: list variant — always returns a list. # Extracts .items from a Listing result, or wraps a bare list. export def tool-list [ tool_name: string params: record legacy: closure --jwt: string = "" ]: nothing -> list { let result = (tool-call $tool_name $params $legacy --jwt $jwt) match ($result | describe) { $t if ($t | str starts-with "list") => { $result } _ => { $result | get items? | default [] } } }