# Snapview

[![npm](https://img.shields.io/npm/v/snapview)](https://www.npmjs.com/package/snapview)
[![CI](https://github.com/Grips001/snapview/actions/workflows/ci.yml/badge.svg)](https://github.com/Grips001/snapview/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)

A capture workflow for Claude Code: ready check, region select, preview with notes, approve, auto-inject, and Claude-requested screenshots.

<p align="center">
  <img src="docs/demo.gif" alt="Snapview capture demo" width="720" />
  <br />
  <em>Get ready → select a region → preview and add notes → approve — screenshot (and notes) land in your conversation</em>
</p>

### Why Snapview when Claude Code can paste images?

Claude Code supports pasting clipboard images (Alt+V on Windows, Cmd+V in iTerm2). That covers quick one-off screenshots well. Snapview is the next level up:

- **Claude-requested captures** — Claude can ask for visual context via an auto-trigger hook, launching the capture UI without you switching windows. Native paste is always user-initiated.
- **Preview before sharing** — See exactly what you're about to inject into the conversation. Clipboard paste sends whatever is on the clipboard with no gate.
- **Precision region selection** — Dedicated overlay with drag-to-select, rather than relying on OS screenshot tools to get the right crop first.
- **Automatic lifecycle** — Temp files are created, tracked, and cleaned up after 24 hours. No leftover screenshots cluttering your desktop.
- **Cross-platform consistency** — Same workflow on Windows, macOS, and Linux/X11, regardless of terminal or clipboard support.

## Install

Requires [Node.js 18+](https://nodejs.org/) and [Claude Code](https://claude.ai/code).

```bash
npm i -g snapview
```

The installer automatically registers the `/snapview` skill and auto-trigger hook into Claude Code.

### Verify

```bash
snapview
```

A transparent overlay should appear on your screen. Press `Esc` to close it.

### Update

```bash
npm i -g snapview@latest
```

The postinstall script re-registers the skill and hooks automatically, so no extra steps are needed.

### Uninstall

```bash
snapview uninstall        # Remove skill, hooks, and settings
npm uninstall -g snapview
```

## Usage

### From Claude Code

Type `/snapview` in any Claude Code conversation — a small "Ready" confirmation applet appears first so you can arrange your screen, then a transparent overlay opens where you drag to select a region. In the preview panel you can optionally type context to send alongside the screenshot, then approve — the screenshot (and any notes) are injected into the conversation. Cancel is available at every step via the X button or Esc.

### From the terminal

```bash
snapview
```

Launches the capture overlay directly. On success (exit code 0), stdout prints a JSON object `{"filePath": "...", "promptText": "..."}` — the temporary PNG path and any text typed in the preview panel. Exit code 2 means the user cancelled (from the Ready applet, the preview panel, or Esc); exit code 1 means an error occurred.

### Auto-trigger

When enabled (default), Claude can automatically request a screen capture when it needs visual context. This works through a Claude Code [Stop hook](https://docs.anthropic.com/en/docs/claude-code/hooks) — when Claude includes a `{"snapview_capture":true}` signal in its response, the hook detects it and launches the capture UI. You still see the Ready/Cancel applet, choose the region, and approve before anything is shared.

The first time an auto-trigger occurs, a separate native OS dialog asks whether Claude may request captures *at all* going forward. This one-time approval is persisted to `~/.snapview/config.json` so you're only asked once. It's independent of the per-capture Ready/Cancel applet, which always appears before every capture (manual or auto-triggered).

Disable auto-trigger by setting `SNAPVIEW_AUTO_TRIGGER` to `0` in `~/.claude/settings.json`:

```json
{ "env": { "SNAPVIEW_AUTO_TRIGGER": "0" } }
```

## How it works

Snapview first shows a small, non-blocking "Ready" confirmation applet — it doesn't cover your whole screen, so you can freely rearrange windows before confirming. Once you click Ready, it creates a transparent overlay on every connected monitor simultaneously. You drag to select a region on any display — the other monitors dim automatically — preview the capture, optionally add a note, then approve or retake. Each overlay uses its own display's native DPI, so captures are pixel-perfect even with mixed-resolution multi-monitor setups. The screenshot is saved as a temporary PNG in your system temp directory with automatic 24-hour cleanup.

**Platform support:**
- **Windows** — Works out of the box
- **macOS** — Requires Screen Recording permission (prompted on first use)
- **Linux/X11** — Supported with GPU compositing workarounds applied automatically

## Configuration

| Environment Variable | Default | Description |
|---|---|---|
| `SNAPVIEW_AUTO_TRIGGER` | `1` | Enable (`1`) or disable (`0`) auto-trigger hook |
| `SNAPVIEW_RETENTION_HOURS` | `24` | Hours to retain temporary screenshots before cleanup |

Set these in `~/.claude/settings.json` under the `env` key.

## Troubleshooting

### macOS: Black or empty screenshot

macOS requires Screen Recording permission for Snapview to capture your screen. If you get a black image or the capture fails:

1. Open **System Settings > Privacy & Security > Screen Recording**
2. Find your terminal app (Terminal, iTerm2, Warp, etc.) and enable it
3. Restart your terminal — the permission change requires a fresh session

Note: macOS Sequoia may re-prompt for this permission periodically.

### Linux: Opaque overlay or capture fails

Snapview applies GPU compositing workarounds automatically for X11, but some setups still have issues:

- **Wayland** is not fully supported. If capture fails, try running with `XDG_SESSION_TYPE=x11` or switch to an X11 session.
- **NVIDIA drivers on X11** — the `disable-gpu` and `enable-transparent-visuals` flags are applied automatically. If the overlay is still opaque, check that your compositor supports transparent windows.

### Capture window doesn't appear

- Run `snapview` directly in your terminal to see error output
- Ensure Node.js 18+ is installed: `node --version`
- On macOS, check that Screen Recording permission is granted (see above)

### Auto-trigger not working

- Verify the hook is registered: check `~/.claude/settings.json` for a `Stop` hook entry pointing to `snapview-autotrigger.js`
- Ensure `SNAPVIEW_AUTO_TRIGGER` is not set to `0`
- Reinstall to re-register hooks: `npm i -g snapview`

## Security

Snapview stores screenshots as temporary PNGs in your system temp directory (`os.tmpdir()/snapview/`). These files may contain sensitive content visible on your screen at the time of capture:

- Files are automatically deleted after 24 hours (configurable via `SNAPVIEW_RETENTION_HOURS`)
- Set `SNAPVIEW_RETENTION_HOURS=1` for faster cleanup in sensitive environments
- Promoted screenshots (saved to `./screenshots/`) are **not** auto-cleaned — manage these manually and consider adding `screenshots/` to your `.gitignore`

The Electron renderer runs with full sandboxing, context isolation, and a strict Content Security Policy. No data leaves your machine — screenshots are stored locally and read directly by Claude Code.

## Development

```bash
bun install          # Install dependencies
bun run dev          # Electron dev mode with hot reload
bun run build        # Production build
bun run typecheck    # TypeScript checking
bun test             # Run all tests
```

Electron 42+ downloads its binary on-demand on first execution rather than during `bun install`. If the very first `bun run dev` or `bun run build` fails with `Error: Electron uninstall`, run `node node_modules/electron/install.js` once to fetch it, then retry. This only affects local contributor setups — the published CLI resolves Electron via `require('electron')`, which triggers this same on-demand download automatically for end users.

### Architecture

Snapview has four layers:

1. **CLI entry** (`bin/snapview.cjs`) — Spawns the Electron process and pipes stdout through (a JSON envelope with the file path and any typed prompt text)
2. **Main process** (`src/main/`) — Window creation (including the Ready applet and per-display capture overlays), IPC routing, screen capture via `desktopCapturer`, PNG output
3. **Preload bridge** (`src/preload/`) — `contextBridge` exposing IPC channels with runtime validation
4. **Renderer** (`src/renderer/`) — Ready confirmation applet, canvas-based transparent overlay with drag-to-select, and preview panel with an optional prompt text box

Claude Code integration lives in `claude-integration/SKILL.md` (skill definition) and `scripts/snapview-autotrigger.js` (Stop hook).

## License

[MIT](LICENSE)
