Skip to content

feat(files): add a Files panel with search, previews and file-link chips - #191

Merged
akemmanuel merged 2 commits into
akemmanuel:masterfrom
touch2be:feat/files-panel
Nov 11, 2026
Merged

akemmanuel merged 2 commits into
akemmanuel:masterfrom
touch2be:feat/files-panel

Conversation

@touch2be

@touch2be touch2be commented Nov 9, 2026

Copy link
Copy Markdown
Collaborator

Problem

File links in model output had nowhere to go. Paths like ./notes.txt:2 or /home/…/report.pdf were treated as web URLs and resolved against the app's address, and on a hosted instance there was no way to open them at all.

What this adds

A right-side Files panel. It reads files through the Host's existing path authorization, so it works the same on desktop, self-hosted and hosted instances.

Browsing

  • Folder view styled like Finder or Explorer: back/forward, breadcrumb, project-wide file-name search, status line.
  • Files this chat created or changed are marked. The list is built from the transcript's tool calls, so it needs no new backend state.
  • Long file and folder names are truncated with …, and the full name is in a tooltip.

Previews

  • Text and code with syntax highlighting. The Host sniffs the first bytes for binary content, so any text file works, not just a fixed list of extensions. Large files show their first ~2 MB plus a download button.
  • Markdown through the chat's renderer, with a source toggle.
  • HTML and SVG in a sandboxed frame without scripts, with embedded images resolved through the Host and a source toggle.
  • CSV as a table, images through the existing viewer.
  • PDF with pdf.js. It is loaded lazily and reads the file through HTTP range requests.
  • Everything else gets an info card with a download button.

Chat integration

  • Local paths in Markdown (./a.txt:12, /abs/path, file://, C:\…, page.html#anchor) render as chips that open the preview. path:line jumps to that line.
  • Relative links that are neither files nor http(s) URLs are no longer resolved against the app's own origin.

Controls

  • PanelRight toggle in the title bar, mirroring the left sidebar button. Shortcut: Ctrl/Cmd+Shift+E.
  • The panel is resizable, and its width and open state are persisted. On mobile it is an overlay.
  • Right-click menu: Open, plus Show in file manager. The second item only appears for local files in the desktop app and is hidden in the web/server build and for remote Hosts.

Backend

  • GET /api/fs/list?files=1 also lists files, with size and modification time.
  • New GET /api/fs/stat returns name, size, mtime and text-encoding detection.
  • GET /api/fs/file?download=1 streams the file as an attachment. There is no limit by default. OPENGUI_DOWNLOAD_MAX_BYTES adds one and is documented in docs/docker.md.
  • GET /api/fs/file?maxBytes=N returns a capped head for text previews. PDFs support Range.
  • All responses share the existing untrusted-file headers (sandbox CSP, nosniff, no-cache). CORS now allows the range header and exposes the range headers.

Also

  • The prompt box re-measures its height when the chat width changes. Before, it could keep a tall height measured while the panel was wide.

Tests

  • vp check: clean
  • vp test --run: 256 files, 1671 tests passing. New tests cover the routes (fs.files-panel.test.ts, path enforcement), link parsing and chat-file collection (host-files.test.ts), the Host client, CSV, HTML resource rewriting and the panel.
  • pnpm run slop-check: ok
  • scripts/browser-acceptance.ts: full journey passes. It is extended with file links, project search, text/CSV/HTML/PDF previews and mobile focus. It now also waits for the model list in the settings step, which raced the list loading.
  • Checked by hand in the Linux dev app against real sessions.

Adds the dependency pdfjs-dist. It is lazy-loaded, and the initial bundle stays within the bundle budget.

🤖 Generated with Claude Code

touch2be and others added 2 commits November 9, 2026 12:24
File links in model output had nowhere to go, and hosted instances could
not open them at all. The new right-side panel reads files through the
Host's existing path checks, so it works the same on every Host.

- Finder-style folder view with back/forward, breadcrumb and project-wide
  name search; files this chat created or changed are marked.
- Previews for text/code (binary sniffing, capped head), Markdown, HTML
  and SVG in a sandboxed frame with embedded images, CSV, images and PDF
  (lazy pdf.js with HTTP range requests).
- Local paths in Markdown (`./a.txt:12`, `/abs`, `file://`, `C:\`,
  `page.html#anchor`) render as chips that open the preview.
- Context menu with Open and, in the desktop app only, Show in file manager.
- Toggle (PanelRight) in the title bar, Ctrl/Cmd+Shift+E, resizable and
  persisted; overlay on mobile.
- Backend: `/api/fs/list?files=1`, new `/api/fs/stat`, streamed downloads
  with optional `OPENGUI_DOWNLOAD_MAX_BYTES` (unset = no limit).
- Prompt box re-measures its height when the chat width changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts:
#	packages/backend/src/routes/fs.ts
#	src/App.tsx
@akemmanuel
akemmanuel merged commit 191ffe2 into akemmanuel:master Nov 11, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants