Skip to content

[Feature]: Clickable file links in chat with file viewer sidebar; workspace navigator previews any in-root file #100615

Description

@steipete

Summary

Auto-link file paths mentioned in Control UI chat messages and open them in a file viewer sidebar with syntax highlighting; let the workspace rail (file navigator) preview any file inside the session workspace, not just transcript-touched ones.

Problem to solve

Chat replies constantly reference workspace files — inline code like ui/src/lib/sessions/navigation.ts, plain paths, and Claude-style markdown links such as [foo.ts](src/utils/foo.ts:42). Today the Control UI renders all of these as dead text:

  • The markdown sanitizer strips host-local file hrefs entirely (ui/src/components/markdown.ts, HOST_LOCAL_FILE_HREF_RE), so agent-emitted file links lose their target.
  • Plain-text and inline-code paths are never linkified.
  • The Session Workspace Rail's file browser disables the preview action for any file the transcript did not touch (canPreview in ui/src/pages/chat/components/chat-session-workspace.ts), and the gateway's sessions.files.get rejects untouched in-root paths, so browsing the workspace is read-only in name only.

To look at a referenced file, users have to leave the app and open an editor.

Proposed solution

  1. Detect file paths in chat message text during markdown rendering (plain multi-segment paths, path:line references, inline code spans, and markdown links whose href is a relative or host-local file path) and render them as clickable file links.
  2. Clicking a file link opens the existing chat detail sidebar with a dedicated file view: path header, line-number gutter, highlight.js syntax highlighting, and scroll-to-line for path:line references. Markdown files keep the rendered-markdown preview.
  3. Workspace rail: clicking any file in the browser/navigator opens the same viewer (drop the transcript-touched restriction).
  4. Gateway: sessions.files.get serves any path that resolves inside the session workspace root. Existing security posture unchanged: root containment, symlink/hardlink rejection, and the 256 KB preview cap stay as-is. No protocol schema change.

Alternatives considered

  • Linkifying only explicit markdown links would miss the dominant pattern (inline code paths) and leave the navigator broken for untouched files.
  • A separate file-viewer modal duplicates the existing detail sidebar; reusing the sidebar keeps one preview surface.
  • Serving file contents over a new protocol method: unnecessary — sessions.files.get already has the right shape, scope (operator.read), and limits.

Impact

  • Affected: all Control UI users (web + desktop app shell) working with coding agents
  • Severity: medium — blocks a core review loop (reading files an agent mentions)
  • Frequency: constant in coding sessions
  • Consequence: context switching to an editor/terminal for every referenced file

Evidence/examples

  • sessions.files.get currently rejects in-root files that the transcript did not touch: src/gateway/server-methods/sessions-files.ts (findSessionFile returns not-found when there is no sessionKind).
  • Rail preview gate: ui/src/pages/chat/components/chat-session-workspace.ts (canPreview = entry.kind === "file" && Boolean(entry.sessionKind)).
  • Sanitizer strips local-file hrefs: ui/src/components/markdown.ts (isHostLocalFileHref -> node.removeAttribute("href")).

Additional information

The browser listing already exposes names/sizes of all in-root files (sessions.files.list), so serving their contents at the same scope does not widen the trust boundary. Files above the preview cap keep returning the existing session_file_too_large error.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.enhancementNew feature or requestimpact:ux-frictionUser-facing flow adds avoidable confusion or support burden without fully blocking progress.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.maintainerMaintainer-authored PRmaturity:stableIssue affects a taxonomy feature currently scored M4/M5.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions