Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

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

Open
#1,134 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
35/100
Issue type
Feature
Clarity
Needs clarification
Activity status
Quiet
Tech stack
csharp
Domain
api, cli

Research direction

Start in dotnet/src/Types.cs and Client.cs, especially StartCliServerAsync, the port-discovery loop, and the stderr capture loop. Confirm the CLI flag, TCP routing for userInput.request, and port behavior with the CLI team before changing the SDK. Done means TuiServerMode is validated, launches the intended mode, preserves terminal output, and has tests for its option handling.

Written by the indexing model from the issue text.

Description

enhancement

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
 /// <summary>
 /// 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 <see cref="SessionConfig.OnUserInputRequest"/>.
 /// Requires <see cref="Port"/> to be set (stdout is not available for port discovery).
 /// Mutually exclusive with <see cref="UseStdio"/>.
 /// </summary>
 public bool TuiServerMode { get; set; }
  1. Client.cs — StartCliServerAsync, args
 - 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]);
  1. Client.cs — StartCliServerAsync, ProcessStartInfo
   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,
   };
  1. Client.cs — StartCliServerAsync, port discovery
 - 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)

  1. Client.cs — validation in constructor
 + 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.

Dominant language
Java
Stars
10.5k
Forks
1.5k
Avg merge
1d 9h
Merged PRs (30d)
129

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from github/copilot-sdk

All issues in github/copilot-sdk

Similar issues

More Java issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.