fix(worker): route WeekReportService permission-mode through PermissionModeResolver

Closes the last unrouted --permission-mode call site: haiku default models were
hardcoding raw "auto", which the CLI silently downgrades to interactive "default"
and hangs the report generation. Also drops the author's personal C:\Private
default exclude in favor of an empty default (config stays via ReportExcludedPaths).
This commit is contained in:
mika kuns
2026-09-10 13:13:16 +02:00
parent 1177463a82
commit 1c76852957
2 changed files with 30 additions and 3 deletions
@@ -10,7 +10,7 @@ namespace ClaudeDo.Worker.Report;
public sealed class WeekReportService public sealed class WeekReportService
{ {
private static readonly string[] DefaultExcludes = { @"C:\Private" }; private static readonly string[] DefaultExcludes = Array.Empty<string>();
private const string NoActivity = "_No activity in this period._"; private const string NoActivity = "_No activity in this period._";
private readonly IClaudeHistoryReader _reader; private readonly IClaudeHistoryReader _reader;
@@ -72,7 +72,7 @@ public sealed class WeekReportService
IReadOnlyList<string> args = IReadOnlyList<string> args =
[ [
"-p", "--output-format", "stream-json", "--verbose", "-p", "--output-format", "stream-json", "--verbose",
"--permission-mode", "auto", "--permission-mode", PermissionModeResolver.Resolve(safeModel, "auto"),
"--model", safeModel, "--model", safeModel,
]; ];
var result = await _claude.RunAsync(args, prompt, Path.GetTempPath(), _ => Task.CompletedTask, ct); var result = await _claude.RunAsync(args, prompt, Path.GetTempPath(), _ => Task.CompletedTask, ct);
@@ -26,9 +26,10 @@ public class WeekReportServiceTests : IDisposable
private sealed class FakeClaude : IClaudeProcess private sealed class FakeClaude : IClaudeProcess
{ {
public int Calls; public int Calls;
public IReadOnlyList<string>? LastArgs;
public RunResult Next = new() { ExitCode = 0, ResultMarkdown = "## Bericht" }; public RunResult Next = new() { ExitCode = 0, ResultMarkdown = "## Bericht" };
public Task<RunResult> RunAsync(IReadOnlyList<string> args, string prompt, string wd, Func<string, Task> onLine, CancellationToken ct) public Task<RunResult> RunAsync(IReadOnlyList<string> args, string prompt, string wd, Func<string, Task> onLine, CancellationToken ct)
{ Calls++; return Task.FromResult(Next); } { Calls++; LastArgs = args; return Task.FromResult(Next); }
} }
private WeekReportService Make(FakeReader reader, FakeClaude claude) => private WeekReportService Make(FakeReader reader, FakeClaude claude) =>
@@ -65,6 +66,32 @@ public class WeekReportServiceTests : IDisposable
Assert.Equal(md, await svc.GetStoredAsync(Start, End)); Assert.Equal(md, await svc.GetStoredAsync(Start, End));
} }
[Fact]
public async Task HaikuDefaultModel_RoutesPermissionModeThroughResolver()
{
using (var ctx = _db.CreateContext())
{
var repo = new AppSettingsRepository(ctx);
var settings = await repo.GetAsync();
settings.DefaultModel = "haiku";
await repo.UpdateAsync(settings);
}
var activityRepo = new RepoActivity { RepoPath = @"C:\Dev\App" };
var day = new DayActivity { Date = new DateOnly(2026, 6, 1) };
day.Prompts.Add("x");
activityRepo.Days.Add(day);
var claude = new FakeClaude();
var svc = Make(new FakeReader { Result = new[] { activityRepo } }, claude);
await svc.GenerateAsync(Start, End);
Assert.NotNull(claude.LastArgs);
var modeIndex = claude.LastArgs!.ToList().IndexOf("--permission-mode") + 1;
Assert.Equal(PermissionModeResolver.Resolve("haiku", "auto"), claude.LastArgs[modeIndex]);
Assert.NotEqual("auto", claude.LastArgs[modeIndex]);
}
[Fact] [Fact]
public async Task ClaudeFailure_Throws_AndDoesNotStore() public async Task ClaudeFailure_Throws_AndDoesNotStore()
{ {