feat(settings): claude_bin im Dateien-Tab setzbar, mit Auflösungs-Check
Bisher nur per Hand in worker.config.json. Neuer Abschnitt CLAUDE CLI mit eigenem Save-Button (die Datei gehoert dem Worker, nicht app_settings) und einer Zeile, wohin der Wert per ExecutableResolver tatsaechlich aufloest — 'nicht im PATH gefunden' war bisher erst am fehlgeschlagenen Run zu sehen. WorkerConfig ist DI-Singleton und ClaudeProcess loest pro Spawn auf, also greift die Aenderung ab dem naechsten Run ohne Neustart. SaveOnlineInbox/SaveClaudeBin teilen jetzt ein SaveKey(), damit beide dieselbe read-modify-write-Semantik haben (alle anderen Keys bleiben unberuehrt). Die zugehoerigen Locale-Keys sind im vorigen Commit mitgelaufen.
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
using ClaudeDo.Worker.Config;
|
||||
using Xunit;
|
||||
|
||||
namespace ClaudeDo.Worker.Tests.Config;
|
||||
|
||||
/// SaveClaudeBin/SaveOnlineInbox are read-modify-write on a file the user also hand-edits, so the
|
||||
/// one thing that must hold is: every other key survives.
|
||||
public sealed class WorkerConfigSaveTests : IDisposable
|
||||
{
|
||||
private readonly string _path = Path.Combine(
|
||||
Path.GetTempPath(), $"cd_workercfg_{Guid.NewGuid():N}.json");
|
||||
|
||||
public void Dispose() { try { File.Delete(_path); } catch { } }
|
||||
|
||||
[Fact]
|
||||
public void SaveClaudeBin_keeps_every_other_key()
|
||||
{
|
||||
File.WriteAllText(_path, """
|
||||
{
|
||||
"claude_bin": "claude",
|
||||
"signalr_port": 12345,
|
||||
"external_mcp_api_key": "secret",
|
||||
"online_inbox": { "enabled": true }
|
||||
}
|
||||
""");
|
||||
|
||||
var cfg = WorkerConfig.Load(_path);
|
||||
cfg.ClaudeBin = @"C:\tools\claude.cmd";
|
||||
cfg.SaveClaudeBin(_path);
|
||||
|
||||
var reloaded = WorkerConfig.Load(_path);
|
||||
Assert.Equal(@"C:\tools\claude.cmd", reloaded.ClaudeBin);
|
||||
Assert.Equal(12345, reloaded.SignalRPort);
|
||||
Assert.Equal("secret", reloaded.ExternalMcpApiKey);
|
||||
Assert.True(reloaded.OnlineInbox.Enabled);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SaveClaudeBin_creates_the_file_when_missing()
|
||||
{
|
||||
var cfg = new WorkerConfig { ClaudeBin = "claude-next" };
|
||||
cfg.SaveClaudeBin(_path);
|
||||
|
||||
Assert.Equal("claude-next", WorkerConfig.Load(_path).ClaudeBin);
|
||||
}
|
||||
}
|
||||
@@ -159,6 +159,8 @@ sealed class FakeWorkerClient : IWorkerClient
|
||||
public Task<string> GetLastPrepLogAsync() => Task.FromResult(string.Empty);
|
||||
public Task<WorkerBuildInfoDto?> GetWorkerBuildInfoAsync() => Task.FromResult<WorkerBuildInfoDto?>(null);
|
||||
public Task RefineTaskAsync(string taskId) => Task.CompletedTask;
|
||||
public Task<ClaudeBinDto?> GetClaudeBinAsync() => Task.FromResult<ClaudeBinDto?>(null);
|
||||
public Task<ClaudeBinDto?> SetClaudeBinAsync(string? value) => Task.FromResult<ClaudeBinDto?>(null);
|
||||
public Task<OnlineInboxStateDto?> GetOnlineInboxStateAsync() => Task.FromResult<OnlineInboxStateDto?>(null);
|
||||
public Task SetOnlineInboxConfigAsync(OnlineInboxConfigInputDto input) => Task.CompletedTask;
|
||||
public Task SetOnlineInboxAuthAsync(string refreshToken) => Task.CompletedTask;
|
||||
|
||||
Reference in New Issue
Block a user