RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Configs/SethRobinson/UGTLive/diff

Two files, one repository

SethRobinson/UGTLive ships 2 formats across 13 indexed files. The question worth asking is whether the second one says anything the first does not.

CompareAGENTS.md ↔ Cursor rules
A · AGENTS.md · 710 wordsB · .cursor/rules/architecture-patterns.mdc · 1179 words
What each file covers, counted
DimensionSharedOnly in AOnly in BOverlap
Sections07490%
Commands0300%
Section tags23815%

What each file covers

Sections

0 shared · 7 only in A · 49 only in B
  • − AGENTS.md
  • − Shared Project Memory
  • − Testing
  • − Cloud LLM Model Maintenance
  • − Feature Index
  • − Security
  • − Git
  • + Architecture Patterns
  • + Project Structure
  • + Directory Organization
  • + File Naming
  • + Design Patterns
  • + Singleton Pattern
  • + Factory Pattern
  • + Strategy Pattern
  • + Separation of Concerns
  • + UI Layer
  • + Business Logic Layer
  • + Data Layer
  • + Dependency Management
  • + Service Dependencies
  • + Manager Dependencies
  • + Communication Patterns
  • + Window Communication
  • + Event-Driven Architecture
  • + Hotkey System
  • + Resource Management
  • + Disposable Resources
  • + Using Statements
  • + State Management
  • + Application State
  • + Runtime State
  • + Error Propagation
  • + Error Handling Strategy
  • + Extension Points
  • + Adding New Translation Service
  • + Adding New OCR Method
  • + Adding New Python OCR Service
  • + Performance Considerations
  • + Lazy Initialization
  • + Caching
  • + Threading Model
  • + UI Thread
  • + Background Threads
  • + Module Boundaries
  • + Service Boundaries
  • + Manager Boundaries
  • + Testing Architecture
  • + Testable Components
  • + Mock-Friendly Design
  • + Version Management
  • + Version Updates
  • + Version Format
  • + Build Configuration
  • + Output Structure
  • + Dependencies

Commands

0 shared · 3 only in A · 0 only in B
  • − dotnet build .\UGTLive.sln --configuration Release
  • − git commit
  • − git push

Section tags

2 shared · 3 only in A · 8 only in B
  • − git-pr
  • − security
  • − do-not
  • + build
  • + lint-format
  • + code-style
  • + architecture
  • + testing-strategy
  • + dependencies
  • + ui
  • + deployment
  •   test
  •   performance

Line diff

+398 added−38 removed17 unchanged4.1% identical
SethRobinson/UGTLive · AGENTS.md
@@ −1 @@
1# AGENTS.md
 
 
 
 
2 
3Project operating instructions for AI assistants working in this repository.
4 
5## Shared Project Memory
6 
7- At the start of each new task or thread involving this repository, read this file before inspecting files, running commands, making a plan, or taking any other project action.
8- Treat follow-up replies in the same continuous task as part of that task. Do not reread this file unless the repository or working directory changes, this file is modified, or its instructions are no longer available in context.
9- Treat this file as the shared project memory for AI assistants.
10- Do not rely on vendor-specific, proprietary, or hidden memory systems for project facts, preferences, or operating instructions. (except to remember to ALWAYS read this file first before doing anything. Remember that.)
11- Update this file with important repo-specific information learned during work, including build commands, test commands, conventions, decisions, pitfalls, and current project preferences.
12- Keep this file accurate and current. Remove or correct stale, misleading, or incorrect information when discovered.
13- If information is temporary or uncertain, label it clearly rather than presenting it as permanent fact.
 
 
 
 
 
 
 
 
 
 
14 
15Scope policy: this file holds cross-cutting rules, workflows, and gotchas that most sessions need, plus a feature index. Keep it around 30 KB. Feature deep-dives live in `docs/<topic>.md`: before working on a feature listed in the index, read its doc; when finishing feature work, update that doc and keep the index entry here to one or two lines (where it lives + the non-obvious constraint). Cross-cutting rules and new gotchas still land here directly. When a change makes anything stale, here or in a linked doc, update it in the same change.
 
 
 
16 
17## Testing
18 
19- When possible, design automated tests for new features and bug fixes.
20- Run relevant automated tests after finishing changes to guard against regressions.
21- If tests cannot be run or do not exist, state that clearly in the handoff and describe any manual verification performed.
22- Always finish project changes by building the Release configuration: `dotnet build .\UGTLive.sln --configuration Release`.
23- If a running UGTLive process prevents the Release build, capture its executable/command line, stop it, complete the build, and restart it afterward. Do not start UGTLive if it was not running before the build.
 
 
 
 
 
 
 
 
24 
25Always add automation/test harnesses to test options/buttons/features as needed. Document them.
 
 
26 
27## Cloud LLM Model Maintenance
 
 
 
 
 
 
 
 
 
 
28 
29- Cloud and CLI model picker presets live in `src/SettingsWindow.xaml`; their fallback/default values live in `src/ConfigManager.cs`, `src/ConfigManager.Translation.cs`, and `src/SettingsWindow.TranslationSettings.cs`.
30- Subscription-backed CLI providers display as `Anthropic Sub`, `OpenAI Sub`, and `Gemini CLI (Enterprise)`, but their stable internal IDs remain `ClaudeCli`, `CodexCli`, and `GeminiCli`; use `ComboBoxItem.Tag` for the internal ID. Google ended personal/free/AI Pro/AI Ultra access through Gemini CLI on June 18, 2026; do not replace it with Antigravity CLI until `agy -p` reliably exposes captured stdout to Windows parent processes (see `docs/settings-connection-tests.md`).
31- Keep provider-specific capability handling in the matching translation service. In particular, Anthropic model generations use different manual/adaptive thinking request shapes.
32- Verify model IDs and request compatibility against current official provider documentation. Verify OpenRouter-prefixed slugs against its `/api/v1/models` catalog before adding presets.
33 
34## Feature Index
 
35 
36- Settings API/model/voice tests: see `docs/settings-connection-tests.md`. UI buttons and `--test-settings-connection` must continue to call the shared `SettingsConnectionTester` implementation.
37- OpenAI All In One Snap translation: see `docs/openai-all-in-one.md`. It is a Snap-only, visual-only `gpt-image-2` Image Edits path; Auto and realtime processing must remain on the standard OCR pipeline.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38 
 
 
39 
40## Security
 
 
 
 
 
 
 
 
41 
42- Never commit sensitive data, including credentials, tokens, passwords, private keys, cookies, customer data, personal data, or machine-specific authentication material.
43- If an AI assistant needs authentication data or other secrets for local work, use `agents_secret.md` for those notes.
44- `agents_secret.md` must stay ignored by git and must not be committed.
45- Do not put secrets in commit messages, logs, issue text, pull request descriptions, generated docs, or other tracked files.
46- Configuration logging must pass key names through `ConfigManager.IsSensitiveConfigKey`; never print raw secret values in startup or harness output.
47- Before committing, review staged changes for accidental secrets.
48 
49## Git
 
 
 
50 
51- Never add OpenAI/Codex/Claude etc as a co-author on git commits.
52- NEVER `git commit` unless explicitly told to commit.
53- NEVER `git push` unless explicitly told to push. "Commit" means commit
54 locally only; committing is not permission to push.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55 
SethRobinson/UGTLive · .cursor/rules/architecture-patterns.mdc
@@ +1 @@
1---
2description: Architecture patterns and project structure guidelines
3globs: ["**/*.cs"]
4alwaysApply: false
5---
6 
7# Architecture Patterns
8 
9## Project Structure
10 
11### Directory Organization
12```
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 binaries
22 - 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```
28 
29### File Naming
30- One class per file
31- File name matches class name
32- XAML files: `WindowName.xaml` and `WindowName.xaml.cs`
33 
34## Design Patterns
35 
36### Singleton Pattern
37Used 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 services
43- `HotkeyManager.Instance` - Manages global keyboard shortcuts (replaces KeyboardShortcuts)
44- `AudioPlaybackManager.Instance` - Manages audio playback
45- `AudioPreloadService.Instance` - Preloads TTS audio
46- `ErrorPopupManager` - Static class for error popups
47- `GamepadManager.Instance` - Manages gamepad input
48- `WebViewEnvironmentManager` - Static class for WebView2 environment
49 
50**Implementation:**
51```csharp
52private static ConfigManager? _instance;
53 
54public static ConfigManager Instance
55{
56 get
57 {
58 if (_instance == null)
59 {
60 _instance = new ConfigManager();
61 }
62 return _instance;
63 }
64}
65 
66private ConfigManager() { }
67```
 
 
68 
69### Factory Pattern
70Used for creating service instances:
71 
72```csharp
73public static class TranslationServiceFactory
74{
75 public static ITranslationService CreateService(string serviceName)
76 {
77 return serviceName switch
78 {
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```
89 
90### Strategy Pattern
91Translation services implement common interface:
92 
93```csharp
94public interface ITranslationService
95{
96 Task<TranslationResult?> TranslateAsync(
97 string sourceText,
98 string targetLanguage,
99 string context);
100}
101```
102 
103## Separation of Concerns
 
 
 
 
 
104 
105### UI Layer
106- XAML files define UI structure
107- Code-behind handles UI events
108- Minimal business logic in UI code
109 
110### Business Logic Layer
111- `Logic.cs` - Core translation workflow
112- `UniversalBlockDetector.cs` - Advanced text block detection and grouping
113- Service classes - External API integration
114 
115### Data Layer
116- `ConfigManager.cs` - Configuration persistence
117- File-based storage (config.txt, service-specific configs)
118 
119## Dependency Management
120 
121### Service Dependencies
122Services depend on ConfigManager, not each other:
123 
124```csharp
125public class GeminiTranslationService
126{
127 private readonly string _apiKey;
128
129 public GeminiTranslationService()
130 {
131 _apiKey = ConfigManager.Instance.GetGeminiApiKey();
132 }
133}
134```
135 
136### Manager Dependencies
137Managers can depend on other managers:
138 
139```csharp
140public class Logic
141{
142 private readonly ConfigManager _configManager;
143 private readonly UniversalBlockDetector _blockDetector;
144
145 public Logic()
146 {
147 _configManager = ConfigManager.Instance;
148 _blockDetector = UniversalBlockDetector.Instance;
149 }
150}
151```
152 
153## Communication Patterns
154 
155### Window Communication
156Windows communicate through Logic.Instance:
157 
158```csharp
159// In ChatBoxWindow
160Logic.Instance.OnTranslationReceived += HandleTranslation;
161 
162// In Logic
163public event EventHandler<TranslationEventArgs>? OnTranslationReceived;
164```
165 
166### Event-Driven Architecture
167Use events for loose coupling:
168 
169```csharp
170public class TranslationEventArgs : EventArgs
171{
172 public string TranslatedText { get; set; } = "";
173 public string SourceText { get; set; } = "";
174}
175```
176 
177### Hotkey System
178Hotkeys managed through HotkeyManager events:
179 
180```csharp
181HotkeyManager.Instance.StartStopRequested += OnStartStopRequested;
182HotkeyManager.Instance.MonitorToggleRequested += OnMonitorToggleRequested;
183```
184 
185## Resource Management
186 
187### Disposable Resources
188Implement IDisposable for resources:
189 
190```csharp
191public class ResourceManager : IDisposable
192{
193 private bool _disposed = false;
194
195 public void Dispose()
196 {
197 Dispose(true);
198 GC.SuppressFinalize(this);
199 }
200
201 protected virtual void Dispose(bool disposing)
202 {
203 if (!_disposed)
204 {
205 if (disposing)
206 {
207 // Dispose managed resources
208 }
209 // Dispose unmanaged resources
210 _disposed = true;
211 }
212 }
213}
214```
215 
216### Using Statements
217Always use `using` for disposable resources:
218 
219```csharp
220using (var bitmap = new Bitmap(width, height))
221{
222 // Use bitmap
223} // Automatically disposed
224 
225// Or with async
226using var httpClient = new HttpClient();
227var response = await httpClient.GetAsync(url);
228```
229 
230## State Management
231 
232### Application State
233State stored in ConfigManager:
234 
235```csharp
236// Current translation service
237_currentTranslationService = ConfigManager.Instance.GetCurrentTranslationService();
238 
239// Window positions
240var pos = ConfigManager.Instance.GetWindowPosition("ChatBox");
241```
242 
243### Runtime State
244Runtime state in Logic or window classes:
245 
246```csharp
247private bool _isProcessing = false;
248private List<TextObject> _currentTextBlocks = new();
249```
250 
251## Error Propagation
252 
253### Error Handling Strategy
254- Services return null on error
255- Log errors using LogManager
256- Show user-friendly messages via ErrorPopupManager
257- Don't crash the application
258 
259```csharp
260public async Task<Result?> ProcessAsync()
261{
262 try
263 {
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 throwing
271 }
272}
273```
274 
275## Extension Points
276 
277### Adding New Translation Service
2781. Implement `ITranslationService`
2792. Add config keys to ConfigManager
2803. Update TranslationServiceFactory
2814. Add UI in SettingsWindow
282 
283### Adding New OCR Method
2841. Add method name to `SupportedOcrMethods` in ConfigManager
2852. Implement processing logic
286 - 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 UI
2894. Add configuration options
290 
291### Adding New Python OCR Service
2921. 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 images
300 - `/info` - Service information
301 - `/health` - Health check
302 - `/shutdown` - Graceful shutdown
3034. Create batch scripts: `Install.bat`, `RunServer.bat`, `DiagnosticTest.bat`, `Uninstall.bat`
3045. Service will be automatically discovered by `PythonServicesManager` on app startup
305 
306## Performance Considerations
307 
308### Lazy Initialization
309Initialize expensive resources on demand:
310 
311```csharp
312private HttpClient? _httpClient;
313 
314private HttpClient HttpClient
315{
316 get
317 {
318 if (_httpClient == null)
319 {
320 _httpClient = new HttpClient();
321 }
322 return _httpClient;
323 }
324}
325```
326 
327### Caching
328Cache expensive operations:
329 
330```csharp
331private Dictionary<string, TranslationResult> _translationCache = new();
332 
333public TranslationResult? GetCachedTranslation(string text)
334{
335 if (_translationCache.TryGetValue(text, out var cached))
336 {
337 return cached;
338 }
339 return null;
340}
341```
342 
343## Threading Model
344 
345### UI Thread
346- All UI updates on UI thread
347- Use Dispatcher.Invoke for cross-thread updates
348- Long operations off UI thread
349 
350### Background Threads
351- OCR processing on background thread
352- Network requests async/await
353- Screen capture on timer thread
354 
355## Module Boundaries
356 
357### Service Boundaries
358Services are independent modules:
359- Each service in own file
360- No direct dependencies between services
361- Communicate through interfaces
362 
363### Manager Boundaries
364Managers provide cross-cutting concerns:
365- ConfigManager - Configuration
366- LogManager - Logging
367- UniversalBlockDetector - Text processing
368- HotkeyManager - Keyboard shortcuts
369- AudioPlaybackManager - Audio playback
370 
371## Testing Architecture
372 
373### Testable Components
374- Business logic separate from UI
375- Services implement interfaces
376- Static utility methods where possible
377 
378### Mock-Friendly Design
379```csharp
380// Use interface for testability
381public interface ITranslationService
382{
383 Task<TranslationResult?> TranslateAsync(...);
384}
385 
386// Can be mocked in tests
387var mockService = new Mock<ITranslationService>();
388```
389 
390## Version Management
391 
392### Version Updates
393Update version in three places:
3941. `SplashManager.cs` - `CurrentVersion` constant
3952. `media/latest_version_checker.json` - `latest_version` field
3963. `README.md` - Version badge and history entry
397 
398### Version Format
399- Use double/float (e.g., 0.60)
400- Increment by 0.01 for minor updates
401- Increment by 0.10 for major features
402 
403## Build Configuration
404 
405### Output Structure
406- Debug: `ugtlive_debug.exe` in `app/`
407- Release: `ugtlive.exe` in `app/`
408- All dependencies in `app/` directory
409 
410### Dependencies
411- .NET 8.0 Windows
412- WPF and Windows Forms
413- NAudio for audio
414- WebView2 for web content
415 
@@ −1 +1 @@
1−# AGENTS.md
1+---
2+description: Architecture patterns and project structure guidelines
3+globs: ["**/*.cs"]
4+alwaysApply: false
5+---
26  
3−Project operating instructions for AI assistants working in this repository.
7+# Architecture Patterns
48  
5−## Shared Project Memory
9+## Project Structure
610  
7−- At the start of each new task or thread involving this repository, read this file before inspecting files, running commands, making a plan, or taking any other project action.
8−- Treat follow-up replies in the same continuous task as part of that task. Do not reread this file unless the repository or working directory changes, this file is modified, or its instructions are no longer available in context.
9−- Treat this file as the shared project memory for AI assistants.
10−- Do not rely on vendor-specific, proprietary, or hidden memory systems for project facts, preferences, or operating instructions. (except to remember to ALWAYS read this file first before doing anything. Remember that.)
11−- Update this file with important repo-specific information learned during work, including build commands, test commands, conventions, decisions, pitfalls, and current project preferences.
12−- Keep this file accurate and current. Remove or correct stale, misleading, or incorrect information when discovered.
13−- If information is temporary or uncertain, label it clearly rather than presenting it as permanent fact.
11+### Directory Organization
12+```
13+src/
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.)
20+app/
21+ - Compiled binaries
22+ - 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+```
1428  
15−Scope policy: this file holds cross-cutting rules, workflows, and gotchas that most sessions need, plus a feature index. Keep it around 30 KB. Feature deep-dives live in `docs/<topic>.md`: before working on a feature listed in the index, read its doc; when finishing feature work, update that doc and keep the index entry here to one or two lines (where it lives + the non-obvious constraint). Cross-cutting rules and new gotchas still land here directly. When a change makes anything stale, here or in a linked doc, update it in the same change.
29+### File Naming
30+- One class per file
31+- File name matches class name
32+- XAML files: `WindowName.xaml` and `WindowName.xaml.cs`
1633  
17−## Testing
34+## Design Patterns
1835  
19−- When possible, design automated tests for new features and bug fixes.
20−- Run relevant automated tests after finishing changes to guard against regressions.
21−- If tests cannot be run or do not exist, state that clearly in the handoff and describe any manual verification performed.
22−- Always finish project changes by building the Release configuration: `dotnet build .\UGTLive.sln --configuration Release`.
23−- If a running UGTLive process prevents the Release build, capture its executable/command line, stop it, complete the build, and restart it afterward. Do not start UGTLive if it was not running before the build.
36+### Singleton Pattern
37+Used 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 services
43+- `HotkeyManager.Instance` - Manages global keyboard shortcuts (replaces KeyboardShortcuts)
44+- `AudioPlaybackManager.Instance` - Manages audio playback
45+- `AudioPreloadService.Instance` - Preloads TTS audio
46+- `ErrorPopupManager` - Static class for error popups
47+- `GamepadManager.Instance` - Manages gamepad input
48+- `WebViewEnvironmentManager` - Static class for WebView2 environment
2449  
25−Always add automation/test harnesses to test options/buttons/features as needed. Document them.
50+**Implementation:**
51+```csharp
52+private static ConfigManager? _instance;
2653  
27−## Cloud LLM Model Maintenance
54+public static ConfigManager Instance
55+{
56+ get
57+ {
58+ if (_instance == null)
59+ {
60+ _instance = new ConfigManager();
61+ }
62+ return _instance;
63+ }
64+}
2865  
29−- Cloud and CLI model picker presets live in `src/SettingsWindow.xaml`; their fallback/default values live in `src/ConfigManager.cs`, `src/ConfigManager.Translation.cs`, and `src/SettingsWindow.TranslationSettings.cs`.
30−- Subscription-backed CLI providers display as `Anthropic Sub`, `OpenAI Sub`, and `Gemini CLI (Enterprise)`, but their stable internal IDs remain `ClaudeCli`, `CodexCli`, and `GeminiCli`; use `ComboBoxItem.Tag` for the internal ID. Google ended personal/free/AI Pro/AI Ultra access through Gemini CLI on June 18, 2026; do not replace it with Antigravity CLI until `agy -p` reliably exposes captured stdout to Windows parent processes (see `docs/settings-connection-tests.md`).
31−- Keep provider-specific capability handling in the matching translation service. In particular, Anthropic model generations use different manual/adaptive thinking request shapes.
32−- Verify model IDs and request compatibility against current official provider documentation. Verify OpenRouter-prefixed slugs against its `/api/v1/models` catalog before adding presets.
66+private ConfigManager() { }
67+```
3368  
34−## Feature Index
69+### Factory Pattern
70+Used for creating service instances:
3571  
36−- Settings API/model/voice tests: see `docs/settings-connection-tests.md`. UI buttons and `--test-settings-connection` must continue to call the shared `SettingsConnectionTester` implementation.
37−- OpenAI All In One Snap translation: see `docs/openai-all-in-one.md`. It is a Snap-only, visual-only `gpt-image-2` Image Edits path; Auto and realtime processing must remain on the standard OCR pipeline.
72+```csharp
73+public static class TranslationServiceFactory
74+{
75+ public static ITranslationService CreateService(string serviceName)
76+ {
77+ return serviceName switch
78+ {
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+```
3889  
90+### Strategy Pattern
91+Translation services implement common interface:
3992  
40−## Security
93+```csharp
94+public interface ITranslationService
95+{
96+ Task<TranslationResult?> TranslateAsync(
97+ string sourceText,
98+ string targetLanguage,
99+ string context);
100+}
101+```
41102  
42−- Never commit sensitive data, including credentials, tokens, passwords, private keys, cookies, customer data, personal data, or machine-specific authentication material.
43−- If an AI assistant needs authentication data or other secrets for local work, use `agents_secret.md` for those notes.
44−- `agents_secret.md` must stay ignored by git and must not be committed.
45−- Do not put secrets in commit messages, logs, issue text, pull request descriptions, generated docs, or other tracked files.
46−- Configuration logging must pass key names through `ConfigManager.IsSensitiveConfigKey`; never print raw secret values in startup or harness output.
47−- Before committing, review staged changes for accidental secrets.
103+## Separation of Concerns
48104  
49−## Git
105+### UI Layer
106+- XAML files define UI structure
107+- Code-behind handles UI events
108+- Minimal business logic in UI code
50109  
51−- Never add OpenAI/Codex/Claude etc as a co-author on git commits.
52−- NEVER `git commit` unless explicitly told to commit.
53−- NEVER `git push` unless explicitly told to push. "Commit" means commit
54− locally only; committing is not permission to push.
110+### Business Logic Layer
111+- `Logic.cs` - Core translation workflow
112+- `UniversalBlockDetector.cs` - Advanced text block detection and grouping
113+- Service classes - External API integration
114+ 
115+### Data Layer
116+- `ConfigManager.cs` - Configuration persistence
117+- File-based storage (config.txt, service-specific configs)
118+ 
119+## Dependency Management
120+ 
121+### Service Dependencies
122+Services depend on ConfigManager, not each other:
123+ 
124+```csharp
125+public class GeminiTranslationService
126+{
127+ private readonly string _apiKey;
128+
129+ public GeminiTranslationService()
130+ {
131+ _apiKey = ConfigManager.Instance.GetGeminiApiKey();
132+ }
133+}
134+```
135+ 
136+### Manager Dependencies
137+Managers can depend on other managers:
138+ 
139+```csharp
140+public class Logic
141+{
142+ private readonly ConfigManager _configManager;
143+ private readonly UniversalBlockDetector _blockDetector;
144+
145+ public Logic()
146+ {
147+ _configManager = ConfigManager.Instance;
148+ _blockDetector = UniversalBlockDetector.Instance;
149+ }
150+}
151+```
152+ 
153+## Communication Patterns
154+ 
155+### Window Communication
156+Windows communicate through Logic.Instance:
157+ 
158+```csharp
159+// In ChatBoxWindow
160+Logic.Instance.OnTranslationReceived += HandleTranslation;
161+ 
162+// In Logic
163+public event EventHandler<TranslationEventArgs>? OnTranslationReceived;
164+```
165+ 
166+### Event-Driven Architecture
167+Use events for loose coupling:
168+ 
169+```csharp
170+public class TranslationEventArgs : EventArgs
171+{
172+ public string TranslatedText { get; set; } = "";
173+ public string SourceText { get; set; } = "";
174+}
175+```
176+ 
177+### Hotkey System
178+Hotkeys managed through HotkeyManager events:
179+ 
180+```csharp
181+HotkeyManager.Instance.StartStopRequested += OnStartStopRequested;
182+HotkeyManager.Instance.MonitorToggleRequested += OnMonitorToggleRequested;
183+```
184+ 
185+## Resource Management
186+ 
187+### Disposable Resources
188+Implement IDisposable for resources:
189+ 
190+```csharp
191+public class ResourceManager : IDisposable
192+{
193+ private bool _disposed = false;
194+
195+ public void Dispose()
196+ {
197+ Dispose(true);
198+ GC.SuppressFinalize(this);
199+ }
200+
201+ protected virtual void Dispose(bool disposing)
202+ {
203+ if (!_disposed)
204+ {
205+ if (disposing)
206+ {
207+ // Dispose managed resources
208+ }
209+ // Dispose unmanaged resources
210+ _disposed = true;
211+ }
212+ }
213+}
214+```
215+ 
216+### Using Statements
217+Always use `using` for disposable resources:
218+ 
219+```csharp
220+using (var bitmap = new Bitmap(width, height))
221+{
222+ // Use bitmap
223+} // Automatically disposed
224+ 
225+// Or with async
226+using var httpClient = new HttpClient();
227+var response = await httpClient.GetAsync(url);
228+```
229+ 
230+## State Management
231+ 
232+### Application State
233+State stored in ConfigManager:
234+ 
235+```csharp
236+// Current translation service
237+_currentTranslationService = ConfigManager.Instance.GetCurrentTranslationService();
238+ 
239+// Window positions
240+var pos = ConfigManager.Instance.GetWindowPosition("ChatBox");
241+```
242+ 
243+### Runtime State
244+Runtime state in Logic or window classes:
245+ 
246+```csharp
247+private bool _isProcessing = false;
248+private List<TextObject> _currentTextBlocks = new();
249+```
250+ 
251+## Error Propagation
252+ 
253+### Error Handling Strategy
254+- Services return null on error
255+- Log errors using LogManager
256+- Show user-friendly messages via ErrorPopupManager
257+- Don't crash the application
258+ 
259+```csharp
260+public async Task<Result?> ProcessAsync()
261+{
262+ try
263+ {
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 throwing
271+ }
272+}
273+```
274+ 
275+## Extension Points
276+ 
277+### Adding New Translation Service
278+1. Implement `ITranslationService`
279+2. Add config keys to ConfigManager
280+3. Update TranslationServiceFactory
281+4. Add UI in SettingsWindow
282+ 
283+### Adding New OCR Method
284+1. Add method name to `SupportedOcrMethods` in ConfigManager
285+2. Implement processing logic
286+ - 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)
288+3. Update OCR selection UI
289+4. Add configuration options
290+ 
291+### Adding New Python OCR Service
292+1. Create service directory in `app/services/` (e.g., `app/services/NewOCR/`)
293+2. 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.
298+3. Create `server.py` implementing FastAPI endpoints:
299+ - `/process` - Process images
300+ - `/info` - Service information
301+ - `/health` - Health check
302+ - `/shutdown` - Graceful shutdown
303+4. Create batch scripts: `Install.bat`, `RunServer.bat`, `DiagnosticTest.bat`, `Uninstall.bat`
304+5. Service will be automatically discovered by `PythonServicesManager` on app startup
305+ 
306+## Performance Considerations
307+ 
308+### Lazy Initialization
309+Initialize expensive resources on demand:
310+ 
311+```csharp
312+private HttpClient? _httpClient;
313+ 
314+private HttpClient HttpClient
315+{
316+ get
317+ {
318+ if (_httpClient == null)
319+ {
320+ _httpClient = new HttpClient();
321+ }
322+ return _httpClient;
323+ }
324+}
325+```
326+ 
327+### Caching
328+Cache expensive operations:
329+ 
330+```csharp
331+private Dictionary<string, TranslationResult> _translationCache = new();
332+ 
333+public TranslationResult? GetCachedTranslation(string text)
334+{
335+ if (_translationCache.TryGetValue(text, out var cached))
336+ {
337+ return cached;
338+ }
339+ return null;
340+}
341+```
342+ 
343+## Threading Model
344+ 
345+### UI Thread
346+- All UI updates on UI thread
347+- Use Dispatcher.Invoke for cross-thread updates
348+- Long operations off UI thread
349+ 
350+### Background Threads
351+- OCR processing on background thread
352+- Network requests async/await
353+- Screen capture on timer thread
354+ 
355+## Module Boundaries
356+ 
357+### Service Boundaries
358+Services are independent modules:
359+- Each service in own file
360+- No direct dependencies between services
361+- Communicate through interfaces
362+ 
363+### Manager Boundaries
364+Managers provide cross-cutting concerns:
365+- ConfigManager - Configuration
366+- LogManager - Logging
367+- UniversalBlockDetector - Text processing
368+- HotkeyManager - Keyboard shortcuts
369+- AudioPlaybackManager - Audio playback
370+ 
371+## Testing Architecture
372+ 
373+### Testable Components
374+- Business logic separate from UI
375+- Services implement interfaces
376+- Static utility methods where possible
377+ 
378+### Mock-Friendly Design
379+```csharp
380+// Use interface for testability
381+public interface ITranslationService
382+{
383+ Task<TranslationResult?> TranslateAsync(...);
384+}
385+ 
386+// Can be mocked in tests
387+var mockService = new Mock<ITranslationService>();
388+```
389+ 
390+## Version Management
391+ 
392+### Version Updates
393+Update version in three places:
394+1. `SplashManager.cs` - `CurrentVersion` constant
395+2. `media/latest_version_checker.json` - `latest_version` field
396+3. `README.md` - Version badge and history entry
397+ 
398+### Version Format
399+- Use double/float (e.g., 0.60)
400+- Increment by 0.01 for minor updates
401+- Increment by 0.10 for major features
402+ 
403+## Build Configuration
404+ 
405+### Output Structure
406+- Debug: `ugtlive_debug.exe` in `app/`
407+- Release: `ugtlive.exe` in `app/`
408+- All dependencies in `app/` directory
409+ 
410+### Dependencies
411+- .NET 8.0 Windows
412+- WPF and Windows Forms
413+- NAudio for audio
414+- WebView2 for web content
55415  

Also from Kynth Studios

Built for the same person as RuleStack

ToolDrift

What the AI coding tools changed last night

tooldrift.kynth.studio

StillShipping

Which agent tools have stopped shipping

stillshipping.kynth.studio

BlockDex

Search inside every shadcn registry

blockdex.kynth.studio

The studio list

One product, taken apart, once a month

Kynth Studios pulls one shipped product open every month — what it does, what it cost to build, what the pipeline behind it looks like, and what the numbers did. One email a month, nothing in between.

Double opt-in — we send one confirmation link and nothing else until you click it.

RuleStack

Built by

Kynth Studios

the studio behind ToolDrift, StillShipping and BlockDex

part of Toolproof, the measurement layer for AI agent tooling

Directory

Configs
Stacks
Compare formats
AGENTS.md vs CLAUDE.md
Cursor rules alternatives
Diff two configs
Best AGENTS.md examples
Best Cursor rules examples
What goes in a CLAUDE.md

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

© 2026 RuleStack. A Kynth Studios product. Changelog

RuleStack

The studio list

One product, taken apart, once a month

Kynth Studios pulls one shipped product open every month — what it does, what it cost to build, what the pipeline behind it looks like, and what the numbers did. One email a month, nothing in between.

Double opt-in — we send one confirmation link and nothing else until you click it.

RuleStack

Built by

Kynth Studios

the studio behind ToolDrift, StillShipping and BlockDex

part of Toolproof, the measurement layer for AI agent tooling

Directory

Configs
Stacks
Compare formats
AGENTS.md vs CLAUDE.md
Cursor rules alternatives
Diff two configs
Best AGENTS.md examples
Best Cursor rules examples
What goes in a CLAUDE.md

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

© 2026 RuleStack. A Kynth Studios product. Changelog

RuleStack

The studio list

One product, taken apart, once a month

Kynth Studios pulls one shipped product open every month — what it does, what it cost to build, what the pipeline behind it looks like, and what the numbers did. One email a month, nothing in between.

Double opt-in — we send one confirmation link and nothing else until you click it.

RuleStack

Built by

Kynth Studios

the studio behind ToolDrift, StillShipping and BlockDex

part of Toolproof, the measurement layer for AI agent tooling

Directory

Configs
Stacks
Compare formats
AGENTS.md vs CLAUDE.md
Cursor rules alternatives
Diff two configs
Best AGENTS.md examples
Best Cursor rules examples
What goes in a CLAUDE.md

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

© 2026 RuleStack. A Kynth Studios product. Changelog

RuleStack