# Files, Markdown & Preview Sidecars

> The right-sidebar file workflow that mixes file search, terminal path insertion, command-click routing, Markdown rendering, PDF/image previews, and review-feedback surfaces.

- Repository: manaflow-ai/cmux
- GitHub: https://github.com/manaflow-ai/cmux
- Human wiki: https://grok-wiki.com/public/wiki/manaflow-ai-cmux-5a511656cb1a
- Complete Markdown: https://grok-wiki.com/public/wiki/manaflow-ai-cmux-5a511656cb1a/llms-full.txt

## Source Files

- `Sources/FileExplorerStore.swift`
- `Sources/FileExplorerTerminalPathInsertion.swift`
- `Sources/CommandClickFileOpenRouter.swift`
- `Sources/Panels/MarkdownPanel.swift`
- `Sources/Panels/FilePreviewPanel.swift`
- `Sources/Panels/FilePreviewWorkspaceOpenSupport.swift`
- `cmuxTests/FileExplorerStoreTests.swift`
- `cmuxTests/FilePreviewReviewFeedbackTests.swift`

---

<details>
<summary>Relevant source files</summary>
The following files were used as context for generating this wiki page:
- [Sources/FileExplorerStore.swift](Sources/FileExplorerStore.swift)
- [Sources/FileExplorerState.swift](Sources/FileExplorerState.swift)
- [Sources/RightSidebarPanelView.swift](Sources/RightSidebarPanelView.swift)
- [Sources/FileExplorerView.swift](Sources/FileExplorerView.swift)
- [Sources/FileExplorerSearchController.swift](Sources/FileExplorerSearchController.swift)
- [Sources/FileExplorerTerminalPathInsertion.swift](Sources/FileExplorerTerminalPathInsertion.swift)
- [Sources/CommandClickFileOpenRouter.swift](Sources/CommandClickFileOpenRouter.swift)
- [Sources/cmuxApp.swift](Sources/cmuxApp.swift)
- [Sources/CommandPalette/CommandPaletteSettingsToggle.swift](Sources/CommandPalette/CommandPaletteSettingsToggle.swift)
- [Sources/SettingsNavigation.swift](Sources/SettingsNavigation.swift)
- [Sources/Panels/MarkdownPanel.swift](Sources/Panels/MarkdownPanel.swift)
- [Sources/Panels/MarkdownPanelView.swift](Sources/Panels/MarkdownPanelView.swift)
- [Sources/Panels/MarkdownWebSupport.swift](Sources/Panels/MarkdownWebSupport.swift)
- [Sources/Panels/MarkdownPanelFileLinkResolver.swift](Sources/Panels/MarkdownPanelFileLinkResolver.swift)
- [Sources/Panels/MarkdownWebRenderer.swift](Sources/Panels/MarkdownWebRenderer.swift)
- [Sources/Panels/FilePreviewPanel.swift](Sources/Panels/FilePreviewPanel.swift)
- [Sources/Panels/FilePreviewModeSupport.swift](Sources/Panels/FilePreviewModeSupport.swift)
- [Sources/Panels/FilePreviewWorkspaceOpenSupport.swift](Sources/Panels/FilePreviewWorkspaceOpenSupport.swift)
- [Sources/Panels/PanelOwnedNativeViewSession.swift](Sources/Panels/PanelOwnedNativeViewSession.swift)
- [Sources/FileOpenSocketSupport.swift](Sources/FileOpenSocketSupport.swift)
- [Sources/TerminalController.swift](Sources/TerminalController.swift)
- [cmuxTests/FileExplorerStoreTests.swift](cmuxTests/FileExplorerStoreTests.swift)
- [cmuxTests/FilePreviewReviewFeedbackTests.swift](cmuxTests/FilePreviewReviewFeedbackTests.swift)
</details>

# Files, Markdown & Preview Sidecars

cmux treats files as a first-class pane workflow, not just a Finder-style convenience. The right sidebar can browse a workspace root, run content search, insert selected paths into the active terminal, open local files into cmux surfaces, and hand supported content to Markdown or preview sidecars.

This page focuses on the product workflow and the implementation boundaries that make it useful for agents and humans: local/SSH file roots, ripgrep-backed search, terminal-safe path insertion, command-click routing, Markdown rendering/editing, PDF/image/media/Quick Look previews, and review-feedback-adjacent socket surfaces.

Generation scope: no `docs/solutions/**` directory or `STRATEGY.md` file was present in this checkout, so repository code and tests are the source of truth. The requested Compound Engineering page-shape and QA guidance was treated as bundled recipe metadata, not as an installed local skill execution.

## Workflow Map

```text
Right Sidebar
  files mode  -> NSOutlineView tree -> double-click local file -> open preview/markdown sidecar
  find mode   -> ripgrep results    -> Enter/context menu/drag -> open preview or insert path

Terminal / agent entrypoints
  context menu -> Insert Path / Insert Relative Path -> focused TerminalPanel.sendText(...)
  cmd-click    -> CommandClickFileOpenRouter         -> MarkdownPanel or FilePreviewPanel
  socket API   -> file.open                          -> explicit pane or focused pane

Sidecar surfaces
  MarkdownPanel     -> WKWebView preview + TextEdit mode + Markdown link routing
  FilePreviewPanel  -> text/PDF/image/media/QuickLook + external-open menu
```

Sources: [Sources/RightSidebarPanelView.swift:149-158](), [Sources/RightSidebarPanelView.swift:365-381](), [Sources/FileExplorerView.swift:605-621](), [Sources/FilePreviewWorkspaceOpenSupport.swift:4-58](), [Sources/FileOpenSocketSupport.swift:73-176]()

## Right Sidebar Files And Find Modes

`FileExplorerState` owns sidebar visibility, width, divider position, hidden-file display, and the active `RightSidebarMode`. The root sidebar view hosts a mode bar, then renders `FileExplorerPanelView` for both `.files` and `.find`; the same opening callback is passed through both modes. This keeps file tree and search result opening on one path instead of divergent UI actions.

`FileExplorerStore` is the file tree model. It has a provider abstraction for local and SSH roots, tracks expanded paths, selected paths, loading paths, root status, git status, and a content revision. Local roots use `FileManager.contentsOfDirectory`; SSH roots use a transport that shells out to `/usr/bin/ssh`, resolves `$HOME`, and lists directories remotely. That shape is important for BYOC/BYOK and vendor neutrality: file browsing is provider/transport based, not tied to any hosted model provider or proprietary connector.

Sources: [Sources/FileExplorerState.swift:6-47](), [Sources/RightSidebarPanelView.swift:188-226](), [Sources/RightSidebarPanelView.swift:365-381](), [Sources/FileExplorerStore.swift:258-309](), [Sources/FileExplorerStore.swift:264-289](), [Sources/FileExplorerStore.swift:664-696]()

### Search Is A File Workflow, Not A Separate Product

Find mode is backed by `FileSearchController`, which parses ripgrep JSON into `FileSearchResult` values containing absolute path, relative path, line/column, and preview text. It resolves `rg` from a configured path, common package-manager paths, `PATH`, and Nix-style paths, then streams results through a pipeline that emits partial snapshots and stops after the configured maximum.

The UI result table can open a selected result in cmux, open externally, reveal in Finder, copy paths, insert paths into the terminal, or drag the result as a file preview payload. Tests cover ignored generated directories, all matching files in a folder, high-volume result limiting at 500, refresh on content revision changes, and typing debounce.

Sources: [Sources/FileExplorerSearchController.swift:4-67](), [Sources/FileExplorerSearchController.swift:69-168](), [Sources/FileExplorerSearchController.swift:245-371](), [Sources/FileExplorerView.swift:1484-1519](), [Sources/FileExplorerView.swift:1522-1674](), [cmuxTests/FileExplorerStoreTests.swift:520-631](), [cmuxTests/FileExplorerStoreTests.swift:633-725]()

## Terminal Path Insertion

The file sidebar context menu adds two terminal-oriented actions: `Insert Path` and `Insert Relative Path`. Both tree rows and search results can use them. The implementation delegates quoting/escaping to `TerminalImageTransferPlanner.insertedText`, then finds the focused terminal panel for the current window, window context, or fallback tab manager and sends the text directly.

Relative insertion normalizes filesystem paths, handles `/private/tmp`, `/private/var`, and `/private/etc` display rewrites, returns `.` when the selected path equals the root, and otherwise drops the root prefix. Search results already carry a relative path, so their relative insertion path sends the result’s `relativePath` directly.

Sources: [Sources/FileExplorerTerminalPathInsertion.swift:3-87](), [Sources/FileExplorerTerminalPathInsertion.swift:89-150](), [Sources/FileExplorerTerminalPathInsertion.swift:152-184](), [Sources/FileExplorerView.swift:623-699](), [Sources/FileExplorerView.swift:1653-1674]()

## Command-Click And Socket Routing

Command-click file routing is intentionally narrow. `CommandClickFileOpenRouter.shouldRouteInCmux` checks Markdown routing and general supported-file routing. `openInCmux` tries Markdown first, then falls back to file preview only when the supported-file setting accepts the path. The settings are user-visible through the command palette and settings navigation as “Open Supported Files in cmux” and “Open Markdown in cmux Viewer.”

Routing settings reject unreadable or non-regular files. Markdown routing is disabled by default, extension-gated, and uses the same readable regular-file check as supported file previews. Supported-file routing is enabled by default and posts a notification when changed.

The socket API offers the agent-facing version of this workflow through `file.open`: paths are expanded and standardized, must be absolute readable files, and then open as Markdown or file preview surfaces in an explicit pane/surface destination or the focused pane. The response reports surface IDs, pane IDs, panel type, path, and either preview mode or Markdown display mode.

Sources: [Sources/CommandClickFileOpenRouter.swift:3-24](), [Sources/cmuxApp.swift:4909-4971](), [Sources/CommandPalette/CommandPaletteSettingsToggle.swift:170-216](), [Sources/SettingsNavigation.swift:300-305](), [Sources/FileOpenSocketSupport.swift:4-70](), [Sources/FileOpenSocketSupport.swift:73-176]()

## Markdown Sidecars

Markdown files use a dedicated `MarkdownPanel`, not the generic file preview panel. New panels default to preview mode, keep a panel-owned `MarkdownRendererSession`, load file content immediately, and install file/directory watchers so external saves, atomic rewrites, deletes, and recreates update the panel. Text mode supports editing, dirty tracking, saving through `FilePreviewTextSaver`, and global search capture.

Rendering is WebKit-based. `MarkdownPanelView` keeps the rendered preview and text editor stacked, toggling hit testing and opacity by `displayMode`. The comments in the view explain the product reason: browser-native selection, GitHub markdown CSS behavior, and copyable rendered HTML. The renderer session is panel-owned so SwiftUI wrapper churn during split/tab layout changes does not recreate the web view and flash content.

Markdown links are also routed inside cmux. `MarkdownPanelFileLinkResolver` accepts path-like Markdown filenames, strips fragments/query strings, rejects non-file URLs, resolves relative paths against the Markdown file directory and current working directory, and only returns existing files. `MarkdownWebRenderer` uses that resolver to answer web requests and open Markdown links as new Markdown surfaces in the same pane.

Sources: [Sources/Panels/MarkdownPanel.swift:12-82](), [Sources/Panels/MarkdownPanel.swift:110-187](), [Sources/Panels/MarkdownPanel.swift:191-246](), [Sources/Panels/MarkdownPanel.swift:269-429](), [Sources/Panels/MarkdownPanelView.swift:5-19](), [Sources/Panels/MarkdownPanelView.swift:81-160](), [Sources/Panels/MarkdownWebSupport.swift:69-98](), [Sources/Panels/MarkdownPanelFileLinkResolver.swift:3-58](), [Sources/Panels/MarkdownWebRenderer.swift:503-541]()

## File Preview Sidecars

`FilePreviewPanel` is the general-purpose preview surface. It resolves a `FilePreviewMode` from filename, extension, UTType, and light content sniffing. Known text filenames/extensions become text, PDF/image/media UTTypes get native preview modes, binary plists prefer Quick Look, and extensionless content initially opens in Quick Look until async sniffing can promote it to text. Text loading has a 16 MiB guard and supports UTF-8, UTF-16, and ISO Latin-1.

```swift
// Sources/Panels/FilePreviewPanel.swift
enum FilePreviewMode: Equatable {
    case text
    case pdf
    case image
    case media
    case quickLook
}
```

The view layer switches on that mode: text editor, PDF view, image view, media view, or Quick Look. Non-PDF previews get a file path header with save/revert controls when editable and an external-open menu. Native AppKit views are held in `FilePreviewNativeViewSessions` via `PanelOwnedNativeViewSession`, which reuses mounted views, retires views on close, and avoids letting stale SwiftUI teardown reset the active preview item.

| Mode | Main surface | Notes |
|---|---|---|
| `text` | `FilePreviewTextEditor` | Editable, dirty-tracked, save/revert enabled. |
| `pdf` | `FilePreviewPDFView` | Dedicated PDF chrome and focus intent. |
| `image` | `FilePreviewImageView` | Native image canvas with zoom/rotate support. |
| `media` | `FilePreviewMediaView` | AVKit-backed playback surface. |
| `quickLook` | `QuickLookPreviewView` | Fallback for supported binary/unknown files. |

Sources: [Sources/Panels/FilePreviewPanel.swift:629-826](), [Sources/Panels/FilePreviewPanel.swift:828-897](), [Sources/Panels/FilePreviewPanel.swift:899-944](), [Sources/Panels/FilePreviewPanel.swift:1056-1186](), [Sources/Panels/FilePreviewPanel.swift:1188-1320](), [Sources/Panels/FilePreviewModeSupport.swift:3-17](), [Sources/Panels/PanelOwnedNativeViewSession.swift:3-68](), [cmuxTests/FilePreviewReviewFeedbackTests.swift:60-68](), [cmuxTests/FilePreviewReviewFeedbackTests.swift:70-184]()

## Open-Surface Selection Rules

The workspace helper `openFileSurfaces` is the central product boundary for mixed file opens. It checks `MarkdownPanelFileLinkResolver.isMarkdownPathLike(filePath)` first; Markdown files become Markdown surfaces, while all other paths become file preview surfaces. The same helper supports opening multiple files, target index placement, focus inheritance from the current pane, and optional reuse of existing surfaces.

That shared helper is used by socket `file.open` and by pane drop/split paths. A regression test verifies that explicit pane destinations create a new preview in the requested pane instead of reusing an existing preview elsewhere, which is the right behavior for review workflows and agent-driven UI composition.

Sources: [Sources/Panels/FilePreviewWorkspaceOpenSupport.swift:4-58](), [Sources/Panels/FilePreviewWorkspaceOpenSupport.swift:60-99](), [Sources/Workspace.swift:15456-15477](), [Sources/FileOpenSocketSupport.swift:107-141](), [cmuxTests/FilePreviewReviewFeedbackTests.swift:200-247]()

## Review-Feedback Surfaces

There is no separate “review feedback preview panel” in the inspected implementation. Instead, review feedback connects through two adjacent surfaces:

1. Sidebar metadata commands: `report_pr` and `report_review` both route to pull-request reporting, and help text describes `report_review` as an alias for provider-specific review items.
2. File preview regression coverage: `FilePreviewReviewFeedbackTests` protects the file preview behaviors that matter when review feedback asks an agent or human to inspect artifacts: chorded save shortcuts, extensionless text sniffing, Quick Look lifecycle safety, oversized text rejection, pending focus restoration, and explicit pane targeting.

Settings navigation also exposes review-related sidebar features such as showing pull requests, making PR links clickable, and opening sidebar PR links in the cmux browser. The useful product pattern is to keep review metadata in the sidebar while file artifacts open through the same Markdown/file preview sidecars as every other path.

Sources: [Sources/TerminalController.swift:3067-3074](), [Sources/TerminalController.swift:15895-15905](), [Sources/SettingsNavigation.swift:343-347](), [cmuxTests/FilePreviewReviewFeedbackTests.swift:25-58](), [cmuxTests/FilePreviewReviewFeedbackTests.swift:186-247]()

## Portable Integration Notes

For a Grok-Wiki or similar integration, the safest architecture is to treat files, repositories, and skill/catalog context as portable sources that produce paths and metadata, then let cmux’s existing routing decide the surface. Do not bind wiki previews to a specific model provider. Use repository-relative citations and generated Markdown files as ordinary files: Markdown paths route to `MarkdownPanel`, supported binary/text artifacts route to `FilePreviewPanel`, and terminal commands can insert absolute or relative paths through the existing context menu helpers.

A provider-neutral integration should preserve these boundaries:

| Boundary | Reuse this | Avoid |
|---|---|---|
| File source | `FileExplorerProvider` / `SSHFileExplorerTransport` style abstraction | Hard-coding local-only or vendor-hosted paths |
| Opening files | `openFileSurfaces` / `file.open` | Separate Markdown-vs-preview duplicate routing |
| Markdown links | `MarkdownPanelFileLinkResolver` | Treating arbitrary URLs as local files |
| Agent review metadata | `report_pr` / `report_review` sidebar metadata | Embedding review state inside preview panels |
| Terminal workflows | `FileExplorerTerminalPathInsertion` | Ad hoc shell quoting |

Sources: [Sources/FileExplorerStore.swift:258-289](), [Sources/FileExplorerStore.swift:311-577](), [Sources/Panels/FilePreviewWorkspaceOpenSupport.swift:4-58](), [Sources/Panels/MarkdownPanelFileLinkResolver.swift:6-45](), [Sources/FileExplorerTerminalPathInsertion.swift:57-87](), [Sources/TerminalController.swift:15897-15899]()

## Summary

The right-sidebar file workflow is a compact, reusable product pattern: search and tree navigation produce file paths; path insertion keeps terminal work fast; command-click and socket APIs route files into sidecars; Markdown gets a richer rendered/editor surface; non-Markdown files get mode-specific previews; and review metadata stays in the sidebar while artifacts open through the same file surfaces. The implementation is mostly provider-neutral already because roots and remote access are abstracted, and surface selection is centralized rather than spread across UI entrypoints. Sources: [Sources/FileExplorerStore.swift:664-717](), [Sources/FileExplorerTerminalPathInsertion.swift:57-87](), [Sources/CommandClickFileOpenRouter.swift:3-24](), [Sources/Panels/FilePreviewWorkspaceOpenSupport.swift:4-58](), [Sources/FileOpenSocketSupport.swift:73-176]()
