npx agentspec-cli install d1c1933b-0c39-46c4-9d80-37695201644e --file-type copilot-instructions→ .github/instructions/
# MEGA PROMPT: Multi-Client Game Input Mirroring System
# GitHub Copilot Instructions - MultiSync Project
# =====================================================
## Project Identity
MultiSync - Multi-client game input mirroring system. Control multiple game windows from one mouse/keyboard.
Core Principle: Input mirroring via window messages ONLY. NEVER memory manipulation or packet injection.
Platform: Windows 10/11 (win32api/win32con).
## Technology Stack
- Python 3.9+ with strict type hints
- pynput (global input hooks)
- pywin32 (win32gui, win32process for window management)
- Input simulation: Windows API PostMessage ONLY (never SetCursorPos/SendInput)
- tkinter (overlay UI) + colorama (CLI)
- PyYAML (configuration)
- threading.RLock (all shared state)
## Architecture
InputCapture (pynput) → InputRouter → SyncEngine → InputSimulation (PostMessage)
## Critical Rules - FOLLOW EXACTLY
### IF generating ClientManager:
- Use threading.RLock for self._clients dict access
- Window discovery: win32gui.EnumWindows + filter by process name via win32process.GetWindowThreadProcessId
- Store per client: hwnd, pid, rect (x,y,w,h), client_area, is_primary, state (Enum)
- Auto-promote first client to primary if none exists
- Handle window closure: catch win32gui.error, set state DISCONNECTED, remove from active list
- Methods: scan_for_clients(process_name), add_client(hwnd), remove_client(client_id), get_primary_client(), get_active_clients()
### IF generating InputCapture:
- pynput.mouse.Listener(on_move, on_click, on_scroll)
- pynput.keyboard.Listener for GlobalHotKeys
- Queue events via queue.Queue(maxsize=100) - drop if full, don't block
- Coordinates are ABSOLUTE SCREEN coordinates (0,0 = top-left primary monitor)
- on_move(x,y): if mouse in primary client bounds, create InputEvent(event_type='move', abs_x=x, abs_y=y, source_client_id=primary.id)
### IF generating SyncEngine:
- MIRROR MODE (default): rel_x = (abs_x - src.client_area[0]) / src.client_area[2], new_x = int(tgt.client_area[0] + rel_x * tgt.client_area[2])
- OFFSET MODE: new_x = abs_x + offset[0], clamp to window bounds
- Add humanization: random.randint(-2, 2) pixel jitter
- Throttle: time.sleep(max(0, 1/60 - elapsed)) for 60 FPS target
- Methods: process_input(event, clients), _transform_mirror(event, source, target), _transform_offset(event, target)
### IF generating InputSimulation:
- ALWAYS use win32gui.PostMessage(hwnd, msg, wParam, lParam) - async, non-blocking
- NEVER use win32gui.SendMessage (blocking)
- NEVER use win32api.SetCursorPos (moves global cursor - forbidden)
- Convert to client-relative: rel_x = abs_x - client_area[0], rel_y = abs_y - client_area[1]
- lParam = win32api.MAKELONG(rel_x, rel_y)
- Button mapping: WM_LBUTTONDOWN/UP (0x201/0x202), WM_RBUTTONDOWN/UP (0x204/0x205), WM_MBUTTONDOWN/UP (0x207/0x208)
- Scroll: WM_MOUSEWHEEL (0x20A), wParam = (dy * 120) << 16
- Validate: win32gui.IsWindow(hwnd) before sending
- Methods: send_mouse_move(client, abs_x, abs_y), send_mouse_click(client, abs_x, abs_y, button, pressed), send_scroll(client, dx, dy)
### IF generating StatusOverlay (tkinter):
- root = tk.Tk(), root.overrideredirect(True), root.attributes('-topmost', True), root.attributes('-alpha', 0.85)
- Position: (screen_width - 250, 10), size 240x150
- Content: Title "MultiSync", status indicator (● Green=active/Yellow=paused/Red=error), client count, FPS, sync mode
- Update loop: root.after(100, self._update) querying ClientManager
- Drag to move: bind <Button-1> and <B1-Motion>
- Right-click menu: Pause/Resume, Add/Remove Client, Exit
## Data Models (USE THESE EXACT DEFINITIONS)
from dataclasses import dataclass, field
from typing import Tuple, Optional
from enum import Enum, auto
import threading
class ClientState(Enum):
DISCONNECTED = auto()
CONNECTED = auto()
ACTIVE = auto()
PAUSED = auto()
ERROR = auto()
class SyncMode(Enum):
MIRROR = auto()
OFFSET = auto()
GRID = auto()
@dataclass
class WindowInfo:
hwnd: Optional[int]
pid: int
title: str
rect: Tuple[int, int, int, int] # x, y, width, height
is_foreground: bool = False
client_area: Optional[Tuple[int, int, int, int]] = None # Excludes borders
@dataclass
class ClientInstance:
id: str # UUID4 string
window: WindowInfo
state: ClientState = field(default=ClientState.DISCONNECTED)
is_primary: bool = False
sync_mode: SyncMode = field(default=SyncMode.MIRROR)
offset: Tuple[int, int] = field(default=(0, 0))
last_input_time: float = field(default_factory=time.time)
_lock: threading.RLock = field(default_factory=threading.RLock, repr=False)
def update_state(self, new_state: ClientState) -> None:
with self._lock:
self.state = new_state
@dataclass
class InputEvent:
timestamp: float
event_type: str # 'move', 'click', 'scroll', 'key'
abs_x: Optional[int] = None
abs_y: Optional[int] = None
button: Optional[str] = None # 'left', 'right', 'middle'
pressed: Optional[bool] = None # True=down, False=up
scroll_dx: Optional[int] = None
scroll_dy: Optional[int] = None
key: Optional[str] = None
source_client_id: Optional[str] = None
## Error Handling (IMPLEMENT ALL 7)
1. Window Closed: try/except win32gui.error around IsWindow calls, set DISCONNECTED, log "Client {id} disconnected"
2. Permission Denied: except PermissionError, try admin elevation, else disable input for that client
3. High Latency: if elapsed > 0.1s, reduce throttle_fps by 10, log warning
4. Minimized: if win32gui.IsIconic(hwnd), set PAUSED, resume on restore
5. Resolution Change: listen for WM_DISPLAYCHANGE via Windows message hook, recalculate all geometries
6. Multi-Monitor: handle negative coordinates (monitors left/above primary), use win32api.GetMonitorInfo
7. Blocked Input: if PostMessage returns success but no response detected, set ERROR state after 5 attempts
## Hotkeys (pynput.keyboard.GlobalHotKeys)
- Ctrl+Shift+S: Toggle sync on/off
- Ctrl+Shift+A: Add client under cursor (click to select window)
- Ctrl+Shift+R: Remove last added client
- Ctrl+Shift+F12: Emergency stop (sys.exit(0))
## Safety Boundaries - NEVER IMPLEMENT
- Memory reading/writing (OpenProcess, ReadProcessMemory, WriteProcessMemory)
- Packet manipulation or network interception
- DLL injection or code hooking
- Automated gameplay/botting (this is manual control only)
- SendInput or SetCursorPos (synthetic input at driver level)
## Code Style Requirements
- Type hints: ALL function signatures (def func(x: int) -> bool:)
- Docstrings: Google style (Args:, Returns:)
- Constants: UPPER_CASE (DEFAULT_FPS = 60, INPUT_DELAY_MS = 16.0)
- Thread safety: with self._lock: for ANY shared state access
- Imports: stdlib, third-party, local (alphabetical within groups)
## Testing Strategy
Test targets (safe):
- notepad.exe - Window detection
- mpaint.exe - Coordinate accuracy (draw lines in both windows)
- calc.exe - Button clicking
Success criteria:
- Input latency < 50ms end-to-end
- Coordinate accuracy ±2 pixels
- No global cursor movement (SetCursorPos check)
## Dependencies (requirements.txt)
pynput>=1.7.6
pywin32>=306; platform_system=="Windows"
pygetwindow>=0.0.9; platform_system=="Windows"
PyYAML>=6.0
colorama>=0.4.6
psutil>=5.9.0
## Generation Commands (Use These Prompts)
1. "Implement ClientManager class with thread-safe client tracking using RLock, window discovery via EnumWindows, and methods scan_for_clients, add_client, remove_client"
2. "Create InputCapture using pynput with on_move/on_click/on_scroll callbacks, queue.Queue(maxsize=100), and GlobalHotKeys for Ctrl+Shift+S/A/R/F12"
3. "Build SyncEngine with MIRROR mode coordinate transformation and OFFSET mode, including _transform_mirror and _transform_offset methods"
4. "Implement InputSimulation using ONLY win32gui.PostMessage for WM_LBUTTONDOWN/UP, WM_RBUTTONDOWN/UP, WM_MOUSEMOVE, validate with IsWindow first"
5. "Create StatusOverlay tkinter class with overrideredirect, topmost, alpha 0.85, positioned top-right, showing client count and sync status"
## Final Checklist
Before generating each component, verify:
- [ ] All methods have type hints
- [ ] All shared state uses RLock
- [ ] No SetCursorPos or SendInput calls exist
- [ ] All win32 calls wrapped in try/except
- [ ] Humanization jitter (random.randint(-2, 2)) applied in SyncEngine
- [ ] Emergency stop hotkey (Ctrl+Shift+F12) implemented
- [ ] PostMessage used exclusively for input simulation
tmux
Remote-control tmux sessions for interactive CLIs by sending keystrokes and scraping pane output.
by AgentHub Crawler
Unity C Expert Developer Prompt
You are an expert Unity C# developer with deep knowledge of game development best practices, performance optimization, and cross-platform considerations. When generating code or providing solutions: 1. Write clear, concise, well-documented C# code adhering to Unity best practices.
by AgentHub Crawler
AI Assistant Rules for The Mirror Project
You are assisting with *The Mirror Project* - a local-first, privacy-respecting AI workspace that unifies LLMs, personal health & context streams, and autonomous agents. Always prioritize:
by AgentHub Crawler
Sign in to leave a comment.
Chess Coach AI Agents
This project implements a chess coaching application with AI agents that can analyze chess positions, suggest moves, and provide strategic advice. The system combines a modern React frontend with a Python-based AI agent backend.
by AgentHub Crawler