JetBrains / JetBrains/thinkrail

Opening an image file shows a Monaco buffer of its bytes instead of the picture

Open
#439 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
478
Forks
37
Avg merge
1d 52m
Merged PRs (30d)
143

Description

## Description

Double-clicking a PNG (or JPEG, GIF, WebP, SVG, BMP, ICO, AVIF) in the Files tree opens a read-only Monaco editor filled with the file's binary decoded as UTF-8: a wall of replacement characters and stray glyphs. There is no way to actually look at the image from inside ThinkRail, even though the host already streams a worktree file's raw bytes over `GET /files//` for relative images in the markdown viewer.

Every extension goes through `fs.readFile` in `openFileInTab` / `FilePane`, which reads the file as text and ships it to the tab as `tab.content`. For an image that content is useless, and the round trip is wasted on every open and every `fsChanged` refresh.

My personal use case: I wanted to generate a Mermaid diagram to share and wanted to look at the result.

## Steps to reproduce

1. Open a project whose worktree contains an image, e.g. `logo.png`.
2. Switch to the Files tab and double-click the image.

## Expected behavior

The tab renders the picture: an `` pointed at the `/files/…` route, natural dimensions shown somewhere, and zoom controls. When an agent or an external tool rewrites the file (including delete-and-rename, as exporters do), the tab reloads the new pixels in place without reopening.

## Actual behavior

A Monaco editor opens with the decoded bytes as text. The tab is read-only, has no image, and the markdown chrome is absent, so nothing on screen says the file is a picture.

## Environment

- OS: macOS 26.6.2
- Bun version (`bun --version`): 1.4.0
- Node version (`node --version`): v26.8.1
- ThinkRail version / commit: reproducible on `main` at 127a8cef

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Contributor guide

Open the contributing guide

Research direction

Trace image handling from openFileInTab and FilePane, then inspect the existing GET /files// route used by the markdown viewer. Check how fsChanged refreshes an open tab, including delete-and-rename updates. Done means supported image extensions render pixels with dimensions and zoom controls, refresh in place, and no longer load binary data into Monaco.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.