diff --git a/src/ClaudeDo.Localization/locales/de.json b/src/ClaudeDo.Localization/locales/de.json index 41797703..f047fe27 100644 --- a/src/ClaudeDo.Localization/locales/de.json +++ b/src/ClaudeDo.Localization/locales/de.json @@ -334,6 +334,8 @@ "defaultCommitType": "Standard-Commit-Typ", "manualList": "Manuelle Liste (Erinnerungen)", "manualListHint": "Neue Aufgaben in dieser Liste sind zunächst manuell: kein Einreihen, Ausführen oder Verfeinern, und die Automatik überspringt sie. Eine handgesteuerte Sitzung kannst du weiterhin öffnen.", + "findingsTracked": "Findings-Ordner .claudedo einchecken", + "findingsTrackedHint": "Aus: der Ordner bleibt über .git/info/exclude aus git heraus. An: Findings reisen mit dem Repo.", "sectionAgent": "AGENT", "resetAgentSettings": "Agent-Einstellungen zurücksetzen", "sectionVerify": "VERIFIKATION", diff --git a/src/ClaudeDo.Localization/locales/en.json b/src/ClaudeDo.Localization/locales/en.json index c8f18116..84fc46b2 100644 --- a/src/ClaudeDo.Localization/locales/en.json +++ b/src/ClaudeDo.Localization/locales/en.json @@ -334,6 +334,8 @@ "defaultCommitType": "Default commit type", "manualList": "Manual list (reminders)", "manualListHint": "New tasks in this list start out manual: no queueing, running or refining, and automation skips them. You can still open a hand-driven session.", + "findingsTracked": "Commit the .claudedo findings folder", + "findingsTrackedHint": "Off: the folder stays out of git via .git/info/exclude. On: findings travel with the repo.", "sectionAgent": "AGENT", "resetAgentSettings": "Reset agent settings", "sectionVerify": "VERIFICATION", diff --git a/src/ClaudeDo.Ui/Services/WorkerClient.cs b/src/ClaudeDo.Ui/Services/WorkerClient.cs index 33bb3c25..60787e04 100644 --- a/src/ClaudeDo.Ui/Services/WorkerClient.cs +++ b/src/ClaudeDo.Ui/Services/WorkerClient.cs @@ -695,7 +695,7 @@ public record MergeTargetsDto(string DefaultBranch, IReadOnlyList LocalB public record MergeConflictDocumentsDto(string TaskId, IReadOnlyList Files); public record ConflictDocumentDto(string Path, bool IsBinary, IReadOnlyList Segments); public record MergeSegmentDto(bool IsConflict, string Text, string Ours, string? Base, string Theirs); -public sealed record UpdateListDto(string Id, string Name, string? WorkingDir, string DefaultCommitType, bool IsManual = false); +public sealed record UpdateListDto(string Id, string Name, string? WorkingDir, string DefaultCommitType, bool IsManual = false, bool FindingsTracked = false); public sealed record UpdateListConfigDto(string ListId, string? Model, string? SystemPrompt, string? AgentPath, int? MaxTurns = null, List? SessionSkills = null, string? VerifyCommand = null); public sealed record UpdateTaskAgentSettingsDto(string TaskId, string? Model, string? SystemPrompt, string? AgentPath, int? MaxTurns = null, List? SessionSkills = null); public sealed record ListConfigDto(string? Model, string? SystemPrompt, string? AgentPath, int? MaxTurns = null, List? SessionSkills = null, string? VerifyCommand = null); diff --git a/src/ClaudeDo.Ui/ViewModels/Islands/ListNavItemViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Islands/ListNavItemViewModel.cs index eae38177..9e14bb9f 100644 --- a/src/ClaudeDo.Ui/ViewModels/Islands/ListNavItemViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/Islands/ListNavItemViewModel.cs @@ -14,6 +14,8 @@ public sealed partial class ListNavItemViewModel : ViewModelBase [ObservableProperty] private string _defaultCommitType = CommitTypeRegistry.DefaultType; // Reminder list: tasks created here default to manual. [ObservableProperty] private bool _isManual; + // Whether this list's .claudedo/ findings folder is committed with the repo (ListEntity.FindingsTracked). + [ObservableProperty] private bool _findingsTracked; [ObservableProperty] private bool _dropHintAbove; [ObservableProperty] private bool _dropHintBelow; // Set while a dragged task hovers over this row as a move target — distinct from diff --git a/src/ClaudeDo.Ui/ViewModels/Islands/ListsIslandViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Islands/ListsIslandViewModel.cs index 004dae2a..aa06d64d 100644 --- a/src/ClaudeDo.Ui/ViewModels/Islands/ListsIslandViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/Islands/ListsIslandViewModel.cs @@ -50,7 +50,7 @@ public sealed partial class ListsIslandViewModel : ViewModelBase, IDisposable if (row is null || Dialogs is null || _services is null) return; var rawId = row.Id.StartsWith("user:", StringComparison.Ordinal) ? row.Id["user:".Length..] : row.Id; var vm = _services.GetRequiredService(); - await vm.LoadAsync(rawId, row.Name, row.WorkingDir, row.DefaultCommitType, row.IsManual); + await vm.LoadAsync(rawId, row.Name, row.WorkingDir, row.DefaultCommitType, row.IsManual, row.FindingsTracked); await Dialogs.ShowListSettingsAsync(vm); if (vm.Deleted) await LoadAsync(); else await RefreshRowAsync(row.Id); @@ -249,6 +249,7 @@ public sealed partial class ListsIslandViewModel : ViewModelBase, IDisposable WorkingDir = l.WorkingDir, DefaultCommitType = l.DefaultCommitType, IsManual = l.IsManual, + FindingsTracked = l.FindingsTracked, }; Items.Add(item); UserLists.Add(item); @@ -323,7 +324,7 @@ public sealed partial class ListsIslandViewModel : ViewModelBase, IDisposable if (Dialogs is not null && _services is not null) { var vm = _services.GetRequiredService(); - await vm.LoadAsync(entity.Id, entity.Name, entity.WorkingDir, entity.DefaultCommitType, entity.IsManual); + await vm.LoadAsync(entity.Id, entity.Name, entity.WorkingDir, entity.DefaultCommitType, entity.IsManual, entity.FindingsTracked); await Dialogs.ShowListSettingsAsync(vm); if (vm.Deleted) await LoadAsync(); else await RefreshRowAsync(item.Id); @@ -404,6 +405,7 @@ public sealed partial class ListsIslandViewModel : ViewModelBase, IDisposable row.WorkingDir = entity.WorkingDir; row.DefaultCommitType = entity.DefaultCommitType; row.IsManual = entity.IsManual; + row.FindingsTracked = entity.FindingsTracked; } catch { /* best-effort refresh */ } } diff --git a/src/ClaudeDo.Ui/ViewModels/Modals/ListSettingsModalViewModel.cs b/src/ClaudeDo.Ui/ViewModels/Modals/ListSettingsModalViewModel.cs index 6793713d..cbfcca6b 100644 --- a/src/ClaudeDo.Ui/ViewModels/Modals/ListSettingsModalViewModel.cs +++ b/src/ClaudeDo.Ui/ViewModels/Modals/ListSettingsModalViewModel.cs @@ -30,6 +30,9 @@ public sealed partial class ListSettingsModalViewModel : ViewModelBase [ObservableProperty] private string _defaultCommitType = CommitTypeRegistry.DefaultType; // A manual list holds reminders: tasks created here start out manual (TaskEntity.IsManual). [ObservableProperty] private bool _isManual; + // When true the project's .claudedo/ findings store is committed with the repo; when false it + // is kept out of git via .git/info/exclude (see FindingsStore / ListEntity.FindingsTracked). + [ObservableProperty] private bool _findingsTracked; // Optional post-merge verification command (build/test), run in WorkingDir after a merge // lands; a non-zero exit keeps the task out of Done instead of silently reporting merged. [ObservableProperty] private string _verifyCommand = ""; @@ -55,11 +58,13 @@ public sealed partial class ListSettingsModalViewModel : ViewModelBase string? workingDir, string defaultCommitType, bool isManual = false, + bool findingsTracked = false, CancellationToken ct = default) { ListId = listId; Name = name; IsManual = isManual; + FindingsTracked = findingsTracked; WorkingDir = workingDir ?? ""; DefaultCommitType = string.IsNullOrWhiteSpace(defaultCommitType) ? CommitTypeRegistry.DefaultType : defaultCommitType; @@ -76,7 +81,8 @@ public sealed partial class ListSettingsModalViewModel : ViewModelBase string.IsNullOrWhiteSpace(Name) ? Loc.T("vm.listSettings.untitled") : Name, string.IsNullOrWhiteSpace(WorkingDir) ? null : WorkingDir, DefaultCommitType, - IsManual)); + IsManual, + FindingsTracked)); await Agent.SaveAsync(string.IsNullOrWhiteSpace(VerifyCommand) ? null : VerifyCommand); diff --git a/src/ClaudeDo.Ui/Views/Modals/ListSettingsModalView.axaml b/src/ClaudeDo.Ui/Views/Modals/ListSettingsModalView.axaml index 6242ab0c..4e8a659d 100644 --- a/src/ClaudeDo.Ui/Views/Modals/ListSettingsModalView.axaml +++ b/src/ClaudeDo.Ui/Views/Modals/ListSettingsModalView.axaml @@ -67,6 +67,13 @@ + + + + + diff --git a/src/ClaudeDo.Worker/Hub/WorkerHub.cs b/src/ClaudeDo.Worker/Hub/WorkerHub.cs index fccea1a1..7add000e 100644 --- a/src/ClaudeDo.Worker/Hub/WorkerHub.cs +++ b/src/ClaudeDo.Worker/Hub/WorkerHub.cs @@ -93,7 +93,7 @@ public record MergeTargetsDto(string DefaultBranch, IReadOnlyList LocalB public record MergeConflictDocumentsDto(string TaskId, IReadOnlyList Files); public record ConflictDocumentDto(string Path, bool IsBinary, IReadOnlyList Segments); public record MergeSegmentDto(bool IsConflict, string Text, string Ours, string? Base, string Theirs); -public record UpdateListDto(string Id, string Name, string? WorkingDir, string DefaultCommitType, bool IsManual = false); +public record UpdateListDto(string Id, string Name, string? WorkingDir, string DefaultCommitType, bool IsManual = false, bool FindingsTracked = false); public record UpdateListConfigDto(string ListId, string? Model, string? SystemPrompt, string? AgentPath, int? MaxTurns = null, List? SessionSkills = null, string? VerifyCommand = null); public record UpdateTaskAgentSettingsDto(string TaskId, string? Model, string? SystemPrompt, string? AgentPath, int? MaxTurns = null, List? SessionSkills = null); public record ListConfigDto(string? Model, string? SystemPrompt, string? AgentPath, int? MaxTurns = null, List? SessionSkills = null, string? VerifyCommand = null); @@ -659,6 +659,7 @@ public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub entity.WorkingDir = string.IsNullOrWhiteSpace(dto.WorkingDir) ? null : dto.WorkingDir; entity.DefaultCommitType = string.IsNullOrWhiteSpace(dto.DefaultCommitType) ? CommitTypeRegistry.DefaultType : dto.DefaultCommitType; entity.IsManual = dto.IsManual; + entity.FindingsTracked = dto.FindingsTracked; await repo.UpdateAsync(entity); await _broadcaster.ListUpdated(dto.Id);