#20392: feat(tui): add image attachment support via /image command and drag-and-drop
size: M
Cluster:
Web UI Enhancements and Fixes
## 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
#17610: feat(tui): add image file attachment support via @path syntax and /...
by frntn · 2026-02-16
87.3%
#6663: Web UI: handle drag-drop image attachments
by mar0der · 2026-02-01
72.3%
#16346: feat: support image attachments in OpenAI chat completions endpoint
by sh1nj1 · 2026-02-14
70.3%
#22113: feat: support non-image file attachments in webchat chat.send
by Kt-L · 2026-02-20
69.8%
#16777: feat(gateway): add multimodal image support to /v1/chat/completions
by dzianisv · 2026-02-15
68.0%
#4327: Gateway Web Chat: add image/file upload (attach, drag-drop, paste)
by RogerHsu7 · 2026-01-30
66.8%
#8284: Fix: Webchat images now persist after sending
by vishaltandale00 · 2026-02-03
65.7%
#10441: webchat: switch file uploads to HTTP /uploads
by supernewbilityxht1 · 2026-02-06
65.6%
#10394: feat(mattermost): add image attachment support for inbound messages
by mithril-logic · 2026-02-06
65.6%
#23764: feat(tui): render inline images via MEDIA: protocol and pi-tui Image
by ademczuk · 2026-02-22
65.4%