private/Open-WtwCmuxRemoteWorkspace.ps1

function Get-WtwCmuxRemoteGoInnerCommand {
    <#
    .SYNOPSIS
        ``wtw --on <host> go [name]`` payload typed into a cmux surface.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)][string] $HostSelector,
        [AllowNull()][AllowEmptyString()][string] $Name,
        [string] $Via
    )

    $tokens = [System.Collections.Generic.List[string]]::new()
    foreach ($part in @('wtw', '--on', $HostSelector)) { $tokens.Add($part) }
    if ($Via) {
        $tokens.Add('--via')
        $tokens.Add($Via)
    }
    $tokens.Add('go')
    if ($Name) { $tokens.Add($Name) }

    $quoted = foreach ($token in $tokens) {
        if ($token -match "[\s'`"]") {
            "'" + $token.Replace("'", "''") + "'"
        } else {
            $token
        }
    }
    return ($quoted -join ' ')
}

function Get-WtwCmuxRemoteGoCommand {
    <#
    .SYNOPSIS
        Local pwsh command that SSHs into a remote wtw target from a cmux surface.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)][string] $HostSelector,
        [AllowNull()][AllowEmptyString()][string] $Name,
        [string] $Via
    )

    $inner = Get-WtwCmuxRemoteGoInnerCommand -HostSelector $HostSelector -Name $Name -Via $Via
    return "pwsh -NoLogo -NoExit -Command `"Clear-Host; $inner`""
}

function Get-WtwCmuxRemoteStatusValue {
    <#
    .SYNOPSIS
        Stable ``wtw-remote:`` description that later tabs can parse back into go args.
    .DESCRIPTION
        Host selector and the original ``wtw go`` name are space-separated so a
        title like ``app/auth`` cannot be mistaken for the name you type.
        Older tabs used ``wtw-remote: at/app/auth`` (title after a slash).
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)][string] $HostSelector,
        [AllowNull()][AllowEmptyString()][string] $Name
    )

    if ($Name) { return "wtw-remote: $HostSelector $Name" }
    return "wtw-remote: $HostSelector"
}

function ConvertFrom-WtwCmuxRemoteStatusValue {
    <#
    .SYNOPSIS
        Parse ``wtw-remote: <host> [<name>]`` or the legacy ``wtw-remote: host/title`` form.
    #>

    [CmdletBinding()]
    param([AllowNull()][AllowEmptyString()][string] $StatusValue)

    if ([string]::IsNullOrWhiteSpace($StatusValue)) { return $null }

    $rest = [string]$StatusValue
    if ($rest.StartsWith('wtw-remote:', [System.StringComparison]::OrdinalIgnoreCase)) {
        $rest = $rest.Substring('wtw-remote:'.Length).Trim()
    } else {
        return $null
    }
    if (-not $rest) { return $null }

    if ($rest -match '^(?<host>\S+)\s+(?<name>.+)$') {
        return [PSCustomObject]@{
            HostSelector = $matches.host
            Name         = $matches.name.Trim()
        }
    }

    if ($rest -match '^(?<host>[^/\s]+)/(?<name>.+)$') {
        return [PSCustomObject]@{
            HostSelector = $matches.host
            Name         = $matches.name.Trim()
        }
    }

    return [PSCustomObject]@{
        HostSelector = $rest
        Name         = ''
    }
}

function Test-WtwCmuxWorkspaceRefMatch {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)] $Workspace,
        [Parameter(Mandatory)][string] $Ref
    )

    foreach ($name in @('ref', 'workspaceRef', 'workspace', 'id', 'uuid', 'workspace_id', 'workspaceId')) {
        $value = Get-WtwCmuxObjectValue -Object $Workspace -Names @($name)
        if ($value -and [string]::Equals("$value", $Ref, [System.StringComparison]::OrdinalIgnoreCase)) {
            return $true
        }
    }

    return $false
}

function Get-WtwCmuxWorkspaceByRef {
    [CmdletBinding()]
    param([Parameter(Mandatory)][string] $WorkspaceRef)

    foreach ($workspace in @(Get-WtwCmuxLiveWorkspaces)) {
        if (Test-WtwCmuxWorkspaceRefMatch -Workspace $workspace -Ref $WorkspaceRef) {
            return $workspace
        }
    }

    return $null
}

function Get-WtwCmuxCurrentWorkspaceObject {
    [CmdletBinding()]
    param()

    $ref = $env:CMUX_WORKSPACE_ID
    if ($ref) {
        $byRef = Get-WtwCmuxWorkspaceByRef -WorkspaceRef $ref
        if ($byRef) { return $byRef }
    }

    $currentResult = Invoke-WtwCmuxCommand -ArgumentList @('current-workspace')
    if ($currentResult.ExitCode -eq 0) {
        $current = ConvertFrom-WtwCmuxCurrentWorkspaceOutput -Output $currentResult.Output
        if ($current) {
            $fromCurrent = $current
            $currentRef = Get-WtwCmuxWorkspaceRef -Workspace $current
            if ($currentRef) {
                $byRef = Get-WtwCmuxWorkspaceByRef -WorkspaceRef $currentRef
                if ($byRef) { return $byRef }
            }
            if (Resolve-WtwCmuxRemoteSessionFromWorkspace -Workspace $fromCurrent) {
                return $fromCurrent
            }
        }
    }

    foreach ($workspace in @(Get-WtwCmuxLiveWorkspaces)) {
        $selected = Get-WtwCmuxObjectValue -Object $workspace -Names @('selected', 'is_selected', 'isSelected')
        if ($selected -eq $true) { return $workspace }
    }

    return $null
}

function Get-WtwCmuxRemoteGoNameFromTitleRest {
    <#
    .SYNOPSIS
        Drop leading glyphs from a host-prefixed title so the go-name remains.
    .DESCRIPTION
        Live titles look like ``🧊AT 🐇 scoring-system-that-works``. After the
        host prefix the worktree emoji is still there; remote ``wtw go`` wants
        ``scoring-system-that-works``.
    #>

    [CmdletBinding()]
    param([AllowNull()][AllowEmptyString()][string] $Rest)

    if ([string]::IsNullOrWhiteSpace($Rest)) { return '' }

    $parts = @($Rest.Trim() -split '\s+' | Where-Object { $_ })
    if ($parts.Count -eq 0) { return '' }

    $index = 0
    while ($index -lt $parts.Count -and $parts[$index] -notmatch '[\p{L}\p{N}]') {
        $index++
    }
    if ($index -ge $parts.Count) { return ($parts[-1]) }
    return ($parts[$index..($parts.Count - 1)] -join ' ')
}

function Resolve-WtwCmuxRemoteSessionFromWorkspace {
    <#
    .SYNOPSIS
        Recover host + go-name from a live cmux workspace when process env is empty.
    .DESCRIPTION
        Older remote tabs were created before ``WTW_REMOTE_*`` was stamped. Those
        still carry a ``wtw-remote:`` description, workspace env, or a title that
        starts with the host prefix (``🧊AT scoring-system-that-works``).
    #>

    [CmdletBinding()]
    param($Workspace)

    if (-not $Workspace) { return $null }

    $envHost = Get-WtwCmuxObjectValue -Object $Workspace -Names @(
        'env.WTW_REMOTE_HOST',
        'environment.WTW_REMOTE_HOST',
        'workspace.env.WTW_REMOTE_HOST'
    )
    if ($envHost) {
        return [PSCustomObject]@{
            HostSelector = [string]$envHost
            Name         = [string](Get-WtwCmuxObjectValue -Object $Workspace -Names @(
                    'env.WTW_REMOTE_NAME',
                    'environment.WTW_REMOTE_NAME',
                    'workspace.env.WTW_REMOTE_NAME'
                ))
        }
    }

    $status = Get-WtwCmuxObjectValue -Object $Workspace -Names @(
        'description', 'desc', 'subtitle', 'sidebar.description', 'status'
    )
    $parsed = ConvertFrom-WtwCmuxRemoteStatusValue -StatusValue $status
    if ($parsed) { return $parsed }

    $title = Get-WtwCmuxWorkspaceName -Workspace $Workspace
    if (-not $title) { return $null }

    foreach ($hostEntry in (Get-WtwHosts)) {
        $prefix = Get-WtwHostTitlePrefix -HostEntry $hostEntry
        if (-not $prefix) { continue }
        if (-not $title.StartsWith($prefix, [System.StringComparison]::OrdinalIgnoreCase)) { continue }

        $rest = Get-WtwCmuxRemoteGoNameFromTitleRest -Rest ($title.Substring($prefix.Length))
        $known = @(@($hostEntry.Name) + @($hostEntry.Aliases) | Where-Object { $_ })
        $name = if (-not $rest -or ($rest -in $known)) { '' } else { $rest }
        return [PSCustomObject]@{
            HostSelector = [string]$hostEntry.Name
            Name         = $name
        }
    }

    return $null
}

function Get-WtwCmuxCurrentRemoteSession {
    <#
    .SYNOPSIS
        Host + go-name for the current cmux workspace when it is a wtw SSH session.
    .DESCRIPTION
        Prefers ``WTW_REMOTE_HOST`` / ``WTW_REMOTE_NAME`` (set on the workspace
        when it was created, inherited by every new tab). Falls back to the
        workspace object (env, ``wtw-remote:`` description, or host-prefixed
        title) so older tabs and Command Palette actions still SSH.
    #>

    [CmdletBinding()]
    param()

    $hostSelector = $env:WTW_REMOTE_HOST
    $name = $env:WTW_REMOTE_NAME

    if (-not $hostSelector) {
        $parsed = Resolve-WtwCmuxRemoteSessionFromWorkspace -Workspace (Get-WtwCmuxCurrentWorkspaceObject)
        if ($parsed) {
            $hostSelector = $parsed.HostSelector
            $name = $parsed.Name
        }
    }

    if (-not $hostSelector) { return $null }

    $hostEntry = Resolve-WtwHost -Name $hostSelector
    if (-not $hostEntry) { return $null }

    return [PSCustomObject]@{
        HostEntry    = $hostEntry
        HostSelector = $hostSelector
        Name         = $name
    }
}

function Get-WtwCmuxRemoteWorkspaceLayoutJson {
    <#
    .SYNOPSIS
        Two-tab layout: 🌴 wtw and a normal remote pwsh, both SSH into the same target.
    #>

    [CmdletBinding()]
    param([Parameter(Mandatory)] $Session)

    $layout = [PSCustomObject]@{
        pane = [PSCustomObject]@{
            surfaces = @(
                [PSCustomObject]@{
                    type    = 'terminal'
                    name    = '🌴 wtw'
                    command = $Session.Command
                    focus   = $true
                }
                [PSCustomObject]@{
                    type    = 'terminal'
                    name    = 'pwsh'
                    command = $Session.Command
                }
            )
        }
    }

    return ($layout | ConvertTo-Json -Compress -Depth 8)
}

function Add-WtwCmuxRemoteWorkspaceEnvArgs {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)][System.Collections.Generic.List[string]] $ArgumentList,
        [Parameter(Mandatory)][string] $HostSelector,
        [AllowNull()][AllowEmptyString()][string] $Name
    )

    [void]$ArgumentList.Add('--env')
    [void]$ArgumentList.Add("WTW_REMOTE_HOST=$HostSelector")
    if ($Name) {
        [void]$ArgumentList.Add('--env')
        [void]$ArgumentList.Add("WTW_REMOTE_NAME=$Name")
    }
}

function Add-WtwCmuxRemoteShellSurface {
    [CmdletBinding()]
    param(
        [string] $WorkspaceRef,
        [Parameter(Mandatory)][string] $Command
    )

    $args = [System.Collections.Generic.List[string]]::new()
    [void]$args.Add('new-surface')
    [void]$args.Add('--type')
    [void]$args.Add('terminal')
    [void]$args.Add('--command')
    [void]$args.Add($Command)
    [void]$args.Add('--focus')
    [void]$args.Add('false')
    if ($WorkspaceRef) {
        [void]$args.Add('--workspace')
        [void]$args.Add($WorkspaceRef)
    }

    Invoke-WtwCmuxCommand -ArgumentList @($args) | Out-Null
}

function Connect-WtwCmuxCurrentRemoteSession {
    <#
    .SYNOPSIS
        SSH into the remote target owned by the current cmux workspace.
    #>

    [CmdletBinding()]
    param()

    $remote = Get-WtwCmuxCurrentRemoteSession
    if (-not $remote) { return $false }

    Connect-WtwRemoteWorktree -HostEntry $remote.HostEntry -Name $remote.Name
    return $true
}

function Resolve-WtwCmuxRemoteSession {
    <#
    .SYNOPSIS
        Title, status, color, and shell command for a cmux remote SSH workspace.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)] $HostEntry,
        [Parameter(Mandatory)][string] $HostSelector,
        [AllowNull()][AllowEmptyString()][string] $Name,
        [string] $Via
    )

    $label = $HostSelector
    $color = $null
    $remotePath = $null
    $repoName = $null
    $repoEmoji = $null

    if ($Name) {
        $remote = Get-WtwRemoteTarget -HostEntry $HostEntry -Name $Name
        if (-not $remote -or -not $remote.Path) {
            return $null
        }
        $remotePath = $remote.Path
        $color = $remote.Color
        $label = if ($remote.PrettyName) { $remote.PrettyName }
        elseif ($remote.Title) { $remote.Title }
        else { $Name }
        $repoName = Get-WtwPropertyValue -Object $remote -Name 'Repo'
        $repoEmoji = Get-WtwPropertyValue -Object $remote -Name 'RepoEmoji'
    }

    $inner = Get-WtwCmuxRemoteGoInnerCommand -HostSelector $HostSelector -Name $Name -Via $Via
    return [PSCustomObject]@{
        PrettyName        = "$(Get-WtwHostTitlePrefix -HostEntry $HostEntry)$label"
        StatusValue       = (Get-WtwCmuxRemoteStatusValue -HostSelector $HostSelector -Name $Name)
        Command           = "pwsh -NoLogo -NoExit -Command `"Clear-Host; $inner`""
        TypedCommand      = "Clear-Host; $inner"
        ShellInitCommand  = "clear; $inner"
        Color             = $color
        RemotePath        = $remotePath
        HostSelector      = $HostSelector
        Name              = $Name
        RepoName          = $repoName
        RepoEmoji         = $repoEmoji
    }
}

function Find-WtwCmuxRemoteWorkspace {
    <#
    .SYNOPSIS
        Find a live cmux workspace for a remote SSH session by title or description.
    .DESCRIPTION
        Remote sessions share a local cwd (usually the home directory), so they
        must not be matched by path the way local worktrees are.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)][string] $PrettyName,
        [string] $StatusValue
    )

    foreach ($workspace in @(Get-WtwCmuxLiveWorkspaces)) {
        $name = Get-WtwCmuxWorkspaceName -Workspace $workspace
        if ($name -and [string]::Equals($name, $PrettyName, [System.StringComparison]::OrdinalIgnoreCase)) {
            return $workspace
        }

        if ($StatusValue) {
            $description = Get-WtwCmuxObjectValue -Object $workspace -Names @(
                'description', 'desc', 'subtitle', 'sidebar.description', 'status'
            )
            if ($description -and [string]::Equals("$description", $StatusValue, [System.StringComparison]::OrdinalIgnoreCase)) {
                return $workspace
            }

            $wanted = ConvertFrom-WtwCmuxRemoteStatusValue -StatusValue $StatusValue
            $have = ConvertFrom-WtwCmuxRemoteStatusValue -StatusValue $description
            if (
                $wanted -and $have -and
                [string]::Equals($wanted.HostSelector, $have.HostSelector, [System.StringComparison]::OrdinalIgnoreCase) -and
                [string]::Equals("$($wanted.Name)", "$($have.Name)", [System.StringComparison]::OrdinalIgnoreCase)
            ) {
                return $workspace
            }
        }
    }

    return $null
}

function Open-WtwCmuxRemoteWorkspace {
    <#
    .SYNOPSIS
        Open a local cmux workspace whose terminal is an SSH session to a wtw host.
    .DESCRIPTION
        The cmux window stays on this machine. The workspace opens two tabs —
        🌴 wtw and a normal remote pwsh — both running
        ``wtw --on <host> go [name]``. Extra 🌴 wtw / pwsh Command Palette
        actions in that workspace SSH to the same target (they inherit
        ``WTW_REMOTE_HOST`` / ``WTW_REMOTE_NAME``). Omit the target name to
        land in the remote home directory.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)] $HostEntry,
        [Parameter(Mandatory)][string] $HostSelector,
        [AllowNull()][AllowEmptyString()][string] $Name,
        [string] $Via,
        [switch] $PrintOnly
    )

    if ($Name) {
        Write-WtwHost " Resolving '$Name' on $($HostEntry.Name)..." -ForegroundColor DarkGray
    }

    $session = Resolve-WtwCmuxRemoteSession `
        -HostEntry $HostEntry `
        -HostSelector $HostSelector `
        -Name $Name `
        -Via $Via

    if (-not $session) {
        $numericHint = Get-WtwNumericNameHint -Name $Name
        if ($numericHint) { Write-WtwHost " $numericHint" -ForegroundColor Yellow }
        Show-WtwRemoteTargetSuggestions -HostEntry $HostEntry -Name $Name
        Write-Error "Could not resolve '$Name' on $($HostEntry.Name)."
        return
    }

    $localCwd = if ($HOME -and (Test-Path $HOME)) { [System.IO.Path]::GetFullPath($HOME) } else { (Get-Location).Path }

    if ($PrintOnly) {
        $layout = Get-WtwCmuxRemoteWorkspaceLayoutJson -Session $session
        Write-WtwHost " cmux new-workspace --name $($session.PrettyName) --cwd $localCwd --description $($session.StatusValue) --layout $layout" -ForegroundColor White
        return
    }

    if (-not (Test-WtwCmuxPresent)) {
        Write-Error "cmux is not installed or not on PATH. Install cmux or symlink '/Applications/cmux.app/Contents/Resources/bin/cmux'."
        return
    }

    # Machine-level project (sidebar / Command Palette), independent of this
    # invocation's optional worktree name. Opening `wtw --on at cmux auth`
    # still creates the live auth tab; the host project stays `wtw --on at go`.
    Register-WtwCmuxRemoteProject -HostEntry $HostEntry -HostSelector $HostSelector | Out-Null

    $groupSpec = Get-WtwCmuxRemoteWorkspaceGroupSpec -HostEntry $HostEntry -Session $session
    $group = Ensure-WtwCmuxWorkspaceGroup -Spec $groupSpec

    $existing = Find-WtwCmuxRemoteWorkspace -PrettyName $session.PrettyName -StatusValue $session.StatusValue
    if ($existing) {
        $workspaceRef = Get-WtwCmuxWorkspaceRef -Workspace $existing
        if ($workspaceRef) {
            $selectResult = Invoke-WtwCmuxCommand -ArgumentList @('select-workspace', '--workspace', "$workspaceRef")
            if ($selectResult.ExitCode -eq 0) {
                Set-WtwCmuxWorkspaceMetadata `
                    -WorkspaceRef "$workspaceRef" `
                    -PrettyName $session.PrettyName `
                    -Color $session.Color `
                    -StatusValue $session.StatusValue `
                    -CurrentName (Get-WtwCmuxWorkspaceName -Workspace $existing) `
                    -CurrentColor (Get-WtwCmuxObjectValue -Object $existing -Names @('color', 'workspace.color', 'sidebar.color', 'sidebarState.color'))
                Add-WtwCmuxWorkspaceToGroup -Group $group -WorkspaceRef "$workspaceRef"
                Write-WtwHost " cmux: selected remote workspace '$($session.PrettyName)' ($($groupSpec.Name))" -ForegroundColor Green
                return
            }
        }
    }

    $layout = Get-WtwCmuxRemoteWorkspaceLayoutJson -Session $session
    $cmuxArgs = [System.Collections.Generic.List[string]]::new()
    foreach ($part in @(
            'new-workspace',
            '--name', $session.PrettyName,
            '--cwd', $localCwd,
            '--layout', $layout,
            '--focus', 'true',
            '--description', $session.StatusValue
        )) {
        [void]$cmuxArgs.Add($part)
    }
    foreach ($part in @(Get-WtwCmuxNewWorkspaceGroupArgs -Group $group)) {
        [void]$cmuxArgs.Add($part)
    }
    Add-WtwCmuxRemoteWorkspaceEnvArgs -ArgumentList $cmuxArgs -HostSelector $HostSelector -Name $Name

    $createResult = Invoke-WtwCmuxCommand -ArgumentList @($cmuxArgs)
    $usedSingleCommand = $false
    if ($createResult.ExitCode -ne 0) {
        $fallbackArgs = [System.Collections.Generic.List[string]]::new()
        foreach ($part in @(
                'new-workspace',
                '--name', $session.PrettyName,
                '--cwd', $localCwd,
                '--command', $session.Command,
                '--focus', 'true',
                '--description', $session.StatusValue
            )) {
            [void]$fallbackArgs.Add($part)
        }
        foreach ($part in @(Get-WtwCmuxNewWorkspaceGroupArgs -Group $group)) {
            [void]$fallbackArgs.Add($part)
        }
        Add-WtwCmuxRemoteWorkspaceEnvArgs -ArgumentList $fallbackArgs -HostSelector $HostSelector -Name $Name
        $createResult = Invoke-WtwCmuxCommand -ArgumentList @($fallbackArgs)
        $usedSingleCommand = $true
    }
    if ($createResult.ExitCode -ne 0 -and $group) {
        $plainArgs = [System.Collections.Generic.List[string]]::new()
        foreach ($part in $cmuxArgs) {
            if ($part -in @('--group', $group.Ref)) { continue }
            [void]$plainArgs.Add($part)
        }
        $createResult = Invoke-WtwCmuxCommand -ArgumentList @($plainArgs)
    }
    if ($createResult.ExitCode -ne 0) {
        if (Open-WtwCmuxAppleScriptWorkspace -ProjectPath $localCwd -PrettyName $session.PrettyName -InitCommand $session.ShellInitCommand -MatchByNameOnly) {
            if (Test-WtwCmuxSocketPermissionDenied -Output $createResult.Output) {
                Write-WtwHost " cmux: opened remote session via AppleScript fallback (socket access denied)." -ForegroundColor Green
            } else {
                Write-WtwHost " cmux: opened remote session via AppleScript fallback." -ForegroundColor Green
            }
            return
        }

        Write-Error "cmux remote workspace create failed: $($createResult.Output)"
        return
    }

    $currentResult = Invoke-WtwCmuxCommand -ArgumentList @('current-workspace')
    $workspaceRef = $null
    if ($currentResult.ExitCode -eq 0) {
        $currentWorkspace = ConvertFrom-WtwCmuxCurrentWorkspaceOutput -Output $currentResult.Output
        if ($currentWorkspace) {
            $workspaceRef = Get-WtwCmuxWorkspaceRef -Workspace $currentWorkspace
        }
    }
    if (-not $workspaceRef) {
        $created = Find-WtwCmuxRemoteWorkspace -PrettyName $session.PrettyName -StatusValue $session.StatusValue
        if ($created) {
            $workspaceRef = Get-WtwCmuxWorkspaceRef -Workspace $created
        }
    }

    Set-WtwCmuxWorkspaceMetadata `
        -WorkspaceRef "$workspaceRef" `
        -PrettyName $session.PrettyName `
        -Color $session.Color `
        -StatusValue $session.StatusValue `
        -CurrentName $session.PrettyName `
        -CurrentColor $null

    if ($usedSingleCommand) {
        Add-WtwCmuxRemoteShellSurface -WorkspaceRef $workspaceRef -Command $session.Command
    }

    Add-WtwCmuxWorkspaceToGroup -Group $group -WorkspaceRef "$workspaceRef"

    $where = if ($session.RemotePath) { $session.RemotePath } else { $HostEntry.Name }
    Write-WtwHost " cmux: remote session '$($session.PrettyName)' → $where ($($groupSpec.Name))" -ForegroundColor Green
}