File viewer v1: Files / Changes / Diff pane with markdown preview #19

Closed
opened 2026-10-07 20:04:30 -04:00 by jared · 0 comments
Owner

Source: file viewer/editor design review, 2026-10-07.

Layout: a Files toggle opens a split pane at ≥1400px (draggable, terminal ≥80 cols), an overlay drawer at 1100–1399px, and a full-screen Terminal | Files switch on phone. Hide the terminal with display:none, never by squeezing it to zero width, which resizes tmux for every client.

Server (over the ttyd channel, no sidecar):

  • --fs-list SESSION [REL]: one directory level, skips .git, caps entries, flags symlinks.
  • --fs-read SESSION REL: header JSON, then base64 between markers. 2 MiB cap; NUL-byte binary detection; invalid UTF-8 opens read-only; keeps CRLF and BOM.
  • --git-status (porcelain -z plus numstat plus the Claude edit log) and --git-show (HEAD version for diffs).
  • Path safety: realpath must stay inside the session folder; reject absolute paths, newlines and symlink escapes. Paths over ~200 bytes hit ttyd's argument limit.

Client:

  • Lean CodeMirror 6: core, search, markdownLanguage, legacy stream modes and @codemirror/merge, plus marked and DOMPurify. About 169 KB gzip, lazy import().
  • The markdown preview renders in a sandboxed iframe with no scripts, because the page holds a root terminal.
  • Changes tab: git status plus a "Claude" badge from an edit log recorded by devdesk-state-hook on Edit/Write/MultiEdit.

Estimate ~4 days. Risk: page grows 231 → ~400 KB gzip.

_Source: file viewer/editor design review, 2026-10-07._ **Layout:** a **Files** toggle opens a split pane at ≥1400px (draggable, terminal ≥80 cols), an overlay drawer at 1100–1399px, and a full-screen Terminal | Files switch on phone. Hide the terminal with `display:none`, never by squeezing it to zero width, which resizes tmux for every client. **Server** (over the ttyd channel, no sidecar): - `--fs-list SESSION [REL]`: one directory level, skips `.git`, caps entries, flags symlinks. - `--fs-read SESSION REL`: header JSON, then base64 between markers. 2 MiB cap; NUL-byte binary detection; invalid UTF-8 opens read-only; keeps CRLF and BOM. - `--git-status` (porcelain `-z` plus numstat plus the Claude edit log) and `--git-show` (HEAD version for diffs). - Path safety: `realpath` must stay inside the session folder; reject absolute paths, newlines and symlink escapes. Paths over ~200 bytes hit ttyd's argument limit. **Client:** - Lean CodeMirror 6: core, search, `markdownLanguage`, legacy stream modes and `@codemirror/merge`, plus marked and DOMPurify. About 169 KB gzip, lazy `import()`. - The markdown preview renders in a **sandboxed iframe with no scripts**, because the page holds a root terminal. - **Changes** tab: git status plus a "Claude" badge from an edit log recorded by `devdesk-state-hook` on Edit/Write/MultiEdit. Estimate ~4 days. Risk: page grows 231 → ~400 KB gzip.
jared added this to the v0.7.0 file viewer milestone 2026-10-07 20:04:30 -04:00
jared added the feature label 2026-10-07 20:04:30 -04:00
jared closed this issue 2026-10-08 01:16:38 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: LotusGuild/devdesk#19