function Show-Help { Write-Host "Usage: copilot-debug [--print] [--no-cache] [--save] [--help] " Write-Host "" Write-Host "Options:" Write-Host " --print Print the generated configuration without running it" Write-Host " --no-cache Generate a new configuration without checking the cache." Write-Host " --save Save the configuration to your launch.json." Write-Host " --once Exit after the debug session ends." Write-Host " --help Print this help." } $flagConfig = @{ "--print" = $false "--no-cache" = $false "--help" = $false "--save" = $false "--once" = $false } $cmdArgs = $args while ($cmdArgs.Length -gt 0 -and $flagConfig.ContainsKey($cmdArgs[0])) { $flagConfig[$cmdArgs[0]] = $true $cmdArgs = $cmdArgs[1..$cmdArgs.Length] } if ($cmdArgs.Length -eq 0 -or $flagConfig["--help"]) { Show-Help exit $([int]$flagConfig["--help"]) } $pipeName = "copilot-dbg.$([System.Diagnostics.Process]::GetCurrentProcess().Id)-$([System.Guid]::NewGuid().ToString('N')).sock" $callbackUrl = "vscode://github.copilot-chat" $remoteCommand = "" $listener = [System.IO.Pipes.NamedPipeServerStream]::new($pipeName, [System.IO.Pipes.PipeDirection]::InOut, 1, [System.IO.Pipes.PipeTransmissionMode]::Byte, [System.IO.Pipes.PipeOptions]::Asynchronous) function Watch-Client { param ( [System.IO.Pipes.NamedPipeServerStream]$pipe, [string[]]$cmdArgs ) $reader = [System.IO.StreamReader]::new($pipe) $writer = [System.IO.StreamWriter]::new($pipe) $writer.AutoFlush = $true $request = @{ id = 0 method = "start" params = @{ cwd = (Get-Location).Path args = $cmdArgs forceNew = $flagConfig["--no-cache"] printOnly = $flagConfig["--print"] save = $flagConfig["--save"] once = $flagConfig["--once"] } } $writer.WriteLine((ConvertTo-Json -Compress $request)) while ($true) { $line = $reader.ReadLine() if ($null -eq $line) { break } try { $request = ConvertFrom-Json $line } catch { Write-Error "Failed to parse line: $line" continue } switch ($request.method) { "output" { $category = $request.params.category $output = $request.params.output if ($category -eq 'stderr') { [Console]::Error.Write($output) } elseif ($category -eq 'stdout') { [Console]::Out.Write($output) } elseif ($category -ne 'telemetry' -and $output) { Write-Host $output } $response = @{ id = $request.id result = $null } $writer.WriteLine((ConvertTo-Json -Compress $response)) } "question" { $defaultValue = $request.params.defaultValue $message = $request.params.message if ($request.params.singleKey) { Write-Host $message $answer = [Console]::ReadKey($true).Key.ToString() } else { $answer = Read-Host "$message$(if ($defaultValue) { " [$defaultValue]" } else { '' }) " } $response = @{ id = $request.id result = $answer } $writer.WriteLine((ConvertTo-Json -Compress $response)) } "confirm" { $message = $request.params.message $defaultValue = $request.params.defaultValue $answer = Read-Host "$message [$(if ($defaultValue) { 'Y/n' } else { 'y/N' })] " $response = @{ id = $request.id result = if ($answer -eq '') { $defaultValue } else { $answer.ToLower().Substring(0, 1) -eq 'y' } } $writer.WriteLine((ConvertTo-Json -Compress $response)) } "exit" { $code = $request.params.code $err = $request.params.error if ($err) { Write-Host "$err" } $response = @{ id = $request.id result = $null } $writer.WriteLine((ConvertTo-Json -Compress $response)) Exit $code } } } } if ($remoteCommand -eq "") { Start-Process -FilePath "cmd.exe" -ArgumentList "/c start `"`" `"$callbackUrl/$pipeName`"" -NoNewWindow } else { $fullCommand = "$remoteCommand`"$callbackUrl/$pipeName`"" Start-Process -FilePath "cmd.exe" -ArgumentList "/c $fullCommand" -NoNewWindow } $listener.WaitForConnection() Watch-Client -pipe $listener -cmdArgs $cmdArgs