assists/main.ps1

$Global:FountAssist = @{
    Enabled                   = $true
    AssistCharname            = $null
    FountUsername             = $null
    shellhistory              = [System.Collections.ArrayList]@()
    rejected_commands         = [System.Collections.ArrayList]@()
    chat_scoped_char_memories = @{}
    # 以非0返回值指示信息而非错误的命令
    NonZeroReturnWhiteList    = [System.Collections.ArrayList]@('robocopy')
}

$script:FountAssistInstalled = $false

function Set-FountAssist(
    [ArgumentCompleter({
            param ( $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters )
            $(Get-FountUserList).Where({ $_.StartsWith($WordToComplete) })
        })]
    $FountUsername,
    [ArgumentCompleter({
            param ( $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters )
            $FountUsername = $fakeBoundParameters.FountUsername
            $(Get-FountPartList -Username $FountUsername -PartPath chars).Where({ $_.StartsWith($WordToComplete) })
        })]
    $AssistCharname
) {
    $FountUsername = Get-FountUserList | Where-Object { $_ -eq $FountUsername }
    $AssistCharname = Get-FountPartList -PartPath chars -Username $FountUsername | Where-Object { $_ -eq $AssistCharname }
    if ($AssistCharname) { $Global:FountAssist.AssistCharname = $AssistCharname }
    if ($FountUsername) { $Global:FountAssist.FountUsername = $FountUsername }
    if (!(Test-FountRunning)) {
        Start-Fount background keepalive runas $Global:FountAssist.FountUsername 'shells/preload' "chars/$($Global:FountAssist.AssistCharname)"
    }
    if ($script:FountAssistInstalled) { return }
    if ($EshellUI) { . $PSScriptRoot/esh-assist.ps1 }
    else { . $PSScriptRoot/pwsh-assist.ps1 }
    $script:FountAssistInstalled = $true
}

function Install-FountAssist(
    [ArgumentCompleter({
            param ( $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters )
            $(Get-FountUserList).Where({ $_.StartsWith($WordToComplete) })
        })]
    $FountUsername,
    [ArgumentCompleter({
            param ( $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters )
            $FountUsername = $fakeBoundParameters.FountUsername
            $(Get-FountPartList -Username $FountUsername -PartPath chars).Where({ $_.StartsWith($WordToComplete) })
        })]
    $AssistCharname
) {
    $FountUsername = Get-FountUserList | Where-Object { $_ -eq $FountUsername }
    $AssistCharname = Get-FountPartList -PartPath chars -Username $FountUsername | Where-Object { $_ -eq $AssistCharname }
    if ($AssistCharname) { $Global:FountAssist.AssistCharname = $AssistCharname }
    if ($FountUsername) { $Global:FountAssist.FountUsername = $FountUsername }
    if ($EshellUI) {
        $EshellUI.FountAssist = "$($Global:FountAssist.FountUsername):$($Global:FountAssist.AssistCharname)"
    }
    else {
        $content = Get-Content $PROFILE -ErrorAction Ignore
        $content = $content -split "`n" | Where-Object { $_ -notmatch 'Set-FountAssist' }
        $content += "Set-FountAssist $($Global:FountAssist.FountUsername) $($Global:FountAssist.AssistCharname)"
        $content = $content -join "`n"
        Set-Content $PROFILE $content
    }
    Set-FountAssist
}

# 随辅助请求提交终端宽度,让 fount 在同一次响应中完成渲染。
function Get-FountTerminalWidth {
    try { return [int]$Host.UI.RawUI.WindowSize.Width } catch { return 80 }
}

# 记录 shellassist 的回复:先吸收回复带来的记忆与历史,再补上一条命令的记录,最后显示回复。
function Show-FountAssistReply($Reply, $CommandOutput, $CommandError) {
    if ($Reply.chat_scoped_char_memories) { $Global:FountAssist.chat_scoped_char_memories = $Reply.chat_scoped_char_memories }
    if ($Reply.shellhistory) { $Global:FountAssist.shellhistory = [System.Collections.ArrayList]$Reply.shellhistory }
    if ($Global:FountAssist.last_commaned) {
        $Global:FountAssist.last_commaned.output = $CommandOutput | Out-String -Width 65536
        $Global:FountAssist.last_commaned.error = $CommandError
        $Global:FountAssist.shellhistory.Add($Global:FountAssist.last_commaned) | Out-Null
        $Global:FountAssist.last_commaned = $null
    }
    if (-not ($Reply.content -or $null -ne $Reply.content_for_show)) { return }
    $Global:FountAssist.shellhistory.Add(@{
        name      = $Reply.name
        avatar    = $Reply.avatar
        role      = "char"
        content   = $Reply.content
        extension = $Reply.extension
    }) | Out-Null
    $rendered = [string]$(if ($null -ne $Reply.content_for_show) { $Reply.content_for_show } else { $Reply.content })
    if ($rendered.Length) {
        Write-Host $rendered -NoNewline
        if (-not $rendered.EndsWith("`n")) { Write-Host }
    }
}