

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
1234567# Architecture Patterns89## Project Structure1011### Directory Organization12```13src/14 - Core application files (App.xaml, Logic.cs, ConfigManager.cs)15 - Window classes (MainWindow, MonitorWindow, ChatBoxWindow, SettingsWindow, etc.)16 - Translation services (Gemini, ChatGPT, Ollama, GoogleTranslate, LlamaCpp)17 - OCR services (WindowsOCRManager, GoogleVisionOCRService)18 - Managers (UniversalBlockDetector, LogManager, HotkeyManager, PythonServicesManager, AudioPlaybackManager, etc.)19 - Utilities (TextObject, TranslationEventArgs, etc.)20app/21 - Compiled binaries22 - services/ (Python OCR services - EasyOCR, MangaOCR, PaddleOCR, DocTR)23 - shared/ (Shared Python utilities)24 - util/ (Python installation utilities)25 - EasyOCR/, MangaOCR/, PaddleOCR/, DocTR/ (Individual service directories)26 - media/ (Resources)27```2829### File Naming30- One class per file31- File name matches class name32- XAML files: `WindowName.xaml` and `WindowName.xaml.cs`3334## Design Patterns3536### Singleton Pattern37Used for core managers:38- `ConfigManager.Instance`39- `Logic.Instance`40- `UniversalBlockDetector.Instance` - Advanced text block detection (replaces BlockDetectionManager)41- `LogManager.Instance`42- `PythonServicesManager.Instance` - Manages Python OCR services43- `HotkeyManager.Instance` - Manages global keyboard shortcuts (replaces KeyboardShortcuts)44- `AudioPlaybackManager.Instance` - Manages audio playback45- `AudioPreloadService.Instance` - Preloads TTS audio46- `ErrorPopupManager` - Static class for error popups47- `GamepadManager.Instance` - Manages gamepad input48- `WebViewEnvironmentManager` - Static class for WebView2 environment4950**Implementation:**51```csharp52private static ConfigManager? _instance;5354public static ConfigManager Instance55{56 get57 {58 if (_instance == null)59 {60 _instance = new ConfigManager();61 }62 return _instance;63 }64}6566private ConfigManager() { }67```6869### Factory Pattern70Used for creating service instances:7172```csharp73public static class TranslationServiceFactory74{75 public static ITranslationService CreateService(string serviceName)76 {77 return serviceName switch78 {79 "Gemini" => new GeminiTranslationService(),80 "ChatGPT" => new ChatGptTranslationService(),81 "Ollama" => new OllamaTranslationService(),82 "Google Translate" => new GoogleTranslateService(),83 "llama.cpp" => new LlamaCppTranslationService(),84 _ => throw new ArgumentException(...)85 };86 }87}88```8990### Strategy Pattern91Translation services implement common interface:9293```csharp94public interface ITranslationService95{96 Task<TranslationResult?> TranslateAsync(97 string sourceText,98 string targetLanguage,99 string context);100}101```102103## Separation of Concerns104105### UI Layer106- XAML files define UI structure107- Code-behind handles UI events108- Minimal business logic in UI code109110### Business Logic Layer111- `Logic.cs` - Core translation workflow112- `UniversalBlockDetector.cs` - Advanced text block detection and grouping113- Service classes - External API integration114115### Data Layer116- `ConfigManager.cs` - Configuration persistence117- File-based storage (config.txt, service-specific configs)118119## Dependency Management120121### Service Dependencies122Services depend on ConfigManager, not each other:123124```csharp125public class GeminiTranslationService126{127 private readonly string _apiKey;128129 public GeminiTranslationService()130 {131 _apiKey = ConfigManager.Instance.GetGeminiApiKey();132 }133}134```135136### Manager Dependencies137Managers can depend on other managers:138139```csharp140public class Logic141{142 private readonly ConfigManager _configManager;143 private readonly UniversalBlockDetector _blockDetector;144145 public Logic()146 {147 _configManager = ConfigManager.Instance;148 _blockDetector = UniversalBlockDetector.Instance;149 }150}151```152153## Communication Patterns154155### Window Communication156Windows communicate through Logic.Instance:157158```csharp159// In ChatBoxWindow160Logic.Instance.OnTranslationReceived += HandleTranslation;161162// In Logic163public event EventHandler<TranslationEventArgs>? OnTranslationReceived;164```165166### Event-Driven Architecture167Use events for loose coupling:168169```csharp170public class TranslationEventArgs : EventArgs171{172 public string TranslatedText { get; set; } = "";173 public string SourceText { get; set; } = "";174}175```176177### Hotkey System178Hotkeys managed through HotkeyManager events:179180```csharp181HotkeyManager.Instance.StartStopRequested += OnStartStopRequested;182HotkeyManager.Instance.MonitorToggleRequested += OnMonitorToggleRequested;183```184185## Resource Management186187### Disposable Resources188Implement IDisposable for resources:189190```csharp191public class ResourceManager : IDisposable192{193 private bool _disposed = false;194195 public void Dispose()196 {197 Dispose(true);198 GC.SuppressFinalize(this);199 }200201 protected virtual void Dispose(bool disposing)202 {203 if (!_disposed)204 {205 if (disposing)206 {207 // Dispose managed resources208 }209 // Dispose unmanaged resources210 _disposed = true;211 }212 }213}214```215216### Using Statements217Always use `using` for disposable resources:218219```csharp220using (var bitmap = new Bitmap(width, height))221{222 // Use bitmap223} // Automatically disposed224225// Or with async226using var httpClient = new HttpClient();227var response = await httpClient.GetAsync(url);228```229230## State Management231232### Application State233State stored in ConfigManager:234235```csharp236// Current translation service237_currentTranslationService = ConfigManager.Instance.GetCurrentTranslationService();238239// Window positions240var pos = ConfigManager.Instance.GetWindowPosition("ChatBox");241```242243### Runtime State244Runtime state in Logic or window classes:245246```csharp247private bool _isProcessing = false;248private List<TextObject> _currentTextBlocks = new();249```250251## Error Propagation252253### Error Handling Strategy254- Services return null on error255- Log errors using LogManager256- Show user-friendly messages via ErrorPopupManager257- Don't crash the application258259```csharp260public async Task<Result?> ProcessAsync()261{262 try263 {264 return await DoWorkAsync();265 }266 catch (Exception ex)267 {268 LogManager.Instance.LogError("Process failed", ex);269 ErrorPopupManager.ShowError("Process failed", ex.Message);270 return null; // Return null instead of throwing271 }272}273```274275## Extension Points276277### Adding New Translation Service2781. Implement `ITranslationService`2792. Add config keys to ConfigManager2803. Update TranslationServiceFactory2814. Add UI in SettingsWindow282283### Adding New OCR Method2841. Add method name to `SupportedOcrMethods` in ConfigManager2852. Implement processing logic286 - For Python services: Add service directory in `app/services/` with `service_config.txt` and `server.py`287 - For built-in OCR: Implement in appropriate manager class (e.g., WindowsOCRManager, GoogleVisionOCRService)2883. Update OCR selection UI2894. Add configuration options290291### Adding New Python OCR Service2921. Create service directory in `app/services/` (e.g., `app/services/NewOCR/`)2932. Create `service_config.txt` with required fields:294 - `service_name` (ASCII only, no spaces)295 - `venv_name` (ASCII only, e.g., `ugt_newocr`)296 - `port` (unique port number)297 - `description`, `version`, `author`, `github_url`, etc.2983. Create `server.py` implementing FastAPI endpoints:299 - `/process` - Process images300 - `/info` - Service information301 - `/health` - Health check302 - `/shutdown` - Graceful shutdown3034. Create batch scripts: `Install.bat`, `RunServer.bat`, `DiagnosticTest.bat`, `Uninstall.bat`3045. Service will be automatically discovered by `PythonServicesManager` on app startup305306## Performance Considerations307308### Lazy Initialization309Initialize expensive resources on demand:310311```csharp312private HttpClient? _httpClient;313314private HttpClient HttpClient315{316 get317 {318 if (_httpClient == null)319 {320 _httpClient = new HttpClient();321 }322 return _httpClient;323 }324}325```326327### Caching328Cache expensive operations:329330```csharp331private Dictionary<string, TranslationResult> _translationCache = new();332333public TranslationResult? GetCachedTranslation(string text)334{335 if (_translationCache.TryGetValue(text, out var cached))336 {337 return cached;338 }339 return null;340}341```342343## Threading Model344345### UI Thread346- All UI updates on UI thread347- Use Dispatcher.Invoke for cross-thread updates348- Long operations off UI thread349350### Background Threads351- OCR processing on background thread352- Network requests async/await353- Screen capture on timer thread354355## Module Boundaries356357### Service Boundaries358Services are independent modules:359- Each service in own file360- No direct dependencies between services361- Communicate through interfaces362363### Manager Boundaries364Managers provide cross-cutting concerns:365- ConfigManager - Configuration366- LogManager - Logging367- UniversalBlockDetector - Text processing368- HotkeyManager - Keyboard shortcuts369- AudioPlaybackManager - Audio playback370371## Testing Architecture372373### Testable Components374- Business logic separate from UI375- Services implement interfaces376- Static utility methods where possible377378### Mock-Friendly Design379```csharp380// Use interface for testability381public interface ITranslationService382{383 Task<TranslationResult?> TranslateAsync(...);384}385386// Can be mocked in tests387var mockService = new Mock<ITranslationService>();388```389390## Version Management391392### Version Updates393Update version in three places:3941. `SplashManager.cs` - `CurrentVersion` constant3952. `media/latest_version_checker.json` - `latest_version` field3963. `README.md` - Version badge and history entry397398### Version Format399- Use double/float (e.g., 0.60)400- Increment by 0.01 for minor updates401- Increment by 0.10 for major features402403## Build Configuration404405### Output Structure406- Debug: `ugtlive_debug.exe` in `app/`407- Release: `ugtlive.exe` in `app/`408- All dependencies in `app/` directory409410### Dependencies411- .NET 8.0 Windows412- WPF and Windows Forms413- NAudio for audio414- WebView2 for web content415
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| SethRobinson/UGTLive.cursor/rules/translation-workflow.mdc · 107 | Cursor rules | testlint-formatarchapi+3 | 66/100 | 14 days ago | |
| SethRobinson/UGTLive.cursor/rules/async-threading-patterns.mdc · 107 | Cursor rules | styleuido-not | 65/100 | 14 days ago | |
| SethRobinson/UGTLive.cursor/rules/code-style-conventions.mdc · 107 | Cursor rules | stylearchtypesdocs | 62/100 | 14 days ago | |
| SethRobinson/UGTLive.cursor/rules/configuration-management.mdc · 107 | Cursor rules | archsecuritydatabaseapi+1 | 65/100 | 14 days ago | |
| SethRobinson/UGTLive.cursor/rules/debugging-testing.mdc · 107 | Cursor rules | buildteststylearch+3 | 69/100 | 14 days ago | |
| SethRobinson/UGTLive.cursor/rules/locale-invariant-formatting.mdc · 107 | Cursor rules | lint-formatuido-not | 61/100 | 14 days ago | |
| SethRobinson/UGTLive.cursor/rules/service-integration-patterns.mdc · 107 | Cursor rules | buildteststylearch | 69/100 | 14 days ago | |
| SethRobinson/UGTLive.cursor/rules/ugtlive-project-guide.mdc · 107 | Cursor rules | stylearchuideployment+1 | 69/100 | 14 days ago | |
| SethRobinson/UGTLive.cursor/rules/ui-ux-patterns.mdc · 107 | Cursor rules | stylearchtypesui+1 | 62/100 | 14 days ago | |
| SethRobinson/UGTLive.cursor/rules/versioning-workflow.mdc · 107 | Cursor rules | stylegitdeploymentagent-behaviour+1 | 62/100 | 14 days ago | |
| SethRobinson/UGTLive.cursor/rules/wpf-ui-patterns.mdc · 107 | Cursor rules | setuplint-formatstylearch+1 | 66/100 | 14 days ago | |
| SethRobinson/UGTLiveAGENTS.md · 107 | AGENTS.md | testgitsecurityperformance+1 | 74/100 | 14 days ago |
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| ThanhTrunggDEV/DontBeLazy.cursor/rules/rust-testing.mdc · 6 | Cursor rules | teststyletesting-strategy | 90/100 | 14 days ago | |
| ThanhTrunggDEV/DontBeLazy.cursor/rules/dart-testing.mdc · 6 | Cursor rules | teststyletypestesting-strategy | 85/100 | 14 days ago | |
| ThanhTrunggDEV/DontBeLazy.cursor/rules/dart-coding-style.mdc · 6 | Cursor rules | lint-formatstyletypesdo-not | 84/100 | 14 days ago | |
| ThanhTrunggDEV/DontBeLazy.cursor/rules/rust-security.mdc · 6 | Cursor rules | stylesecuritydatabasedo-not | 80/100 | 14 days ago | |
| imazen/imageflow.cursor/rules/ci.mdc · 4.4k | Cursor rules | setupbuildtestarch+3 | 79/100 | 14 days ago | |
| ThanhTrunggDEV/DontBeLazy.cursor/rules/dart-hooks.mdc · 6 | Cursor rules | lint-formatarchtesting-strategygit+1 | 78/100 | 14 days ago | |
| ThanhTrunggDEV/DontBeLazy.cursor/rules/rust-coding-style.mdc · 6 | Cursor rules | lint-formatstyle | 78/100 | 14 days ago | |
| abpframework/abpnpm/ng-packs/packages/schematics/src/commands/ai-config/files/cursor/.cursor/rules/cursor.mdc · 14k | Cursor rules | testlint-formatstylearch+8 | 76/100 | 13 days ago |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/sethrobinson-ugtlive-cursor-rules-architecture-patterns)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.