Merge claudedo/1b599d6711914658b9857b3df996f6e0
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using ClaudeDo.Data;
|
||||
using ClaudeDo.Ui.Localization;
|
||||
@@ -13,6 +14,7 @@ public sealed partial class FilesSettingsTabViewModel : ViewModelBase
|
||||
|
||||
[ObservableProperty] private string _statusMessage = "";
|
||||
[ObservableProperty] private bool _isBusy;
|
||||
[ObservableProperty] private bool _hasCustomizedPrompts;
|
||||
|
||||
public string SystemPromptPath { get; } = PromptFiles.PathFor(PromptKind.System);
|
||||
public string PlanningPromptPath { get; } = PromptFiles.PathFor(PromptKind.Planning);
|
||||
@@ -21,7 +23,13 @@ public sealed partial class FilesSettingsTabViewModel : ViewModelBase
|
||||
public string DailyPrepPromptPath { get; } = PromptFiles.PathFor(PromptKind.DailyPrep);
|
||||
public string WeeklyReportPromptPath { get; } = PromptFiles.PathFor(PromptKind.WeeklyReport);
|
||||
|
||||
public FilesSettingsTabViewModel(IWorkerClient worker) => _worker = worker;
|
||||
public ObservableCollection<CustomizedPromptRowViewModel> CustomizedPrompts { get; } = new();
|
||||
|
||||
public FilesSettingsTabViewModel(IWorkerClient worker)
|
||||
{
|
||||
_worker = worker;
|
||||
RefreshCustomizedPrompts();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private async Task RestoreDefaultAgents()
|
||||
@@ -46,10 +54,51 @@ public sealed partial class FilesSettingsTabViewModel : ViewModelBase
|
||||
if (!Enum.TryParse<PromptKind>(kindName, ignoreCase: true, out var kind)) return;
|
||||
try
|
||||
{
|
||||
PromptFiles.EnsureExists(kind);
|
||||
var path = PromptFiles.PathFor(kind);
|
||||
Process.Start(new ProcessStartInfo(path) { UseShellExecute = true });
|
||||
// No override file yet: seed it with today's bundled default (hash-tracked, so a later
|
||||
// default change reconciles this file away automatically unless the user actually edits it)
|
||||
// rather than leaving a plain file that would freeze the prompt forever.
|
||||
if (!File.Exists(PromptFiles.PathFor(kind)))
|
||||
PromptFiles.Save(kind, PromptFiles.DefaultFor(kind));
|
||||
Process.Start(new ProcessStartInfo(PromptFiles.PathFor(kind)) { UseShellExecute = true });
|
||||
}
|
||||
catch (Exception ex) { StatusMessage = Loc.T("vm.filesTab.openFailed", ex.Message); }
|
||||
finally { RefreshCustomizedPrompts(); }
|
||||
}
|
||||
|
||||
private void RefreshCustomizedPrompts()
|
||||
{
|
||||
CustomizedPrompts.Clear();
|
||||
foreach (var kind in Enum.GetValues<PromptKind>())
|
||||
{
|
||||
if (PromptFiles.Classify(kind) != PromptFileState.Edited) continue;
|
||||
CustomizedPrompts.Add(new CustomizedPromptRowViewModel(kind, PromptFiles.DiffAgainstDefault(kind), OnResetPromptToDefault));
|
||||
}
|
||||
HasCustomizedPrompts = CustomizedPrompts.Count > 0;
|
||||
}
|
||||
|
||||
private void OnResetPromptToDefault(PromptKind kind)
|
||||
{
|
||||
PromptFiles.ResetToDefault(kind);
|
||||
RefreshCustomizedPrompts();
|
||||
StatusMessage = Loc.T("vm.filesTab.resetToDefault");
|
||||
}
|
||||
}
|
||||
|
||||
public sealed partial class CustomizedPromptRowViewModel : ObservableObject
|
||||
{
|
||||
private readonly Action<PromptKind> _onReset;
|
||||
|
||||
public PromptKind Kind { get; }
|
||||
public string KindName => Kind.ToString();
|
||||
public string DiffPreview { get; }
|
||||
|
||||
public CustomizedPromptRowViewModel(PromptKind kind, string diffPreview, Action<PromptKind> onReset)
|
||||
{
|
||||
Kind = kind;
|
||||
DiffPreview = diffPreview;
|
||||
_onReset = onReset;
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void Reset() => _onReset(Kind);
|
||||
}
|
||||
|
||||
@@ -297,6 +297,24 @@
|
||||
Command="{Binding Files.OpenPromptCommand}" CommandParameter="WeeklyReport"/>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
<StackPanel Spacing="6" IsVisible="{Binding Files.HasCustomizedPrompts}">
|
||||
<TextBlock Classes="section-label" Text="{loc:Tr settings.files.customizedSection}"/>
|
||||
<TextBlock Classes="meta" Text="{loc:Tr settings.files.customizedHint}" TextWrapping="Wrap"/>
|
||||
<ItemsControl ItemsSource="{Binding Files.CustomizedPrompts}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Spacing="4" Margin="0,0,0,10">
|
||||
<Grid ColumnDefinitions="*,Auto">
|
||||
<TextBlock Grid.Column="0" Classes="field-label" Text="{Binding KindName}" VerticalAlignment="Center"/>
|
||||
<Button Grid.Column="1" Classes="btn" Content="{loc:Tr settings.files.resetToDefault}"
|
||||
Command="{Binding ResetCommand}"/>
|
||||
</Grid>
|
||||
<TextBlock Classes="path-mono" Text="{Binding DiffPreview}" TextWrapping="Wrap"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
<TextBlock Classes="meta" Text="{Binding Files.StatusMessage}"
|
||||
IsVisible="{Binding Files.StatusMessage, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
|
||||
</StackPanel>
|
||||
|
||||
Reference in New Issue
Block a user