src/Execution.ps1

function Invoke-QuietCli {
    [CmdletBinding(DefaultParameterSetName='Document')]param(
        [Parameter(Mandatory)][string]$FilePath,[string[]]$ArgumentList=@(),[string]$WorkingDirectory=(Get-Location).Path,
        [Parameter(Mandatory,ParameterSetName='Document')][scriptblock]$Parse,
        [Parameter(Mandatory,ParameterSetName='Streaming')][scriptblock]$OnOutput,
        [Parameter(Mandatory,ParameterSetName='Batch')][scriptblock]$OnBatch,
        [object]$State,[scriptblock]$Complete,[scriptblock]$Projection,
        [char]$RecordDelimiter=[char]10,[char]$StdErrDelimiter=[char]10,[string]$Encoding='utf-8',
        [Collections.IDictionary]$Environment=@{},[AllowNull()][string]$InputText,
        [int[]]$SuccessExitCodes=@(0),[int]$TimeoutSeconds=600,
        [ValidateRange(1,10485760)][int]$MaxRecordCharacters=65536,[long]$MaxCaptureBytes=-1,
        [int]$MaxCaptureCharacters=0,[int]$MaxOutputBytes=4096,
        [Threading.CancellationToken]$CancellationToken=[Threading.CancellationToken]::None,[string]$CancellationFile,
        [string]$Summary='Native command processed.',[string]$ObservedVersion,[switch]$Record)
        if($script:QuietBuildingContract){throw 'Factories construct contracts; put native calls in Execute or execute an explicit contract.'}
    $nativeWatch=[Diagnostics.Stopwatch]::StartNew()
    if($script:QuietReplay){
        if(!$script:QuietReplayContext -or !$script:QuietReplayContext.Count){throw 'Native execution is prohibited while replaying a record.'}
        $source=$script:QuietReplayContext.Dequeue()
        if($source.Request.FilePath -cne $FilePath -or (ConvertTo-Json -InputObject @($source.Request.ArgumentList) -Compress) -cne (ConvertTo-Json -InputObject @($ArgumentList) -Compress)){throw 'Replay invocation differs from the recorded command and argument vector.'}
        $options=@{Id='replay.step';FilePath=$FilePath;ArgumentList=$ArgumentList;State=$State;Complete=$Complete;Projection=$Projection;SuccessExitCodes=$SuccessExitCodes}
        if($Parse){$options.Parse=$Parse}elseif($OnBatch){$options.OnBatch=$OnBatch}else{$options.OnOutput=$OnOutput}
        return Invoke-QuietCapturedCall $source (New-QuietContract @options)
    }
    $settings=Get-QuietConfiguration
    if(!$PSBoundParameters.ContainsKey('TimeoutSeconds')){$TimeoutSeconds=$settings.TimeoutSeconds}
    if($MaxCaptureBytes -lt 0){$MaxCaptureBytes=$settings.MaxCaptureBytes}
    if($MaxCaptureCharacters -gt 0){$MaxCaptureBytes=[long]$MaxCaptureCharacters}
    if($TimeoutSeconds -lt 1 -or $MaxCaptureBytes -lt 0){throw 'Invalid execution limits.'}
    $directory=$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($WorkingDirectory)
    if($CancellationFile){$CancellationFile=[IO.Path]::GetFullPath($CancellationFile,$directory)}
    $inputValue=if($PSBoundParameters.ContainsKey('InputText')){$InputText}else{$null}
    $session=$null;$capture=$null;$parseError=$null;$finalizerError=$null;$data=$null
    $emissions=[Collections.Generic.List[object]]::new();$callbackWatch=[Diagnostics.Stopwatch]::new()
    try{
        $session=[QuietCliStack.V2.NativeSession]::new($FilePath,$ArgumentList,$directory,$Environment,$inputValue,$Encoding,
            $TimeoutSeconds,$MaxRecordCharacters,$MaxCaptureBytes,$RecordDelimiter,$StdErrDelimiter,$CancellationToken,$CancellationFile)
        while($null -ne ($frame=$session.Next())){
            if($PSCmdlet.ParameterSetName -ne 'Document' -and !$parseError){
                $callbackWatch.Start()
                try{
                    $items=if($OnBatch){@(Invoke-QuietCallback $OnBatch @((,@($frame)),$State))}else{@(Invoke-QuietCallback $OnOutput @($frame,$State))}
                    foreach($item in $items){$emissions.Add($item)}
                }catch{$parseError=@{Code='ParserFailed';Phase='Analyze';Message=$_.Exception.Message}}
                finally{$callbackWatch.Stop()}
            }
        }
        $capture=$session.Result
        if($PSCmdlet.ParameterSetName -eq 'Document'){
            if(!$capture.CaptureComplete){$parseError=@{Code='CaptureLimit';Phase='Analyze';Message='Document parsing requires a complete capture.'}}
            elseif(!$capture.StartError){
                try{$items=@(Invoke-QuietCallback $Parse @($capture));$data=if($items.Count -eq 1){$items[0]}elseif($items.Count){,$items}else{$null}}
                catch{$parseError=@{Code='ParserFailed';Phase='Analyze';Message=$_.Exception.Message}}
            }
        }elseif($Complete){
            try{$items=@(Invoke-QuietCallback $Complete @($State,$capture));$data=if($items.Count -eq 1){$items[0]}elseif($items.Count){,$items}else{$null}}
            catch{$finalizerError=@{Code='FinalizerFailed';Phase='Complete';Message=$_.Exception.Message}}
        }elseif($emissions.Count){$data=if($emissions.Count -eq 1){$emissions[0]}else{,$emissions.ToArray()}}
    }catch{$parseError=@{Code='ExecutionFailed';Phase='Execute';Message=$_.Exception.GetBaseException().Message}}
    finally{if($session){$session.Dispose()}}
    $outcome='Success';$errorInfo=$null
    if($capture -and $capture.Cancelled){$outcome='Cancelled';$errorInfo=@{Code='Cancelled';Phase='Execute'}}
    elseif($capture -and $capture.TimedOut){$outcome='Timeout';$errorInfo=@{Code='Timeout';Phase='Execute'}}
    elseif($capture -and $capture.StartError){$outcome='Failed';$errorInfo=@{Code='NativeStartOrReadFailed';Phase='Execute';Message=$capture.StartError}}
    elseif($capture -and $capture.ExitCode -notin $SuccessExitCodes){$outcome='Failed';$errorInfo=@{Code='NativeFailed';Phase='Execute'}}
    elseif($capture -and $capture.Lossy){$outcome='Failed';$errorInfo=@{Code='DecodeFailed';Phase='Decode';Message='Invalid bytes were replaced while decoding.'}}
    elseif($parseError){$outcome='Failed';$errorInfo=$parseError}
    elseif($capture -and $capture.LostRecords){$outcome='Failed';$errorInfo=@{Code='RecordLimit';Phase='Analyze'}}
    elseif($finalizerError){$outcome='Failed';$errorInfo=$finalizerError}
    $sourceComplete=[bool]($capture -and $capture.SourceComplete)
    $analysisComplete=$sourceComplete -and !$parseError -and !$finalizerError -and !$capture.LostRecords -and !$capture.Lossy
    $execution=@{ExitCode=$(if($capture){$capture.ExitCode}else{$null});ElapsedMs=$(if($capture){$capture.ElapsedMs}else{$null})
        AnalysisComplete=$analysisComplete;SourceComplete=$sourceComplete
        StdoutBytes=$(if($capture){$capture.StdoutBytes}else{0L});StderrBytes=$(if($capture){$capture.StderrBytes}else{0L})
        LostRecords=$(if($capture){$capture.LostRecords}else{0L});FinalizerError=$finalizerError;ParserError=$parseError
        Timing=@{SetupMs=$(if($capture){$capture.SetupMs}else{$null});ProcessMs=$(if($capture){$capture.ProcessMs}else{$null});CallbackMs=$callbackWatch.Elapsed.TotalMilliseconds;BackpressureMs=$(if($capture){$capture.BackpressureMs}else{$null})}}
    $result=New-QuietResult -Summary $Summary -Outcome $outcome -Data $data -Execution $execution -ErrorInfo $errorInfo -Projection $Projection
    $result.Capture=$capture;$result.Completeness.Source=$sourceComplete;$result.Completeness.Analysis=$analysisComplete
    $result.Completeness.Capture=[bool]($capture -and $capture.CaptureComplete)
    if($capture -and $capture.LostRecords){$result.Truncation.Applied=$true;$result.Truncation.Reasons=@('RecordLimit');$result.Truncation.Omitted=$capture.LostRecords}
    $source=@{Id=$result.Internal.Id;Command=(Get-QuietExecutableName $FilePath);Request=@{FilePath=$FilePath;ArgumentList=@($ArgumentList);WorkingDirectory=$directory}
        Capture=$capture;SourceComplete=$sourceComplete;AnalysisComplete=$analysisComplete;Outcome=$outcome
        ExitCode=$execution.ExitCode;Bytes=([long]$execution.StdoutBytes+[long]$execution.StderrBytes);Timing=$execution.Timing
        ElapsedMs=$nativeWatch.Elapsed.TotalMilliseconds;RecordDelimiter=[int]$RecordDelimiter;StdErrDelimiter=[int]$StdErrDelimiter;Encoding=$Encoding
        Contract=$null;SourcePaths=@();Documentation=@();ObservedVersion=$ObservedVersion;Delivered=[Collections.Generic.HashSet[string]]::new()}
    $result.Internal.Sources[$source.Id]=$source
    Save-QuietInvocation $source
    $wanted=$Record -or @($script:QuietTasks|Where-Object Record).Count -gt 0
    if($wanted){Save-QuietRecord $result -Explicit|Out-Null}
    $result
}