Merge branch 'claudedo/12bae32376504fd28bedb3c7202feba5'
This commit is contained in:
@@ -19,6 +19,14 @@ namespace ClaudeDo.Ui.Services;
|
||||
/// </summary>
|
||||
public sealed class PtyTerminalSession : IDisposable
|
||||
{
|
||||
// Guards the set-env + LaunchProcess critical section below: two sessions starting
|
||||
// back-to-back (e.g. planning sessions for two different tasks) could otherwise interleave
|
||||
// their SetEnvironmentVariable calls before either LaunchProcess() forks, so one process
|
||||
// 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.
|
||||
private static readonly SemaphoreSlim s_launchGate = new(1, 1);
|
||||
|
||||
private TerminalControl? _control;
|
||||
private bool _disposed;
|
||||
|
||||
@@ -38,14 +46,22 @@ public sealed class PtyTerminalSession : IDisposable
|
||||
_control = control;
|
||||
control.ProcessExited += OnControlProcessExited;
|
||||
|
||||
foreach (var (key, value) in descriptor.Env)
|
||||
Environment.SetEnvironmentVariable(key, value);
|
||||
|
||||
control.Process = descriptor.Exe;
|
||||
control.Args = new List<string>(descriptor.Args);
|
||||
control.StartingDirectory = descriptor.Cwd;
|
||||
|
||||
await control.LaunchProcess();
|
||||
await s_launchGate.WaitAsync(ct);
|
||||
try
|
||||
{
|
||||
foreach (var (key, value) in descriptor.Env)
|
||||
Environment.SetEnvironmentVariable(key, value);
|
||||
|
||||
await control.LaunchProcess();
|
||||
}
|
||||
finally
|
||||
{
|
||||
s_launchGate.Release();
|
||||
}
|
||||
|
||||
// Permanent reparent mode: TerminalView.OnDetachedFromLogicalTree kills the child
|
||||
// process unless BeginReparent() suppressed it, and Mission Control detaches pane
|
||||
|
||||
Reference in New Issue
Block a user