feat(ui): Yazi-style Files tab in the Repo box #111

Merged
deadstyle merged 6 commits from feature/106-files-tab into develop 2026-10-09 15:30:50 -05:00
Owner

Summary

Part 3 of 3 of #98. The [6] Repo box's Files tab browses the default branch Yazi-style: the list of the current directory on the left, a preview of the selected entry on the right. Read-only.

Changes

  • New optional forge.TreeReader capability (+ ActFiles), implemented by the Gitea/Forgejo and GitHub adapters and the fake/demo forge; domain.TreeEntry.
  • core.Service lists directories (directories first) and previews files. Core owns the preview policy: files over 256 KiB are never downloaded ("too large to preview"), and files with NUL bytes or invalid UTF-8 show "binary file".
  • Files tab: j/k move, l/enter enter a directory or focus a text file's preview, h goes up (at the root it leaves the tab), gg/G jump, ctrl-d/ctrl-u scroll the focused preview, o opens the entry in the browser. The breadcrumb shows the current directory.
  • File contents and entry names are stripped of control characters so a file can't inject terminal escape sequences.
  • docs/design.md, docs/architecture.md, docs/mockup.html updated.

Decisions

  • Decided: adapters return raw bytes and core applies the size cap and binary check, so both forges behave the same.
  • Decided: previews are plain text (no syntax highlighting, no wrapping).
  • Decided: symlinks and submodules are listed but never entered or downloaded.
  • Assumed: the breadcrumb shows the current directory, not the selected entry, which matches the ticket's src/ui example.
  • Other branches are out of scope (#107).

Test plan

  • go test -race, golangci-lint (0 issues), format check: pass locally. A manual run in demo mode showed the listing, navigation, breadcrumb, and the binary and oversized messages.
  • make check's install-script test needs shellcheck, absent on this machine; CI runs it.
  • Adapter calls are verified against fixtures only, not a live server.

Refs #106, #98

🤖 Generated with Claude Code

https://claude.ai/code/session_01RTN2GnGvYhWwPhsSDiWp8n

## Summary Part 3 of 3 of #98. The `[6]` Repo box's Files tab browses the default branch Yazi-style: the list of the current directory on the left, a preview of the selected entry on the right. Read-only. ## Changes - New optional `forge.TreeReader` capability (+ `ActFiles`), implemented by the Gitea/Forgejo and GitHub adapters and the fake/demo forge; `domain.TreeEntry`. - `core.Service` lists directories (directories first) and previews files. Core owns the preview policy: files over 256 KiB are never downloaded ("too large to preview"), and files with NUL bytes or invalid UTF-8 show "binary file". - Files tab: `j`/`k` move, `l`/enter enter a directory or focus a text file's preview, `h` goes up (at the root it leaves the tab), `gg`/`G` jump, `ctrl-d`/`ctrl-u` scroll the focused preview, `o` opens the entry in the browser. The breadcrumb shows the current directory. - File contents and entry names are stripped of control characters so a file can't inject terminal escape sequences. - `docs/design.md`, `docs/architecture.md`, `docs/mockup.html` updated. ## Decisions - Decided: adapters return raw bytes and core applies the size cap and binary check, so both forges behave the same. - Decided: previews are plain text (no syntax highlighting, no wrapping). - Decided: symlinks and submodules are listed but never entered or downloaded. - Assumed: the breadcrumb shows the current directory, not the selected entry, which matches the ticket's `src/ui` example. - Other branches are out of scope (#107). ## Test plan - `go test -race`, `golangci-lint` (0 issues), format check: pass locally. A manual run in demo mode showed the listing, navigation, breadcrumb, and the binary and oversized messages. - `make check`'s install-script test needs `shellcheck`, absent on this machine; CI runs it. - Adapter calls are verified against fixtures only, not a live server. Refs #106, #98 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01RTN2GnGvYhWwPhsSDiWp8n
Refs #106

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RTN2GnGvYhWwPhsSDiWp8n
Refs #106

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RTN2GnGvYhWwPhsSDiWp8n
Refs #106

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RTN2GnGvYhWwPhsSDiWp8n
Adds a Files tab to the Repo box: the current directory on the left, the cursor entry's preview on the right. Files over 256 KiB and binary files show a note instead of a preview. The tab is hidden when the forge lacks TreeReader.

Refs #106

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RTN2GnGvYhWwPhsSDiWp8n
Refs #106

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RTN2GnGvYhWwPhsSDiWp8n
fix(ui): mark symlinks, drop trailing blank preview line
All checks were successful
ci / check (pull_request) Successful in 1m39s
0f82ca5318
The Files list now suffixes symlinks with @, a text ending in a newline
no longer adds a blank last row to the preview, and the README tab test
expects the Files listing state now that the Fake implements TreeReader.

Refs #106

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RTN2GnGvYhWwPhsSDiWp8n
deadstyle merged commit 1cfd0192bf into develop 2026-10-09 15:30:50 -05:00
deadstyle deleted branch feature/106-files-tab 2026-10-09 15:30:50 -05:00
Sign in to join this conversation.
No description provided.