Files
platform/src
pastilhasandClaude Opus 5 e2b0d5c06b edit any text file, and make new ones from the empty panel
Two things, both asked for.

── Open in editor now covers text ──

It was markdown and code only, because `text` is `getFileType`'s FALLBACK and so
also catches binaries. That was the wrong trade: media, archives and pdf are
already claimed by earlier branches, so what actually lands in the fallback is
.txt, .log, .csv, .conf, dotfiles, Makefile-likes and anything with an extension
the platform has never heard of. Refusing all of that to avoid one bad case cost
far more than it saved.

The bad case is named instead of guessed at — a ~40-entry list of extensions that
reach the fallback but are not text (.exe .so .sqlite .docx .woff …). A denylist
that is too short costs one bad render; a `text` test that is too strict costs
the feature. Not a security control: `/file-browser/read` is UTF-8 and capped at
5 MB, so the worst outcome is mojibake.

Checked against 18 names: notes.txt, server.log, data.csv, nginx.conf, .env,
Makefile, script.sh, and an extensionless file all offer it; jpg, mp3, zip, pdf,
exe, so, sqlite and docx all do not.

── New file, from the empty panel ──

Right-click → New file takes a name WHOLE, extension included, creates it empty
and opens it in the editor. The extension is what the editor uses to pick a
language, so guessing one would be wrong more often than not; no extension is
fine and opens as plain text.

It refuses to clobber. `/write` is an overwrite, so creating over an existing
name would silently empty it — the one outcome nobody wants from a menu item
called "New file". There is no stat endpoint, so the check is a read that is
expected to fail.

`prompt()` to match New folder directly above it. Both deserve a real dialog and
neither has one; making this one different would just be inconsistent.

── Verified rather than assumed ──

`getActiveFile()` only matches ALREADY-OPEN files, so a path arriving in the URL
could have landed on an empty editor — the exact silent failure this whole audit
keeps turning up. It does not: CodeEditor.tsx:60-76 fetches and opens an unopened
`?file=`, with an `unreadable` set guarding the retry loop. Confirmed
/code-editor renders with `urlState`, without which the param is ignored entirely.

The param is imported as `EDITOR_FILE_PARAM` rather than written as 'file' twice,
so renaming it cannot leave this behind.

tsgo clean, frontend builds, 808 pass / 7 fail unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 19:15:05 +00:00
..