Skip to content

feat(response-viewer): ASCII diagram wrap toggle, mobile code blocks, chrome-stripping fallback#75

Merged
Ark0N merged 8 commits intoArk0N:masterfrom
TeigenZhang:feat/response-viewer-enhancements
Apr 28, 2026
Merged

feat(response-viewer): ASCII diagram wrap toggle, mobile code blocks, chrome-stripping fallback#75
Ark0N merged 8 commits intoArk0N:masterfrom
TeigenZhang:feat/response-viewer-enhancements

Conversation

@TeigenZhang
Copy link
Copy Markdown
Contributor

Summary

Seven small commits that polish the Response Viewer (merged in #62) for daily use on mobile and desktop:

  • Card-style message separation + table wrap (89a79a3) — messages get bordered cards; tables wrap in a horizontal-scroll container so they don't collapse on narrow viewports.
  • ANSI/CLI-chrome stripping fallback (30b802b) — when the JSONL transcript isn't available, the viewer falls back to the terminal buffer; strip ANSI CSI/OSC/DCS, status bar, hints, spinner, and progress-bar glyphs so what the user sees is conversational text, not the TUI. Also captures the Claude CLI's real session ID for transcript lookup.
  • Mobile code-block wrap (0bb4b85) — regular code blocks wrap on mobile by default (no more sideways scroll for every snippet); ASCII diagrams stay rigid with a horizontal scroll hint.
  • Per-block wrap toggle (440b5c0) — add a toggle button on code blocks identified as ASCII diagrams so the user can flip between wrap (readable) and horizontal scroll (structure preserved).
  • Wrap-by-default + pinned toggle button (dfe1dd9) — wrap is now the default; the toggle button lives outside the <pre> scroll container so it stays pinned to the visual right edge even while scrolling horizontally.
  • Narrow diagram detection (e777ed9) — only box-drawing (─-╿) and block elements (▀-▟) trigger the diagram toggle. Previously arrows and geometric shapes in prose caused false positives.
  • Desktop eye icon (49139d3) — the Response Viewer entry point now shows on desktop too (was mobile-only).

All changes are additive to _renderMarkdown / _cleanTerminalBuffer / _preprocessAsciiArt in app.js plus scoped CSS under .rv-* in styles.css. _sanitizeHtml (introduced in master) is still applied to markdown output.

Test plan

  • Narrow mobile viewport: regular code blocks wrap, long responses scroll vertically only
  • ASCII diagram block shows wrap toggle; clicking flips wrap ↔ horizontal scroll
  • Table in response wraps in a scroll container instead of overflowing
  • When transcript file is missing, viewer shows clean conversation text (no ANSI, no TUI chrome)
  • Desktop browser shows the eye icon next to session tabs
  • npm run typecheck / npm run lint / npm run build pass

Teigen and others added 8 commits April 24, 2026 09:50
…ripping in response viewer fallback

Session constructor seeded _claudeSessionId with Codeman's session.id as a
placeholder, and the message-driven update was gated on !_claudeSessionId —
meaning Claude CLI's actual session UUID was never adopted. This broke
/api/sessions/:id/last-response JSONL lookups, silently falling through to
the terminal-buffer path whose ANSI regex missed \x1b[>c / \x1b[>q queries.

- session.ts: update _claudeSessionId whenever a message's session_id differs
  from current (covers placeholder and stale-resume cases)
- app.js: extract _cleanTerminalBuffer with proper CSI regex (param bytes
  0x30-0x3F now covers > ? < =) plus a chrome filter for status bar,
  progress bar, spinner, shell prompt, and hint lines
The response viewer button was mobile-only via a display:none default with a
mobile.css override. Flip the default to inline-flex and drop the override so
the eye icon appears in the header on every form factor — desktop users get
the same quick "Last Response" pane as mobile.
… _renderMarkdown

- `_renderMarkdown` referenced an undefined `src` (should be `text`),
  causing a ReferenceError on every markdown render. The try/catch
  swallowed it, so the new table-wrap and ASCII-diagram features
  never actually ran — output silently fell through to plain-text.
  app.js is excluded from ESLint, so this wasn't caught at lint time.
- `_sanitizeHtml` was removed when refactoring the response viewer,
  leaving `marked.parse()` output going straight into `innerHTML`
  without sanitization (XSS regression vs. master). Restored the
  helper and re-applied it before any post-processing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Ark0N
Copy link
Copy Markdown
Owner

Ark0N commented Apr 28, 2026

Thanks @TeigenZhang for this — the polish on mobile, the chrome-stripping fallback, and the wrap-toggle button are all great improvements.

Before merging I pushed one fix commit (bdcd808) addressing two issues in _renderMarkdown:

  1. src is not defined — the new code passes src to _preprocessAsciiArt but the parameter is text. The try/catch swallowed the ReferenceError, so _renderMarkdown always fell through to the plain-text <pre> branch. The new table-wrap, diagram-toggle, and ASCII preprocessing never actually ran in practice. ESLint can't catch this because src/web/public/app.js is in the eslint ignore list.
  2. XSS regression — the description says _sanitizeHtml "is still applied", but the function was deleted in the refactor and the call removed, so marked.parse() output went straight into innerHTML unsanitized. Restored the helper and re-applied it before the table-wrap / diagram-toggle post-processing.

npm run typecheck and npm run build pass after the fix. Merging now.

@Ark0N Ark0N merged commit e549e15 into Ark0N:master Apr 28, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants