diff --git a/.specstory/history/2025-12-17_23-08Z-build-status-query.md b/.specstory/history/2025-12-17_23-08Z-build-status-query.md
index be5fd48..7e851a1 100644
--- a/.specstory/history/2025-12-17_23-08Z-build-status-query.md
+++ b/.specstory/history/2025-12-17_23-08Z-build-status-query.md
@@ -34201,3 +34201,5245 @@ The fixes resolved the pipeline input binding issue, and the script now handles
---
+_**User**_
+
+even if attach is functional, the start function may not be. selecting the GPU in worker settings doesn't appear to do anything; if I open settings, it must be selected again.
+
+---
+
+_**Agent (model default, mode Plan)**_
+
+
+Investigating GPU selection persistence and how it's used when starting workers. Reviewing the relevant code:
+
+
+---
+
+
+Tool use: **read_file_v2** • Read file: Models/WorkerTypeConfig.cs
+
+
+
+
+---
+
+
+Tool use: **read_file_v2** • Read file: ViewModels/WorkerEditViewModel.cs
+
+
+
+
+---
+
+
+Tool use: **read_file_v2** • Read file: Views/WorkerEditWindow.axaml
+
+
+
+
+---
+
+
+
+Tool use: **ripgrep_raw_search**
+
+
+Parameters:
+
+```json
+{
+ "pattern": "Gpu|GPU",
+ "path": ".",
+ "caseInsensitive": true
+}
+```
+Result:
+
+```json
+{
+ "success": {
+ "pattern": "Gpu|GPU",
+ "path": ".",
+ "outputMode": "content",
+ "workspaceResults": {
+ "c:\\Users\\Nathan\\Desktop\\UFL": {
+ "content": {
+ "matches": [
+ {
+ "file": "ViewModels/WorkerEditViewModel.cs",
+ "matches": [
+ {
+ "lineNumber": 18,
+ "content": " private string _sheepItGpu = \"OPTIX_0\";"
+ },
+ {
+ "lineNumber": 87,
+ "content": " public string SheepItGpu"
+ },
+ {
+ "lineNumber": 89,
+ "content": " get => _sheepItGpu;"
+ },
+ {
+ "lineNumber": 90,
+ "content": " set => SetAndRaise(ref _sheepItGpu, value);"
+ },
+ {
+ "lineNumber": 108,
+ "content": " SheepItGpu = worker.WorkerTypes.SheepIt.Gpu;"
+ },
+ {
+ "lineNumber": 147,
+ "content": " Gpu = SheepItGpu"
+ }
+ ]
+ },
+ {
+ "file": "Models\\WorkerTypeConfig.cs",
+ "matches": [
+ {
+ "lineNumber": 9,
+ "content": " [JsonPropertyName(\"gpu\")]"
+ },
+ {
+ "lineNumber": 10,
+ "content": " public string Gpu { get; set; } = string.Empty;"
+ }
+ ]
+ },
+ {
+ "file": ".gitignore",
+ "matches": [
+ {
+ "lineNumber": 6,
+ "content": "[Dd]ebugPublic/"
+ },
+ {
+ "lineNumber": 37,
+ "content": "[Dd]ebugPublic/"
+ },
+ {
+ "lineNumber": 80,
+ "content": "[Dd]ebugPublic/"
+ },
+ {
+ "lineNumber": 384,
+ "content": "# NVidia Nsight GPU debugger configuration file"
+ }
+ ]
+ },
+ {
+ "file": "README.md",
+ "matches": [
+ {
+ "lineNumber": 62,
+ "content": " \"gpu\": \"CPU\""
+ }
+ ]
+ },
+ {
+ "file": "ViewModels\\WorkerEditViewModel.cs",
+ "matches": [
+ {
+ "lineNumber": 18,
+ "content": " private string _sheepItGpu = \"OPTIX_0\";"
+ },
+ {
+ "lineNumber": 87,
+ "content": " public string SheepItGpu"
+ },
+ {
+ "lineNumber": 89,
+ "content": " get => _sheepItGpu;"
+ },
+ {
+ "lineNumber": 90,
+ "content": " set => SetAndRaise(ref _sheepItGpu, value);"
+ },
+ {
+ "lineNumber": 108,
+ "content": " SheepItGpu = worker.WorkerTypes.SheepIt.Gpu;"
+ },
+ {
+ "lineNumber": 147,
+ "content": " Gpu = SheepItGpu"
+ }
+ ]
+ },
+ {
+ "file": ".specstory/history/2025-12-17_22-32Z-readme-for-sheepit-worker-incompatibility-fix.md",
+ "matches": [
+ {
+ "lineNumber": 228,
+ "content": "+ \"gpu\": \"CPU\""
+ },
+ {
+ "lineNumber": 406,
+ "content": "| `history\\2025-05-06_20-07Z-switching-to-optix-gpu-rendering.md` |"
+ },
+ {
+ "lineNumber": 596,
+ "content": "+ - Switched to OptiX GPU rendering"
+ }
+ ]
+ },
+ {
+ "file": "Services\\WorkerControllerService.cs",
+ "matches": [
+ {
+ "lineNumber": 145,
+ "content": " '-gpu', '{sheepIt.Gpu}', '-login', '{safeUser}', '-password', '{safeKey}')"
+ }
+ ]
+ },
+ {
+ "file": "Views\\WorkerEditWindow.axaml",
+ "matches": [
+ {
+ "lineNumber": 36,
+ "content": " <TextBlock Text=\"GPU:\" IsVisible=\"{Binding HasSheepIt}\"/>"
+ },
+ {
+ "lineNumber": 37,
+ "content": " <ComboBox Name=\"GpuComboBox\" IsVisible=\"{Binding HasSheepIt}\" SelectedItem=\"{Binding SheepItGpu}\">"
+ }
+ ]
+ },
+ {
+ "file": "CHANGELOG.md",
+ "matches": [
+ {
+ "lineNumber": 98,
+ "content": "- Switched to OptiX GPU rendering"
+ }
+ ]
+ },
+ {
+ "file": "Views/WorkerEditWindow.axaml",
+ "matches": [
+ {
+ "lineNumber": 36,
+ "content": " <TextBlock Text=\"GPU:\" IsVisible=\"{Binding HasSheepIt}\"/>"
+ },
+ {
+ "lineNumber": 37,
+ "content": " <ComboBox Name=\"GpuComboBox\" IsVisible=\"{Binding HasSheepIt}\" SelectedItem=\"{Binding SheepItGpu}\">"
+ }
+ ]
+ },
+ {
+ "file": "Models/WorkerTypeConfig.cs",
+ "matches": [
+ {
+ "lineNumber": 9,
+ "content": " [JsonPropertyName(\"gpu\")]"
+ },
+ {
+ "lineNumber": 10,
+ "content": " public string Gpu { get; set; } = string.Empty;"
+ }
+ ]
+ },
+ {
+ "file": "Services/WorkerControllerService.cs",
+ "matches": [
+ {
+ "lineNumber": 145,
+ "content": " '-gpu', '{sheepIt.Gpu}', '-login', '{safeUser}', '-password', '{safeKey}')"
+ }
+ ]
+ }
+ ],
+ "totalLines": 31,
+ "totalMatchedLines": 31
+ }
+ }
+ }
+ }
+}
+```
+Status: **completed**
+
+
+
+
+
+---
+
+
+Tool use: **read_file_v2** • Read file: Services/WorkerControllerService.cs
+
+
+
+
+---
+
+
+Checking how the ComboBox binding works and how the configuration is saved:
+
+
+---
+
+
+Tool use: **read_file_v2** • Read file: Services/ConfigService.cs
+
+
+
+
+---
+
+
+Tool use: **read_file_v2** • Read file: Views/WorkerEditWindow.axaml.cs
+
+
+
+
+---
+
+
+
+Tool use: **semantic_search_full**
+
+
+Parameters:
+
+```json
+{
+ "query": "How is the GPU ComboBox selection saved and loaded in the worker edit window?",
+ "includePattern": "Views",
+ "topK": 10,
+ "explanation": ""
+}
+```
+Result:
+
+```json
+{
+ "codeResults": [
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\Views\\WorkerEditWindow.axaml",
+ "range": {
+ "startPosition": {
+ "line": 27
+ },
+ "endPosition": {
+ "line": 53
+ }
+ },
+ "contents": " </StackPanel>\n </TabItem>\n\n <!-- SheepIt Tab -->\n <TabItem Header=\"SheepIt\">\n <StackPanel Margin=\"10\" Spacing=\"10\">\n <CheckBox Name=\"HasSheepItCheckBox\" Content=\"Enable SheepIt Worker\" IsChecked=\"{Binding HasSheepIt}\" Margin=\"0,0,0,10\"/>\n \n <TextBlock Text=\"GPU:\" IsVisible=\"{Binding HasSheepIt}\"/>\n <ComboBox Name=\"GpuComboBox\" IsVisible=\"{Binding HasSheepIt}\" SelectedItem=\"{Binding SheepItGpu}\">\n <ComboBox.Items>\n <ComboBoxItem Content=\"OPTIX_0\"/>\n <ComboBoxItem Content=\"CUDA_0\"/>\n <ComboBoxItem Content=\"OPENCL_0\"/>\n </ComboBox.Items>\n </ComboBox>\n \n <TextBlock Text=\"Note: Username and Render Key are configured in Global Settings.\" \n IsVisible=\"{Binding HasSheepIt}\" \n Margin=\"0,10,0,0\"\n Foreground=\"Gray\"\n TextWrapping=\"Wrap\"/>\n </StackPanel>\n </TabItem>\n\n <!-- Flamenco Tab -->",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": " </StackPanel>",
+ "lineNumber": 28
+ },
+ {
+ "text": " </TabItem>",
+ "lineNumber": 29
+ },
+ {
+ "lineNumber": 30
+ },
+ {
+ "text": " <!-- SheepIt Tab -->",
+ "lineNumber": 31
+ },
+ {
+ "text": " <TabItem Header=\"SheepIt\">",
+ "lineNumber": 32
+ },
+ {
+ "text": " <StackPanel Margin=\"10\" Spacing=\"10\">",
+ "lineNumber": 33
+ },
+ {
+ "text": " <CheckBox Name=\"HasSheepItCheckBox\" Content=\"Enable SheepIt Worker\" IsChecked=\"{Binding HasSheepIt}\" Margin=\"0,0,0,10\"/>",
+ "lineNumber": 34
+ },
+ {
+ "text": " ",
+ "lineNumber": 35
+ },
+ {
+ "text": " <TextBlock Text=\"GPU:\" IsVisible=\"{Binding HasSheepIt}\"/>",
+ "lineNumber": 36
+ },
+ {
+ "text": " <ComboBox Name=\"GpuComboBox\" IsVisible=\"{Binding HasSheepIt}\" SelectedItem=\"{Binding SheepItGpu}\">",
+ "lineNumber": 37
+ },
+ {
+ "text": " <ComboBox.Items>",
+ "lineNumber": 38
+ },
+ {
+ "text": " <ComboBoxItem Content=\"OPTIX_0\"/>",
+ "lineNumber": 39
+ },
+ {
+ "text": " <ComboBoxItem Content=\"CUDA_0\"/>",
+ "lineNumber": 40
+ },
+ {
+ "text": " <ComboBoxItem Content=\"OPENCL_0\"/>",
+ "lineNumber": 41
+ },
+ {
+ "text": " </ComboBox.Items>",
+ "lineNumber": 42
+ },
+ {
+ "text": " </ComboBox>",
+ "lineNumber": 43
+ },
+ {
+ "text": " ",
+ "lineNumber": 44
+ },
+ {
+ "text": " <TextBlock Text=\"Note: Username and Render Key are configured in Global Settings.\" ",
+ "lineNumber": 45
+ },
+ {
+ "text": " IsVisible=\"{Binding HasSheepIt}\" ",
+ "lineNumber": 46
+ },
+ {
+ "text": " Margin=\"0,10,0,0\"",
+ "lineNumber": 47
+ },
+ {
+ "text": " Foreground=\"Gray\"",
+ "lineNumber": 48
+ },
+ {
+ "text": " TextWrapping=\"Wrap\"/>",
+ "lineNumber": 49
+ },
+ {
+ "text": " </StackPanel>",
+ "lineNumber": 50
+ },
+ {
+ "text": " </TabItem>",
+ "lineNumber": 51
+ },
+ {
+ "lineNumber": 52
+ },
+ {
+ "text": " <!-- Flamenco Tab -->",
+ "lineNumber": 53
+ }
+ ]
+ },
+ "score": 0.47021031379699707
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\ViewModels\\WorkerEditViewModel.cs",
+ "range": {
+ "startPosition": {
+ "line": 65
+ },
+ "endPosition": {
+ "line": 127
+ }
+ },
+ "contents": " set => SetAndRaise(ref _sshPort, value);\n }\n\n public string SshArgs\n {\n get => _sshArgs;\n set => SetAndRaise(ref _sshArgs, value);\n }\n\n public bool HasSheepIt\n {\n get => _hasSheepIt;\n set => SetAndRaise(ref _hasSheepIt, value);\n }\n\n public bool HasFlamenco\n {\n get => _hasFlamenco;\n set => SetAndRaise(ref _hasFlamenco, value);\n }\n\n public string SheepItGpu\n {\n get => _sheepItGpu;\n set => SetAndRaise(ref _sheepItGpu, value);\n }\n\n public ObservableCollection<string> NetworkDrives { get; }\n public ObservableCollection<string> NetworkPaths { get; }\n\n private void LoadWorker(WorkerConfig worker)\n {\n Id = worker.Id;\n Name = worker.Name;\n Enabled = worker.Enabled;\n SshHost = worker.Ssh.Host;\n SshPort = worker.Ssh.Port;\n SshArgs = worker.Ssh.Args;\n\n if (worker.WorkerTypes.SheepIt != null)\n {\n HasSheepIt = true;\n SheepItGpu = worker.WorkerTypes.SheepIt.Gpu;\n }\n\n if (worker.WorkerTypes.Flamenco != null)\n {\n HasFlamenco = true;\n NetworkDrives.Clear();\n foreach (var drive in worker.WorkerTypes.Flamenco.NetworkDrives)\n {\n NetworkDrives.Add(drive);\n }\n NetworkPaths.Clear();\n foreach (var path in worker.WorkerTypes.Flamenco.NetworkPaths)\n {\n NetworkPaths.Add(path);\n }\n }\n }\n\n public WorkerConfig ToWorkerConfig()",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": " set => SetAndRaise(ref _sshPort, value);",
+ "lineNumber": 66
+ },
+ {
+ "text": " }",
+ "lineNumber": 67
+ },
+ {
+ "lineNumber": 68
+ },
+ {
+ "text": " public string SshArgs",
+ "lineNumber": 69
+ },
+ {
+ "text": " {",
+ "lineNumber": 70
+ },
+ {
+ "text": " get => _sshArgs;",
+ "lineNumber": 71
+ },
+ {
+ "text": " set => SetAndRaise(ref _sshArgs, value);",
+ "lineNumber": 72
+ },
+ {
+ "text": " }",
+ "lineNumber": 73
+ },
+ {
+ "lineNumber": 74
+ },
+ {
+ "text": " public bool HasSheepIt",
+ "lineNumber": 75
+ },
+ {
+ "text": " {",
+ "lineNumber": 76
+ },
+ {
+ "text": " get => _hasSheepIt;",
+ "lineNumber": 77
+ },
+ {
+ "text": " set => SetAndRaise(ref _hasSheepIt, value);",
+ "lineNumber": 78
+ },
+ {
+ "text": " }",
+ "lineNumber": 79
+ },
+ {
+ "lineNumber": 80
+ },
+ {
+ "text": " public bool HasFlamenco",
+ "lineNumber": 81
+ },
+ {
+ "text": " {",
+ "lineNumber": 82
+ },
+ {
+ "text": " get => _hasFlamenco;",
+ "lineNumber": 83
+ },
+ {
+ "text": " set => SetAndRaise(ref _hasFlamenco, value);",
+ "lineNumber": 84
+ },
+ {
+ "text": " }",
+ "lineNumber": 85
+ },
+ {
+ "lineNumber": 86
+ },
+ {
+ "text": " public string SheepItGpu",
+ "lineNumber": 87
+ },
+ {
+ "text": " {",
+ "lineNumber": 88
+ },
+ {
+ "text": " get => _sheepItGpu;",
+ "lineNumber": 89
+ },
+ {
+ "text": " set => SetAndRaise(ref _sheepItGpu, value);",
+ "lineNumber": 90
+ },
+ {
+ "text": " }",
+ "lineNumber": 91
+ },
+ {
+ "lineNumber": 92
+ },
+ {
+ "text": " public ObservableCollection<string> NetworkDrives { get; }",
+ "lineNumber": 93
+ },
+ {
+ "text": " public ObservableCollection<string> NetworkPaths { get; }",
+ "lineNumber": 94
+ },
+ {
+ "lineNumber": 95
+ },
+ {
+ "text": " private void LoadWorker(WorkerConfig worker)",
+ "lineNumber": 96
+ },
+ {
+ "text": " {",
+ "lineNumber": 97
+ },
+ {
+ "text": " Id = worker.Id;",
+ "lineNumber": 98
+ },
+ {
+ "text": " Name = worker.Name;",
+ "lineNumber": 99
+ },
+ {
+ "text": " Enabled = worker.Enabled;",
+ "lineNumber": 100
+ },
+ {
+ "text": " SshHost = worker.Ssh.Host;",
+ "lineNumber": 101
+ },
+ {
+ "text": " SshPort = worker.Ssh.Port;",
+ "lineNumber": 102
+ },
+ {
+ "text": " SshArgs = worker.Ssh.Args;",
+ "lineNumber": 103
+ },
+ {
+ "lineNumber": 104
+ },
+ {
+ "text": " if (worker.WorkerTypes.SheepIt != null)",
+ "lineNumber": 105
+ },
+ {
+ "text": " {",
+ "lineNumber": 106
+ },
+ {
+ "text": " HasSheepIt = true;",
+ "lineNumber": 107
+ },
+ {
+ "text": " SheepItGpu = worker.WorkerTypes.SheepIt.Gpu;",
+ "lineNumber": 108
+ },
+ {
+ "text": " }",
+ "lineNumber": 109
+ },
+ {
+ "lineNumber": 110
+ },
+ {
+ "text": " if (worker.WorkerTypes.Flamenco != null)",
+ "lineNumber": 111
+ },
+ {
+ "text": " {",
+ "lineNumber": 112
+ },
+ {
+ "text": " HasFlamenco = true;",
+ "lineNumber": 113
+ },
+ {
+ "text": " NetworkDrives.Clear();",
+ "lineNumber": 114
+ },
+ {
+ "text": " foreach (var drive in worker.WorkerTypes.Flamenco.NetworkDrives)",
+ "lineNumber": 115
+ },
+ {
+ "text": " {",
+ "lineNumber": 116
+ },
+ {
+ "text": " NetworkDrives.Add(drive);",
+ "lineNumber": 117
+ },
+ {
+ "text": " }",
+ "lineNumber": 118
+ },
+ {
+ "text": " NetworkPaths.Clear();",
+ "lineNumber": 119
+ },
+ {
+ "text": " foreach (var path in worker.WorkerTypes.Flamenco.NetworkPaths)",
+ "lineNumber": 120
+ },
+ {
+ "text": " {",
+ "lineNumber": 121
+ },
+ {
+ "text": " NetworkPaths.Add(path);",
+ "lineNumber": 122
+ },
+ {
+ "text": " }",
+ "lineNumber": 123
+ },
+ {
+ "text": " }",
+ "lineNumber": 124
+ },
+ {
+ "text": " }",
+ "lineNumber": 125
+ },
+ {
+ "lineNumber": 126
+ },
+ {
+ "text": " public WorkerConfig ToWorkerConfig()",
+ "lineNumber": 127
+ }
+ ]
+ },
+ "score": 0.428444504737854
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\ViewModels\\WorkerEditViewModel.cs",
+ "range": {
+ "startPosition": {},
+ "endPosition": {
+ "line": 71
+ }
+ },
+ "contents": "using System.Collections.ObjectModel;\nusing System.Linq;\nusing UnifiedFarmLauncher.Models;\nusing UnifiedFarmLauncher.Services;\n\nnamespace UnifiedFarmLauncher.ViewModels\n{\n public class WorkerEditViewModel : ViewModelBase\n {\n private readonly ConfigService _configService;\n private readonly bool _isNew;\n private int _id;\n private string _name = string.Empty;\n private bool _enabled = true;\n private string _sshHost = string.Empty;\n private int _sshPort = 22;\n private string _sshArgs = string.Empty;\n private string _sheepItGpu = \"OPTIX_0\";\n private bool _hasSheepIt;\n private bool _hasFlamenco;\n\n public WorkerEditViewModel(ConfigService configService, WorkerConfig? worker = null)\n {\n _configService = configService;\n _isNew = worker == null;\n NetworkDrives = new ObservableCollection<string>();\n NetworkPaths = new ObservableCollection<string>();\n\n if (worker != null)\n {\n LoadWorker(worker);\n }\n else\n {\n _id = _configService.GetNextWorkerId();\n }\n }\n\n public int Id\n {\n get => _id;\n set => SetAndRaise(ref _id, value);\n }\n\n public string Name\n {\n get => _name;\n set => SetAndRaise(ref _name, value);\n }\n\n public bool Enabled\n {\n get => _enabled;\n set => SetAndRaise(ref _enabled, value);\n }\n\n public string SshHost\n {\n get => _sshHost;\n set => SetAndRaise(ref _sshHost, value);\n }\n\n public int SshPort\n {\n get => _sshPort;\n set => SetAndRaise(ref _sshPort, value);\n }\n\n public string SshArgs\n {\n get => _sshArgs;",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": "using System.Collections.ObjectModel;",
+ "lineNumber": 1
+ },
+ {
+ "text": "using System.Linq;",
+ "lineNumber": 2
+ },
+ {
+ "text": "using UnifiedFarmLauncher.Models;",
+ "lineNumber": 3
+ },
+ {
+ "text": "using UnifiedFarmLauncher.Services;",
+ "lineNumber": 4
+ },
+ {
+ "lineNumber": 5
+ },
+ {
+ "text": "namespace UnifiedFarmLauncher.ViewModels",
+ "lineNumber": 6
+ },
+ {
+ "text": "{",
+ "lineNumber": 7
+ },
+ {
+ "text": " public class WorkerEditViewModel : ViewModelBase",
+ "lineNumber": 8
+ },
+ {
+ "text": " {",
+ "lineNumber": 9
+ },
+ {
+ "text": " private readonly ConfigService _configService;",
+ "lineNumber": 10
+ },
+ {
+ "text": " private readonly bool _isNew;",
+ "lineNumber": 11
+ },
+ {
+ "text": " private int _id;",
+ "lineNumber": 12
+ },
+ {
+ "text": " private string _name = string.Empty;",
+ "lineNumber": 13
+ },
+ {
+ "text": " private bool _enabled = true;",
+ "lineNumber": 14
+ },
+ {
+ "text": " private string _sshHost = string.Empty;",
+ "lineNumber": 15
+ },
+ {
+ "text": " private int _sshPort = 22;",
+ "lineNumber": 16
+ },
+ {
+ "text": " private string _sshArgs = string.Empty;",
+ "lineNumber": 17
+ },
+ {
+ "text": " private string _sheepItGpu = \"OPTIX_0\";",
+ "lineNumber": 18
+ },
+ {
+ "text": " private bool _hasSheepIt;",
+ "lineNumber": 19
+ },
+ {
+ "text": " private bool _hasFlamenco;",
+ "lineNumber": 20
+ },
+ {
+ "lineNumber": 21
+ },
+ {
+ "text": " public WorkerEditViewModel(ConfigService configService, WorkerConfig? worker = null)",
+ "lineNumber": 22
+ },
+ {
+ "text": " {",
+ "lineNumber": 23
+ },
+ {
+ "text": " _configService = configService;",
+ "lineNumber": 24
+ },
+ {
+ "text": " _isNew = worker == null;",
+ "lineNumber": 25
+ },
+ {
+ "text": " NetworkDrives = new ObservableCollection<string>();",
+ "lineNumber": 26
+ },
+ {
+ "text": " NetworkPaths = new ObservableCollection<string>();",
+ "lineNumber": 27
+ },
+ {
+ "lineNumber": 28
+ },
+ {
+ "text": " if (worker != null)",
+ "lineNumber": 29
+ },
+ {
+ "text": " {",
+ "lineNumber": 30
+ },
+ {
+ "text": " LoadWorker(worker);",
+ "lineNumber": 31
+ },
+ {
+ "text": " }",
+ "lineNumber": 32
+ },
+ {
+ "text": " else",
+ "lineNumber": 33
+ },
+ {
+ "text": " {",
+ "lineNumber": 34
+ },
+ {
+ "text": " _id = _configService.GetNextWorkerId();",
+ "lineNumber": 35
+ },
+ {
+ "text": " }",
+ "lineNumber": 36
+ },
+ {
+ "text": " }",
+ "lineNumber": 37
+ },
+ {
+ "lineNumber": 38
+ },
+ {
+ "text": " public int Id",
+ "lineNumber": 39
+ },
+ {
+ "text": " {",
+ "lineNumber": 40
+ },
+ {
+ "text": " get => _id;",
+ "lineNumber": 41
+ },
+ {
+ "text": " set => SetAndRaise(ref _id, value);",
+ "lineNumber": 42
+ },
+ {
+ "text": " }",
+ "lineNumber": 43
+ },
+ {
+ "lineNumber": 44
+ },
+ {
+ "text": " public string Name",
+ "lineNumber": 45
+ },
+ {
+ "text": " {",
+ "lineNumber": 46
+ },
+ {
+ "text": " get => _name;",
+ "lineNumber": 47
+ },
+ {
+ "text": " set => SetAndRaise(ref _name, value);",
+ "lineNumber": 48
+ },
+ {
+ "text": " }",
+ "lineNumber": 49
+ },
+ {
+ "lineNumber": 50
+ },
+ {
+ "text": " public bool Enabled",
+ "lineNumber": 51
+ },
+ {
+ "text": " {",
+ "lineNumber": 52
+ },
+ {
+ "text": " get => _enabled;",
+ "lineNumber": 53
+ },
+ {
+ "text": " set => SetAndRaise(ref _enabled, value);",
+ "lineNumber": 54
+ },
+ {
+ "text": " }",
+ "lineNumber": 55
+ },
+ {
+ "lineNumber": 56
+ },
+ {
+ "text": " public string SshHost",
+ "lineNumber": 57
+ },
+ {
+ "text": " {",
+ "lineNumber": 58
+ },
+ {
+ "text": " get => _sshHost;",
+ "lineNumber": 59
+ },
+ {
+ "text": " set => SetAndRaise(ref _sshHost, value);",
+ "lineNumber": 60
+ },
+ {
+ "text": " }",
+ "lineNumber": 61
+ },
+ {
+ "lineNumber": 62
+ },
+ {
+ "text": " public int SshPort",
+ "lineNumber": 63
+ },
+ {
+ "text": " {",
+ "lineNumber": 64
+ },
+ {
+ "text": " get => _sshPort;",
+ "lineNumber": 65
+ },
+ {
+ "text": " set => SetAndRaise(ref _sshPort, value);",
+ "lineNumber": 66
+ },
+ {
+ "text": " }",
+ "lineNumber": 67
+ },
+ {
+ "lineNumber": 68
+ },
+ {
+ "text": " public string SshArgs",
+ "lineNumber": 69
+ },
+ {
+ "text": " {",
+ "lineNumber": 70
+ },
+ {
+ "text": " get => _sshArgs;",
+ "lineNumber": 71
+ }
+ ]
+ },
+ "score": 0.42505720257759094
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\ViewModels\\WorkerEditViewModel.cs",
+ "range": {
+ "startPosition": {
+ "line": 122,
+ "column": 16
+ },
+ "endPosition": {
+ "line": 177
+ }
+ },
+ "contents": "}\n }\n }\n\n public WorkerConfig ToWorkerConfig()\n {\n var worker = new WorkerConfig\n {\n Id = Id,\n Name = Name,\n Enabled = Enabled,\n Ssh = new SshConfig\n {\n Host = SshHost,\n Port = SshPort,\n Args = SshArgs\n },\n WorkerTypes = new WorkerTypeConfig()\n };\n\n if (HasSheepIt)\n {\n worker.WorkerTypes.SheepIt = new SheepItConfig\n {\n Gpu = SheepItGpu\n };\n }\n\n if (HasFlamenco)\n {\n worker.WorkerTypes.Flamenco = new FlamencoConfig\n {\n NetworkDrives = NetworkDrives.ToList(),\n NetworkPaths = NetworkPaths.ToList()\n };\n }\n\n return worker;\n }\n\n public void Save()\n {\n var worker = ToWorkerConfig();\n if (_isNew)\n {\n _configService.AddWorker(worker);\n }\n else\n {\n _configService.UpdateWorker(worker);\n }\n }\n }\n}",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": "}",
+ "lineNumber": 123
+ },
+ {
+ "text": " }",
+ "lineNumber": 124
+ },
+ {
+ "text": " }",
+ "lineNumber": 125
+ },
+ {
+ "lineNumber": 126
+ },
+ {
+ "text": " public WorkerConfig ToWorkerConfig()",
+ "lineNumber": 127
+ },
+ {
+ "text": " {",
+ "lineNumber": 128
+ },
+ {
+ "text": " var worker = new WorkerConfig",
+ "lineNumber": 129
+ },
+ {
+ "text": " {",
+ "lineNumber": 130
+ },
+ {
+ "text": " Id = Id,",
+ "lineNumber": 131
+ },
+ {
+ "text": " Name = Name,",
+ "lineNumber": 132
+ },
+ {
+ "text": " Enabled = Enabled,",
+ "lineNumber": 133
+ },
+ {
+ "text": " Ssh = new SshConfig",
+ "lineNumber": 134
+ },
+ {
+ "text": " {",
+ "lineNumber": 135
+ },
+ {
+ "text": " Host = SshHost,",
+ "lineNumber": 136
+ },
+ {
+ "text": " Port = SshPort,",
+ "lineNumber": 137
+ },
+ {
+ "text": " Args = SshArgs",
+ "lineNumber": 138
+ },
+ {
+ "text": " },",
+ "lineNumber": 139
+ },
+ {
+ "text": " WorkerTypes = new WorkerTypeConfig()",
+ "lineNumber": 140
+ },
+ {
+ "text": " };",
+ "lineNumber": 141
+ },
+ {
+ "lineNumber": 142
+ },
+ {
+ "text": " if (HasSheepIt)",
+ "lineNumber": 143
+ },
+ {
+ "text": " {",
+ "lineNumber": 144
+ },
+ {
+ "text": " worker.WorkerTypes.SheepIt = new SheepItConfig",
+ "lineNumber": 145
+ },
+ {
+ "text": " {",
+ "lineNumber": 146
+ },
+ {
+ "text": " Gpu = SheepItGpu",
+ "lineNumber": 147
+ },
+ {
+ "text": " };",
+ "lineNumber": 148
+ },
+ {
+ "text": " }",
+ "lineNumber": 149
+ },
+ {
+ "lineNumber": 150
+ },
+ {
+ "text": " if (HasFlamenco)",
+ "lineNumber": 151
+ },
+ {
+ "text": " {",
+ "lineNumber": 152
+ },
+ {
+ "text": " worker.WorkerTypes.Flamenco = new FlamencoConfig",
+ "lineNumber": 153
+ },
+ {
+ "text": " {",
+ "lineNumber": 154
+ },
+ {
+ "text": " NetworkDrives = NetworkDrives.ToList(),",
+ "lineNumber": 155
+ },
+ {
+ "text": " NetworkPaths = NetworkPaths.ToList()",
+ "lineNumber": 156
+ },
+ {
+ "text": " };",
+ "lineNumber": 157
+ },
+ {
+ "text": " }",
+ "lineNumber": 158
+ },
+ {
+ "lineNumber": 159
+ },
+ {
+ "text": " return worker;",
+ "lineNumber": 160
+ },
+ {
+ "text": " }",
+ "lineNumber": 161
+ },
+ {
+ "lineNumber": 162
+ },
+ {
+ "text": " public void Save()",
+ "lineNumber": 163
+ },
+ {
+ "text": " {",
+ "lineNumber": 164
+ },
+ {
+ "text": " var worker = ToWorkerConfig();",
+ "lineNumber": 165
+ },
+ {
+ "text": " if (_isNew)",
+ "lineNumber": 166
+ },
+ {
+ "text": " {",
+ "lineNumber": 167
+ },
+ {
+ "text": " _configService.AddWorker(worker);",
+ "lineNumber": 168
+ },
+ {
+ "text": " }",
+ "lineNumber": 169
+ },
+ {
+ "text": " else",
+ "lineNumber": 170
+ },
+ {
+ "text": " {",
+ "lineNumber": 171
+ },
+ {
+ "text": " _configService.UpdateWorker(worker);",
+ "lineNumber": 172
+ },
+ {
+ "text": " }",
+ "lineNumber": 173
+ },
+ {
+ "text": " }",
+ "lineNumber": 174
+ },
+ {
+ "text": " }",
+ "lineNumber": 175
+ },
+ {
+ "text": "}",
+ "lineNumber": 176
+ }
+ ]
+ },
+ "score": 0.40253424644470215
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\Views\\WorkerEditWindow.axaml",
+ "range": {
+ "startPosition": {},
+ "endPosition": {
+ "line": 32,
+ "column": 16
+ }
+ },
+ "contents": "<Window xmlns=\"https://github.com/avaloniaui\"\n xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n xmlns:vm=\"using:UnifiedFarmLauncher.ViewModels\"\n x:Class=\"UnifiedFarmLauncher.Views.WorkerEditWindow\"\n x:DataType=\"vm:WorkerEditViewModel\"\n Title=\"Edit Worker\"\n Width=\"600\" Height=\"700\"\n MinWidth=\"500\" MinHeight=\"600\">\n <Grid RowDefinitions=\"Auto,*,Auto\" Margin=\"10\">\n <!-- Tabs -->\n <TabControl Grid.Row=\"1\" Margin=\"0,10\">\n <!-- Basic Info Tab -->\n <TabItem Header=\"Basic Info\">\n <StackPanel Margin=\"10\" Spacing=\"10\">\n <TextBlock Text=\"Worker Name:\"/>\n <TextBox Name=\"NameTextBox\" Text=\"{Binding Name}\"/>\n \n <CheckBox Name=\"EnabledCheckBox\" Content=\"Enabled\" IsChecked=\"{Binding Enabled}\" Margin=\"0,10,0,0\"/>\n \n <TextBlock Text=\"SSH Host:\" Margin=\"0,10,0,0\"/>\n <TextBox Name=\"SshHostTextBox\" Text=\"{Binding SshHost}\"/>\n \n <TextBlock Text=\"SSH Port:\" Margin=\"0,10,0,0\"/>\n <NumericUpDown Name=\"SshPortNumeric\" Value=\"{Binding SshPort}\" Minimum=\"1\" Maximum=\"65535\"/>\n \n <TextBlock Text=\"SSH Args:\" Margin=\"0,10,0,0\"/>\n <TextBox Name=\"SshArgsTextBox\" Text=\"{Binding SshArgs}\"/>\n </StackPanel>\n </TabItem>\n\n <!-- SheepIt Tab -->\n <TabItem Header=\"SheepIt\">\n ",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": "<Window xmlns=\"https://github.com/avaloniaui\"",
+ "lineNumber": 1
+ },
+ {
+ "text": " xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"",
+ "lineNumber": 2
+ },
+ {
+ "text": " xmlns:vm=\"using:UnifiedFarmLauncher.ViewModels\"",
+ "lineNumber": 3
+ },
+ {
+ "text": " x:Class=\"UnifiedFarmLauncher.Views.WorkerEditWindow\"",
+ "lineNumber": 4
+ },
+ {
+ "text": " x:DataType=\"vm:WorkerEditViewModel\"",
+ "lineNumber": 5
+ },
+ {
+ "text": " Title=\"Edit Worker\"",
+ "lineNumber": 6
+ },
+ {
+ "text": " Width=\"600\" Height=\"700\"",
+ "lineNumber": 7
+ },
+ {
+ "text": " MinWidth=\"500\" MinHeight=\"600\">",
+ "lineNumber": 8
+ },
+ {
+ "text": " <Grid RowDefinitions=\"Auto,*,Auto\" Margin=\"10\">",
+ "lineNumber": 9
+ },
+ {
+ "text": " <!-- Tabs -->",
+ "lineNumber": 10
+ },
+ {
+ "text": " <TabControl Grid.Row=\"1\" Margin=\"0,10\">",
+ "lineNumber": 11
+ },
+ {
+ "text": " <!-- Basic Info Tab -->",
+ "lineNumber": 12
+ },
+ {
+ "text": " <TabItem Header=\"Basic Info\">",
+ "lineNumber": 13
+ },
+ {
+ "text": " <StackPanel Margin=\"10\" Spacing=\"10\">",
+ "lineNumber": 14
+ },
+ {
+ "text": " <TextBlock Text=\"Worker Name:\"/>",
+ "lineNumber": 15
+ },
+ {
+ "text": " <TextBox Name=\"NameTextBox\" Text=\"{Binding Name}\"/>",
+ "lineNumber": 16
+ },
+ {
+ "text": " ",
+ "lineNumber": 17
+ },
+ {
+ "text": " <CheckBox Name=\"EnabledCheckBox\" Content=\"Enabled\" IsChecked=\"{Binding Enabled}\" Margin=\"0,10,0,0\"/>",
+ "lineNumber": 18
+ },
+ {
+ "text": " ",
+ "lineNumber": 19
+ },
+ {
+ "text": " <TextBlock Text=\"SSH Host:\" Margin=\"0,10,0,0\"/>",
+ "lineNumber": 20
+ },
+ {
+ "text": " <TextBox Name=\"SshHostTextBox\" Text=\"{Binding SshHost}\"/>",
+ "lineNumber": 21
+ },
+ {
+ "text": " ",
+ "lineNumber": 22
+ },
+ {
+ "text": " <TextBlock Text=\"SSH Port:\" Margin=\"0,10,0,0\"/>",
+ "lineNumber": 23
+ },
+ {
+ "text": " <NumericUpDown Name=\"SshPortNumeric\" Value=\"{Binding SshPort}\" Minimum=\"1\" Maximum=\"65535\"/>",
+ "lineNumber": 24
+ },
+ {
+ "text": " ",
+ "lineNumber": 25
+ },
+ {
+ "text": " <TextBlock Text=\"SSH Args:\" Margin=\"0,10,0,0\"/>",
+ "lineNumber": 26
+ },
+ {
+ "text": " <TextBox Name=\"SshArgsTextBox\" Text=\"{Binding SshArgs}\"/>",
+ "lineNumber": 27
+ },
+ {
+ "text": " </StackPanel>",
+ "lineNumber": 28
+ },
+ {
+ "text": " </TabItem>",
+ "lineNumber": 29
+ },
+ {
+ "lineNumber": 30
+ },
+ {
+ "text": " <!-- SheepIt Tab -->",
+ "lineNumber": 31
+ },
+ {
+ "text": " <TabItem Header=\"SheepIt\">",
+ "lineNumber": 32
+ },
+ {
+ "text": " ",
+ "lineNumber": 33
+ }
+ ]
+ },
+ "score": 0.349617600440979
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\Views\\WorkerEditWindow.axaml.cs",
+ "range": {
+ "startPosition": {},
+ "endPosition": {
+ "line": 50
+ }
+ },
+ "contents": "using System;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing Avalonia.Controls;\nusing Avalonia.Interactivity;\nusing Avalonia.Platform.Storage;\nusing UnifiedFarmLauncher.Models;\nusing UnifiedFarmLauncher.Services;\nusing UnifiedFarmLauncher.ViewModels;\nusing MsBox.Avalonia;\nusing MsBox.Avalonia.Enums;\n\nnamespace UnifiedFarmLauncher.Views\n{\n public partial class WorkerEditWindow : Window\n {\n private readonly WorkerEditViewModel _viewModel;\n private bool _result;\n\n public WorkerEditWindow() : this(null)\n {\n }\n\n public WorkerEditWindow(WorkerConfig? worker)\n {\n InitializeComponent();\n var configService = new ConfigService();\n _viewModel = new WorkerEditViewModel(configService, worker);\n DataContext = _viewModel;\n SetupEventHandlers();\n }\n\n private void InitializeComponent()\n {\n Avalonia.Markup.Xaml.AvaloniaXamlLoader.Load(this);\n }\n\n private void SetupEventHandlers()\n {\n this.FindControl<Button>(\"OkButton\")!.Click += OkButton_Click;\n this.FindControl<Button>(\"CancelButton\")!.Click += CancelButton_Click;\n this.FindControl<Button>(\"AddDriveButton\")!.Click += AddDriveButton_Click;\n this.FindControl<Button>(\"RemoveDriveButton\")!.Click += RemoveDriveButton_Click;\n this.FindControl<Button>(\"AddPathButton\")!.Click += AddPathButton_Click;\n this.FindControl<Button>(\"RemovePathButton\")!.Click += RemovePathButton_Click;\n }\n\n private async void OkButton_Click(object? sender, RoutedEventArgs e)\n {\n if (string.IsNullOrWhiteSpace(_viewModel.Name))",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": "using System;",
+ "lineNumber": 1
+ },
+ {
+ "text": "using System.Linq;",
+ "lineNumber": 2
+ },
+ {
+ "text": "using System.Threading.Tasks;",
+ "lineNumber": 3
+ },
+ {
+ "text": "using Avalonia.Controls;",
+ "lineNumber": 4
+ },
+ {
+ "text": "using Avalonia.Interactivity;",
+ "lineNumber": 5
+ },
+ {
+ "text": "using Avalonia.Platform.Storage;",
+ "lineNumber": 6
+ },
+ {
+ "text": "using UnifiedFarmLauncher.Models;",
+ "lineNumber": 7
+ },
+ {
+ "text": "using UnifiedFarmLauncher.Services;",
+ "lineNumber": 8
+ },
+ {
+ "text": "using UnifiedFarmLauncher.ViewModels;",
+ "lineNumber": 9
+ },
+ {
+ "text": "using MsBox.Avalonia;",
+ "lineNumber": 10
+ },
+ {
+ "text": "using MsBox.Avalonia.Enums;",
+ "lineNumber": 11
+ },
+ {
+ "lineNumber": 12
+ },
+ {
+ "text": "namespace UnifiedFarmLauncher.Views",
+ "lineNumber": 13
+ },
+ {
+ "text": "{",
+ "lineNumber": 14
+ },
+ {
+ "text": " public partial class WorkerEditWindow : Window",
+ "lineNumber": 15
+ },
+ {
+ "text": " {",
+ "lineNumber": 16
+ },
+ {
+ "text": " private readonly WorkerEditViewModel _viewModel;",
+ "lineNumber": 17
+ },
+ {
+ "text": " private bool _result;",
+ "lineNumber": 18
+ },
+ {
+ "lineNumber": 19
+ },
+ {
+ "text": " public WorkerEditWindow() : this(null)",
+ "lineNumber": 20
+ },
+ {
+ "text": " {",
+ "lineNumber": 21
+ },
+ {
+ "text": " }",
+ "lineNumber": 22
+ },
+ {
+ "lineNumber": 23
+ },
+ {
+ "text": " public WorkerEditWindow(WorkerConfig? worker)",
+ "lineNumber": 24
+ },
+ {
+ "text": " {",
+ "lineNumber": 25
+ },
+ {
+ "text": " InitializeComponent();",
+ "lineNumber": 26
+ },
+ {
+ "text": " var configService = new ConfigService();",
+ "lineNumber": 27
+ },
+ {
+ "text": " _viewModel = new WorkerEditViewModel(configService, worker);",
+ "lineNumber": 28
+ },
+ {
+ "text": " DataContext = _viewModel;",
+ "lineNumber": 29
+ },
+ {
+ "text": " SetupEventHandlers();",
+ "lineNumber": 30
+ },
+ {
+ "text": " }",
+ "lineNumber": 31
+ },
+ {
+ "lineNumber": 32
+ },
+ {
+ "text": " private void InitializeComponent()",
+ "lineNumber": 33
+ },
+ {
+ "text": " {",
+ "lineNumber": 34
+ },
+ {
+ "text": " Avalonia.Markup.Xaml.AvaloniaXamlLoader.Load(this);",
+ "lineNumber": 35
+ },
+ {
+ "text": " }",
+ "lineNumber": 36
+ },
+ {
+ "lineNumber": 37
+ },
+ {
+ "text": " private void SetupEventHandlers()",
+ "lineNumber": 38
+ },
+ {
+ "text": " {",
+ "lineNumber": 39
+ },
+ {
+ "text": " this.FindControl<Button>(\"OkButton\")!.Click += OkButton_Click;",
+ "lineNumber": 40
+ },
+ {
+ "text": " this.FindControl<Button>(\"CancelButton\")!.Click += CancelButton_Click;",
+ "lineNumber": 41
+ },
+ {
+ "text": " this.FindControl<Button>(\"AddDriveButton\")!.Click += AddDriveButton_Click;",
+ "lineNumber": 42
+ },
+ {
+ "text": " this.FindControl<Button>(\"RemoveDriveButton\")!.Click += RemoveDriveButton_Click;",
+ "lineNumber": 43
+ },
+ {
+ "text": " this.FindControl<Button>(\"AddPathButton\")!.Click += AddPathButton_Click;",
+ "lineNumber": 44
+ },
+ {
+ "text": " this.FindControl<Button>(\"RemovePathButton\")!.Click += RemovePathButton_Click;",
+ "lineNumber": 45
+ },
+ {
+ "text": " }",
+ "lineNumber": 46
+ },
+ {
+ "lineNumber": 47
+ },
+ {
+ "text": " private async void OkButton_Click(object? sender, RoutedEventArgs e)",
+ "lineNumber": 48
+ },
+ {
+ "text": " {",
+ "lineNumber": 49
+ },
+ {
+ "text": " if (string.IsNullOrWhiteSpace(_viewModel.Name))",
+ "lineNumber": 50
+ }
+ ]
+ },
+ "score": 0.31477874517440796
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\Views\\WorkerEditWindow.axaml.cs",
+ "range": {
+ "startPosition": {
+ "line": 48
+ },
+ "endPosition": {
+ "line": 104
+ }
+ },
+ "contents": " {\n if (string.IsNullOrWhiteSpace(_viewModel.Name))\n {\n var box = MessageBoxManager.GetMessageBoxStandard(\"Error\", \n \"Worker name is required.\", \n ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error);\n await box.ShowAsync();\n return;\n }\n\n try\n {\n _viewModel.Save();\n _result = true;\n Close();\n }\n catch (Exception ex)\n {\n var errorBox = MessageBoxManager.GetMessageBoxStandard(\"Error\", \n $\"Failed to save worker: {ex.Message}\", \n ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error);\n await errorBox.ShowAsync();\n }\n }\n\n private void CancelButton_Click(object? sender, RoutedEventArgs e)\n {\n _result = false;\n Close();\n }\n\n private void AddDriveButton_Click(object? sender, RoutedEventArgs e)\n {\n // Simplified: use a simple input box\n // In a full implementation, you'd use a proper input dialog\n _viewModel.NetworkDrives.Add(\"A:\");\n }\n\n private void RemoveDriveButton_Click(object? sender, RoutedEventArgs e)\n {\n if (this.FindControl<ListBox>(\"NetworkDrivesListBox\")?.SelectedItem is string drive)\n {\n _viewModel.NetworkDrives.Remove(drive);\n }\n }\n\n private void AddPathButton_Click(object? sender, RoutedEventArgs e)\n {\n // Simplified: use a simple input box\n // In a full implementation, you'd use a proper input dialog\n _viewModel.NetworkPaths.Add(\"\\\\\\\\SERVER\\\\share\");\n }\n\n private void RemovePathButton_Click(object? sender, RoutedEventArgs e)\n {\n if (this.FindControl<ListBox>(\"NetworkPathsListBox\")?.SelectedItem is string path)",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": " {",
+ "lineNumber": 49
+ },
+ {
+ "text": " if (string.IsNullOrWhiteSpace(_viewModel.Name))",
+ "lineNumber": 50
+ },
+ {
+ "text": " {",
+ "lineNumber": 51
+ },
+ {
+ "text": " var box = MessageBoxManager.GetMessageBoxStandard(\"Error\", ",
+ "lineNumber": 52
+ },
+ {
+ "text": " \"Worker name is required.\", ",
+ "lineNumber": 53
+ },
+ {
+ "text": " ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error);",
+ "lineNumber": 54
+ },
+ {
+ "text": " await box.ShowAsync();",
+ "lineNumber": 55
+ },
+ {
+ "text": " return;",
+ "lineNumber": 56
+ },
+ {
+ "text": " }",
+ "lineNumber": 57
+ },
+ {
+ "lineNumber": 58
+ },
+ {
+ "text": " try",
+ "lineNumber": 59
+ },
+ {
+ "text": " {",
+ "lineNumber": 60
+ },
+ {
+ "text": " _viewModel.Save();",
+ "lineNumber": 61
+ },
+ {
+ "text": " _result = true;",
+ "lineNumber": 62
+ },
+ {
+ "text": " Close();",
+ "lineNumber": 63
+ },
+ {
+ "text": " }",
+ "lineNumber": 64
+ },
+ {
+ "text": " catch (Exception ex)",
+ "lineNumber": 65
+ },
+ {
+ "text": " {",
+ "lineNumber": 66
+ },
+ {
+ "text": " var errorBox = MessageBoxManager.GetMessageBoxStandard(\"Error\", ",
+ "lineNumber": 67
+ },
+ {
+ "text": " $\"Failed to save worker: {ex.Message}\", ",
+ "lineNumber": 68
+ },
+ {
+ "text": " ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error);",
+ "lineNumber": 69
+ },
+ {
+ "text": " await errorBox.ShowAsync();",
+ "lineNumber": 70
+ },
+ {
+ "text": " }",
+ "lineNumber": 71
+ },
+ {
+ "text": " }",
+ "lineNumber": 72
+ },
+ {
+ "lineNumber": 73
+ },
+ {
+ "text": " private void CancelButton_Click(object? sender, RoutedEventArgs e)",
+ "lineNumber": 74
+ },
+ {
+ "text": " {",
+ "lineNumber": 75
+ },
+ {
+ "text": " _result = false;",
+ "lineNumber": 76
+ },
+ {
+ "text": " Close();",
+ "lineNumber": 77
+ },
+ {
+ "text": " }",
+ "lineNumber": 78
+ },
+ {
+ "lineNumber": 79
+ },
+ {
+ "text": " private void AddDriveButton_Click(object? sender, RoutedEventArgs e)",
+ "lineNumber": 80
+ },
+ {
+ "text": " {",
+ "lineNumber": 81
+ },
+ {
+ "text": " // Simplified: use a simple input box",
+ "lineNumber": 82
+ },
+ {
+ "text": " // In a full implementation, you'd use a proper input dialog",
+ "lineNumber": 83
+ },
+ {
+ "text": " _viewModel.NetworkDrives.Add(\"A:\");",
+ "lineNumber": 84
+ },
+ {
+ "text": " }",
+ "lineNumber": 85
+ },
+ {
+ "lineNumber": 86
+ },
+ {
+ "text": " private void RemoveDriveButton_Click(object? sender, RoutedEventArgs e)",
+ "lineNumber": 87
+ },
+ {
+ "text": " {",
+ "lineNumber": 88
+ },
+ {
+ "text": " if (this.FindControl<ListBox>(\"NetworkDrivesListBox\")?.SelectedItem is string drive)",
+ "lineNumber": 89
+ },
+ {
+ "text": " {",
+ "lineNumber": 90
+ },
+ {
+ "text": " _viewModel.NetworkDrives.Remove(drive);",
+ "lineNumber": 91
+ },
+ {
+ "text": " }",
+ "lineNumber": 92
+ },
+ {
+ "text": " }",
+ "lineNumber": 93
+ },
+ {
+ "lineNumber": 94
+ },
+ {
+ "text": " private void AddPathButton_Click(object? sender, RoutedEventArgs e)",
+ "lineNumber": 95
+ },
+ {
+ "text": " {",
+ "lineNumber": 96
+ },
+ {
+ "text": " // Simplified: use a simple input box",
+ "lineNumber": 97
+ },
+ {
+ "text": " // In a full implementation, you'd use a proper input dialog",
+ "lineNumber": 98
+ },
+ {
+ "text": " _viewModel.NetworkPaths.Add(\"\\\\\\\\SERVER\\\\share\");",
+ "lineNumber": 99
+ },
+ {
+ "text": " }",
+ "lineNumber": 100
+ },
+ {
+ "lineNumber": 101
+ },
+ {
+ "text": " private void RemovePathButton_Click(object? sender, RoutedEventArgs e)",
+ "lineNumber": 102
+ },
+ {
+ "text": " {",
+ "lineNumber": 103
+ },
+ {
+ "text": " if (this.FindControl<ListBox>(\"NetworkPathsListBox\")?.SelectedItem is string path)",
+ "lineNumber": 104
+ }
+ ]
+ },
+ "score": 0.30428460240364075
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\Views\\MainWindow.axaml.cs",
+ "range": {
+ "startPosition": {
+ "line": 31
+ },
+ "endPosition": {
+ "line": 66
+ }
+ },
+ "contents": " }\n\n private void SetupEventHandlers()\n {\n this.FindControl<Button>(\"AddWorkerButton\")!.Click += AddWorkerButton_Click;\n this.FindControl<Button>(\"EditWorkerButton\")!.Click += EditWorkerButton_Click;\n this.FindControl<Button>(\"DeleteWorkerButton\")!.Click += DeleteWorkerButton_Click;\n this.FindControl<Button>(\"StartWorkerButton\")!.Click += StartWorkerButton_Click;\n this.FindControl<Button>(\"StopWorkerButton\")!.Click += StopWorkerButton_Click;\n this.FindControl<Button>(\"AttachWorkerButton\")!.Click += AttachWorkerButton_Click;\n this.FindControl<Button>(\"SettingsButton\")!.Click += SettingsButton_Click;\n this.FindControl<Button>(\"OperationModeToggleButton\")!.Click += OperationModeToggleButton_Click;\n this.FindControl<TabControl>(\"WorkerTypeTabs\")!.SelectionChanged += WorkerTypeTabs_SelectionChanged;\n this.FindControl<DataGrid>(\"WorkersGrid\")!.SelectionChanged += WorkersGrid_SelectionChanged;\n \n }\n\n private void OperationModeToggleButton_Click(object? sender, RoutedEventArgs e)\n {\n if (DataContext is MainWindowViewModel vm)\n {\n vm.OperationMode = vm.OperationMode == \"sheepit\" ? \"flamenco\" : \"sheepit\";\n }\n }\n\n private async void AddWorkerButton_Click(object? sender, RoutedEventArgs e)\n {\n var dialog = new WorkerEditWindow();\n if (await dialog.ShowDialogAsync(this))\n {\n ((MainWindowViewModel)DataContext!).RefreshWorkers();\n }\n }\n\n private async void EditWorkerButton_Click(object? sender, RoutedEventArgs e)",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": " }",
+ "lineNumber": 32
+ },
+ {
+ "lineNumber": 33
+ },
+ {
+ "text": " private void SetupEventHandlers()",
+ "lineNumber": 34
+ },
+ {
+ "text": " {",
+ "lineNumber": 35
+ },
+ {
+ "text": " this.FindControl<Button>(\"AddWorkerButton\")!.Click += AddWorkerButton_Click;",
+ "lineNumber": 36
+ },
+ {
+ "text": " this.FindControl<Button>(\"EditWorkerButton\")!.Click += EditWorkerButton_Click;",
+ "lineNumber": 37
+ },
+ {
+ "text": " this.FindControl<Button>(\"DeleteWorkerButton\")!.Click += DeleteWorkerButton_Click;",
+ "lineNumber": 38
+ },
+ {
+ "text": " this.FindControl<Button>(\"StartWorkerButton\")!.Click += StartWorkerButton_Click;",
+ "lineNumber": 39
+ },
+ {
+ "text": " this.FindControl<Button>(\"StopWorkerButton\")!.Click += StopWorkerButton_Click;",
+ "lineNumber": 40
+ },
+ {
+ "text": " this.FindControl<Button>(\"AttachWorkerButton\")!.Click += AttachWorkerButton_Click;",
+ "lineNumber": 41
+ },
+ {
+ "text": " this.FindControl<Button>(\"SettingsButton\")!.Click += SettingsButton_Click;",
+ "lineNumber": 42
+ },
+ {
+ "text": " this.FindControl<Button>(\"OperationModeToggleButton\")!.Click += OperationModeToggleButton_Click;",
+ "lineNumber": 43
+ },
+ {
+ "text": " this.FindControl<TabControl>(\"WorkerTypeTabs\")!.SelectionChanged += WorkerTypeTabs_SelectionChanged;",
+ "lineNumber": 44
+ },
+ {
+ "text": " this.FindControl<DataGrid>(\"WorkersGrid\")!.SelectionChanged += WorkersGrid_SelectionChanged;",
+ "lineNumber": 45
+ },
+ {
+ "text": " ",
+ "lineNumber": 46
+ },
+ {
+ "text": " }",
+ "lineNumber": 47
+ },
+ {
+ "lineNumber": 48
+ },
+ {
+ "text": " private void OperationModeToggleButton_Click(object? sender, RoutedEventArgs e)",
+ "lineNumber": 49
+ },
+ {
+ "text": " {",
+ "lineNumber": 50
+ },
+ {
+ "text": " if (DataContext is MainWindowViewModel vm)",
+ "lineNumber": 51
+ },
+ {
+ "text": " {",
+ "lineNumber": 52
+ },
+ {
+ "text": " vm.OperationMode = vm.OperationMode == \"sheepit\" ? \"flamenco\" : \"sheepit\";",
+ "lineNumber": 53
+ },
+ {
+ "text": " }",
+ "lineNumber": 54
+ },
+ {
+ "text": " }",
+ "lineNumber": 55
+ },
+ {
+ "lineNumber": 56
+ },
+ {
+ "text": " private async void AddWorkerButton_Click(object? sender, RoutedEventArgs e)",
+ "lineNumber": 57
+ },
+ {
+ "text": " {",
+ "lineNumber": 58
+ },
+ {
+ "text": " var dialog = new WorkerEditWindow();",
+ "lineNumber": 59
+ },
+ {
+ "text": " if (await dialog.ShowDialogAsync(this))",
+ "lineNumber": 60
+ },
+ {
+ "text": " {",
+ "lineNumber": 61
+ },
+ {
+ "text": " ((MainWindowViewModel)DataContext!).RefreshWorkers();",
+ "lineNumber": 62
+ },
+ {
+ "text": " }",
+ "lineNumber": 63
+ },
+ {
+ "text": " }",
+ "lineNumber": 64
+ },
+ {
+ "lineNumber": 65
+ },
+ {
+ "text": " private async void EditWorkerButton_Click(object? sender, RoutedEventArgs e)",
+ "lineNumber": 66
+ }
+ ]
+ },
+ "score": 0.30311059951782227
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\Views\\WorkerEditWindow.axaml",
+ "range": {
+ "startPosition": {
+ "line": 50
+ },
+ "endPosition": {
+ "line": 75
+ }
+ },
+ "contents": " </TabItem>\n\n <!-- Flamenco Tab -->\n <TabItem Header=\"Flamenco\">\n <StackPanel Margin=\"10\" Spacing=\"10\">\n <CheckBox Name=\"HasFlamencoCheckBox\" Content=\"Enable Flamenco Worker\" IsChecked=\"{Binding HasFlamenco}\" Margin=\"0,0,0,10\"/>\n \n <TextBlock Text=\"Note: Worker Path is configured in Global Settings.\" \n IsVisible=\"{Binding HasFlamenco}\" \n Margin=\"0,0,0,10\"\n Foreground=\"Gray\"\n TextWrapping=\"Wrap\"/>\n \n <TextBlock Text=\"Network Drives:\" IsVisible=\"{Binding HasFlamenco}\"/>\n <Grid IsVisible=\"{Binding HasFlamenco}\" RowDefinitions=\"*,Auto\" Margin=\"0,5,0,0\">\n <ListBox Name=\"NetworkDrivesListBox\" Grid.Row=\"0\" ItemsSource=\"{Binding NetworkDrives}\" MaxHeight=\"100\"/>\n <StackPanel Grid.Row=\"1\" Orientation=\"Horizontal\" Margin=\"0,5,0,0\">\n <Button Name=\"AddDriveButton\" Content=\"Add\" Width=\"60\" Margin=\"0,0,5,0\"/>\n <Button Name=\"RemoveDriveButton\" Content=\"Remove\" Width=\"60\"/>\n </StackPanel>\n </Grid>\n \n <TextBlock Text=\"Network Paths:\" IsVisible=\"{Binding HasFlamenco}\" Margin=\"0,10,0,0\"/>\n <Grid IsVisible=\"{Binding HasFlamenco}\" RowDefinitions=\"*,Auto\" Margin=\"0,5,0,0\">\n <ListBox Name=\"NetworkPathsListBox\" Grid.Row=\"0\" ItemsSource=\"{Binding NetworkPaths}\" MaxHeight=\"100\"/>",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": " </TabItem>",
+ "lineNumber": 51
+ },
+ {
+ "lineNumber": 52
+ },
+ {
+ "text": " <!-- Flamenco Tab -->",
+ "lineNumber": 53
+ },
+ {
+ "text": " <TabItem Header=\"Flamenco\">",
+ "lineNumber": 54
+ },
+ {
+ "text": " <StackPanel Margin=\"10\" Spacing=\"10\">",
+ "lineNumber": 55
+ },
+ {
+ "text": " <CheckBox Name=\"HasFlamencoCheckBox\" Content=\"Enable Flamenco Worker\" IsChecked=\"{Binding HasFlamenco}\" Margin=\"0,0,0,10\"/>",
+ "lineNumber": 56
+ },
+ {
+ "text": " ",
+ "lineNumber": 57
+ },
+ {
+ "text": " <TextBlock Text=\"Note: Worker Path is configured in Global Settings.\" ",
+ "lineNumber": 58
+ },
+ {
+ "text": " IsVisible=\"{Binding HasFlamenco}\" ",
+ "lineNumber": 59
+ },
+ {
+ "text": " Margin=\"0,0,0,10\"",
+ "lineNumber": 60
+ },
+ {
+ "text": " Foreground=\"Gray\"",
+ "lineNumber": 61
+ },
+ {
+ "text": " TextWrapping=\"Wrap\"/>",
+ "lineNumber": 62
+ },
+ {
+ "text": " ",
+ "lineNumber": 63
+ },
+ {
+ "text": " <TextBlock Text=\"Network Drives:\" IsVisible=\"{Binding HasFlamenco}\"/>",
+ "lineNumber": 64
+ },
+ {
+ "text": " <Grid IsVisible=\"{Binding HasFlamenco}\" RowDefinitions=\"*,Auto\" Margin=\"0,5,0,0\">",
+ "lineNumber": 65
+ },
+ {
+ "text": " <ListBox Name=\"NetworkDrivesListBox\" Grid.Row=\"0\" ItemsSource=\"{Binding NetworkDrives}\" MaxHeight=\"100\"/>",
+ "lineNumber": 66
+ },
+ {
+ "text": " <StackPanel Grid.Row=\"1\" Orientation=\"Horizontal\" Margin=\"0,5,0,0\">",
+ "lineNumber": 67
+ },
+ {
+ "text": " <Button Name=\"AddDriveButton\" Content=\"Add\" Width=\"60\" Margin=\"0,0,5,0\"/>",
+ "lineNumber": 68
+ },
+ {
+ "text": " <Button Name=\"RemoveDriveButton\" Content=\"Remove\" Width=\"60\"/>",
+ "lineNumber": 69
+ },
+ {
+ "text": " </StackPanel>",
+ "lineNumber": 70
+ },
+ {
+ "text": " </Grid>",
+ "lineNumber": 71
+ },
+ {
+ "text": " ",
+ "lineNumber": 72
+ },
+ {
+ "text": " <TextBlock Text=\"Network Paths:\" IsVisible=\"{Binding HasFlamenco}\" Margin=\"0,10,0,0\"/>",
+ "lineNumber": 73
+ },
+ {
+ "text": " <Grid IsVisible=\"{Binding HasFlamenco}\" RowDefinitions=\"*,Auto\" Margin=\"0,5,0,0\">",
+ "lineNumber": 74
+ },
+ {
+ "text": " <ListBox Name=\"NetworkPathsListBox\" Grid.Row=\"0\" ItemsSource=\"{Binding NetworkPaths}\" MaxHeight=\"100\"/>",
+ "lineNumber": 75
+ }
+ ]
+ },
+ "score": 0.2986319065093994
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\ViewModels\\GlobalSettingsViewModel.cs",
+ "range": {
+ "startPosition": {},
+ "endPosition": {
+ "line": 61
+ }
+ },
+ "contents": "using UnifiedFarmLauncher.Models;\nusing UnifiedFarmLauncher.Services;\n\nnamespace UnifiedFarmLauncher.ViewModels\n{\n public class GlobalSettingsViewModel : ViewModelBase\n {\n private readonly ConfigService _configService;\n private string _sheepItUsername = string.Empty;\n private string _sheepItRenderKey = string.Empty;\n private bool _isRenderKeyVisible = false;\n private string _flamencoWorkerPath = string.Empty;\n\n public GlobalSettingsViewModel(ConfigService configService)\n {\n _configService = configService;\n LoadSettings();\n }\n\n public string SheepItUsername\n {\n get => _sheepItUsername;\n set => SetAndRaise(ref _sheepItUsername, value);\n }\n\n public string SheepItRenderKey\n {\n get => _sheepItRenderKey;\n set => SetAndRaise(ref _sheepItRenderKey, value);\n }\n\n public bool IsRenderKeyVisible\n {\n get => _isRenderKeyVisible;\n set => SetAndRaise(ref _isRenderKeyVisible, value);\n }\n\n public string FlamencoWorkerPath\n {\n get => _flamencoWorkerPath;\n set => SetAndRaise(ref _flamencoWorkerPath, value);\n }\n\n private void LoadSettings()\n {\n var config = _configService.Load();\n SheepItUsername = config.GlobalSettings.SheepItUsername;\n SheepItRenderKey = config.GlobalSettings.SheepItRenderKey;\n FlamencoWorkerPath = config.GlobalSettings.FlamencoWorkerPath;\n }\n\n public void Save()\n {\n var config = _configService.Load();\n config.GlobalSettings.SheepItUsername = SheepItUsername;\n config.GlobalSettings.SheepItRenderKey = SheepItRenderKey;\n config.GlobalSettings.FlamencoWorkerPath = FlamencoWorkerPath;\n _configService.Save(config);\n }\n }\n}",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": "using UnifiedFarmLauncher.Models;",
+ "lineNumber": 1
+ },
+ {
+ "text": "using UnifiedFarmLauncher.Services;",
+ "lineNumber": 2
+ },
+ {
+ "lineNumber": 3
+ },
+ {
+ "text": "namespace UnifiedFarmLauncher.ViewModels",
+ "lineNumber": 4
+ },
+ {
+ "text": "{",
+ "lineNumber": 5
+ },
+ {
+ "text": " public class GlobalSettingsViewModel : ViewModelBase",
+ "lineNumber": 6
+ },
+ {
+ "text": " {",
+ "lineNumber": 7
+ },
+ {
+ "text": " private readonly ConfigService _configService;",
+ "lineNumber": 8
+ },
+ {
+ "text": " private string _sheepItUsername = string.Empty;",
+ "lineNumber": 9
+ },
+ {
+ "text": " private string _sheepItRenderKey = string.Empty;",
+ "lineNumber": 10
+ },
+ {
+ "text": " private bool _isRenderKeyVisible = false;",
+ "lineNumber": 11
+ },
+ {
+ "text": " private string _flamencoWorkerPath = string.Empty;",
+ "lineNumber": 12
+ },
+ {
+ "lineNumber": 13
+ },
+ {
+ "text": " public GlobalSettingsViewModel(ConfigService configService)",
+ "lineNumber": 14
+ },
+ {
+ "text": " {",
+ "lineNumber": 15
+ },
+ {
+ "text": " _configService = configService;",
+ "lineNumber": 16
+ },
+ {
+ "text": " LoadSettings();",
+ "lineNumber": 17
+ },
+ {
+ "text": " }",
+ "lineNumber": 18
+ },
+ {
+ "lineNumber": 19
+ },
+ {
+ "text": " public string SheepItUsername",
+ "lineNumber": 20
+ },
+ {
+ "text": " {",
+ "lineNumber": 21
+ },
+ {
+ "text": " get => _sheepItUsername;",
+ "lineNumber": 22
+ },
+ {
+ "text": " set => SetAndRaise(ref _sheepItUsername, value);",
+ "lineNumber": 23
+ },
+ {
+ "text": " }",
+ "lineNumber": 24
+ },
+ {
+ "lineNumber": 25
+ },
+ {
+ "text": " public string SheepItRenderKey",
+ "lineNumber": 26
+ },
+ {
+ "text": " {",
+ "lineNumber": 27
+ },
+ {
+ "text": " get => _sheepItRenderKey;",
+ "lineNumber": 28
+ },
+ {
+ "text": " set => SetAndRaise(ref _sheepItRenderKey, value);",
+ "lineNumber": 29
+ },
+ {
+ "text": " }",
+ "lineNumber": 30
+ },
+ {
+ "lineNumber": 31
+ },
+ {
+ "text": " public bool IsRenderKeyVisible",
+ "lineNumber": 32
+ },
+ {
+ "text": " {",
+ "lineNumber": 33
+ },
+ {
+ "text": " get => _isRenderKeyVisible;",
+ "lineNumber": 34
+ },
+ {
+ "text": " set => SetAndRaise(ref _isRenderKeyVisible, value);",
+ "lineNumber": 35
+ },
+ {
+ "text": " }",
+ "lineNumber": 36
+ },
+ {
+ "lineNumber": 37
+ },
+ {
+ "text": " public string FlamencoWorkerPath",
+ "lineNumber": 38
+ },
+ {
+ "text": " {",
+ "lineNumber": 39
+ },
+ {
+ "text": " get => _flamencoWorkerPath;",
+ "lineNumber": 40
+ },
+ {
+ "text": " set => SetAndRaise(ref _flamencoWorkerPath, value);",
+ "lineNumber": 41
+ },
+ {
+ "text": " }",
+ "lineNumber": 42
+ },
+ {
+ "lineNumber": 43
+ },
+ {
+ "text": " private void LoadSettings()",
+ "lineNumber": 44
+ },
+ {
+ "text": " {",
+ "lineNumber": 45
+ },
+ {
+ "text": " var config = _configService.Load();",
+ "lineNumber": 46
+ },
+ {
+ "text": " SheepItUsername = config.GlobalSettings.SheepItUsername;",
+ "lineNumber": 47
+ },
+ {
+ "text": " SheepItRenderKey = config.GlobalSettings.SheepItRenderKey;",
+ "lineNumber": 48
+ },
+ {
+ "text": " FlamencoWorkerPath = config.GlobalSettings.FlamencoWorkerPath;",
+ "lineNumber": 49
+ },
+ {
+ "text": " }",
+ "lineNumber": 50
+ },
+ {
+ "lineNumber": 51
+ },
+ {
+ "text": " public void Save()",
+ "lineNumber": 52
+ },
+ {
+ "text": " {",
+ "lineNumber": 53
+ },
+ {
+ "text": " var config = _configService.Load();",
+ "lineNumber": 54
+ },
+ {
+ "text": " config.GlobalSettings.SheepItUsername = SheepItUsername;",
+ "lineNumber": 55
+ },
+ {
+ "text": " config.GlobalSettings.SheepItRenderKey = SheepItRenderKey;",
+ "lineNumber": 56
+ },
+ {
+ "text": " config.GlobalSettings.FlamencoWorkerPath = FlamencoWorkerPath;",
+ "lineNumber": 57
+ },
+ {
+ "text": " _configService.Save(config);",
+ "lineNumber": 58
+ },
+ {
+ "text": " }",
+ "lineNumber": 59
+ },
+ {
+ "text": " }",
+ "lineNumber": 60
+ },
+ {
+ "text": "}",
+ "lineNumber": 61
+ }
+ ]
+ },
+ "score": 0.2920593023300171
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\Views\\MainWindow.axaml.cs",
+ "range": {
+ "startPosition": {
+ "line": 209
+ },
+ "endPosition": {
+ "line": 246
+ }
+ },
+ "contents": " }\n catch (System.Exception ex)\n {\n var errorBox = MessageBoxManager.GetMessageBoxStandard(\"Error\", \n $\"Failed to attach to worker: {ex.Message}\", \n ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error);\n await errorBox.ShowAsync();\n }\n }\n }\n\n private void WorkerTypeTabs_SelectionChanged(object? sender, SelectionChangedEventArgs e)\n {\n if (this.FindControl<TabControl>(\"WorkerTypeTabs\")?.SelectedItem is TabItem tab)\n {\n var type = tab.Header?.ToString() ?? \"All\";\n if (type == \"All Workers\") type = \"All\";\n ((MainWindowViewModel)DataContext!).SelectedWorkerType = type;\n }\n }\n\n private async void SettingsButton_Click(object? sender, RoutedEventArgs e)\n {\n var dialog = new GlobalSettingsWindow();\n await dialog.ShowDialogAsync(this);\n }\n\n private void WorkersGrid_SelectionChanged(object? sender, SelectionChangedEventArgs e)\n {\n if (DataContext is MainWindowViewModel vm)\n {\n vm.SelectedWorker = this.FindControl<DataGrid>(\"WorkersGrid\")?.SelectedItem as WorkerConfig;\n }\n }\n }\n}",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": " }",
+ "lineNumber": 210
+ },
+ {
+ "text": " catch (System.Exception ex)",
+ "lineNumber": 211
+ },
+ {
+ "text": " {",
+ "lineNumber": 212
+ },
+ {
+ "text": " var errorBox = MessageBoxManager.GetMessageBoxStandard(\"Error\", ",
+ "lineNumber": 213
+ },
+ {
+ "text": " $\"Failed to attach to worker: {ex.Message}\", ",
+ "lineNumber": 214
+ },
+ {
+ "text": " ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error);",
+ "lineNumber": 215
+ },
+ {
+ "text": " await errorBox.ShowAsync();",
+ "lineNumber": 216
+ },
+ {
+ "text": " }",
+ "lineNumber": 217
+ },
+ {
+ "text": " }",
+ "lineNumber": 218
+ },
+ {
+ "text": " }",
+ "lineNumber": 219
+ },
+ {
+ "lineNumber": 220
+ },
+ {
+ "text": " private void WorkerTypeTabs_SelectionChanged(object? sender, SelectionChangedEventArgs e)",
+ "lineNumber": 221
+ },
+ {
+ "text": " {",
+ "lineNumber": 222
+ },
+ {
+ "text": " if (this.FindControl<TabControl>(\"WorkerTypeTabs\")?.SelectedItem is TabItem tab)",
+ "lineNumber": 223
+ },
+ {
+ "text": " {",
+ "lineNumber": 224
+ },
+ {
+ "text": " var type = tab.Header?.ToString() ?? \"All\";",
+ "lineNumber": 225
+ },
+ {
+ "text": " if (type == \"All Workers\") type = \"All\";",
+ "lineNumber": 226
+ },
+ {
+ "text": " ((MainWindowViewModel)DataContext!).SelectedWorkerType = type;",
+ "lineNumber": 227
+ },
+ {
+ "text": " }",
+ "lineNumber": 228
+ },
+ {
+ "text": " }",
+ "lineNumber": 229
+ },
+ {
+ "lineNumber": 230
+ },
+ {
+ "text": " private async void SettingsButton_Click(object? sender, RoutedEventArgs e)",
+ "lineNumber": 231
+ },
+ {
+ "text": " {",
+ "lineNumber": 232
+ },
+ {
+ "text": " var dialog = new GlobalSettingsWindow();",
+ "lineNumber": 233
+ },
+ {
+ "text": " await dialog.ShowDialogAsync(this);",
+ "lineNumber": 234
+ },
+ {
+ "text": " }",
+ "lineNumber": 235
+ },
+ {
+ "lineNumber": 236
+ },
+ {
+ "text": " private void WorkersGrid_SelectionChanged(object? sender, SelectionChangedEventArgs e)",
+ "lineNumber": 237
+ },
+ {
+ "text": " {",
+ "lineNumber": 238
+ },
+ {
+ "text": " if (DataContext is MainWindowViewModel vm)",
+ "lineNumber": 239
+ },
+ {
+ "text": " {",
+ "lineNumber": 240
+ },
+ {
+ "text": " vm.SelectedWorker = this.FindControl<DataGrid>(\"WorkersGrid\")?.SelectedItem as WorkerConfig;",
+ "lineNumber": 241
+ },
+ {
+ "text": " }",
+ "lineNumber": 242
+ },
+ {
+ "text": " }",
+ "lineNumber": 243
+ },
+ {
+ "text": " }",
+ "lineNumber": 244
+ },
+ {
+ "text": "}",
+ "lineNumber": 245
+ }
+ ]
+ },
+ "score": 0.27719610929489136
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\ViewModels\\MainWindowViewModel.cs",
+ "range": {
+ "startPosition": {
+ "line": 52
+ },
+ "endPosition": {
+ "line": 119
+ }
+ },
+ "contents": " }\n }\n\n public string OperationMode\n {\n get => _operationMode;\n set\n {\n if (SetAndRaise(ref _operationMode, value))\n {\n // Notify that dependent properties also changed\n OnPropertyChanged(nameof(OperationModeDisplayName));\n OnPropertyChanged(nameof(OperationModeIcon));\n }\n }\n }\n\n public string OperationModeDisplayName => OperationMode == \"sheepit\" ? \"SheepIt\" : \"Flamenco\";\n \n public string OperationModeIcon => OperationMode == \"sheepit\" ? \"🐑\" : \"🔥\";\n\n public void LoadWorkers()\n {\n _configService.Reload();\n var config = _configService.Load();\n Workers.Clear();\n\n var workers = config.Workers;\n if (SelectedWorkerType != \"All\")\n {\n workers = workers.Where(w =>\n {\n if (SelectedWorkerType == \"SheepIt\")\n return w.WorkerTypes.SheepIt != null;\n if (SelectedWorkerType == \"Flamenco\")\n return w.WorkerTypes.Flamenco != null;\n return true;\n }).ToList();\n }\n\n foreach (var worker in workers)\n {\n Workers.Add(worker);\n }\n\n UpdateStatusText();\n }\n\n private void UpdateStatusText()\n {\n if (SelectedWorker == null)\n {\n StatusText = $\"Total workers: {Workers.Count}\";\n }\n else\n {\n StatusText = $\"Selected: {SelectedWorker.Name} ({SelectedWorker.Ssh.Host}:{SelectedWorker.Ssh.Port})\";\n }\n }\n\n public void RefreshWorkers()\n {\n LoadWorkers();\n }\n }\n}",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": " }",
+ "lineNumber": 53
+ },
+ {
+ "text": " }",
+ "lineNumber": 54
+ },
+ {
+ "lineNumber": 55
+ },
+ {
+ "text": " public string OperationMode",
+ "lineNumber": 56
+ },
+ {
+ "text": " {",
+ "lineNumber": 57
+ },
+ {
+ "text": " get => _operationMode;",
+ "lineNumber": 58
+ },
+ {
+ "text": " set",
+ "lineNumber": 59
+ },
+ {
+ "text": " {",
+ "lineNumber": 60
+ },
+ {
+ "text": " if (SetAndRaise(ref _operationMode, value))",
+ "lineNumber": 61
+ },
+ {
+ "text": " {",
+ "lineNumber": 62
+ },
+ {
+ "text": " // Notify that dependent properties also changed",
+ "lineNumber": 63
+ },
+ {
+ "text": " OnPropertyChanged(nameof(OperationModeDisplayName));",
+ "lineNumber": 64
+ },
+ {
+ "text": " OnPropertyChanged(nameof(OperationModeIcon));",
+ "lineNumber": 65
+ },
+ {
+ "text": " }",
+ "lineNumber": 66
+ },
+ {
+ "text": " }",
+ "lineNumber": 67
+ },
+ {
+ "text": " }",
+ "lineNumber": 68
+ },
+ {
+ "lineNumber": 69
+ },
+ {
+ "text": " public string OperationModeDisplayName => OperationMode == \"sheepit\" ? \"SheepIt\" : \"Flamenco\";",
+ "lineNumber": 70
+ },
+ {
+ "text": " ",
+ "lineNumber": 71
+ },
+ {
+ "text": " public string OperationModeIcon => OperationMode == \"sheepit\" ? \"🐑\" : \"🔥\";",
+ "lineNumber": 72
+ },
+ {
+ "lineNumber": 73
+ },
+ {
+ "text": " public void LoadWorkers()",
+ "lineNumber": 74
+ },
+ {
+ "text": " {",
+ "lineNumber": 75
+ },
+ {
+ "text": " _configService.Reload();",
+ "lineNumber": 76
+ },
+ {
+ "text": " var config = _configService.Load();",
+ "lineNumber": 77
+ },
+ {
+ "text": " Workers.Clear();",
+ "lineNumber": 78
+ },
+ {
+ "lineNumber": 79
+ },
+ {
+ "text": " var workers = config.Workers;",
+ "lineNumber": 80
+ },
+ {
+ "text": " if (SelectedWorkerType != \"All\")",
+ "lineNumber": 81
+ },
+ {
+ "text": " {",
+ "lineNumber": 82
+ },
+ {
+ "text": " workers = workers.Where(w =>",
+ "lineNumber": 83
+ },
+ {
+ "text": " {",
+ "lineNumber": 84
+ },
+ {
+ "text": " if (SelectedWorkerType == \"SheepIt\")",
+ "lineNumber": 85
+ },
+ {
+ "text": " return w.WorkerTypes.SheepIt != null;",
+ "lineNumber": 86
+ },
+ {
+ "text": " if (SelectedWorkerType == \"Flamenco\")",
+ "lineNumber": 87
+ },
+ {
+ "text": " return w.WorkerTypes.Flamenco != null;",
+ "lineNumber": 88
+ },
+ {
+ "text": " return true;",
+ "lineNumber": 89
+ },
+ {
+ "text": " }).ToList();",
+ "lineNumber": 90
+ },
+ {
+ "text": " }",
+ "lineNumber": 91
+ },
+ {
+ "lineNumber": 92
+ },
+ {
+ "text": " foreach (var worker in workers)",
+ "lineNumber": 93
+ },
+ {
+ "text": " {",
+ "lineNumber": 94
+ },
+ {
+ "text": " Workers.Add(worker);",
+ "lineNumber": 95
+ },
+ {
+ "text": " }",
+ "lineNumber": 96
+ },
+ {
+ "lineNumber": 97
+ },
+ {
+ "text": " UpdateStatusText();",
+ "lineNumber": 98
+ },
+ {
+ "text": " }",
+ "lineNumber": 99
+ },
+ {
+ "lineNumber": 100
+ },
+ {
+ "text": " private void UpdateStatusText()",
+ "lineNumber": 101
+ },
+ {
+ "text": " {",
+ "lineNumber": 102
+ },
+ {
+ "text": " if (SelectedWorker == null)",
+ "lineNumber": 103
+ },
+ {
+ "text": " {",
+ "lineNumber": 104
+ },
+ {
+ "text": " StatusText = $\"Total workers: {Workers.Count}\";",
+ "lineNumber": 105
+ },
+ {
+ "text": " }",
+ "lineNumber": 106
+ },
+ {
+ "text": " else",
+ "lineNumber": 107
+ },
+ {
+ "text": " {",
+ "lineNumber": 108
+ },
+ {
+ "text": " StatusText = $\"Selected: {SelectedWorker.Name} ({SelectedWorker.Ssh.Host}:{SelectedWorker.Ssh.Port})\";",
+ "lineNumber": 109
+ },
+ {
+ "text": " }",
+ "lineNumber": 110
+ },
+ {
+ "text": " }",
+ "lineNumber": 111
+ },
+ {
+ "lineNumber": 112
+ },
+ {
+ "text": " public void RefreshWorkers()",
+ "lineNumber": 113
+ },
+ {
+ "text": " {",
+ "lineNumber": 114
+ },
+ {
+ "text": " LoadWorkers();",
+ "lineNumber": 115
+ },
+ {
+ "text": " }",
+ "lineNumber": 116
+ },
+ {
+ "text": " }",
+ "lineNumber": 117
+ },
+ {
+ "text": "}",
+ "lineNumber": 118
+ }
+ ]
+ },
+ "score": 0.26766306161880493
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\Views\\MainWindow.axaml.cs",
+ "range": {
+ "startPosition": {
+ "line": 62
+ },
+ "endPosition": {
+ "line": 104
+ }
+ },
+ "contents": " }\n }\n\n private async void EditWorkerButton_Click(object? sender, RoutedEventArgs e)\n {\n if (this.FindControl<DataGrid>(\"WorkersGrid\")?.SelectedItem is WorkerConfig worker)\n {\n var dialog = new WorkerEditWindow(worker);\n if (await dialog.ShowDialogAsync(this))\n {\n ((MainWindowViewModel)DataContext!).RefreshWorkers();\n }\n }\n }\n\n private async void DeleteWorkerButton_Click(object? sender, RoutedEventArgs e)\n {\n if (this.FindControl<DataGrid>(\"WorkersGrid\")?.SelectedItem is WorkerConfig worker)\n {\n var box = MessageBoxManager.GetMessageBoxStandard(\"Delete Worker\", \n $\"Are you sure you want to delete worker '{worker.Name}'?\", \n ButtonEnum.YesNo, MsBox.Avalonia.Enums.Icon.Warning);\n var result = await box.ShowAsync();\n \n if (result == ButtonResult.Yes)\n {\n _configService.DeleteWorker(worker.Id);\n ((MainWindowViewModel)DataContext!).RefreshWorkers();\n }\n }\n }\n\n private async void StartWorkerButton_Click(object? sender, RoutedEventArgs e)\n {\n if (this.FindControl<DataGrid>(\"WorkersGrid\")?.SelectedItem is WorkerConfig worker)\n {\n try\n {\n var vm = (MainWindowViewModel)DataContext!;\n string? workerType = vm.OperationMode;\n\n // Verify the worker supports the selected operation mode",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": " }",
+ "lineNumber": 63
+ },
+ {
+ "text": " }",
+ "lineNumber": 64
+ },
+ {
+ "lineNumber": 65
+ },
+ {
+ "text": " private async void EditWorkerButton_Click(object? sender, RoutedEventArgs e)",
+ "lineNumber": 66
+ },
+ {
+ "text": " {",
+ "lineNumber": 67
+ },
+ {
+ "text": " if (this.FindControl<DataGrid>(\"WorkersGrid\")?.SelectedItem is WorkerConfig worker)",
+ "lineNumber": 68
+ },
+ {
+ "text": " {",
+ "lineNumber": 69
+ },
+ {
+ "text": " var dialog = new WorkerEditWindow(worker);",
+ "lineNumber": 70
+ },
+ {
+ "text": " if (await dialog.ShowDialogAsync(this))",
+ "lineNumber": 71
+ },
+ {
+ "text": " {",
+ "lineNumber": 72
+ },
+ {
+ "text": " ((MainWindowViewModel)DataContext!).RefreshWorkers();",
+ "lineNumber": 73
+ },
+ {
+ "text": " }",
+ "lineNumber": 74
+ },
+ {
+ "text": " }",
+ "lineNumber": 75
+ },
+ {
+ "text": " }",
+ "lineNumber": 76
+ },
+ {
+ "lineNumber": 77
+ },
+ {
+ "text": " private async void DeleteWorkerButton_Click(object? sender, RoutedEventArgs e)",
+ "lineNumber": 78
+ },
+ {
+ "text": " {",
+ "lineNumber": 79
+ },
+ {
+ "text": " if (this.FindControl<DataGrid>(\"WorkersGrid\")?.SelectedItem is WorkerConfig worker)",
+ "lineNumber": 80
+ },
+ {
+ "text": " {",
+ "lineNumber": 81
+ },
+ {
+ "text": " var box = MessageBoxManager.GetMessageBoxStandard(\"Delete Worker\", ",
+ "lineNumber": 82
+ },
+ {
+ "text": " $\"Are you sure you want to delete worker '{worker.Name}'?\", ",
+ "lineNumber": 83
+ },
+ {
+ "text": " ButtonEnum.YesNo, MsBox.Avalonia.Enums.Icon.Warning);",
+ "lineNumber": 84
+ },
+ {
+ "text": " var result = await box.ShowAsync();",
+ "lineNumber": 85
+ },
+ {
+ "text": " ",
+ "lineNumber": 86
+ },
+ {
+ "text": " if (result == ButtonResult.Yes)",
+ "lineNumber": 87
+ },
+ {
+ "text": " {",
+ "lineNumber": 88
+ },
+ {
+ "text": " _configService.DeleteWorker(worker.Id);",
+ "lineNumber": 89
+ },
+ {
+ "text": " ((MainWindowViewModel)DataContext!).RefreshWorkers();",
+ "lineNumber": 90
+ },
+ {
+ "text": " }",
+ "lineNumber": 91
+ },
+ {
+ "text": " }",
+ "lineNumber": 92
+ },
+ {
+ "text": " }",
+ "lineNumber": 93
+ },
+ {
+ "lineNumber": 94
+ },
+ {
+ "text": " private async void StartWorkerButton_Click(object? sender, RoutedEventArgs e)",
+ "lineNumber": 95
+ },
+ {
+ "text": " {",
+ "lineNumber": 96
+ },
+ {
+ "text": " if (this.FindControl<DataGrid>(\"WorkersGrid\")?.SelectedItem is WorkerConfig worker)",
+ "lineNumber": 97
+ },
+ {
+ "text": " {",
+ "lineNumber": 98
+ },
+ {
+ "text": " try",
+ "lineNumber": 99
+ },
+ {
+ "text": " {",
+ "lineNumber": 100
+ },
+ {
+ "text": " var vm = (MainWindowViewModel)DataContext!;",
+ "lineNumber": 101
+ },
+ {
+ "text": " string? workerType = vm.OperationMode;",
+ "lineNumber": 102
+ },
+ {
+ "lineNumber": 103
+ },
+ {
+ "text": " // Verify the worker supports the selected operation mode",
+ "lineNumber": 104
+ }
+ ]
+ },
+ "score": 0.26550209522247314
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\Views\\MainWindow.axaml",
+ "range": {
+ "startPosition": {
+ "line": 33
+ },
+ "endPosition": {
+ "line": 73,
+ "column": 12
+ }
+ },
+ "contents": " MinWidth=\"120\">\n <StackPanel Orientation=\"Horizontal\" Spacing=\"5\">\n <TextBlock Text=\"{Binding OperationModeIcon}\" FontSize=\"16\" VerticalAlignment=\"Center\"/>\n <TextBlock Text=\"{Binding OperationModeDisplayName}\" \n VerticalAlignment=\"Center\" FontWeight=\"Bold\"/>\n </StackPanel>\n </Button>\n </Grid>\n\n <!-- Worker Type Filter -->\n <TabControl Name=\"WorkerTypeTabs\" Grid.Row=\"1\" Margin=\"5,0\">\n <TabItem Header=\"All Workers\">\n <TextBlock Text=\"All Workers\" IsVisible=\"False\"/>\n </TabItem>\n <TabItem Header=\"SheepIt\">\n <TextBlock Text=\"SheepIt\" IsVisible=\"False\"/>\n </TabItem>\n <TabItem Header=\"Flamenco\">\n <TextBlock Text=\"Flamenco\" IsVisible=\"False\"/>\n </TabItem>\n </TabControl>\n\n <!-- Worker List -->\n <DataGrid Name=\"WorkersGrid\" Grid.Row=\"2\" Margin=\"5\"\n AutoGenerateColumns=\"False\"\n IsReadOnly=\"True\"\n SelectionMode=\"Single\"\n GridLinesVisibility=\"All\"\n ItemsSource=\"{Binding Workers}\">\n <DataGrid.Columns>\n <DataGridTextColumn Header=\"Name\" Binding=\"{Binding Name}\" Width=\"150\"/>\n <DataGridCheckBoxColumn Header=\"Enabled\" Binding=\"{Binding Enabled}\" Width=\"80\"/>\n <DataGridTextColumn Header=\"SSH Host\" Binding=\"{Binding Ssh.Host}\" Width=\"150\"/>\n <DataGridTextColumn Header=\"SSH Port\" Binding=\"{Binding Ssh.Port}\" Width=\"80\"/>\n <DataGridTextColumn Header=\"Worker Types\" Binding=\"{Binding WorkerTypes}\" Width=\"*\"/>\n </DataGrid.Columns>\n </DataGrid>\n\n <!-- Status Bar -->\n <Border Grid.Row=\"3\" Background=\"{DynamicResource ThemeControlLowBackgroundBrush}\" BorderBrush=\"{DynamicResource ThemeBorderLowBrush}\" BorderThickness=\"0,1,0,0\">\n ",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": " MinWidth=\"120\">",
+ "lineNumber": 34
+ },
+ {
+ "text": " <StackPanel Orientation=\"Horizontal\" Spacing=\"5\">",
+ "lineNumber": 35
+ },
+ {
+ "text": " <TextBlock Text=\"{Binding OperationModeIcon}\" FontSize=\"16\" VerticalAlignment=\"Center\"/>",
+ "lineNumber": 36
+ },
+ {
+ "text": " <TextBlock Text=\"{Binding OperationModeDisplayName}\" ",
+ "lineNumber": 37
+ },
+ {
+ "text": " VerticalAlignment=\"Center\" FontWeight=\"Bold\"/>",
+ "lineNumber": 38
+ },
+ {
+ "text": " </StackPanel>",
+ "lineNumber": 39
+ },
+ {
+ "text": " </Button>",
+ "lineNumber": 40
+ },
+ {
+ "text": " </Grid>",
+ "lineNumber": 41
+ },
+ {
+ "lineNumber": 42
+ },
+ {
+ "text": " <!-- Worker Type Filter -->",
+ "lineNumber": 43
+ },
+ {
+ "text": " <TabControl Name=\"WorkerTypeTabs\" Grid.Row=\"1\" Margin=\"5,0\">",
+ "lineNumber": 44
+ },
+ {
+ "text": " <TabItem Header=\"All Workers\">",
+ "lineNumber": 45
+ },
+ {
+ "text": " <TextBlock Text=\"All Workers\" IsVisible=\"False\"/>",
+ "lineNumber": 46
+ },
+ {
+ "text": " </TabItem>",
+ "lineNumber": 47
+ },
+ {
+ "text": " <TabItem Header=\"SheepIt\">",
+ "lineNumber": 48
+ },
+ {
+ "text": " <TextBlock Text=\"SheepIt\" IsVisible=\"False\"/>",
+ "lineNumber": 49
+ },
+ {
+ "text": " </TabItem>",
+ "lineNumber": 50
+ },
+ {
+ "text": " <TabItem Header=\"Flamenco\">",
+ "lineNumber": 51
+ },
+ {
+ "text": " <TextBlock Text=\"Flamenco\" IsVisible=\"False\"/>",
+ "lineNumber": 52
+ },
+ {
+ "text": " </TabItem>",
+ "lineNumber": 53
+ },
+ {
+ "text": " </TabControl>",
+ "lineNumber": 54
+ },
+ {
+ "lineNumber": 55
+ },
+ {
+ "text": " <!-- Worker List -->",
+ "lineNumber": 56
+ },
+ {
+ "text": " <DataGrid Name=\"WorkersGrid\" Grid.Row=\"2\" Margin=\"5\"",
+ "lineNumber": 57
+ },
+ {
+ "text": " AutoGenerateColumns=\"False\"",
+ "lineNumber": 58
+ },
+ {
+ "text": " IsReadOnly=\"True\"",
+ "lineNumber": 59
+ },
+ {
+ "text": " SelectionMode=\"Single\"",
+ "lineNumber": 60
+ },
+ {
+ "text": " GridLinesVisibility=\"All\"",
+ "lineNumber": 61
+ },
+ {
+ "text": " ItemsSource=\"{Binding Workers}\">",
+ "lineNumber": 62
+ },
+ {
+ "text": " <DataGrid.Columns>",
+ "lineNumber": 63
+ },
+ {
+ "text": " <DataGridTextColumn Header=\"Name\" Binding=\"{Binding Name}\" Width=\"150\"/>",
+ "lineNumber": 64
+ },
+ {
+ "text": " <DataGridCheckBoxColumn Header=\"Enabled\" Binding=\"{Binding Enabled}\" Width=\"80\"/>",
+ "lineNumber": 65
+ },
+ {
+ "text": " <DataGridTextColumn Header=\"SSH Host\" Binding=\"{Binding Ssh.Host}\" Width=\"150\"/>",
+ "lineNumber": 66
+ },
+ {
+ "text": " <DataGridTextColumn Header=\"SSH Port\" Binding=\"{Binding Ssh.Port}\" Width=\"80\"/>",
+ "lineNumber": 67
+ },
+ {
+ "text": " <DataGridTextColumn Header=\"Worker Types\" Binding=\"{Binding WorkerTypes}\" Width=\"*\"/>",
+ "lineNumber": 68
+ },
+ {
+ "text": " </DataGrid.Columns>",
+ "lineNumber": 69
+ },
+ {
+ "text": " </DataGrid>",
+ "lineNumber": 70
+ },
+ {
+ "lineNumber": 71
+ },
+ {
+ "text": " <!-- Status Bar -->",
+ "lineNumber": 72
+ },
+ {
+ "text": " <Border Grid.Row=\"3\" Background=\"{DynamicResource ThemeControlLowBackgroundBrush}\" BorderBrush=\"{DynamicResource ThemeBorderLowBrush}\" BorderThickness=\"0,1,0,0\">",
+ "lineNumber": 73
+ },
+ {
+ "text": " ",
+ "lineNumber": 74
+ }
+ ]
+ },
+ "score": 0.2587176561355591
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\Views\\WorkerEditWindow.axaml",
+ "range": {
+ "startPosition": {
+ "line": 73
+ },
+ "endPosition": {
+ "line": 92
+ }
+ },
+ "contents": " <Grid IsVisible=\"{Binding HasFlamenco}\" RowDefinitions=\"*,Auto\" Margin=\"0,5,0,0\">\n <ListBox Name=\"NetworkPathsListBox\" Grid.Row=\"0\" ItemsSource=\"{Binding NetworkPaths}\" MaxHeight=\"100\"/>\n <StackPanel Grid.Row=\"1\" Orientation=\"Horizontal\" Margin=\"0,5,0,0\">\n <Button Name=\"AddPathButton\" Content=\"Add\" Width=\"60\" Margin=\"0,0,5,0\"/>\n <Button Name=\"RemovePathButton\" Content=\"Remove\" Width=\"60\"/>\n </StackPanel>\n </Grid>\n </StackPanel>\n </TabItem>\n </TabControl>\n\n <!-- Buttons -->\n <StackPanel Orientation=\"Horizontal\" HorizontalAlignment=\"Right\" Grid.Row=\"2\" Spacing=\"10\" Margin=\"0,10,0,0\">\n <Button Name=\"OkButton\" Content=\"OK\" Width=\"80\" IsDefault=\"True\"/>\n <Button Name=\"CancelButton\" Content=\"Cancel\" Width=\"80\" IsCancel=\"True\"/>\n </StackPanel>\n </Grid>\n</Window>",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": " <Grid IsVisible=\"{Binding HasFlamenco}\" RowDefinitions=\"*,Auto\" Margin=\"0,5,0,0\">",
+ "lineNumber": 74
+ },
+ {
+ "text": " <ListBox Name=\"NetworkPathsListBox\" Grid.Row=\"0\" ItemsSource=\"{Binding NetworkPaths}\" MaxHeight=\"100\"/>",
+ "lineNumber": 75
+ },
+ {
+ "text": " <StackPanel Grid.Row=\"1\" Orientation=\"Horizontal\" Margin=\"0,5,0,0\">",
+ "lineNumber": 76
+ },
+ {
+ "text": " <Button Name=\"AddPathButton\" Content=\"Add\" Width=\"60\" Margin=\"0,0,5,0\"/>",
+ "lineNumber": 77
+ },
+ {
+ "text": " <Button Name=\"RemovePathButton\" Content=\"Remove\" Width=\"60\"/>",
+ "lineNumber": 78
+ },
+ {
+ "text": " </StackPanel>",
+ "lineNumber": 79
+ },
+ {
+ "text": " </Grid>",
+ "lineNumber": 80
+ },
+ {
+ "text": " </StackPanel>",
+ "lineNumber": 81
+ },
+ {
+ "text": " </TabItem>",
+ "lineNumber": 82
+ },
+ {
+ "text": " </TabControl>",
+ "lineNumber": 83
+ },
+ {
+ "lineNumber": 84
+ },
+ {
+ "text": " <!-- Buttons -->",
+ "lineNumber": 85
+ },
+ {
+ "text": " <StackPanel Orientation=\"Horizontal\" HorizontalAlignment=\"Right\" Grid.Row=\"2\" Spacing=\"10\" Margin=\"0,10,0,0\">",
+ "lineNumber": 86
+ },
+ {
+ "text": " <Button Name=\"OkButton\" Content=\"OK\" Width=\"80\" IsDefault=\"True\"/>",
+ "lineNumber": 87
+ },
+ {
+ "text": " <Button Name=\"CancelButton\" Content=\"Cancel\" Width=\"80\" IsCancel=\"True\"/>",
+ "lineNumber": 88
+ },
+ {
+ "text": " </StackPanel>",
+ "lineNumber": 89
+ },
+ {
+ "text": " </Grid>",
+ "lineNumber": 90
+ },
+ {
+ "text": "</Window>",
+ "lineNumber": 91
+ }
+ ]
+ },
+ "score": 0.2566637396812439
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\ViewModels\\MainWindowViewModel.cs",
+ "range": {
+ "startPosition": {},
+ "endPosition": {
+ "line": 56
+ }
+ },
+ "contents": "using System.Collections.ObjectModel;\nusing System.Linq;\nusing System.Threading.Tasks;\nusing UnifiedFarmLauncher.Models;\nusing UnifiedFarmLauncher.Services;\n\nnamespace UnifiedFarmLauncher.ViewModels\n{\n public class MainWindowViewModel : ViewModelBase\n {\n private readonly ConfigService _configService;\n private WorkerConfig? _selectedWorker;\n private string _statusText = \"Ready\";\n private string _selectedWorkerType = \"All\";\n private string _operationMode = \"sheepit\"; // \"sheepit\" or \"flamenco\"\n\n public MainWindowViewModel()\n {\n _configService = new ConfigService();\n Workers = new ObservableCollection<WorkerConfig>();\n LoadWorkers();\n }\n\n public ObservableCollection<WorkerConfig> Workers { get; }\n\n public WorkerConfig? SelectedWorker\n {\n get => _selectedWorker;\n set\n {\n if (SetAndRaise(ref _selectedWorker, value))\n {\n UpdateStatusText();\n }\n }\n }\n\n public string StatusText\n {\n get => _statusText;\n set => SetAndRaise(ref _statusText, value);\n }\n\n public string SelectedWorkerType\n {\n get => _selectedWorkerType;\n set\n {\n if (SetAndRaise(ref _selectedWorkerType, value))\n {\n LoadWorkers();\n }\n }\n }\n\n public string OperationMode",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": "using System.Collections.ObjectModel;",
+ "lineNumber": 1
+ },
+ {
+ "text": "using System.Linq;",
+ "lineNumber": 2
+ },
+ {
+ "text": "using System.Threading.Tasks;",
+ "lineNumber": 3
+ },
+ {
+ "text": "using UnifiedFarmLauncher.Models;",
+ "lineNumber": 4
+ },
+ {
+ "text": "using UnifiedFarmLauncher.Services;",
+ "lineNumber": 5
+ },
+ {
+ "lineNumber": 6
+ },
+ {
+ "text": "namespace UnifiedFarmLauncher.ViewModels",
+ "lineNumber": 7
+ },
+ {
+ "text": "{",
+ "lineNumber": 8
+ },
+ {
+ "text": " public class MainWindowViewModel : ViewModelBase",
+ "lineNumber": 9
+ },
+ {
+ "text": " {",
+ "lineNumber": 10
+ },
+ {
+ "text": " private readonly ConfigService _configService;",
+ "lineNumber": 11
+ },
+ {
+ "text": " private WorkerConfig? _selectedWorker;",
+ "lineNumber": 12
+ },
+ {
+ "text": " private string _statusText = \"Ready\";",
+ "lineNumber": 13
+ },
+ {
+ "text": " private string _selectedWorkerType = \"All\";",
+ "lineNumber": 14
+ },
+ {
+ "text": " private string _operationMode = \"sheepit\"; // \"sheepit\" or \"flamenco\"",
+ "lineNumber": 15
+ },
+ {
+ "lineNumber": 16
+ },
+ {
+ "text": " public MainWindowViewModel()",
+ "lineNumber": 17
+ },
+ {
+ "text": " {",
+ "lineNumber": 18
+ },
+ {
+ "text": " _configService = new ConfigService();",
+ "lineNumber": 19
+ },
+ {
+ "text": " Workers = new ObservableCollection<WorkerConfig>();",
+ "lineNumber": 20
+ },
+ {
+ "text": " LoadWorkers();",
+ "lineNumber": 21
+ },
+ {
+ "text": " }",
+ "lineNumber": 22
+ },
+ {
+ "lineNumber": 23
+ },
+ {
+ "text": " public ObservableCollection<WorkerConfig> Workers { get; }",
+ "lineNumber": 24
+ },
+ {
+ "lineNumber": 25
+ },
+ {
+ "text": " public WorkerConfig? SelectedWorker",
+ "lineNumber": 26
+ },
+ {
+ "text": " {",
+ "lineNumber": 27
+ },
+ {
+ "text": " get => _selectedWorker;",
+ "lineNumber": 28
+ },
+ {
+ "text": " set",
+ "lineNumber": 29
+ },
+ {
+ "text": " {",
+ "lineNumber": 30
+ },
+ {
+ "text": " if (SetAndRaise(ref _selectedWorker, value))",
+ "lineNumber": 31
+ },
+ {
+ "text": " {",
+ "lineNumber": 32
+ },
+ {
+ "text": " UpdateStatusText();",
+ "lineNumber": 33
+ },
+ {
+ "text": " }",
+ "lineNumber": 34
+ },
+ {
+ "text": " }",
+ "lineNumber": 35
+ },
+ {
+ "text": " }",
+ "lineNumber": 36
+ },
+ {
+ "lineNumber": 37
+ },
+ {
+ "text": " public string StatusText",
+ "lineNumber": 38
+ },
+ {
+ "text": " {",
+ "lineNumber": 39
+ },
+ {
+ "text": " get => _statusText;",
+ "lineNumber": 40
+ },
+ {
+ "text": " set => SetAndRaise(ref _statusText, value);",
+ "lineNumber": 41
+ },
+ {
+ "text": " }",
+ "lineNumber": 42
+ },
+ {
+ "lineNumber": 43
+ },
+ {
+ "text": " public string SelectedWorkerType",
+ "lineNumber": 44
+ },
+ {
+ "text": " {",
+ "lineNumber": 45
+ },
+ {
+ "text": " get => _selectedWorkerType;",
+ "lineNumber": 46
+ },
+ {
+ "text": " set",
+ "lineNumber": 47
+ },
+ {
+ "text": " {",
+ "lineNumber": 48
+ },
+ {
+ "text": " if (SetAndRaise(ref _selectedWorkerType, value))",
+ "lineNumber": 49
+ },
+ {
+ "text": " {",
+ "lineNumber": 50
+ },
+ {
+ "text": " LoadWorkers();",
+ "lineNumber": 51
+ },
+ {
+ "text": " }",
+ "lineNumber": 52
+ },
+ {
+ "text": " }",
+ "lineNumber": 53
+ },
+ {
+ "text": " }",
+ "lineNumber": 54
+ },
+ {
+ "lineNumber": 55
+ },
+ {
+ "text": " public string OperationMode",
+ "lineNumber": 56
+ }
+ ]
+ },
+ "score": 0.2511206865310669
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\Views\\WorkerEditWindow.axaml.cs",
+ "range": {
+ "startPosition": {
+ "line": 102
+ },
+ "endPosition": {
+ "line": 117
+ }
+ },
+ "contents": " {\n if (this.FindControl<ListBox>(\"NetworkPathsListBox\")?.SelectedItem is string path)\n {\n _viewModel.NetworkPaths.Remove(path);\n }\n }\n\n public async Task<bool> ShowDialogAsync(Window parent)\n {\n await base.ShowDialog(parent);\n return _result;\n }\n }\n}",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": " {",
+ "lineNumber": 103
+ },
+ {
+ "text": " if (this.FindControl<ListBox>(\"NetworkPathsListBox\")?.SelectedItem is string path)",
+ "lineNumber": 104
+ },
+ {
+ "text": " {",
+ "lineNumber": 105
+ },
+ {
+ "text": " _viewModel.NetworkPaths.Remove(path);",
+ "lineNumber": 106
+ },
+ {
+ "text": " }",
+ "lineNumber": 107
+ },
+ {
+ "text": " }",
+ "lineNumber": 108
+ },
+ {
+ "lineNumber": 109
+ },
+ {
+ "text": " public async Task<bool> ShowDialogAsync(Window parent)",
+ "lineNumber": 110
+ },
+ {
+ "text": " {",
+ "lineNumber": 111
+ },
+ {
+ "text": " await base.ShowDialog(parent);",
+ "lineNumber": 112
+ },
+ {
+ "text": " return _result;",
+ "lineNumber": 113
+ },
+ {
+ "text": " }",
+ "lineNumber": 114
+ },
+ {
+ "text": " }",
+ "lineNumber": 115
+ },
+ {
+ "text": "}",
+ "lineNumber": 116
+ }
+ ]
+ },
+ "score": 0.24458350241184235
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\Views\\GlobalSettingsWindow.axaml",
+ "range": {
+ "startPosition": {
+ "line": 31
+ },
+ "endPosition": {
+ "line": 55
+ }
+ },
+ "contents": " <TabItem Header=\"Flamenco\">\n <StackPanel Margin=\"10\" Spacing=\"10\">\n <TextBlock Text=\"Worker Path:\"/>\n <Grid ColumnDefinitions=\"*,Auto\">\n <TextBox Name=\"FlamencoWorkerPathTextBox\" \n Grid.Column=\"0\" \n Text=\"{Binding FlamencoWorkerPath}\" \n Margin=\"0,0,5,0\"/>\n <Button Name=\"BrowseFlamencoPathButton\" \n Grid.Column=\"1\" \n Content=\"Browse...\" \n Width=\"80\"/>\n </Grid>\n </StackPanel>\n </TabItem>\n </TabControl>\n\n <!-- Buttons -->\n <StackPanel Orientation=\"Horizontal\" HorizontalAlignment=\"Right\" Grid.Row=\"2\" Spacing=\"10\" Margin=\"0,10,0,0\">\n <Button Name=\"OkButton\" Content=\"OK\" Width=\"80\" IsDefault=\"True\"/>\n <Button Name=\"CancelButton\" Content=\"Cancel\" Width=\"80\" IsCancel=\"True\"/>\n </StackPanel>\n </Grid>\n</Window>",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": " <TabItem Header=\"Flamenco\">",
+ "lineNumber": 32
+ },
+ {
+ "text": " <StackPanel Margin=\"10\" Spacing=\"10\">",
+ "lineNumber": 33
+ },
+ {
+ "text": " <TextBlock Text=\"Worker Path:\"/>",
+ "lineNumber": 34
+ },
+ {
+ "text": " <Grid ColumnDefinitions=\"*,Auto\">",
+ "lineNumber": 35
+ },
+ {
+ "text": " <TextBox Name=\"FlamencoWorkerPathTextBox\" ",
+ "lineNumber": 36
+ },
+ {
+ "text": " Grid.Column=\"0\" ",
+ "lineNumber": 37
+ },
+ {
+ "text": " Text=\"{Binding FlamencoWorkerPath}\" ",
+ "lineNumber": 38
+ },
+ {
+ "text": " Margin=\"0,0,5,0\"/>",
+ "lineNumber": 39
+ },
+ {
+ "text": " <Button Name=\"BrowseFlamencoPathButton\" ",
+ "lineNumber": 40
+ },
+ {
+ "text": " Grid.Column=\"1\" ",
+ "lineNumber": 41
+ },
+ {
+ "text": " Content=\"Browse...\" ",
+ "lineNumber": 42
+ },
+ {
+ "text": " Width=\"80\"/>",
+ "lineNumber": 43
+ },
+ {
+ "text": " </Grid>",
+ "lineNumber": 44
+ },
+ {
+ "text": " </StackPanel>",
+ "lineNumber": 45
+ },
+ {
+ "text": " </TabItem>",
+ "lineNumber": 46
+ },
+ {
+ "text": " </TabControl>",
+ "lineNumber": 47
+ },
+ {
+ "lineNumber": 48
+ },
+ {
+ "text": " <!-- Buttons -->",
+ "lineNumber": 49
+ },
+ {
+ "text": " <StackPanel Orientation=\"Horizontal\" HorizontalAlignment=\"Right\" Grid.Row=\"2\" Spacing=\"10\" Margin=\"0,10,0,0\">",
+ "lineNumber": 50
+ },
+ {
+ "text": " <Button Name=\"OkButton\" Content=\"OK\" Width=\"80\" IsDefault=\"True\"/>",
+ "lineNumber": 51
+ },
+ {
+ "text": " <Button Name=\"CancelButton\" Content=\"Cancel\" Width=\"80\" IsCancel=\"True\"/>",
+ "lineNumber": 52
+ },
+ {
+ "text": " </StackPanel>",
+ "lineNumber": 53
+ },
+ {
+ "text": " </Grid>",
+ "lineNumber": 54
+ },
+ {
+ "text": "</Window>",
+ "lineNumber": 55
+ }
+ ]
+ },
+ "score": 0.22779864072799683
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\Views\\MainWindow.axaml.cs",
+ "range": {
+ "startPosition": {
+ "line": 169
+ },
+ "endPosition": {
+ "line": 211
+ }
+ },
+ "contents": " await successBox.ShowAsync();\n }\n catch (System.Exception ex)\n {\n var errorBox = MessageBoxManager.GetMessageBoxStandard(\"Error\", \n $\"Failed to stop worker: {ex.Message}\", \n ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error);\n await errorBox.ShowAsync();\n }\n }\n }\n\n private async void AttachWorkerButton_Click(object? sender, RoutedEventArgs e)\n {\n if (this.FindControl<DataGrid>(\"WorkersGrid\")?.SelectedItem is WorkerConfig worker)\n {\n try\n {\n var vm = (MainWindowViewModel)DataContext!;\n string workerType = vm.OperationMode;\n\n // Verify the worker supports the selected operation mode\n if (workerType == \"sheepit\" && worker.WorkerTypes.SheepIt == null)\n {\n var box = MessageBoxManager.GetMessageBoxStandard(\"Error\", \n $\"Worker '{worker.Name}' does not have SheepIt configured.\", \n ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error);\n await box.ShowAsync();\n return;\n }\n if (workerType == \"flamenco\" && worker.WorkerTypes.Flamenco == null)\n {\n var box = MessageBoxManager.GetMessageBoxStandard(\"Error\", \n $\"Worker '{worker.Name}' does not have Flamenco configured.\", \n ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error);\n await box.ShowAsync();\n return;\n }\n\n await _attachService.AttachToWorkerAsync(worker, workerType);\n }\n catch (System.Exception ex)",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": " await successBox.ShowAsync();",
+ "lineNumber": 170
+ },
+ {
+ "text": " }",
+ "lineNumber": 171
+ },
+ {
+ "text": " catch (System.Exception ex)",
+ "lineNumber": 172
+ },
+ {
+ "text": " {",
+ "lineNumber": 173
+ },
+ {
+ "text": " var errorBox = MessageBoxManager.GetMessageBoxStandard(\"Error\", ",
+ "lineNumber": 174
+ },
+ {
+ "text": " $\"Failed to stop worker: {ex.Message}\", ",
+ "lineNumber": 175
+ },
+ {
+ "text": " ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error);",
+ "lineNumber": 176
+ },
+ {
+ "text": " await errorBox.ShowAsync();",
+ "lineNumber": 177
+ },
+ {
+ "text": " }",
+ "lineNumber": 178
+ },
+ {
+ "text": " }",
+ "lineNumber": 179
+ },
+ {
+ "text": " }",
+ "lineNumber": 180
+ },
+ {
+ "lineNumber": 181
+ },
+ {
+ "text": " private async void AttachWorkerButton_Click(object? sender, RoutedEventArgs e)",
+ "lineNumber": 182
+ },
+ {
+ "text": " {",
+ "lineNumber": 183
+ },
+ {
+ "text": " if (this.FindControl<DataGrid>(\"WorkersGrid\")?.SelectedItem is WorkerConfig worker)",
+ "lineNumber": 184
+ },
+ {
+ "text": " {",
+ "lineNumber": 185
+ },
+ {
+ "text": " try",
+ "lineNumber": 186
+ },
+ {
+ "text": " {",
+ "lineNumber": 187
+ },
+ {
+ "text": " var vm = (MainWindowViewModel)DataContext!;",
+ "lineNumber": 188
+ },
+ {
+ "text": " string workerType = vm.OperationMode;",
+ "lineNumber": 189
+ },
+ {
+ "lineNumber": 190
+ },
+ {
+ "text": " // Verify the worker supports the selected operation mode",
+ "lineNumber": 191
+ },
+ {
+ "text": " if (workerType == \"sheepit\" && worker.WorkerTypes.SheepIt == null)",
+ "lineNumber": 192
+ },
+ {
+ "text": " {",
+ "lineNumber": 193
+ },
+ {
+ "text": " var box = MessageBoxManager.GetMessageBoxStandard(\"Error\", ",
+ "lineNumber": 194
+ },
+ {
+ "text": " $\"Worker '{worker.Name}' does not have SheepIt configured.\", ",
+ "lineNumber": 195
+ },
+ {
+ "text": " ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error);",
+ "lineNumber": 196
+ },
+ {
+ "text": " await box.ShowAsync();",
+ "lineNumber": 197
+ },
+ {
+ "text": " return;",
+ "lineNumber": 198
+ },
+ {
+ "text": " }",
+ "lineNumber": 199
+ },
+ {
+ "text": " if (workerType == \"flamenco\" && worker.WorkerTypes.Flamenco == null)",
+ "lineNumber": 200
+ },
+ {
+ "text": " {",
+ "lineNumber": 201
+ },
+ {
+ "text": " var box = MessageBoxManager.GetMessageBoxStandard(\"Error\", ",
+ "lineNumber": 202
+ },
+ {
+ "text": " $\"Worker '{worker.Name}' does not have Flamenco configured.\", ",
+ "lineNumber": 203
+ },
+ {
+ "text": " ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error);",
+ "lineNumber": 204
+ },
+ {
+ "text": " await box.ShowAsync();",
+ "lineNumber": 205
+ },
+ {
+ "text": " return;",
+ "lineNumber": 206
+ },
+ {
+ "text": " }",
+ "lineNumber": 207
+ },
+ {
+ "lineNumber": 208
+ },
+ {
+ "text": " await _attachService.AttachToWorkerAsync(worker, workerType);",
+ "lineNumber": 209
+ },
+ {
+ "text": " }",
+ "lineNumber": 210
+ },
+ {
+ "text": " catch (System.Exception ex)",
+ "lineNumber": 211
+ }
+ ]
+ },
+ "score": 0.21573659777641296
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\Views\\GlobalSettingsWindow.axaml.cs",
+ "range": {
+ "startPosition": {
+ "line": 52
+ },
+ "endPosition": {
+ "line": 96
+ }
+ },
+ "contents": " {\n _result = false;\n Close();\n }\n\n private void ToggleRenderKeyButton_Click(object? sender, RoutedEventArgs e)\n {\n var textBox = this.FindControl<Avalonia.Controls.TextBox>(\"SheepItRenderKeyTextBox\");\n if (textBox != null)\n {\n _viewModel.IsRenderKeyVisible = !_viewModel.IsRenderKeyVisible;\n textBox.PasswordChar = _viewModel.IsRenderKeyVisible ? '\\0' : '*';\n var button = sender as Button;\n if (button != null)\n {\n button.Content = _viewModel.IsRenderKeyVisible ? \"🙈\" : \"👁\";\n }\n }\n }\n\n private async void BrowseFlamencoPathButton_Click(object? sender, RoutedEventArgs e)\n {\n var topLevel = TopLevel.GetTopLevel(this);\n if (topLevel?.StorageProvider.CanPickFolder == true)\n {\n var folders = await topLevel.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions\n {\n Title = \"Select Flamenco Worker Path\"\n });\n \n if (folders.Count > 0 && folders[0].TryGetLocalPath() is { } localPath)\n {\n _viewModel.FlamencoWorkerPath = localPath;\n }\n }\n }\n\n public async Task<bool> ShowDialogAsync(Window parent)\n {\n await base.ShowDialog(parent);\n return _result;\n }\n }\n}",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": " {",
+ "lineNumber": 53
+ },
+ {
+ "text": " _result = false;",
+ "lineNumber": 54
+ },
+ {
+ "text": " Close();",
+ "lineNumber": 55
+ },
+ {
+ "text": " }",
+ "lineNumber": 56
+ },
+ {
+ "lineNumber": 57
+ },
+ {
+ "text": " private void ToggleRenderKeyButton_Click(object? sender, RoutedEventArgs e)",
+ "lineNumber": 58
+ },
+ {
+ "text": " {",
+ "lineNumber": 59
+ },
+ {
+ "text": " var textBox = this.FindControl<Avalonia.Controls.TextBox>(\"SheepItRenderKeyTextBox\");",
+ "lineNumber": 60
+ },
+ {
+ "text": " if (textBox != null)",
+ "lineNumber": 61
+ },
+ {
+ "text": " {",
+ "lineNumber": 62
+ },
+ {
+ "text": " _viewModel.IsRenderKeyVisible = !_viewModel.IsRenderKeyVisible;",
+ "lineNumber": 63
+ },
+ {
+ "text": " textBox.PasswordChar = _viewModel.IsRenderKeyVisible ? '\\0' : '*';",
+ "lineNumber": 64
+ },
+ {
+ "text": " var button = sender as Button;",
+ "lineNumber": 65
+ },
+ {
+ "text": " if (button != null)",
+ "lineNumber": 66
+ },
+ {
+ "text": " {",
+ "lineNumber": 67
+ },
+ {
+ "text": " button.Content = _viewModel.IsRenderKeyVisible ? \"🙈\" : \"👁\";",
+ "lineNumber": 68
+ },
+ {
+ "text": " }",
+ "lineNumber": 69
+ },
+ {
+ "text": " }",
+ "lineNumber": 70
+ },
+ {
+ "text": " }",
+ "lineNumber": 71
+ },
+ {
+ "lineNumber": 72
+ },
+ {
+ "text": " private async void BrowseFlamencoPathButton_Click(object? sender, RoutedEventArgs e)",
+ "lineNumber": 73
+ },
+ {
+ "text": " {",
+ "lineNumber": 74
+ },
+ {
+ "text": " var topLevel = TopLevel.GetTopLevel(this);",
+ "lineNumber": 75
+ },
+ {
+ "text": " if (topLevel?.StorageProvider.CanPickFolder == true)",
+ "lineNumber": 76
+ },
+ {
+ "text": " {",
+ "lineNumber": 77
+ },
+ {
+ "text": " var folders = await topLevel.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions",
+ "lineNumber": 78
+ },
+ {
+ "text": " {",
+ "lineNumber": 79
+ },
+ {
+ "text": " Title = \"Select Flamenco Worker Path\"",
+ "lineNumber": 80
+ },
+ {
+ "text": " });",
+ "lineNumber": 81
+ },
+ {
+ "text": " ",
+ "lineNumber": 82
+ },
+ {
+ "text": " if (folders.Count > 0 && folders[0].TryGetLocalPath() is { } localPath)",
+ "lineNumber": 83
+ },
+ {
+ "text": " {",
+ "lineNumber": 84
+ },
+ {
+ "text": " _viewModel.FlamencoWorkerPath = localPath;",
+ "lineNumber": 85
+ },
+ {
+ "text": " }",
+ "lineNumber": 86
+ },
+ {
+ "text": " }",
+ "lineNumber": 87
+ },
+ {
+ "text": " }",
+ "lineNumber": 88
+ },
+ {
+ "lineNumber": 89
+ },
+ {
+ "text": " public async Task<bool> ShowDialogAsync(Window parent)",
+ "lineNumber": 90
+ },
+ {
+ "text": " {",
+ "lineNumber": 91
+ },
+ {
+ "text": " await base.ShowDialog(parent);",
+ "lineNumber": 92
+ },
+ {
+ "text": " return _result;",
+ "lineNumber": 93
+ },
+ {
+ "text": " }",
+ "lineNumber": 94
+ },
+ {
+ "text": " }",
+ "lineNumber": 95
+ },
+ {
+ "text": "}",
+ "lineNumber": 96
+ }
+ ]
+ },
+ "score": 0.21289044618606567
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\Views\\GlobalSettingsWindow.axaml.cs",
+ "range": {
+ "startPosition": {},
+ "endPosition": {
+ "line": 58
+ }
+ },
+ "contents": "using System.Threading.Tasks;\nusing Avalonia.Controls;\nusing Avalonia.Interactivity;\nusing Avalonia.Platform.Storage;\nusing UnifiedFarmLauncher.Services;\nusing UnifiedFarmLauncher.ViewModels;\n\nnamespace UnifiedFarmLauncher.Views\n{\n public partial class GlobalSettingsWindow : Window\n {\n private readonly GlobalSettingsViewModel _viewModel;\n private bool _result;\n\n public GlobalSettingsWindow()\n {\n InitializeComponent();\n var configService = new ConfigService();\n _viewModel = new GlobalSettingsViewModel(configService);\n DataContext = _viewModel;\n SetupEventHandlers();\n }\n\n private void InitializeComponent()\n {\n Avalonia.Markup.Xaml.AvaloniaXamlLoader.Load(this);\n }\n\n private void SetupEventHandlers()\n {\n this.FindControl<Button>(\"OkButton\")!.Click += OkButton_Click;\n this.FindControl<Button>(\"CancelButton\")!.Click += CancelButton_Click;\n this.FindControl<Button>(\"ToggleRenderKeyButton\")!.Click += ToggleRenderKeyButton_Click;\n this.FindControl<Button>(\"BrowseFlamencoPathButton\")!.Click += BrowseFlamencoPathButton_Click;\n }\n\n private void OkButton_Click(object? sender, RoutedEventArgs e)\n {\n try\n {\n _viewModel.Save();\n _result = true;\n Close();\n }\n catch (System.Exception ex)\n {\n // Could show error message here\n System.Diagnostics.Debug.WriteLine($\"Failed to save global settings: {ex.Message}\");\n }\n }\n\n private void CancelButton_Click(object? sender, RoutedEventArgs e)\n {\n _result = false;\n Close();\n }\n\n private void ToggleRenderKeyButton_Click(object? sender, RoutedEventArgs e)",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": "using System.Threading.Tasks;",
+ "lineNumber": 1
+ },
+ {
+ "text": "using Avalonia.Controls;",
+ "lineNumber": 2
+ },
+ {
+ "text": "using Avalonia.Interactivity;",
+ "lineNumber": 3
+ },
+ {
+ "text": "using Avalonia.Platform.Storage;",
+ "lineNumber": 4
+ },
+ {
+ "text": "using UnifiedFarmLauncher.Services;",
+ "lineNumber": 5
+ },
+ {
+ "text": "using UnifiedFarmLauncher.ViewModels;",
+ "lineNumber": 6
+ },
+ {
+ "lineNumber": 7
+ },
+ {
+ "text": "namespace UnifiedFarmLauncher.Views",
+ "lineNumber": 8
+ },
+ {
+ "text": "{",
+ "lineNumber": 9
+ },
+ {
+ "text": " public partial class GlobalSettingsWindow : Window",
+ "lineNumber": 10
+ },
+ {
+ "text": " {",
+ "lineNumber": 11
+ },
+ {
+ "text": " private readonly GlobalSettingsViewModel _viewModel;",
+ "lineNumber": 12
+ },
+ {
+ "text": " private bool _result;",
+ "lineNumber": 13
+ },
+ {
+ "lineNumber": 14
+ },
+ {
+ "text": " public GlobalSettingsWindow()",
+ "lineNumber": 15
+ },
+ {
+ "text": " {",
+ "lineNumber": 16
+ },
+ {
+ "text": " InitializeComponent();",
+ "lineNumber": 17
+ },
+ {
+ "text": " var configService = new ConfigService();",
+ "lineNumber": 18
+ },
+ {
+ "text": " _viewModel = new GlobalSettingsViewModel(configService);",
+ "lineNumber": 19
+ },
+ {
+ "text": " DataContext = _viewModel;",
+ "lineNumber": 20
+ },
+ {
+ "text": " SetupEventHandlers();",
+ "lineNumber": 21
+ },
+ {
+ "text": " }",
+ "lineNumber": 22
+ },
+ {
+ "lineNumber": 23
+ },
+ {
+ "text": " private void InitializeComponent()",
+ "lineNumber": 24
+ },
+ {
+ "text": " {",
+ "lineNumber": 25
+ },
+ {
+ "text": " Avalonia.Markup.Xaml.AvaloniaXamlLoader.Load(this);",
+ "lineNumber": 26
+ },
+ {
+ "text": " }",
+ "lineNumber": 27
+ },
+ {
+ "lineNumber": 28
+ },
+ {
+ "text": " private void SetupEventHandlers()",
+ "lineNumber": 29
+ },
+ {
+ "text": " {",
+ "lineNumber": 30
+ },
+ {
+ "text": " this.FindControl<Button>(\"OkButton\")!.Click += OkButton_Click;",
+ "lineNumber": 31
+ },
+ {
+ "text": " this.FindControl<Button>(\"CancelButton\")!.Click += CancelButton_Click;",
+ "lineNumber": 32
+ },
+ {
+ "text": " this.FindControl<Button>(\"ToggleRenderKeyButton\")!.Click += ToggleRenderKeyButton_Click;",
+ "lineNumber": 33
+ },
+ {
+ "text": " this.FindControl<Button>(\"BrowseFlamencoPathButton\")!.Click += BrowseFlamencoPathButton_Click;",
+ "lineNumber": 34
+ },
+ {
+ "text": " }",
+ "lineNumber": 35
+ },
+ {
+ "lineNumber": 36
+ },
+ {
+ "text": " private void OkButton_Click(object? sender, RoutedEventArgs e)",
+ "lineNumber": 37
+ },
+ {
+ "text": " {",
+ "lineNumber": 38
+ },
+ {
+ "text": " try",
+ "lineNumber": 39
+ },
+ {
+ "text": " {",
+ "lineNumber": 40
+ },
+ {
+ "text": " _viewModel.Save();",
+ "lineNumber": 41
+ },
+ {
+ "text": " _result = true;",
+ "lineNumber": 42
+ },
+ {
+ "text": " Close();",
+ "lineNumber": 43
+ },
+ {
+ "text": " }",
+ "lineNumber": 44
+ },
+ {
+ "text": " catch (System.Exception ex)",
+ "lineNumber": 45
+ },
+ {
+ "text": " {",
+ "lineNumber": 46
+ },
+ {
+ "text": " // Could show error message here",
+ "lineNumber": 47
+ },
+ {
+ "text": " System.Diagnostics.Debug.WriteLine($\"Failed to save global settings: {ex.Message}\");",
+ "lineNumber": 48
+ },
+ {
+ "text": " }",
+ "lineNumber": 49
+ },
+ {
+ "text": " }",
+ "lineNumber": 50
+ },
+ {
+ "lineNumber": 51
+ },
+ {
+ "text": " private void CancelButton_Click(object? sender, RoutedEventArgs e)",
+ "lineNumber": 52
+ },
+ {
+ "text": " {",
+ "lineNumber": 53
+ },
+ {
+ "text": " _result = false;",
+ "lineNumber": 54
+ },
+ {
+ "text": " Close();",
+ "lineNumber": 55
+ },
+ {
+ "text": " }",
+ "lineNumber": 56
+ },
+ {
+ "lineNumber": 57
+ },
+ {
+ "text": " private void ToggleRenderKeyButton_Click(object? sender, RoutedEventArgs e)",
+ "lineNumber": 58
+ }
+ ]
+ },
+ "score": 0.20524029433727264
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\Views\\MainWindow.axaml.cs",
+ "range": {
+ "startPosition": {
+ "line": 136
+ },
+ "endPosition": {
+ "line": 172
+ }
+ },
+ "contents": " }\n\n private async void StopWorkerButton_Click(object? sender, RoutedEventArgs e)\n {\n if (this.FindControl<DataGrid>(\"WorkersGrid\")?.SelectedItem is WorkerConfig worker)\n {\n try\n {\n var vm = (MainWindowViewModel)DataContext!;\n string workerType = vm.OperationMode;\n\n // Verify the worker supports the selected operation mode\n if (workerType == \"sheepit\" && worker.WorkerTypes.SheepIt == null)\n {\n var box = MessageBoxManager.GetMessageBoxStandard(\"Error\", \n $\"Worker '{worker.Name}' does not have SheepIt configured.\", \n ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error);\n await box.ShowAsync();\n return;\n }\n if (workerType == \"flamenco\" && worker.WorkerTypes.Flamenco == null)\n {\n var box = MessageBoxManager.GetMessageBoxStandard(\"Error\", \n $\"Worker '{worker.Name}' does not have Flamenco configured.\", \n ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error);\n await box.ShowAsync();\n return;\n }\n\n await _controllerService.StopWorkerAsync(worker, workerType);\n var successBox = MessageBoxManager.GetMessageBoxStandard(\"Stop Worker\", \n $\"Stop command sent to worker '{worker.Name}' ({vm.OperationModeDisplayName}).\", \n ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Info);\n await successBox.ShowAsync();\n }\n catch (System.Exception ex)",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": " }",
+ "lineNumber": 137
+ },
+ {
+ "lineNumber": 138
+ },
+ {
+ "text": " private async void StopWorkerButton_Click(object? sender, RoutedEventArgs e)",
+ "lineNumber": 139
+ },
+ {
+ "text": " {",
+ "lineNumber": 140
+ },
+ {
+ "text": " if (this.FindControl<DataGrid>(\"WorkersGrid\")?.SelectedItem is WorkerConfig worker)",
+ "lineNumber": 141
+ },
+ {
+ "text": " {",
+ "lineNumber": 142
+ },
+ {
+ "text": " try",
+ "lineNumber": 143
+ },
+ {
+ "text": " {",
+ "lineNumber": 144
+ },
+ {
+ "text": " var vm = (MainWindowViewModel)DataContext!;",
+ "lineNumber": 145
+ },
+ {
+ "text": " string workerType = vm.OperationMode;",
+ "lineNumber": 146
+ },
+ {
+ "lineNumber": 147
+ },
+ {
+ "text": " // Verify the worker supports the selected operation mode",
+ "lineNumber": 148
+ },
+ {
+ "text": " if (workerType == \"sheepit\" && worker.WorkerTypes.SheepIt == null)",
+ "lineNumber": 149
+ },
+ {
+ "text": " {",
+ "lineNumber": 150
+ },
+ {
+ "text": " var box = MessageBoxManager.GetMessageBoxStandard(\"Error\", ",
+ "lineNumber": 151
+ },
+ {
+ "text": " $\"Worker '{worker.Name}' does not have SheepIt configured.\", ",
+ "lineNumber": 152
+ },
+ {
+ "text": " ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error);",
+ "lineNumber": 153
+ },
+ {
+ "text": " await box.ShowAsync();",
+ "lineNumber": 154
+ },
+ {
+ "text": " return;",
+ "lineNumber": 155
+ },
+ {
+ "text": " }",
+ "lineNumber": 156
+ },
+ {
+ "text": " if (workerType == \"flamenco\" && worker.WorkerTypes.Flamenco == null)",
+ "lineNumber": 157
+ },
+ {
+ "text": " {",
+ "lineNumber": 158
+ },
+ {
+ "text": " var box = MessageBoxManager.GetMessageBoxStandard(\"Error\", ",
+ "lineNumber": 159
+ },
+ {
+ "text": " $\"Worker '{worker.Name}' does not have Flamenco configured.\", ",
+ "lineNumber": 160
+ },
+ {
+ "text": " ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error);",
+ "lineNumber": 161
+ },
+ {
+ "text": " await box.ShowAsync();",
+ "lineNumber": 162
+ },
+ {
+ "text": " return;",
+ "lineNumber": 163
+ },
+ {
+ "text": " }",
+ "lineNumber": 164
+ },
+ {
+ "lineNumber": 165
+ },
+ {
+ "text": " await _controllerService.StopWorkerAsync(worker, workerType);",
+ "lineNumber": 166
+ },
+ {
+ "text": " var successBox = MessageBoxManager.GetMessageBoxStandard(\"Stop Worker\", ",
+ "lineNumber": 167
+ },
+ {
+ "text": " $\"Stop command sent to worker '{worker.Name}' ({vm.OperationModeDisplayName}).\", ",
+ "lineNumber": 168
+ },
+ {
+ "text": " ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Info);",
+ "lineNumber": 169
+ },
+ {
+ "text": " await successBox.ShowAsync();",
+ "lineNumber": 170
+ },
+ {
+ "text": " }",
+ "lineNumber": 171
+ },
+ {
+ "text": " catch (System.Exception ex)",
+ "lineNumber": 172
+ }
+ ]
+ },
+ "score": 0.19811619818210602
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\Views\\MainWindow.axaml",
+ "range": {
+ "startPosition": {},
+ "endPosition": {
+ "line": 36
+ }
+ },
+ "contents": "<Window xmlns=\"https://github.com/avaloniaui\"\n xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n xmlns:vm=\"using:UnifiedFarmLauncher.ViewModels\"\n xmlns:models=\"using:UnifiedFarmLauncher.Models\"\n x:Class=\"UnifiedFarmLauncher.Views.MainWindow\"\n x:DataType=\"vm:MainWindowViewModel\"\n Title=\"Unified Farm Launcher\"\n Width=\"1000\" Height=\"700\"\n MinWidth=\"800\" MinHeight=\"600\">\n <Grid RowDefinitions=\"Auto,Auto,*,Auto\">\n <!-- Toolbar -->\n <Grid Grid.Row=\"0\" Margin=\"5\">\n <Grid.ColumnDefinitions>\n <ColumnDefinition Width=\"*\"/>\n <ColumnDefinition Width=\"Auto\"/>\n </Grid.ColumnDefinitions>\n <StackPanel Orientation=\"Horizontal\" Grid.Column=\"0\">\n <Button Name=\"AddWorkerButton\" Content=\"Add Worker\" Margin=\"5\" Width=\"120\"/>\n <Button Name=\"EditWorkerButton\" Content=\"Edit Worker\" Margin=\"5\" Width=\"120\"/>\n <Button Name=\"DeleteWorkerButton\" Content=\"Delete Worker\" Margin=\"5\" Width=\"120\"/>\n <Separator Margin=\"10,0\"/>\n <Button Name=\"StartWorkerButton\" Content=\"Start\" Margin=\"5\" Width=\"80\"/>\n <Button Name=\"StopWorkerButton\" Content=\"Stop\" Margin=\"5\" Width=\"80\"/>\n <Button Name=\"AttachWorkerButton\" Content=\"Attach\" Margin=\"5\" Width=\"80\"/>\n <Separator Margin=\"10,0\"/>\n <Button Name=\"SettingsButton\" Content=\"Settings\" Margin=\"5\" Width=\"80\"/>\n </StackPanel>\n <!-- Operation Mode Toggle Button -->\n <Button Name=\"OperationModeToggleButton\" Grid.Column=\"1\" \n HorizontalAlignment=\"Right\" \n VerticalAlignment=\"Center\"\n Margin=\"5\"\n Padding=\"10,5\"\n MinWidth=\"120\">\n <StackPanel Orientation=\"Horizontal\" Spacing=\"5\">\n <TextBlock Text=\"{Binding OperationModeIcon}\" FontSize=\"16\" VerticalAlignment=\"Center\"/>",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": "<Window xmlns=\"https://github.com/avaloniaui\"",
+ "lineNumber": 1
+ },
+ {
+ "text": " xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"",
+ "lineNumber": 2
+ },
+ {
+ "text": " xmlns:vm=\"using:UnifiedFarmLauncher.ViewModels\"",
+ "lineNumber": 3
+ },
+ {
+ "text": " xmlns:models=\"using:UnifiedFarmLauncher.Models\"",
+ "lineNumber": 4
+ },
+ {
+ "text": " x:Class=\"UnifiedFarmLauncher.Views.MainWindow\"",
+ "lineNumber": 5
+ },
+ {
+ "text": " x:DataType=\"vm:MainWindowViewModel\"",
+ "lineNumber": 6
+ },
+ {
+ "text": " Title=\"Unified Farm Launcher\"",
+ "lineNumber": 7
+ },
+ {
+ "text": " Width=\"1000\" Height=\"700\"",
+ "lineNumber": 8
+ },
+ {
+ "text": " MinWidth=\"800\" MinHeight=\"600\">",
+ "lineNumber": 9
+ },
+ {
+ "text": " <Grid RowDefinitions=\"Auto,Auto,*,Auto\">",
+ "lineNumber": 10
+ },
+ {
+ "text": " <!-- Toolbar -->",
+ "lineNumber": 11
+ },
+ {
+ "text": " <Grid Grid.Row=\"0\" Margin=\"5\">",
+ "lineNumber": 12
+ },
+ {
+ "text": " <Grid.ColumnDefinitions>",
+ "lineNumber": 13
+ },
+ {
+ "text": " <ColumnDefinition Width=\"*\"/>",
+ "lineNumber": 14
+ },
+ {
+ "text": " <ColumnDefinition Width=\"Auto\"/>",
+ "lineNumber": 15
+ },
+ {
+ "text": " </Grid.ColumnDefinitions>",
+ "lineNumber": 16
+ },
+ {
+ "text": " <StackPanel Orientation=\"Horizontal\" Grid.Column=\"0\">",
+ "lineNumber": 17
+ },
+ {
+ "text": " <Button Name=\"AddWorkerButton\" Content=\"Add Worker\" Margin=\"5\" Width=\"120\"/>",
+ "lineNumber": 18
+ },
+ {
+ "text": " <Button Name=\"EditWorkerButton\" Content=\"Edit Worker\" Margin=\"5\" Width=\"120\"/>",
+ "lineNumber": 19
+ },
+ {
+ "text": " <Button Name=\"DeleteWorkerButton\" Content=\"Delete Worker\" Margin=\"5\" Width=\"120\"/>",
+ "lineNumber": 20
+ },
+ {
+ "text": " <Separator Margin=\"10,0\"/>",
+ "lineNumber": 21
+ },
+ {
+ "text": " <Button Name=\"StartWorkerButton\" Content=\"Start\" Margin=\"5\" Width=\"80\"/>",
+ "lineNumber": 22
+ },
+ {
+ "text": " <Button Name=\"StopWorkerButton\" Content=\"Stop\" Margin=\"5\" Width=\"80\"/>",
+ "lineNumber": 23
+ },
+ {
+ "text": " <Button Name=\"AttachWorkerButton\" Content=\"Attach\" Margin=\"5\" Width=\"80\"/>",
+ "lineNumber": 24
+ },
+ {
+ "text": " <Separator Margin=\"10,0\"/>",
+ "lineNumber": 25
+ },
+ {
+ "text": " <Button Name=\"SettingsButton\" Content=\"Settings\" Margin=\"5\" Width=\"80\"/>",
+ "lineNumber": 26
+ },
+ {
+ "text": " </StackPanel>",
+ "lineNumber": 27
+ },
+ {
+ "text": " <!-- Operation Mode Toggle Button -->",
+ "lineNumber": 28
+ },
+ {
+ "text": " <Button Name=\"OperationModeToggleButton\" Grid.Column=\"1\" ",
+ "lineNumber": 29
+ },
+ {
+ "text": " HorizontalAlignment=\"Right\" ",
+ "lineNumber": 30
+ },
+ {
+ "text": " VerticalAlignment=\"Center\"",
+ "lineNumber": 31
+ },
+ {
+ "text": " Margin=\"5\"",
+ "lineNumber": 32
+ },
+ {
+ "text": " Padding=\"10,5\"",
+ "lineNumber": 33
+ },
+ {
+ "text": " MinWidth=\"120\">",
+ "lineNumber": 34
+ },
+ {
+ "text": " <StackPanel Orientation=\"Horizontal\" Spacing=\"5\">",
+ "lineNumber": 35
+ },
+ {
+ "text": " <TextBlock Text=\"{Binding OperationModeIcon}\" FontSize=\"16\" VerticalAlignment=\"Center\"/>",
+ "lineNumber": 36
+ }
+ ]
+ },
+ "score": 0.1752990484237671
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\Views\\MainWindow.axaml.cs",
+ "range": {
+ "startPosition": {},
+ "endPosition": {
+ "line": 34
+ }
+ },
+ "contents": "using System.Linq;\nusing Avalonia.Controls;\nusing Avalonia.Interactivity;\nusing UnifiedFarmLauncher.Models;\nusing UnifiedFarmLauncher.Services;\nusing UnifiedFarmLauncher.ViewModels;\nusing Avalonia.Controls.Primitives;\nusing MsBox.Avalonia;\nusing MsBox.Avalonia.Enums;\n\nnamespace UnifiedFarmLauncher.Views\n{\n public partial class MainWindow : Window\n {\n private readonly ConfigService _configService = new();\n private readonly SshService _sshService = new();\n private readonly WorkerControllerService _controllerService;\n private readonly AttachService _attachService;\n\n public MainWindow()\n {\n InitializeComponent();\n _controllerService = new WorkerControllerService(_sshService, _configService);\n _attachService = new AttachService(_sshService, _controllerService);\n DataContext = new MainWindowViewModel();\n SetupEventHandlers();\n }\n\n private void InitializeComponent()\n {\n Avalonia.Markup.Xaml.AvaloniaXamlLoader.Load(this);\n }\n\n private void SetupEventHandlers()",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": "using System.Linq;",
+ "lineNumber": 1
+ },
+ {
+ "text": "using Avalonia.Controls;",
+ "lineNumber": 2
+ },
+ {
+ "text": "using Avalonia.Interactivity;",
+ "lineNumber": 3
+ },
+ {
+ "text": "using UnifiedFarmLauncher.Models;",
+ "lineNumber": 4
+ },
+ {
+ "text": "using UnifiedFarmLauncher.Services;",
+ "lineNumber": 5
+ },
+ {
+ "text": "using UnifiedFarmLauncher.ViewModels;",
+ "lineNumber": 6
+ },
+ {
+ "text": "using Avalonia.Controls.Primitives;",
+ "lineNumber": 7
+ },
+ {
+ "text": "using MsBox.Avalonia;",
+ "lineNumber": 8
+ },
+ {
+ "text": "using MsBox.Avalonia.Enums;",
+ "lineNumber": 9
+ },
+ {
+ "lineNumber": 10
+ },
+ {
+ "text": "namespace UnifiedFarmLauncher.Views",
+ "lineNumber": 11
+ },
+ {
+ "text": "{",
+ "lineNumber": 12
+ },
+ {
+ "text": " public partial class MainWindow : Window",
+ "lineNumber": 13
+ },
+ {
+ "text": " {",
+ "lineNumber": 14
+ },
+ {
+ "text": " private readonly ConfigService _configService = new();",
+ "lineNumber": 15
+ },
+ {
+ "text": " private readonly SshService _sshService = new();",
+ "lineNumber": 16
+ },
+ {
+ "text": " private readonly WorkerControllerService _controllerService;",
+ "lineNumber": 17
+ },
+ {
+ "text": " private readonly AttachService _attachService;",
+ "lineNumber": 18
+ },
+ {
+ "lineNumber": 19
+ },
+ {
+ "text": " public MainWindow()",
+ "lineNumber": 20
+ },
+ {
+ "text": " {",
+ "lineNumber": 21
+ },
+ {
+ "text": " InitializeComponent();",
+ "lineNumber": 22
+ },
+ {
+ "text": " _controllerService = new WorkerControllerService(_sshService, _configService);",
+ "lineNumber": 23
+ },
+ {
+ "text": " _attachService = new AttachService(_sshService, _controllerService);",
+ "lineNumber": 24
+ },
+ {
+ "text": " DataContext = new MainWindowViewModel();",
+ "lineNumber": 25
+ },
+ {
+ "text": " SetupEventHandlers();",
+ "lineNumber": 26
+ },
+ {
+ "text": " }",
+ "lineNumber": 27
+ },
+ {
+ "lineNumber": 28
+ },
+ {
+ "text": " private void InitializeComponent()",
+ "lineNumber": 29
+ },
+ {
+ "text": " {",
+ "lineNumber": 30
+ },
+ {
+ "text": " Avalonia.Markup.Xaml.AvaloniaXamlLoader.Load(this);",
+ "lineNumber": 31
+ },
+ {
+ "text": " }",
+ "lineNumber": 32
+ },
+ {
+ "lineNumber": 33
+ },
+ {
+ "text": " private void SetupEventHandlers()",
+ "lineNumber": 34
+ }
+ ]
+ },
+ "score": 0.16454540193080902
+ },
+ {
+ "codeBlock": {
+ "relativeWorkspacePath": ".\\Views\\MainWindow.axaml.cs",
+ "range": {
+ "startPosition": {
+ "line": 101
+ },
+ "endPosition": {
+ "line": 139
+ }
+ },
+ "contents": " string? workerType = vm.OperationMode;\n\n // Verify the worker supports the selected operation mode\n if (workerType == \"sheepit\" && worker.WorkerTypes.SheepIt == null)\n {\n var box = MessageBoxManager.GetMessageBoxStandard(\"Error\", \n $\"Worker '{worker.Name}' does not have SheepIt configured.\", \n ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error);\n await box.ShowAsync();\n return;\n }\n if (workerType == \"flamenco\" && worker.WorkerTypes.Flamenco == null)\n {\n var box = MessageBoxManager.GetMessageBoxStandard(\"Error\", \n $\"Worker '{worker.Name}' does not have Flamenco configured.\", \n ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error);\n await box.ShowAsync();\n return;\n }\n\n await _controllerService.StartWorkerAsync(worker, workerType);\n var successBox = MessageBoxManager.GetMessageBoxStandard(\"Start Worker\", \n $\"Worker '{worker.Name}' ({vm.OperationModeDisplayName}) started successfully.\", \n ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Success);\n await successBox.ShowAsync();\n vm.RefreshWorkers();\n }\n catch (System.Exception ex)\n {\n var errorBox = MessageBoxManager.GetMessageBoxStandard(\"Error\", \n $\"Failed to start worker: {ex.Message}\", \n ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error);\n await errorBox.ShowAsync();\n }\n }\n }\n\n private async void StopWorkerButton_Click(object? sender, RoutedEventArgs e)",
+ "signatures": {},
+ "detailedLines": [
+ {
+ "text": " string? workerType = vm.OperationMode;",
+ "lineNumber": 102
+ },
+ {
+ "lineNumber": 103
+ },
+ {
+ "text": " // Verify the worker supports the selected operation mode",
+ "lineNumber": 104
+ },
+ {
+ "text": " if (workerType == \"sheepit\" && worker.WorkerTypes.SheepIt == null)",
+ "lineNumber": 105
+ },
+ {
+ "text": " {",
+ "lineNumber": 106
+ },
+ {
+ "text": " var box = MessageBoxManager.GetMessageBoxStandard(\"Error\", ",
+ "lineNumber": 107
+ },
+ {
+ "text": " $\"Worker '{worker.Name}' does not have SheepIt configured.\", ",
+ "lineNumber": 108
+ },
+ {
+ "text": " ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error);",
+ "lineNumber": 109
+ },
+ {
+ "text": " await box.ShowAsync();",
+ "lineNumber": 110
+ },
+ {
+ "text": " return;",
+ "lineNumber": 111
+ },
+ {
+ "text": " }",
+ "lineNumber": 112
+ },
+ {
+ "text": " if (workerType == \"flamenco\" && worker.WorkerTypes.Flamenco == null)",
+ "lineNumber": 113
+ },
+ {
+ "text": " {",
+ "lineNumber": 114
+ },
+ {
+ "text": " var box = MessageBoxManager.GetMessageBoxStandard(\"Error\", ",
+ "lineNumber": 115
+ },
+ {
+ "text": " $\"Worker '{worker.Name}' does not have Flamenco configured.\", ",
+ "lineNumber": 116
+ },
+ {
+ "text": " ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error);",
+ "lineNumber": 117
+ },
+ {
+ "text": " await box.ShowAsync();",
+ "lineNumber": 118
+ },
+ {
+ "text": " return;",
+ "lineNumber": 119
+ },
+ {
+ "text": " }",
+ "lineNumber": 120
+ },
+ {
+ "lineNumber": 121
+ },
+ {
+ "text": " await _controllerService.StartWorkerAsync(worker, workerType);",
+ "lineNumber": 122
+ },
+ {
+ "text": " var successBox = MessageBoxManager.GetMessageBoxStandard(\"Start Worker\", ",
+ "lineNumber": 123
+ },
+ {
+ "text": " $\"Worker '{worker.Name}' ({vm.OperationModeDisplayName}) started successfully.\", ",
+ "lineNumber": 124
+ },
+ {
+ "text": " ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Success);",
+ "lineNumber": 125
+ },
+ {
+ "text": " await successBox.ShowAsync();",
+ "lineNumber": 126
+ },
+ {
+ "text": " vm.RefreshWorkers();",
+ "lineNumber": 127
+ },
+ {
+ "text": " }",
+ "lineNumber": 128
+ },
+ {
+ "text": " catch (System.Exception ex)",
+ "lineNumber": 129
+ },
+ {
+ "text": " {",
+ "lineNumber": 130
+ },
+ {
+ "text": " var errorBox = MessageBoxManager.GetMessageBoxStandard(\"Error\", ",
+ "lineNumber": 131
+ },
+ {
+ "text": " $\"Failed to start worker: {ex.Message}\", ",
+ "lineNumber": 132
+ },
+ {
+ "text": " ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Error);",
+ "lineNumber": 133
+ },
+ {
+ "text": " await errorBox.ShowAsync();",
+ "lineNumber": 134
+ },
+ {
+ "text": " }",
+ "lineNumber": 135
+ },
+ {
+ "text": " }",
+ "lineNumber": 136
+ },
+ {
+ "text": " }",
+ "lineNumber": 137
+ },
+ {
+ "lineNumber": 138
+ },
+ {
+ "text": " private async void StopWorkerButton_Click(object? sender, RoutedEventArgs e)",
+ "lineNumber": 139
+ }
+ ]
+ },
+ "score": 0.15338963270187378
+ }
+ ]
+}
+```
+Status: **completed**
+
+
+
+
+
+---
+
+
+The ComboBox binding issue: `SelectedItem` is bound to a string (`SheepItGpu`), but the items are `ComboBoxItem` objects, so the match fails. Also, if the saved GPU is empty, nothing gets selected.
+
+Creating a plan to fix this:
+
+
+---
+
+
+
+Tool use: **create_plan**
+
+
+Parameters:
+
+```json
+{
+ "plan": "# Fix GPU Selection Persistence\n\n## Problem\nThe GPU ComboBox in the worker edit window doesn't properly bind to the `SheepItGpu` property because:\n1. The ComboBox uses `ComboBoxItem` objects with `Content` properties, but `SelectedItem` is bound to a string\n2. When the saved GPU value is empty or doesn't match, the ComboBox doesn't select anything\n3. The binding mismatch prevents proper saving and loading of GPU selection\n\n## Solution\n\n### 1. Fix ComboBox Binding in `Views/WorkerEditWindow.axaml`\nChange the ComboBox to use plain strings instead of `ComboBoxItem` objects. This allows direct binding to the string property.\n\n**Current code (lines 37-43):**\n```xml\n<ComboBox Name=\"GpuComboBox\" IsVisible=\"{Binding HasSheepIt}\" SelectedItem=\"{Binding SheepItGpu}\">\n <ComboBox.Items>\n <ComboBoxItem Content=\"OPTIX_0\"/>\n <ComboBoxItem Content=\"CUDA_0\"/>\n <ComboBoxItem Content=\"OPENCL_0\"/>\n </ComboBox.Items>\n</ComboBox>\n```\n\n**Change to:**\n```xml\n<ComboBox Name=\"GpuComboBox\" IsVisible=\"{Binding HasSheepIt}\" SelectedItem=\"{Binding SheepItGpu}\">\n <ComboBox.Items>\n <x:String>OPTIX_0</x:String>\n <x:String>CUDA_0</x:String>\n <x:String>OPENCL_0</x:String>\n </ComboBox.Items>\n</ComboBox>\n```\n\nOr use an Items collection in the ViewModel for better maintainability.\n\n### 2. Ensure Default GPU Value is Set\nIn `ViewModels/WorkerEditViewModel.cs`, ensure that when loading a worker with an empty GPU value, it defaults to \"OPTIX_0\":\n\n**Update `LoadWorker` method (around line 108):**\n```csharp\nif (worker.WorkerTypes.SheepIt != null)\n{\n HasSheepIt = true;\n SheepItGpu = string.IsNullOrEmpty(worker.WorkerTypes.SheepIt.Gpu) \n ? \"OPTIX_0\" \n : worker.WorkerTypes.SheepIt.Gpu;\n}\n```\n\n### 3. Verify GPU is Used in Start Function\nConfirm that `Services/WorkerControllerService.cs` correctly uses the GPU value from the worker configuration (line 145 already does this correctly - no changes needed).\n\n## Files to Modify\n- `Views/WorkerEditWindow.axaml` - Fix ComboBox items to use strings\n- `ViewModels/WorkerEditViewModel.cs` - Add default GPU value handling when loading\n\n## Testing\nAfter the fix:\n1. Open worker settings and select a GPU (e.g., CUDA_0)\n2. Save the worker\n3. Reopen the worker settings - the GPU selection should persist\n4. Start a worker and verify the correct GPU is used in the SheepIt command line",
+ "name": "Fix GPU Selection Persistence",
+ "todos": [
+ {
+ "content": "Fix ComboBox in WorkerEditWindow.axaml to use plain strings instead of ComboBoxItem objects",
+ "status": "pending",
+ "id": "1"
+ },
+ {
+ "content": "Add default GPU value handling in WorkerEditViewModel.LoadWorker when GPU is empty",
+ "status": "pending",
+ "id": "2"
+ },
+ {
+ "content": "Verify the GPU value is correctly saved and loaded in the configuration",
+ "status": "pending",
+ "id": "3"
+ }
+ ],
+ "overview": "Fix the GPU ComboBox binding issue in WorkerEditWindow so that GPU selection persists correctly when saving and loading worker configurations."
+}
+```
+Additional data:
+
+```json
+{
+ "reviewData": {
+ "status": "Requested",
+ "selectedOption": "none",
+ "isShowingInput": false
+ },
+ "planUri": "c:\\Users\\Nathan\\.cursor\\plans\\fix_gpu_selection_persistence_9eaace6a.plan.md",
+ "hasOpenedEditor": true
+}
+```
+Result:
+
+```json
+{
+ "rejected": {}
+}
+```
+Status: **completed**
+
+
+
+
+
+---
+
+_**User**_
+
+Implement the plan as specified, it is attached for your reference. Do NOT edit the plan file itself.
+
+To-do's from the plan have already been created. Do not create them again. Mark them as in_progress as you work, starting with the first one. Don't stop until you have completed all the to-dos.
+
+---
+
+_**Agent (model default, mode Agent)**_
+
+
+Implementing the plan to fix GPU selection persistence. Starting with the first task.
+
+
+---
+
+
+Tool use: **todo_write** • Todo List
+
+- [-] Fix ComboBox in WorkerEditWindow.axaml to use plain strings instead of ComboBoxItem objects
+- [ ] Add default GPU value handling in WorkerEditViewModel.LoadWorker when GPU is empty
+- [ ] Verify the GPU value is correctly saved and loaded in the configuration
+
+
+
+
+---
+
+
+Tool use: **read_file_v2** • Read file: Views/WorkerEditWindow.axaml
+
+
+
+
+---
+
+
+
+Tool use: **edit_file_v2**
+
+
+Parameters:
+
+```json
+{
+ "relativeWorkspacePath": "Views/WorkerEditWindow.axaml"
+}
+```
+Additional data:
+
+```json
+{
+ "codeblockId": "371add81-871e-4ac2-bc2b-12aece92cc82"
+}
+```
+Status: **completed**
+
+
+
+
+
+---
+
+
+Tool use: **read_file_v2** • Read file: Views/WorkerEditWindow.axaml
+
+
+
+
+---
+
+
+Updating the ViewModel to handle empty GPU values:
+
+
+---
+
+
+Tool use: **todo_write** • Todo List
+
+- [x] Fix ComboBox in WorkerEditWindow.axaml to use plain strings instead of ComboBoxItem objects
+- [-] Add default GPU value handling in WorkerEditViewModel.LoadWorker when GPU is empty
+- [ ] Verify the GPU value is correctly saved and loaded in the configuration
+
+
+
+
+---
+
+
+Tool use: **read_file_v2** • Read file: ViewModels/WorkerEditViewModel.cs
+
+
+
+
+---
+
+
+
+Tool use: **edit_file_v2**
+
+
+Parameters:
+
+```json
+{
+ "relativeWorkspacePath": "ViewModels/WorkerEditViewModel.cs"
+}
+```
+Additional data:
+
+```json
+{
+ "codeblockId": "e3ff2d54-77b9-48d4-a21f-8163fc220400"
+}
+```
+Status: **completed**
+
+
+
+
+
+---
+
+
+Tool use: **todo_write** • Todo List
+
+- [x] Fix ComboBox in WorkerEditWindow.axaml to use plain strings instead of ComboBoxItem objects
+- [x] Add default GPU value handling in WorkerEditViewModel.LoadWorker when GPU is empty
+- [-] Verify the GPU value is correctly saved and loaded in the configuration
+
+
+
+
+---
+
+
+Tool use: **read_file_v2** • Read file: Services/WorkerControllerService.cs
+
+
+
+
+---
+
+
+
+Tool use: **ripgrep_raw_search**
+
+
+Parameters:
+
+```json
+{
+ "pattern": "sheepIt\\.Gpu|SheepIt.*Gpu",
+ "path": "Services",
+ "caseInsensitive": false
+}
+```
+Result:
+
+```json
+{
+ "success": {
+ "pattern": "sheepIt\\.Gpu|SheepIt.*Gpu",
+ "path": "Services",
+ "outputMode": "content",
+ "workspaceResults": {
+ "c:\\Users\\Nathan\\Desktop\\UFL": {
+ "content": {
+ "matches": [
+ {
+ "file": "Services\\WorkerControllerService.cs",
+ "matches": [
+ {
+ "lineNumber": 145,
+ "content": " '-gpu', '{sheepIt.Gpu}', '-login', '{safeUser}', '-password', '{safeKey}')"
+ }
+ ]
+ },
+ {
+ "file": "Services/WorkerControllerService.cs",
+ "matches": [
+ {
+ "lineNumber": 145,
+ "content": " '-gpu', '{sheepIt.Gpu}', '-login', '{safeUser}', '-password', '{safeKey}')"
+ }
+ ]
+ }
+ ],
+ "totalLines": 2,
+ "totalMatchedLines": 2
+ }
+ }
+ }
+ }
+}
+```
+Status: **completed**
+
+
+
+
+
+---
+
+
+Tool use: **run_terminal_command_v2** • Run command: dotnet build --no-restore 2>&1 | Select-Object -First 40
+
+```bash
+dotnet build --no-restore 2>&1 | Select-Object -First 40
+```
+
+```
+ UnifiedFarmLauncher -> C:\Users\Nathan\Desktop\UFL\bin\Debug\net8.0\UnifiedFarmLauncher.dll
+
+Build succeeded.
+ 0 Warning(s)
+ 0 Error(s)
+
+Time Elapsed 00:00:00.88
+
+```
+
+
+
+---
+
+
+Verifying the save/load flow for the GPU value:
+
+
+---
+
+
+Tool use: **read_file_v2** • Read file: ViewModels/WorkerEditViewModel.cs
+
+
+
+
+---
+
+
+Tool use: **read_file_v2** • Read file: Services/ConfigService.cs
+
+
+
+
+---
+
+
+Tool use: **read_file_v2** • Read file: Models/WorkerTypeConfig.cs
+
+
+
+
+---
+
+
+Tool use: **todo_write** • Todo List
+
+- [x] Fix ComboBox in WorkerEditWindow.axaml to use plain strings instead of ComboBoxItem objects
+- [x] Add default GPU value handling in WorkerEditViewModel.LoadWorker when GPU is empty
+- [x] Verify the GPU value is correctly saved and loaded in the configuration
+
+
+
+
+---
+
+
+## Completed Changes
+
+1. **Fixed ComboBox binding** in `Views/WorkerEditWindow.axaml`:
+ - Changed from `ComboBoxItem` objects to plain `` elements
+ - Enables direct binding to the `SheepItGpu` string property
+
+2. **Added default GPU handling** in `ViewModels/WorkerEditViewModel.cs`:
+ - Updated `LoadWorker()` to default to "OPTIX_0" when the saved GPU value is empty or null
+ - Prevents the ComboBox from showin
+
+---
+
diff --git a/ViewModels/WorkerEditViewModel.cs b/ViewModels/WorkerEditViewModel.cs
index eea4cb9..a7cbce4 100644
--- a/ViewModels/WorkerEditViewModel.cs
+++ b/ViewModels/WorkerEditViewModel.cs
@@ -105,7 +105,9 @@ namespace UnifiedFarmLauncher.ViewModels
if (worker.WorkerTypes.SheepIt != null)
{
HasSheepIt = true;
- SheepItGpu = worker.WorkerTypes.SheepIt.Gpu;
+ SheepItGpu = string.IsNullOrEmpty(worker.WorkerTypes.SheepIt.Gpu)
+ ? "OPTIX_0"
+ : worker.WorkerTypes.SheepIt.Gpu;
}
if (worker.WorkerTypes.Flamenco != null)
diff --git a/Views/WorkerEditWindow.axaml b/Views/WorkerEditWindow.axaml
index 96e554c..8d9041e 100644
--- a/Views/WorkerEditWindow.axaml
+++ b/Views/WorkerEditWindow.axaml
@@ -36,9 +36,9 @@
-
-
-
+ OPTIX_0
+ CUDA_0
+ OPENCL_0