Public/Show-GreenroomSession.ps1
|
# SPDX-License-Identifier: AGPL-3.0-or-later # Copyright (C) 2026 Tyler Vigario <# .SYNOPSIS Reveal a hidden greenroom session's window. .DESCRIPTION Replaces `greenroom attach`. Show- and Hide- are approved verbs and they are also literally what happens: the window exists the whole time and this calls ShowWindow on it, so you get the LIVE session with its full scrollback rather than a resumed copy. "Attach" was always a euphemism for a visibility toggle. The change is confirmed by observation. ShowWindow returns the window's PREVIOUS visibility rather than success, so it reports false on every successful attach; the only trustworthy signal is IsWindowVisible changing. When the target instance runs elevated and this shell does not, the command re-launches itself elevated, because UIPI blocks the window call from a lower integrity level and would otherwise report success while doing nothing. Use -NoElevate to get a refusal instead of a UAC prompt. .PARAMETER Name The instance to reveal. Accepts pipeline input, including Greenroom.Instance objects from Get-GreenroomInstance. .PARAMETER NoElevate Do not escalate when the instance runs elevated. Fails instead, for scripted callers that must not block on a prompt. .EXAMPLE Show-GreenroomSession laptop-admin .EXAMPLE Get-GreenroomInstance | Where-Object { -not $_.Visible } | Show-GreenroomSession Reveal every hidden session. This is the shape the old `list` could not feed, because it emitted formatted text rather than objects. .EXAMPLE Show-GreenroomSession laptop-admin -WhatIf #> function Show-GreenroomSession { [CmdletBinding(SupportsShouldProcess)] [OutputType([void])] param( [Parameter(Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('Instance')] [string]$Name, [switch]$NoElevate ) process { # Resolve first: validation must precede ShouldProcess, or -WhatIf would report # that it would show a window for an instance that is not even running. $target = Resolve-GreenroomTarget -Name $Name -RequireWindow if (-not $target) { return } # ASK BEFORE ESCALATING. Escalation runs this command again in a NEW process, # which starts with its own $WhatIfPreference and $ConfirmPreference -- so # anything decided only over there is decided against defaults, not against what # the operator asked for. Gating here means -WhatIf never escalates at all, and # -Confirm prompts once, in the shell the operator typed in rather than in an # elevated window they may never look at. if (-not $PSCmdlet.ShouldProcess($target.Instance, 'Show-GreenroomSession')) { return } if (-not (Assert-CanActOnInstance -Name $target.Instance -Command 'Show-GreenroomSession' -NoElevate:$NoElevate)) { return } # Success is SILENT: the operator watches a window appear, which beats a line of # text, and a pipeline of ten should not print ten confirmations. -Verbose has it. if (Set-WindowVisible -Handle $target.Window -Show $true) { Write-Verbose "shown '$($target.Instance)' (claude pid $($target.ClaudePid), window $($target.Window))" return } Write-Error -Category InvalidResult -Message (Get-WindowFailureReason -Name $target.Instance) } } |