hermes-agent/web/src/pages
Austin Pickett b8ceba97ed fix(web): make PTY resume sanitizer work against real PTY output
Review follow-up on the salvaged #47772 work. Three defects made the
filter a no-op or actively harmful in production, plus both Copilot
review items.

1. The blank-line burst filter never fired. pty_bridge.py spawns via
   ptyprocess.PtyProcess.spawn() and never calls setraw(), so the PTY
   line discipline runs with ONLCR: every LF the child writes reaches
   xterm as CRLF. The /\n{50,}/ pattern requires consecutive LF, so a
   real 1000-row burst matched nothing (verified against a live PTY:
   b"A"+b"\n"*5+b"B" is read back as b"A\r\n\r\n\r\n\r\n\r\nB").
   Now matches /(?:\r?\n){50,}/.

2. Bursts split across WebSocket frames were not collapsed. bridge.read()
   does os.read(fd, 65536) per drain tick and each read is forwarded as
   its own frame, so a burst spans frames and each fragment fell under
   the 50 threshold (3000 rows survived in a 40-byte-read simulation).
   The sanitizer now holds back a trailing newline run — including a lone
   trailing CR, since a frame can split a CRLF pair — and resolves it on
   the next frame or on flush.

3. Erase-code stripping was permanent, not resume-scoped. resumeParam is
   the durable session identity and is never cleared after connect, so
   every spinner/progress/status redraw in a resumed session lost its
   ESC[K and left stale glyphs. Suppression is now bounded to
   PTY_RESUME_SANITIZE_WINDOW_MS (30s) after connect; burst collapsing
   still applies for the life of the socket.

Copilot review items:
- flush() no longer writes a buffered partial CSI into xterm. #pending
  only ever holds an incomplete sequence, and emitting one leaves the
  parser in an in-escape state that swallows output after reconnect. A
  buffered newline run is still emitted (collapsed).
- Test expectations updated accordingly.

Tests: 29 cases (was 18), now using CRLF fixtures that match real PTY
output, plus cross-frame burst reassembly, CRLF-pair frame splits, and
post-window erase preservation. Full web suite 135 passing.
2026-07-29 12:21:48 -04:00
..
AnalyticsPage.tsx feat(dashboard): nous-blue theme, bulk sessions, schedule picker (#37383) 2026-06-02 12:37:40 -04:00
ChannelsPage.tsx feat(dashboard): clarify manual Telegram bot setup 2026-07-16 00:21:01 -07:00
ChatPage.tsx fix(web): make PTY resume sanitizer work against real PTY output 2026-07-29 12:21:48 -04:00
ConfigPage.tsx fix(dashboard): keep memory.provider in the config schema so Desktop's dropdown survives (#63886) 2026-07-13 18:56:51 -07:00
CronPage.tsx fix(dashboard): QA pass — log colors, nameless channels, config bool, UX gaps 2026-07-26 15:17:30 -07:00
DocsPage.tsx fix(web): force light color-scheme on docs iframe 2026-05-07 04:55:47 -07:00
EnvPage.tsx feat(agent): add Upstage Solar as a model provider 2026-07-15 00:09:24 +05:30
FilesPage.tsx fix(dashboard): stream file uploads via multipart instead of base64 JSON (NS-501) (#47663) 2026-06-18 15:54:32 +10:00
LogsPage.tsx fix(dashboard): QA pass — log colors, nameless channels, config bool, UX gaps 2026-07-26 15:17:30 -07:00
McpPage.tsx fix(mcp): complete OAuth through hosted dashboards 2026-07-17 04:50:47 -07:00
ModelsPage.tsx fix(moa): contain failed reference details 2026-07-23 18:40:09 -07:00
PairingPage.tsx feat(dashboard): full administration panel — MCP, pairing, webhooks, credentials, memory, gateway, ops (#36704) 2026-06-01 02:58:02 -07:00
PluginsPage.tsx Add dashboard memory provider switching 2026-07-07 17:27:54 -07:00
ProfileBuilderPage.tsx fix(dashboard): add MCP auth to profile builder (#65163) 2026-07-16 02:05:04 +05:30
ProfilesPage.tsx fix(web): remove marketing backdrop stack for lighter dashboard shell 2026-06-29 12:30:24 -07:00
SessionsPage.tsx Add dashboard session filtering 2026-07-28 22:41:56 -07:00
SkillsPage.tsx fix(dashboard): persist Discord toolsets to Discord platform 2026-07-16 00:20:33 -07:00
SystemPage.tsx Add dashboard memory provider switching 2026-07-07 17:27:54 -07:00
WebhooksPage.tsx fix(web): remove marketing backdrop stack for lighter dashboard shell 2026-06-29 12:30:24 -07:00