Feature request: /files command — worktree-aware filesystem browser (mirrors /diff)

Resolved 💬 1 comment Opened May 22, 2026 by 0xnfrith Closed Jun 21, 2026

Summary

Add a /files slash command (name negotiable — /tree works too) that opens an interactive filesystem browser scoped to the active session's worktree, mirroring the /diff shape:

  • (a) FS tree view ⭐ — primary, MVP, sufficient on its own. Interactive tree of the active worktree's filesystem. Navigate with ↑/↓ and j/k, / to fuzzy-filter, expand/collapse directories, respect .gitignore, mark dirty files (cross-referenced from the existing DiffSet).
  • (b) File content viewsecondary, bolt-on, depends on (a). Pressing Enter on a file row opens the file in a pager with syntax highlighting; quitting the pager returns to the tree.

If scope is tight, ship (a) only for v1 — it is already a giant unlock on its own.

The problem

Worktrees are now first-class in Claude Code. Background sessions via claude agents are explicitly designed to live in isolated worktrees under .claude/worktrees/<id>/, and the docs (Agent view → "How file edits are isolated") position this as the default workflow for parallel sessions.

But there is no native way inside the CLI to browse the filesystem of the active worktree. The result for any user with a real workflow:

  • External editors are pinned to a fixed cwd. VS Code and neovim sessions opened against the project root cannot follow the agent into .claude/worktrees/<id>/ without manual re-opening — and even then, the editor's own session state (buffers, LSP, undo, jumplist) is now bound to the wrong place.
  • So users either (1) abandon the worktree-first workflow Claude Code is pushing, (2) constantly re-rooting their editor, or (3) drop to ls/find/fd in a bash bypass and lose the conversational flow.
  • The agent knows exactly which files it touched. The CLI is rendering tool calls, /diff lists, hunks. But there is no neutral, general way to look around the worktree's filesystem from the same window — only the specific subsets surfaced by individual tool calls.

/diff already proves the primitive can live in the CLI. /diff answers "what changed?" What's missing is /files"what's in here at all?"

Specifically requested

(a) FS tree view — MVP

A new TUI panel opened by /files:

  • Interactive tree starting at the active session's worktree root.
  • ↑/↓ and j/k for navigation (consistent with /plugin, /config, filed earlier).
  • / Enter on a directory expands it; collapses.
  • / opens a fuzzy filter input (consistent with /plugin, /config, filed earlier).
  • Respects .gitignore by default; a key (e.g. . or Ctrl+H) toggles hidden / ignored files.
  • Dirty-file marker (●, M, +, whatever) on rows whose path is in the current DiffSet — so the tree and /diff are visually consistent.
  • Esc to close.

(b) File content view — bolt-on

  • Enter on a file row opens contents in a pager (Ink + a syntax highlighter, or similar).
  • q / Esc returns to the tree with the same row highlighted.
  • Reasonable defaults for binary detection and size cap (just refuse and say so).

Architecture pitch — why this lands across surfaces

This is the part that makes the feature cheap to proliferate across Claude Code's surface area (CLI today, Desktop, Web, Cowork tomorrow), and the reason this issue is worth doing instead of leaving as "users can shell out":

!Architecture pitch — /files command across surfaces

Zoomable SVG version for reading the small text.

The feature decomposes cleanly into the same three layers /diff already inhabits:

1. Core (worktree-aware) — already exists. Session lifecycle, active worktree path under .claude/worktrees/<id>/, local state under ~/.claude/. Nothing new here.

2. Feature layer (framework-neutral, no UI) — where the new work lands. Two new engines:

  • FileTree — walks the worktree filesystem, respects .gitignore, emits a stable TreeNode data shape { name, kind, children, size, mtime, dirty? }. Reactive on filesystem events. Reads the existing DiffSet to populate dirty?.
  • FileView — given a path, reads file content, detects binary, enforces a size cap, emits a FileContent shape { path, bytes, encoding, language, truncated? }.

3. Surfaces (downstream consumers) — each writes its own renderer.

  • CLI / TUI (this issue): tree pane with j/k, fuzzy filter, pager on Enter.
  • Desktop: file tree side-panel, click → open file in code pane.
  • Web (claude.ai/code): tree card in conversation, click → side viewer.
  • Cowork: reuses the web renderer in the cloud runtime.

The proliferation insight: this is the exact same shape as /diff. One engine at the feature layer, one stable data shape (TreeNode / FileContent), N renderers across N surfaces. A new surface added later only writes a renderer; it doesn't reimplement filesystem walking or .gitignore parsing.

Why this is worth doing

  • Mirrors /diff exactly. Zero new architectural primitives — just one more engine and one more data shape at the existing feature layer.
  • Unblocks the worktree-first workflow Claude Code is already pushing. claude agents is built around the idea that worktrees are the unit of work. An in-CLI FS browser is the obvious missing primitive for inspecting those worktrees without leaving the session.
  • (a) ships independently of (b). Tight scope = the tree browser alone. (b) is a bolt-on for later.
  • Renderer cost is small. Terminal tree widgets are commodity (Ink, react-blessed, ink-tree-select, etc.). The TUI work is bounded.
  • Integrates with /diff from day 1 via the dirty-file marker, so the two features reinforce each other instead of feeling parallel.
  • No new permissions surface. Read-only over the active worktree's cwd. Hooks into the same path scoping the rest of the session already respects.

Related

Thanks!

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗