From ce9fadc0b58ce2dda42dca45327b8b1440defb54 Mon Sep 17 00:00:00 2001 From: mika kuns Date: Sat, 30 May 2026 15:47:46 +0200 Subject: [PATCH] refactor: fold single-consumer helper types into their owners Consolidate small single-purpose types into the files that own them: StreamResult into StreamAnalyzer, the Planning context records into PlanningSessionContext, PrimeClock/PrimeSchedulerOptions into PrimeScheduler, AgentMcpTools into LifecycleMcpTools, the locator subclasses into InstallArtifactLocator, LogLineViewModel into DetailsIslandViewModel, RepoImportItemViewModel into its modal, and StepViewModel into InstallPageViewModel. Co-Authored-By: Claude Opus 4.7 --- .../Pages/InstallPage/InstallPageViewModel.cs | 12 +++++++ .../Pages/InstallPage/StepViewModel.cs | 17 ---------- .../Services/InstallArtifactLocator.cs | 12 +++++++ src/ClaudeDo.Ui/Services/InstallerLocator.cs | 7 ---- src/ClaudeDo.Ui/Services/WorkerLocator.cs | 7 ---- .../Islands/DetailsIslandViewModel.cs | 31 ++++++++++++++++++ .../ViewModels/Islands/LogLineViewModel.cs | 32 ------------------- .../Modals/RepoImportItemViewModel.cs | 18 ----------- .../Modals/RepoImportModalViewModel.cs | 15 +++++++++ src/ClaudeDo.Worker/External/AgentMcpTools.cs | 18 ----------- .../External/LifecycleMcpTools.cs | 14 ++++++++ .../Planning/InteractiveLaunchContext.cs | 6 ---- .../Planning/PlanningMcpContext.cs | 6 ---- .../Planning/PlanningSessionContext.cs | 15 +++++++++ .../Planning/PlanningSessionFiles.cs | 6 ---- src/ClaudeDo.Worker/Prime/PrimeClock.cs | 5 --- src/ClaudeDo.Worker/Prime/PrimeScheduler.cs | 11 +++++++ .../Prime/PrimeSchedulerOptions.cs | 7 ---- src/ClaudeDo.Worker/Runner/StreamAnalyzer.cs | 11 +++++++ src/ClaudeDo.Worker/Runner/StreamResult.cs | 12 ------- 20 files changed, 121 insertions(+), 141 deletions(-) delete mode 100644 src/ClaudeDo.Installer/Pages/InstallPage/StepViewModel.cs delete mode 100644 src/ClaudeDo.Ui/Services/InstallerLocator.cs delete mode 100644 src/ClaudeDo.Ui/Services/WorkerLocator.cs delete mode 100644 src/ClaudeDo.Ui/ViewModels/Islands/LogLineViewModel.cs delete mode 100644 src/ClaudeDo.Ui/ViewModels/Modals/RepoImportItemViewModel.cs delete mode 100644 src/ClaudeDo.Worker/External/AgentMcpTools.cs delete mode 100644 src/ClaudeDo.Worker/Planning/InteractiveLaunchContext.cs delete mode 100644 src/ClaudeDo.Worker/Planning/PlanningMcpContext.cs delete mode 100644 src/ClaudeDo.Worker/Planning/PlanningSessionFiles.cs delete mode 100644 src/ClaudeDo.Worker/Prime/PrimeClock.cs delete mode 100644 src/ClaudeDo.Worker/Prime/PrimeSchedulerOptions.cs delete mode 100644 src/ClaudeDo.Worker/Runner/StreamResult.cs diff --git a/src/ClaudeDo.Installer/Pages/InstallPage/InstallPageViewModel.cs b/src/ClaudeDo.Installer/Pages/InstallPage/InstallPageViewModel.cs index f8fb57a..9f46f68 100644 --- a/src/ClaudeDo.Installer/Pages/InstallPage/InstallPageViewModel.cs +++ b/src/ClaudeDo.Installer/Pages/InstallPage/InstallPageViewModel.cs @@ -10,6 +10,18 @@ using Microsoft.Extensions.DependencyInjection; namespace ClaudeDo.Installer.Pages.InstallPage; +public partial class StepViewModel : ObservableObject +{ + public string Name { get; } + + [ObservableProperty] private StepStatus _status = StepStatus.Pending; + [ObservableProperty] private bool _isExpanded; + + public ObservableCollection Messages { get; } = []; + + public StepViewModel(string name) => Name = name; +} + public partial class InstallPageViewModel : ObservableObject, IInstallerPage { private readonly InstallContext _context; diff --git a/src/ClaudeDo.Installer/Pages/InstallPage/StepViewModel.cs b/src/ClaudeDo.Installer/Pages/InstallPage/StepViewModel.cs deleted file mode 100644 index 176948a..0000000 --- a/src/ClaudeDo.Installer/Pages/InstallPage/StepViewModel.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Collections.ObjectModel; -using ClaudeDo.Installer.Core; -using CommunityToolkit.Mvvm.ComponentModel; - -namespace ClaudeDo.Installer.Pages.InstallPage; - -public partial class StepViewModel : ObservableObject -{ - public string Name { get; } - - [ObservableProperty] private StepStatus _status = StepStatus.Pending; - [ObservableProperty] private bool _isExpanded; - - public ObservableCollection Messages { get; } = []; - - public StepViewModel(string name) => Name = name; -} diff --git a/src/ClaudeDo.Ui/Services/InstallArtifactLocator.cs b/src/ClaudeDo.Ui/Services/InstallArtifactLocator.cs index cead9ee..7536da8 100644 --- a/src/ClaudeDo.Ui/Services/InstallArtifactLocator.cs +++ b/src/ClaudeDo.Ui/Services/InstallArtifactLocator.cs @@ -1,5 +1,17 @@ namespace ClaudeDo.Ui.Services; +public sealed class InstallerLocator : InstallArtifactLocator +{ + protected override string Subdir => "uninstaller"; + protected override string ExeName => "ClaudeDo.Installer.exe"; +} + +public sealed class WorkerLocator : InstallArtifactLocator +{ + protected override string Subdir => "worker"; + protected override string ExeName => "ClaudeDo.Worker.exe"; +} + /// /// Locates an executable inside a ClaudeDo install: walk up from the running /// directory to the folder containing install.json, otherwise read the diff --git a/src/ClaudeDo.Ui/Services/InstallerLocator.cs b/src/ClaudeDo.Ui/Services/InstallerLocator.cs deleted file mode 100644 index 0c6aa24..0000000 --- a/src/ClaudeDo.Ui/Services/InstallerLocator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ClaudeDo.Ui.Services; - -public sealed class InstallerLocator : InstallArtifactLocator -{ - protected override string Subdir => "uninstaller"; - protected override string ExeName => "ClaudeDo.Installer.exe"; -} diff --git a/src/ClaudeDo.Ui/Services/WorkerLocator.cs b/src/ClaudeDo.Ui/Services/WorkerLocator.cs deleted file mode 100644 index 71e1954..0000000 --- a/src/ClaudeDo.Ui/Services/WorkerLocator.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ClaudeDo.Ui.Services; - -public sealed class WorkerLocator : InstallArtifactLocator -{ - protected override string Subdir => "worker"; - protected override string ExeName => "ClaudeDo.Worker.exe"; -} diff --git a/src/ClaudeDo.Ui/ViewModels/Islands/DetailsIslandViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Islands/DetailsIslandViewModel.cs index d2e59ef..7ca1c1c 100644 --- a/src/ClaudeDo.Ui/ViewModels/Islands/DetailsIslandViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/Islands/DetailsIslandViewModel.cs @@ -13,6 +13,37 @@ using Microsoft.Extensions.DependencyInjection; namespace ClaudeDo.Ui.ViewModels.Islands; +public enum LogKind { Sys, Tool, Claude, Stdout, Stderr, Done, Msg } + +public sealed class LogLineViewModel +{ + public required LogKind Kind { get; init; } + public required string Text { get; init; } + public string TimestampFormatted { get; } = DateTime.Now.ToString("HH:mm:ss"); + public string KindMarker => Kind switch + { + LogKind.Sys => "sys", + LogKind.Tool => "tool", + LogKind.Claude => "claude", + LogKind.Stdout => "out", + LogKind.Stderr => "err", + LogKind.Done => "done", + LogKind.Msg => "claude", + _ => "", + }; + public string ClassName => Kind switch + { + LogKind.Sys => "log-sys", + LogKind.Tool => "log-tool", + LogKind.Claude => "log-claude", + LogKind.Stdout => "log-stdout", + LogKind.Stderr => "log-stderr", + LogKind.Done => "log-done", + LogKind.Msg => "log-msg", + _ => "", + }; +} + public sealed partial class DetailsIslandViewModel : ViewModelBase { private readonly IDbContextFactory _dbFactory; diff --git a/src/ClaudeDo.Ui/ViewModels/Islands/LogLineViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Islands/LogLineViewModel.cs deleted file mode 100644 index eed803d..0000000 --- a/src/ClaudeDo.Ui/ViewModels/Islands/LogLineViewModel.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace ClaudeDo.Ui.ViewModels.Islands; - -public enum LogKind { Sys, Tool, Claude, Stdout, Stderr, Done, Msg } - -public sealed class LogLineViewModel -{ - public required LogKind Kind { get; init; } - public required string Text { get; init; } - public string TimestampFormatted { get; } = DateTime.Now.ToString("HH:mm:ss"); - public string KindMarker => Kind switch - { - LogKind.Sys => "sys", - LogKind.Tool => "tool", - LogKind.Claude => "claude", - LogKind.Stdout => "out", - LogKind.Stderr => "err", - LogKind.Done => "done", - LogKind.Msg => "claude", - _ => "", - }; - public string ClassName => Kind switch - { - LogKind.Sys => "log-sys", - LogKind.Tool => "log-tool", - LogKind.Claude => "log-claude", - LogKind.Stdout => "log-stdout", - LogKind.Stderr => "log-stderr", - LogKind.Done => "log-done", - LogKind.Msg => "log-msg", - _ => "", - }; -} diff --git a/src/ClaudeDo.Ui/ViewModels/Modals/RepoImportItemViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Modals/RepoImportItemViewModel.cs deleted file mode 100644 index 3793660..0000000 --- a/src/ClaudeDo.Ui/ViewModels/Modals/RepoImportItemViewModel.cs +++ /dev/null @@ -1,18 +0,0 @@ -using CommunityToolkit.Mvvm.ComponentModel; - -namespace ClaudeDo.Ui.ViewModels.Modals; - -public sealed partial class RepoImportItemViewModel : ViewModelBase -{ - public string Name { get; init; } = ""; - public string FullPath { get; init; } = ""; - - // True when a list already points at this path. Such rows are shown ticked + disabled. - public bool AlreadyAdded { get; init; } - public bool CanToggle => !AlreadyAdded; - - [ObservableProperty] private bool _isChecked; - - // Driven by the search filter; the row collapses when it doesn't match. - [ObservableProperty] private bool _isVisible = true; -} diff --git a/src/ClaudeDo.Ui/ViewModels/Modals/RepoImportModalViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Modals/RepoImportModalViewModel.cs index 6c1d851..e91c4a1 100644 --- a/src/ClaudeDo.Ui/ViewModels/Modals/RepoImportModalViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/Modals/RepoImportModalViewModel.cs @@ -10,6 +10,21 @@ using Microsoft.EntityFrameworkCore; namespace ClaudeDo.Ui.ViewModels.Modals; +public sealed partial class RepoImportItemViewModel : ViewModelBase +{ + public string Name { get; init; } = ""; + public string FullPath { get; init; } = ""; + + // True when a list already points at this path. Such rows are shown ticked + disabled. + public bool AlreadyAdded { get; init; } + public bool CanToggle => !AlreadyAdded; + + [ObservableProperty] private bool _isChecked; + + // Driven by the search filter; the row collapses when it doesn't match. + [ObservableProperty] private bool _isVisible = true; +} + public sealed partial class RepoImportModalViewModel : ViewModelBase { private readonly IDbContextFactory _dbFactory; diff --git a/src/ClaudeDo.Worker/External/AgentMcpTools.cs b/src/ClaudeDo.Worker/External/AgentMcpTools.cs deleted file mode 100644 index 8050960..0000000 --- a/src/ClaudeDo.Worker/External/AgentMcpTools.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.ComponentModel; -using ClaudeDo.Data.Models; -using ClaudeDo.Worker.Agents; -using ModelContextProtocol.Server; - -namespace ClaudeDo.Worker.External; - -[McpServerToolType] -public sealed class AgentMcpTools -{ - private readonly AgentFileService _agents; - - public AgentMcpTools(AgentFileService agents) => _agents = agents; - - [McpServerTool, Description("List available agent definition files (name, description, path) for use as a task's agent path.")] - public async Task> ListAgents(CancellationToken cancellationToken) - => await _agents.ScanAsync(cancellationToken); -} diff --git a/src/ClaudeDo.Worker/External/LifecycleMcpTools.cs b/src/ClaudeDo.Worker/External/LifecycleMcpTools.cs index 5fe2338..33cad9d 100644 --- a/src/ClaudeDo.Worker/External/LifecycleMcpTools.cs +++ b/src/ClaudeDo.Worker/External/LifecycleMcpTools.cs @@ -1,11 +1,25 @@ using System.ComponentModel; +using ClaudeDo.Data.Models; using ClaudeDo.Data.Repositories; +using ClaudeDo.Worker.Agents; using ClaudeDo.Worker.Lifecycle; using ModelContextProtocol.Server; using TaskStatus = ClaudeDo.Data.Models.TaskStatus; namespace ClaudeDo.Worker.External; +[McpServerToolType] +public sealed class AgentMcpTools +{ + private readonly AgentFileService _agents; + + public AgentMcpTools(AgentFileService agents) => _agents = agents; + + [McpServerTool, Description("List available agent definition files (name, description, path) for use as a task's agent path.")] + public async Task> ListAgents(CancellationToken cancellationToken) + => await _agents.ScanAsync(cancellationToken); +} + [McpServerToolType] public sealed class LifecycleMcpTools { diff --git a/src/ClaudeDo.Worker/Planning/InteractiveLaunchContext.cs b/src/ClaudeDo.Worker/Planning/InteractiveLaunchContext.cs deleted file mode 100644 index b49317d..0000000 --- a/src/ClaudeDo.Worker/Planning/InteractiveLaunchContext.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace ClaudeDo.Worker.Planning; - -public sealed record InteractiveLaunchContext( - string TaskId, - string WorkingDir, - string InitialPrompt); diff --git a/src/ClaudeDo.Worker/Planning/PlanningMcpContext.cs b/src/ClaudeDo.Worker/Planning/PlanningMcpContext.cs deleted file mode 100644 index bf29dcd..0000000 --- a/src/ClaudeDo.Worker/Planning/PlanningMcpContext.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace ClaudeDo.Worker.Planning; - -public sealed class PlanningMcpContext -{ - public required string ParentTaskId { get; init; } -} diff --git a/src/ClaudeDo.Worker/Planning/PlanningSessionContext.cs b/src/ClaudeDo.Worker/Planning/PlanningSessionContext.cs index 2150390..e183665 100644 --- a/src/ClaudeDo.Worker/Planning/PlanningSessionContext.cs +++ b/src/ClaudeDo.Worker/Planning/PlanningSessionContext.cs @@ -1,5 +1,20 @@ namespace ClaudeDo.Worker.Planning; +public sealed record PlanningSessionFiles( + string SessionDirectory, + string SystemPromptPath, + string InitialPromptPath); + +public sealed record InteractiveLaunchContext( + string TaskId, + string WorkingDir, + string InitialPrompt); + +public sealed class PlanningMcpContext +{ + public required string ParentTaskId { get; init; } +} + public sealed record PlanningSessionStartContext( string ParentTaskId, string WorkingDir, diff --git a/src/ClaudeDo.Worker/Planning/PlanningSessionFiles.cs b/src/ClaudeDo.Worker/Planning/PlanningSessionFiles.cs deleted file mode 100644 index 3cea808..0000000 --- a/src/ClaudeDo.Worker/Planning/PlanningSessionFiles.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace ClaudeDo.Worker.Planning; - -public sealed record PlanningSessionFiles( - string SessionDirectory, - string SystemPromptPath, - string InitialPromptPath); \ No newline at end of file diff --git a/src/ClaudeDo.Worker/Prime/PrimeClock.cs b/src/ClaudeDo.Worker/Prime/PrimeClock.cs deleted file mode 100644 index 9ce107e..0000000 --- a/src/ClaudeDo.Worker/Prime/PrimeClock.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace ClaudeDo.Worker.Prime; -public sealed class PrimeClock : IPrimeClock -{ - public DateTimeOffset Now => DateTimeOffset.Now; -} diff --git a/src/ClaudeDo.Worker/Prime/PrimeScheduler.cs b/src/ClaudeDo.Worker/Prime/PrimeScheduler.cs index c8eb5cb..4efe7af 100644 --- a/src/ClaudeDo.Worker/Prime/PrimeScheduler.cs +++ b/src/ClaudeDo.Worker/Prime/PrimeScheduler.cs @@ -5,6 +5,17 @@ using Microsoft.Extensions.Hosting; namespace ClaudeDo.Worker.Prime; +public sealed class PrimeClock : IPrimeClock +{ + public DateTimeOffset Now => DateTimeOffset.Now; +} + +public sealed record PrimeSchedulerOptions(TimeSpan CatchUpWindow) +{ + public static PrimeSchedulerOptions Default { get; } = + new(TimeSpan.FromMinutes(30)); +} + public sealed class PrimeScheduler : BackgroundService { private readonly IDbContextFactory _dbFactory; diff --git a/src/ClaudeDo.Worker/Prime/PrimeSchedulerOptions.cs b/src/ClaudeDo.Worker/Prime/PrimeSchedulerOptions.cs deleted file mode 100644 index a6d8a1b..0000000 --- a/src/ClaudeDo.Worker/Prime/PrimeSchedulerOptions.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace ClaudeDo.Worker.Prime; - -public sealed record PrimeSchedulerOptions(TimeSpan CatchUpWindow) -{ - public static PrimeSchedulerOptions Default { get; } = - new(TimeSpan.FromMinutes(30)); -} diff --git a/src/ClaudeDo.Worker/Runner/StreamAnalyzer.cs b/src/ClaudeDo.Worker/Runner/StreamAnalyzer.cs index f50d386..39f9f7e 100644 --- a/src/ClaudeDo.Worker/Runner/StreamAnalyzer.cs +++ b/src/ClaudeDo.Worker/Runner/StreamAnalyzer.cs @@ -2,6 +2,17 @@ using System.Text.Json; namespace ClaudeDo.Worker.Runner; +public sealed class StreamResult +{ + public string? ResultMarkdown { get; set; } + public string? StructuredOutputJson { get; set; } + public string? SessionId { get; set; } + public int TurnCount { get; set; } + public int TokensIn { get; set; } + public int TokensOut { get; set; } + public int ApiRetryCount { get; set; } +} + public sealed class StreamAnalyzer { private string? _resultMarkdown; diff --git a/src/ClaudeDo.Worker/Runner/StreamResult.cs b/src/ClaudeDo.Worker/Runner/StreamResult.cs deleted file mode 100644 index 212e5ad..0000000 --- a/src/ClaudeDo.Worker/Runner/StreamResult.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace ClaudeDo.Worker.Runner; - -public sealed class StreamResult -{ - public string? ResultMarkdown { get; set; } - public string? StructuredOutputJson { get; set; } - public string? SessionId { get; set; } - public int TurnCount { get; set; } - public int TokensIn { get; set; } - public int TokensOut { get; set; } - public int ApiRetryCount { get; set; } -}