Merge claudedo/43bb79c93e694f7cbec8ae41a05004bc
This commit is contained in:
@@ -25,7 +25,21 @@ public sealed class PtyTerminalSession : IDisposable
|
||||
// inherits the other's env (e.g. CLAUDEDO_PLANNING_TOKEN, breaking that session's own MCP
|
||||
// auth). Process-wide env leakage AFTER a launch has forked remains a documented limitation
|
||||
// — Porta.Pty has no per-launch env seam, so the vars stay set on the whole UI process.
|
||||
// The wait is bounded (see WaitForLaunchGateAsync) — a hung launch (slow disk, AV scanning
|
||||
// claude.exe, a Porta.Pty/ConPTY hiccup) must not freeze every other pane open behind it.
|
||||
private static readonly SemaphoreSlim s_launchGate = new(1, 1);
|
||||
private static readonly TimeSpan s_launchGateTimeout = TimeSpan.FromSeconds(30);
|
||||
|
||||
/// <summary>
|
||||
/// Waits on <paramref name="gate"/> for at most <paramref name="timeout"/>, throwing
|
||||
/// <see cref="TimeoutException"/> instead of blocking forever. Never acquires the gate on
|
||||
/// timeout, so callers must not release it in that case.
|
||||
/// </summary>
|
||||
internal static async Task WaitForLaunchGateAsync(SemaphoreSlim gate, TimeSpan timeout, CancellationToken ct)
|
||||
{
|
||||
if (!await gate.WaitAsync(timeout, ct))
|
||||
throw new TimeoutException("Another terminal launch is still starting up. Please retry in a moment.");
|
||||
}
|
||||
|
||||
private TerminalControl? _control;
|
||||
private bool _disposed;
|
||||
@@ -50,7 +64,7 @@ public sealed class PtyTerminalSession : IDisposable
|
||||
control.Args = new List<string>(descriptor.Args);
|
||||
control.StartingDirectory = descriptor.Cwd;
|
||||
|
||||
await s_launchGate.WaitAsync(ct);
|
||||
await WaitForLaunchGateAsync(s_launchGate, s_launchGateTimeout, ct);
|
||||
try
|
||||
{
|
||||
foreach (var (key, value) in descriptor.Env)
|
||||
|
||||
Reference in New Issue
Block a user