A Windows WPF application that auto-approves Claude Code permission prompts in VS Code windows.
When using Claude Code in VS Code, permission prompts appear asking for approval (Yes/No buttons). This app automatically sends keystroke '1' (which selects "Yes") to tracked VS Code windows, allowing unattended operation.
ClaudeAutoResponse/
├── Models/
│ ├── TrackedWindow.cs # Window handle + mode (Yes/YesAlways/Off)
│ └── AutoResponseMode.cs # Enum for response modes
├── Services/
│ ├── PermissionMonitorService.cs # Core keystroke injection logic
│ └── WindowDiscoveryService.cs # Finds VS Code windows
├── MainWindow.xaml(.cs) # WPF UI for window management
└── App.xaml(.cs) # Application entry point
- Uses
EnumWindowsWin32 API to find all VS Code windows - User selects which windows to track and sets mode per window
- Modes:
Yes(send 1),YesAlways(send 1),Off(ignore)
The Challenge: VS Code is an Electron (Chromium) app. Chromium has security features that discard keyboard input when the window is not focused. This prevents background input injection.
Approaches Tried & Failed:
| Approach | Result | Why |
|---|---|---|
PostMessage WM_CHAR |
❌ Background only | Chromium discards - no focus validation |
PostMessage WM_KEYDOWN/UP |
❌ Background only | Same - Chromium security |
AttachThreadInput |
❌ Broke everything | Cross-process, destabilized input queue |
UI Automation InvokePattern |
❌ Can't see buttons | Webview content not in accessibility tree |
Final Solution: Robust focus switch with SendInput
// Foreground: Direct SendInput (instant, no flicker)
if (GetForegroundWindow() == targetWindow)
{
SendKeystroke('1');
}
// Background: Quick focus switch with retry
else
{
for (int retry = 0; retry < 3; retry++)
{
SetForegroundWindow(targetWindow);
Thread.Sleep(100);
if (GetForegroundWindow() == targetWindow)
{
SendKeystroke('1');
Thread.Sleep(50);
SetForegroundWindow(originalForeground); // Restore
break;
}
}
}PermissionMonitorService.cs - Core service:
- Uses
DispatcherTimerpolling (default 1 second interval) SendInputWin32 API for keystroke injection (key down + key up)SetForegroundWindowfor background window activation- Retry logic (3 attempts) for reliable focus switching
- 100ms delay after focus switch for stabilization
- Automatic restoration of original foreground window
Why '1' is Always Safe:
- Claude Code permission prompts always have "Yes" as button 1
- Question prompts (which shouldn't be auto-approved) use radio buttons, not numbered buttons
- Pressing '1' on a question prompt does nothing harmful
| Scenario | Behavior |
|---|---|
| VS Code in foreground | Instant keystroke, no flicker |
| VS Code in background | Brief flicker (~150ms) as focus switches and returns |
| Multiple VS Code windows | Each tracked window processed in sequence |
Chromium Security Model:
- Browser process receives Windows messages
- Renderer process (webview) runs in sandbox
- Keyboard events validated for focus before forwarding to renderer
- No focus = event discarded (prevents input injection attacks)
Windows SetForegroundWindow Restrictions:
- Windows throttles
SetForegroundWindowcalls from background apps - Only works reliably when caller is foreground or recently was
- Hence retry logic and focus verification
cd c:\Users\topem\scripts\ClaudeAutoResponse
dotnet build
.\bin\Debug\net8.0-windows\ClaudeAutoResponse.exe- Target: .NET 8.0 Windows
- Uses WPF for UI
- Uses WinForms for NotifyIcon (system tray)
- Package: System.Text.Json for settings persistence
-
True Background Operation - Would require either:
- VS Code launched with
--force-renderer-accessibilityflag - Chrome DevTools Protocol (CDP) with
--remote-debugging-port - Neither is practical for general use
- VS Code launched with
-
Smarter Detection - Could detect if a permission prompt is actually showing before sending keystroke (currently sends on every poll interval)
-
Settings Persistence - Save tracked windows between sessions
Services/PermissionMonitorService.cs- Multiple iterations to find working approachClaudeAutoResponse.csproj- Added WinForms reference for NotifyIcon- Created test files to trigger permission prompts during development