docs(viewer): fix round 1 — fallback trap, tracked checklist, residual-risk framing
- CLAUDE.md: document the viewer.html fallback trap (missing/broken Vite entry silently serves index.html into the viewer window) and point at the Rust test that pins it. - Give the manual verification checklist a durable, tracked home: append it as a markdown task list to the terminal-file-viewer design spec, including the file-path hover key-hint wording check and the CRLF/BOM round-trip save check. - default.json: state the app-command residual risk and the pending AppManifest lockdown directly in the capability file's own description, not only in CLAUDE.md, since this file is the reviewed threat model of record. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -78,7 +78,11 @@ docker exec stdout → tokio task → emit("terminal-output-{sessionId}") → li
|
|||||||
`components/terminal/filePathLinkProvider.ts` registers it with xterm. The OSC 8 handler now
|
`components/terminal/filePathLinkProvider.ts` registers it with xterm. The OSC 8 handler now
|
||||||
runs with `allowNonHttpProtocols` on and dispatches `file:` to the viewer, so every other scheme
|
runs with `allowNonHttpProtocols` on and dispatches `file:` to the viewer, so every other scheme
|
||||||
must be refused *there*. `viewer.html` must never carry an inline `<style>` — Tauri would add a
|
must be refused *there*. `viewer.html` must never carry an inline `<style>` — Tauri would add a
|
||||||
style nonce and CodeMirror's injected styles would stop applying.
|
style nonce and CodeMirror's injected styles would stop applying. A missing or broken
|
||||||
|
`viewer.html` Vite entry is not caught by Tauri at build time — both Vite dev and Tauri's asset
|
||||||
|
lookup silently fall back to `index.html`, so the window just opens the *main app*, full UI and
|
||||||
|
all, with no error anywhere; `file_viewer::tests::the_viewer_entry_exists_and_is_a_vite_input`
|
||||||
|
in `file_viewer/mod.rs` is the only thing pinning this.
|
||||||
- **`components/layout/`** — TopBar, MainTabs (the unified tab strip), Sidebar, StatusBar
|
- **`components/layout/`** — TopBar, MainTabs (the unified tab strip), Sidebar, StatusBar
|
||||||
- **`components/projects/`** — `ProjectRow` (select-only list row), `ProjectList`, `AddProjectDialog`,
|
- **`components/projects/`** — `ProjectRow` (select-only list row), `ProjectList`, `AddProjectDialog`,
|
||||||
and the editors reused by Project Home
|
and the editors reused by Project Home
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -345,3 +345,52 @@ click, editable, CodeMirror 6, probe-roots resolution, 2 s polling, no autosave,
|
|||||||
10. **Event delivery (§3).** `emit_to(label, …)` still reaches a bare `listen()` in the main
|
10. **Event delivery (§3).** `emit_to(label, …)` still reaches a bare `listen()` in the main
|
||||||
window, so the viewer subscribes via `getCurrentWindow().listen` and the main window has no
|
window, so the viewer subscribes via `getCurrentWindow().listen` and the main window has no
|
||||||
listener for viewer event names.
|
listener for viewer event names.
|
||||||
|
|
||||||
|
## Manual verification checklist
|
||||||
|
|
||||||
|
Not runnable inside the planning/implementation container: it needs `npx tauri dev` on a machine
|
||||||
|
with a display, plus a running project container. Run this after every task on this feature has
|
||||||
|
landed, including any review fix rounds (in particular Task 11's CRLF/BOM save fix, item 16
|
||||||
|
below).
|
||||||
|
|
||||||
|
- [ ] 1. In a Claude session, ask for a file listing; click `src/…` paths, `/workspace/...`
|
||||||
|
absolute paths, a `path:line` and a `path:start-end`. Each opens its own window titled
|
||||||
|
`<basename> — <project>`, scrolled to and highlighting the line/range.
|
||||||
|
- [ ] 2. Click the same path again → the existing window is focused and re-highlights; no
|
||||||
|
duplicate.
|
||||||
|
- [ ] 3. Open 20 windows; the 21st click shows the "20 file windows are already open" toast.
|
||||||
|
- [ ] 4. Edit, `Ctrl+S`: file changes in the container (`cat` it in a bash tab); mode preserved
|
||||||
|
(`stat -c %a`); owner is the container user.
|
||||||
|
- [ ] 5. While a window is open, have Claude edit the file: clean window reloads with "Reloaded";
|
||||||
|
a dirty window shows "Changed on disk" with both buttons; "Overwrite on save" then Save
|
||||||
|
succeeds; "Reload (discard mine)" drops the edits.
|
||||||
|
- [ ] 6. Save while the file changed between polls → "Changed on disk" banner, no data written.
|
||||||
|
- [ ] 7. Delete the file in a bash tab → "File no longer exists", text still copyable, Save
|
||||||
|
disabled.
|
||||||
|
- [ ] 8. Stop the project with a window open → "Container not running" banner; start it → banner
|
||||||
|
clears, polling resumes.
|
||||||
|
- [ ] 9. Click a path under `/etc` or a `file:///etc/hosts` OSC 8 link → read-only badge with the
|
||||||
|
write-roots reason.
|
||||||
|
- [ ] 10. Close a dirty window with the X → Save / Discard / Cancel bar; Cancel keeps it open;
|
||||||
|
Discard closes.
|
||||||
|
- [ ] 11. Close the *main* window with viewers open → app exits, viewers close.
|
||||||
|
- [ ] 12. Ctrl/Cmd+Shift+I opens devtools in a viewer in dev; in a release build the CSP console
|
||||||
|
shows no violations (CodeMirror styles apply).
|
||||||
|
- [ ] 13. A wrapped long path (narrow the terminal) underlines across the wrap and opens.
|
||||||
|
- [ ] 14. Image (`.png`) opens read-only; a `.bin`/binary shows "not text".
|
||||||
|
- [ ] 15. **File-path hover key-hint wording.** Hover a plain-text file-path link in the terminal
|
||||||
|
(not an OSC 8 hyperlink) while a foreground program is holding the mouse (e.g. an
|
||||||
|
interactive TUI like `vim`/`htop`/`claude`'s own REPL) and confirm the hover card's key hint
|
||||||
|
reads correctly for the platform/mode: "Shift+click to open" on non-Mac while the program
|
||||||
|
tracks the mouse, "Click to open" when nothing tracks the mouse, "Option+click to open" on
|
||||||
|
Mac with `macOptionClickForcesSelection`, or "Not clickable while a program holds the mouse"
|
||||||
|
on Mac without it (`openHintLabel` / `fillFileCard` in `TerminalView.tsx`). Then confirm the
|
||||||
|
*click itself* is held to whatever the card promised — the modifier actually required to
|
||||||
|
activate the link matches the hint shown, even if the program changes its mouse-tracking
|
||||||
|
mode between the hover and the click.
|
||||||
|
- [ ] 16. **CRLF/BOM file round-trip save.** Open a file in the container that has Windows line
|
||||||
|
endings (CRLF) and/or a UTF-8 BOM (e.g.
|
||||||
|
`printf '\xEF\xBB\xBF\r\nfoo\r\nbar\r\n' > /workspace/<project>/crlf.txt` in a bash tab),
|
||||||
|
open it in the viewer, make a small text edit, and Save. Then `cat -A` (or `xxd`) the file
|
||||||
|
in the container and confirm the CRLF line endings and the BOM are still present/unchanged
|
||||||
|
apart from the edit — i.e. the save did not silently normalize them to LF or strip the BOM.
|
||||||
|
|||||||
Reference in New Issue
Block a user