# Phase 2: Window and Region Targeting - Context

**Gathered:** 2026-04-12
**Status:** Ready for planning

<domain>
## Phase Boundary

Extend capture targeting from desktop-only to window-specific and region-specific. Agents can list windows, capture a specific window by title or handle, capture a rectangular screen region, or capture a region relative to a window. Graceful handling when target becomes unavailable. Covers: CAPT-02, CAPT-03, CAPT-04, CAPT-05, TIME-05.

</domain>

<decisions>
## Implementation Decisions

### Tool interface design
- **D-01:** Extend existing `start_capture` tool with optional target parameters rather than creating separate tools — backward compatible, no tool proliferation
- **D-02:** Target specification via discriminated union: `target` field accepts "desktop" (default, existing), "window", or "region"
- **D-03:** Window target params: `window_handle` (number, exact match) OR `window_title` (string, substring match); at least one required when target="window"
- **D-04:** Region target params: `x`, `y`, `width`, `height` (all numbers, pixels, screen-absolute coordinates)
- **D-05:** Window-relative region params: `window_handle` or `window_title` + `region_x`, `region_y`, `region_width`, `region_height` (relative to window top-left)
- **D-06:** New `list_windows` MCP tool returns array of visible windows with: `handle` (number), `title` (string), `processName` (string), `x`, `y`, `width`, `height`

### Window matching strategy
- **D-07:** Support both handle-based (exact, from list_windows) and title substring match (case-insensitive convenience)
- **D-08:** If title matches multiple windows, capture the first match and include matched window title in response metadata
- **D-09:** If no window matches, return error immediately (don't start a session that will fail)

### Target failure handling (TIME-05)
- **D-10:** When target window closes or minimizes during active capture: skip that frame, record a null/placeholder entry in frames array
- **D-11:** Session metadata includes `skippedFrames` count and reasons, so agents know data is partial
- **D-12:** Capture continues after skip — don't abort the whole session for a transient window state
- **D-13:** If ALL frames would be skipped (window gone from the start), error the session after 3 consecutive failures

### CaptureTarget extension
- **D-14:** New `WindowTarget` class implementing CaptureTarget interface — wraps node-screenshots Window class
- **D-15:** New `RegionTarget` class implementing CaptureTarget — uses Monitor capture + sharp crop for screen regions
- **D-16:** New `WindowRegionTarget` class — captures window then crops to specified sub-region
- **D-17:** All targets return PNG buffers (same as DesktopTarget) for uniform pipeline processing

### Claude's Discretion
- Window enumeration filtering (whether to exclude zero-size or invisible windows)
- Error message wording for window not found, region out of bounds
- Internal caching strategy for window handle lookups
- Whether to add `stop_capture` tool in this phase or defer

</decisions>

<canonical_refs>
## Canonical References

**Downstream agents MUST read these before planning or implementing.**

### Existing Implementation
- `src/capture/targets/capture-target.ts` — CaptureTarget interface to implement
- `src/capture/targets/desktop-target.ts` — Reference implementation pattern
- `src/server.ts` — Tool/resource registration pattern, start_capture wiring
- `src/types.ts` — CaptureConfig, schemas (need extending)
- `src/capture/session-manager.ts` — Session lifecycle management
- `src/capture/scheduler.ts` — Self-correcting scheduler (needs graceful skip support)

### Phase 1 Context
- `.planning/phases/01-core-capture-pipeline/01-CONTEXT.md` — Prior decisions on tool interface, grid sizing, scheduling

### Library APIs
- node-screenshots: `Window.all()` for enumeration, `window.captureImage()` for window capture, `Monitor.fromPoint()` + `image.crop()` for regions

</canonical_refs>

<code_context>
## Existing Code Insights

### Reusable Assets
- `CaptureTarget` interface (capture-target.ts): Already designed for extension — just implement `name` and `capture()`
- `DesktopTarget` (desktop-target.ts): Reference pattern for new targets
- `SessionManager`: Manages session lifecycle, no changes needed for new targets
- `compileGrid`: Target-agnostic — works with any CaptureFrame buffers
- `startScheduler`: Needs modification for graceful frame skipping (currently assumes capture always succeeds)

### Established Patterns
- Tool registration via `server.registerTool()` with zod schemas
- Async two-tool pattern (start then poll)
- Module-level singletons in server.ts
- CamelCase internal, snake_case MCP API

### Integration Points
- `server.ts`: Register list_windows tool, extend start_capture inputSchema with target params
- `types.ts`: Extend CaptureConfig.target union, add new schemas
- `scheduler.ts`: Add try/catch around capture() calls for graceful skip
- New files: `src/capture/targets/window-target.ts`, `src/capture/targets/region-target.ts`, `src/capture/targets/window-region-target.ts`

</code_context>

<specifics>
## Specific Ideas

- node-screenshots provides the exact APIs needed: Window.all() for enumeration, individual window capture, and Monitor-based region capture
- Window handle is the reliable identifier; title is convenience for human/agent use
- Region capture uses full monitor capture + crop approach (node-screenshots doesn't have direct region capture)
- DPI scaling concern from Phase 1 still applies — coordinates may need DPI adjustment on high-DPI displays

</specifics>

<deferred>
## Deferred Ideas

None — discussion stayed within phase scope

</deferred>

---

*Phase: 02-window-and-region-targeting*
*Context gathered: 2026-04-12*
