← Back to PRs

#20392: feat(tui): add image attachment support via /image command and drag-and-drop

by markshields-tl open 2026-02-18 21:21 View on GitHub →
size: M
## Summary Add image attachment support to the TUI, enabling users to send images to the agent directly from the terminal. Discussion: #20396 ### Features - **`/image <path> [message]`** command — attach image files from the filesystem - **Drag-and-drop** — drop an image file onto the terminal (Ghostty, iTerm2, Kitty, WezTerm, etc.) and it auto-attaches - **Aliases**: `/img`, `/attach` — same as `/image` - **`/detach`** — clear pending image attachments - Pending attachments auto-consumed on next message send - `📎 N` indicator in footer when attachments are queued - `[📎 N images]` shown in chat log for sent messages with attachments ### How it works 1. **`/image` command**: Reads file, validates image type, base64 encodes, stores as pending attachment 2. **Drag-and-drop detection**: Intercepts bracketed paste sequences (`\x1b[200~...\x1b[201~`) in `CustomEditor.handleInput` to detect image file paths before pi-tui processes them 3. **Backslash-escaped spaces**: Handles macOS-style path escaping (`Screenshot\ 2026.png`) from Ghostty and other terminals 4. **Gateway plumbing**: Adds `attachments` to `ChatSendOptions` and passes through to `chat.send` RPC — reuses existing `chat-attachments.ts` infrastructure that the webchat dashboard already uses ### Supported formats `.png`, `.jpg`, `.jpeg`, `.gif`, `.webp`, `.bmp`, `.tiff`, `.svg` — 5 MB max per image. ### Testing - 8 new tests covering: attach, inline send, consume on send, reject non-image, detach, pending count - All 105 existing TUI tests pass - Manually tested on macOS + Ghostty with drag-and-drop screenshots ### AI Disclosure 🤖 - [x] Marked as AI-assisted: Built with Claude (Anthropic) - [x] Testing level: Fully tested (8 new unit tests + manual testing on macOS/Ghostty) - [x] I understand what the code does and can maintain it ### Files changed - `src/tui/components/custom-editor.ts` — bracketed paste interception for image paths - `src/tui/gateway-chat.ts` — `attachments` in `ChatSendOptions` - `src/tui/tui-command-handlers.ts` — `/image`, `/detach` commands, attachment state - `src/tui/tui.ts` — wire up paste handler, footer indicator - `src/tui/commands.ts` — register slash commands + help text - `src/tui/tui-command-handlers.test.ts` — tests †

Most Similar PRs