StreamingClaudeSession drives claude --input-format stream-json over a kept- open stdin: sends user messages, interrupts the in-flight turn via the verified control_request protocol, and tracks turn state from result events (treating an interrupt-aborted error_during_execution result as turn-ended). IClaudeStreamTransport abstracts the process I/O so it is unit-tested with a fake (no real claude). LiveSessionRegistry maps taskId -> live session for the hub to route into. Backs the upcoming in-app interactive sessions; autonomous task execution untouched.
48 lines
1.3 KiB
C#
48 lines
1.3 KiB
C#
using ClaudeDo.Worker.Runner.Interfaces;
|
|
|
|
namespace ClaudeDo.Worker.Tests.Infrastructure;
|
|
|
|
public sealed class FakeClaudeStreamTransport : IClaudeStreamTransport
|
|
{
|
|
public List<string> Written { get; } = [];
|
|
public bool Killed { get; private set; }
|
|
public bool Started { get; private set; }
|
|
|
|
public event Func<string, Task>? LineReceived;
|
|
public event Func<string, Task>? StderrReceived;
|
|
|
|
public Task StartAsync(IReadOnlyList<string> args, string workingDirectory, CancellationToken ct)
|
|
{
|
|
Started = true;
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public Task WriteLineAsync(string jsonLine, CancellationToken ct)
|
|
{
|
|
Written.Add(jsonLine);
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public void Kill() => Killed = true;
|
|
|
|
public Task WaitForExitAsync() => Task.CompletedTask;
|
|
|
|
public ValueTask DisposeAsync() => ValueTask.CompletedTask;
|
|
|
|
// Test helper: push a simulated stdout line to all LineReceived subscribers.
|
|
public async Task PushLineAsync(string line)
|
|
{
|
|
var handler = LineReceived;
|
|
if (handler is not null)
|
|
await handler(line);
|
|
}
|
|
|
|
// Test helper: push a simulated stderr line.
|
|
public async Task PushStderrAsync(string line)
|
|
{
|
|
var handler = StderrReceived;
|
|
if (handler is not null)
|
|
await handler(line);
|
|
}
|
|
}
|