github / github/copilot-sdk

Introduce TUI server mode so ask_user can be intercepted without replacing entire TUI

Offen
#1,134 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
enhancement
Vorherrschende Sprache
Java
Sterne
10.5k
Forks
1.5k
Ø Merge
1 T. 14 Std.
Gemergte PRs (30 T.)
129

Beschreibung

According to copilot analysis, there's a `--ui-server` switch in the sources of the SDK that could be used to preserve the full copilot TUI while intercepting events via TCP.

Unknowns to raise with the CLI team

1. CLI flag name — SDK source comments say --ui-server; copilot --help shows --acp. Which flag actually starts "TUI+server" mode? Are they the same thing?

2. ask_user routing — This is the key question. When the CLI is in TUI+server mode AND an SDK client is connected via TCP, does the CLI:

a. Route `userInput.request` to the SDK client (over TCP), letting the SDK handler intercept it? ← what you need
b. Handle `ask_user` in the TUI itself and not send userInput.request to the SDK at all?

If it's currently (b), a small CLI-side change would be needed: when an SDK client is connected and has registered a userInput.request handler, prefer routing to the client.

3. Port announcement — When running without --headless, does the CLI still write "Listening on port N" to stdout (now the terminal)? That's fine to leave in — users won't mind seeing
it once on startup — but the SDK approach above bypasses it entirely by requiring an explicit port.

Proposal: Add TuiServerMode to CopilotClientOptions. Launches the CLI with its full terminal UX intact (streaming, colors, tool indicators, etc.) while the SDK connects via TCP to intercept only specific callbacks — specifically OnUserInputRequest — replacing the CLI's own prompt with a custom UX (e.g. a native popup). All stdout/stderr flow through to the user's terminal unchanged.

The SDK diff is ~30 lines. The only thing that may require CLI cooperation is whether userInput.request is already routed to TCP clients in TUI+server mode.

SDK changes needed (dotnet/src/)

1. Types.cs — new option on CopilotClientOptions
```csharp
///
/// When true, launches the CLI in TUI+server mode (--ui-server) instead of
/// headless mode. The CLI renders its own terminal UX while the SDK connects
/// via TCP to intercept callbacks such as .
/// Requires to be set (stdout is not available for port discovery).
/// Mutually exclusive with .
///
public bool TuiServerMode { get; set; }
```

2. Client.cs — StartCliServerAsync, args
```csharp
- args.AddRange(["--headless", "--no-auto-update", "--log-level", options.LogLevel]);
+ if (options.TuiServerMode)
+ args.Add("--ui-server"); // ← CLI flag name TBD (see unknowns)
+ else
+ args.Add("--headless");
+ args.AddRange(["--no-auto-update", "--log-level", options.LogLevel]);
```

3. Client.cs — StartCliServerAsync, ProcessStartInfo
```csharp
var startInfo = new ProcessStartInfo
{
...
- RedirectStandardInput = options.UseStdio,
- RedirectStandardOutput = true,
- RedirectStandardError = true,
- CreateNoWindow = true,
+ RedirectStandardInput = options.UseStdio && !options.TuiServerMode,
+ RedirectStandardOutput = !options.TuiServerMode,
+ RedirectStandardError = !options.TuiServerMode,
+ CreateNoWindow = !options.TuiServerMode,
};
```

4. Client.cs — StartCliServerAsync, port discovery
```csharp
- var detectedLocalhostTcpPort = (int?)null;
- if (!options.UseStdio)
- {
- // reads port announcement from stdout...
- }
+ var detectedLocalhostTcpPort = options.TuiServerMode
+ ? options.Port // must be pre-configured; stdout is the user's terminal
+ : await DetectPortFromStdoutAsync(options, cliProcess, cancellationToken);
````
(extract the existing port-reading loop into DetectPortFromStdoutAsync)

5. Client.cs — validation in constructor
```csharp
+ if (options.TuiServerMode && options.UseStdio)
+ throw new ArgumentException("TuiServerMode is mutually exclusive with UseStdio");
+ if (options.TuiServerMode && options.Port <= 0)
+ throw new ArgumentException("TuiServerMode requires Port to be set explicitly");
```

The stderr capture loop (lines ~1247–1265) is also skipped when TuiServerMode — otherwise it would try to read from an unredirected stream.

Beitragsleitfaden

Beitragsleitfaden öffnen

Rechercherichtung

Beginne in dotnet/src/Types.cs und Client.cs, insbesondere bei StartCliServerAsync, der Schleife zur Port-Erkennung und der Schleife zur Erfassung von stderr. Bestätige das CLI-Flag, das TCP-Routing für userInput.request und das Port-Verhalten mit dem CLI-Team, bevor du das SDK änderst. Als erledigt gilt die Aufgabe, wenn TuiServerMode validiert ist, den vorgesehenen Modus startet, die Terminalausgabe beibehält und Tests für die Verarbeitung seiner Option vorhanden sind.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
csharp
Bereich
api, cli
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Ruhig
Klarheit
Muss geklärt werden
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.