refactor: drop the remaining single-implementation interfaces

IBaseDirtyChecker, IInteractiveLaunchSpecService and the LaunchSpec wrapper
had one implementation and one caller each; ProcessRunnerAdapter existed only
to give a static class an interface, and InstallArtifactLocator used
inheritance for two constructor arguments. The external MCP container now
shares its singletons through a Share<T> helper instead of 17 near-identical
registrations.
This commit is contained in:
mika kuns
2026-08-26 13:55:51 +02:00
parent c593be2f02
commit 0f007c5367
14 changed files with 103 additions and 151 deletions
@@ -1,29 +1,19 @@
namespace ClaudeDo.Ui.Services;
public sealed class InstallerLocator : InstallArtifactLocator
{
protected override string Subdir => "uninstaller";
protected override string ExeName => "ClaudeDo.Installer.exe";
}
// Two named types because DI resolves them by type, not by key.
public sealed class InstallerLocator() : InstallArtifactLocator("uninstaller", "ClaudeDo.Installer.exe");
public sealed class WorkerLocator : InstallArtifactLocator
{
protected override string Subdir => "worker";
protected override string ExeName => "ClaudeDo.Worker.exe";
}
public sealed class WorkerLocator() : InstallArtifactLocator("worker", "ClaudeDo.Worker.exe");
/// <summary>
/// Locates an executable inside a ClaudeDo install: walk up from the running
/// directory to the folder containing install.json, otherwise read the
/// uninstall registry key. Subclasses supply the subdirectory and exe name.
/// uninstall registry key (which is what makes this work from a dev build).
/// </summary>
public abstract class InstallArtifactLocator
public abstract class InstallArtifactLocator(string subdir, string exeName)
{
private const string InstallJson = "install.json";
protected abstract string Subdir { get; }
protected abstract string ExeName { get; }
public string? Find()
=> FindByWalkingUp(AppContext.BaseDirectory)
?? (OperatingSystem.IsWindows() ? FindByRegistry() : null);
@@ -34,10 +24,7 @@ public abstract class InstallArtifactLocator
while (dir is not null)
{
if (File.Exists(Path.Combine(dir.FullName, InstallJson)))
{
var candidate = Path.Combine(dir.FullName, Subdir, ExeName);
return File.Exists(candidate) ? candidate : null;
}
return Candidate(dir.FullName);
dir = dir.Parent;
}
return null;
@@ -52,10 +39,14 @@ public abstract class InstallArtifactLocator
using var key = Microsoft.Win32.Registry.LocalMachine
.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Uninstall\ClaudeDo");
var location = key?.GetValue("InstallLocation") as string;
if (string.IsNullOrEmpty(location)) return null;
var candidate = Path.Combine(location, Subdir, ExeName);
return File.Exists(candidate) ? candidate : null;
return string.IsNullOrEmpty(location) ? null : Candidate(location);
}
catch { return null; }
}
private string? Candidate(string installDir)
{
var path = Path.Combine(installDir, subdir, exeName);
return File.Exists(path) ? path : null;
}
}