← Back to PRs

#17610: feat(tui): add image file attachment support via @path syntax and /image command

by frntn open 2026-02-16 00:27 View on GitHub →
size: M
## Summary Adds image file attachment support to the TUI, enabling users to send images to the agent directly from the terminal. ### The problem The Gateway `chat.send` RPC already accepts `attachments[]` (base64 + mimeType), and `parseMessageWithAttachments()` properly validates, sniffs MIME, and converts to Claude API image content blocks. However, the TUI client had no way to send attachments — there was no input mechanism for images. ### The solution Two complementary approaches: **1. Inline `@path` syntax** — Users can reference image files directly in their message: ``` Analyze this screenshot @/home/user/screenshot.png and compare with @./mockup.jpg ``` The paths are extracted, files loaded as base64, and sent as attachments alongside the cleaned message text. **2. `/image <path>` slash command** — For sending an image without additional text: ``` /image /tmp/error-screenshot.png ``` ### Supported path formats - Absolute: `@/home/user/photo.png` - Relative: `@./images/test.jpg` - Home-relative: `@~/Pictures/screenshot.webp` - Quoted (spaces): `@"/path/with spaces/image.png"` or `@'./path/with spaces/image.png'` ### Supported image formats png, jpg/jpeg, gif, webp, bmp, svg (max 5 MB) ### Changes | File | Change | |------|--------| | `src/tui/gateway-chat.ts` | Add `attachments` to `ChatSendOptions`, pass through in `sendChat()` | | `src/tui/tui-image-extract.ts` | **New** — `extractImagePaths()` + `loadImageAttachments()` | | `src/tui/tui-image-extract.test.ts` | **New** — 18 unit tests | | `src/tui/tui-command-handlers.ts` | Integrate image extraction in `sendMessage()` + handle `/image` command | | `src/tui/commands.ts` | Add `/image` to slash command list + help text | ### Testing - 18 new unit tests covering path extraction patterns, MIME detection, file size validation, multi-file loading, and error cases - All existing TUI tests continue to pass - Lint + format clean (0 warnings, 0 errors) <!-- greptile_comment --> <h3>Greptile Summary</h3> Adds image file attachment support to the TUI via two input methods: inline `@path` syntax within messages and a `/image <path>` slash command. The implementation introduces a new `tui-image-extract.ts` module for regex-based path extraction and file loading (with extension, size, and MIME validation), wires attachments through `gateway-chat.ts` to the existing `chat.send` RPC, and includes 18 unit tests. - The attachment type shape (`content`, `mimeType`, `fileName`) correctly matches what the gateway's `normalizeRpcAttachmentsToChatAttachments` expects - Both the `/image` handler and `sendMessage` have a bug in their error-handling paths: if `loadImageAttachments` throws (file not found, too large, etc.) **before** the new run ID is assigned to `state.activeChatRunId`, the catch block will forget and null out a **previous** unrelated active run ID, potentially orphaning an in-flight chat request <h3>Confidence Score: 3/5</h3> - Mergeable with a targeted fix to the error-handling paths in both `/image` and `sendMessage` - The core image extraction and loading logic is solid, the gateway integration type shapes match, and test coverage is good. However, the error-handling catch blocks in both the `/image` command handler and the modified `sendMessage` function can clobber an unrelated active run when the newly-added `loadImageAttachments` call throws before the new run ID is assigned. This is a real bug that can cause visible misbehavior (orphaned chat runs, lost error status) in a scenario that users will encounter (e.g. typo in image path). - `src/tui/tui-command-handlers.ts` — both error-handling catch blocks need to be scoped to only clean up the run created within their own handler invocation <sub>Last reviewed commit: 0d37b82</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs