Repository navigation
/view: render HTML natively, HTML files and HTML inside Markdown (#454) - #455
Merged
Merged
Conversation
A space was dropped when the space and the next word did not fit, but the
next word itself was then measured without it: when the word alone fit
exactly, it was drawn straight after the previous one ("aaaa bbbb" at 8
columns gave "aaaabbbb"; a README line gave "A calmerterminal"). Every
Markdown surface used this wrap (agent replies, help, /view, GitHub
bodies). The next word now starts the next row.
Found while testing /view's HTML rendering (QA F01); present on 68c1cbb.
…F01) Requested in the v0.22 physical QA: README files showed their embedded <picture>, <img> and <div> literally. /view now renders HTML as terminal rows, with no browser engine, through the Markdown renderer's own blocks, so wrapping, narrow widths, search, NO_COLOR and Safe glyphs come from the tested renderer. Supported subset: headings, paragraphs and containers (div, section, center, details/summary, figure), ordered and unordered lists (nested, task check boxes), tables (header row, alignment), <pre> code with its language class, block quotes, rules, definition lists; inline emphasis, code and keys, strikethrough, links and images. In Markdown, HTML blocks follow CommonMark's kinds and Markdown between them reads as Markdown, as on GitHub; inline tags are read from a whitelist, and an unknown <word> stays text. .html/.htm/.xhtml open rendered; m shows the source. Never run or loaded: scripts, styles, templates, embedded and interactive content and the document head are dropped with their contents; event handlers and every attribute but a few are ignored; CSS is not applied; an image is its alt text (never fetched or read, so no local file is disclosed); links keep the renderer's http(s)-only rule and a refused target shows as text; character references decode through the existing safe decoder (moved to markup.ts unchanged). The parser is linear, at most 200,000 tokens and 48 levels deep (deeper content stays, flattened), 4 KiB per tag, 2 KiB per attribute; rendering stays under the existing 1 MiB limit. html.ts imports nothing that reads files or the network. HTML is rendered only where /view asks (MarkdownOptions.html): agent replies, help and GitHub bodies keep showing tags as text. Tests: tests/viewHtml.test.ts (README, document structure, hostile markup, controls via text/entities/attributes, size and nesting bounds, no I/O imports, opt-in, narrow/NO_COLOR/Safe, viewer integration). Rendering, viewer, agent, Ask and report suites: 604 pass, 0 fail.
…document (QA F01) Self-review of the HTML reader: a quoted attribute was searched for its closing quote past the tag's own bound, and in Markdown each unclosed <code> searched to the end again (a 64 KiB paragraph of them took 125 ms, so a 1 MiB document could take seconds to open). The quote search now stops at the tag's bound, and close-tag searches remember their answer per name, so they only move forward. Worst cases measured: 14 ms per 64 KiB paragraph, about 300 ms per MiB of HTML; covered in the limits test.
This was referenced Oct 19, 2026
Input ownership: a line queued during a command that is not a command waits for approval (#426)
#448
Merged
Merged
Composer: a block mixing NMSh and shell commands is reviewed, then offered one at a time (#450)
#451
Merged
Owner
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements #454 (QA F01). Kept separate from the security fixes, with its own tests.
What renders: HTML is mapped onto the Markdown renderer's own blocks, so wrapping, narrow widths, search, NO_COLOR and Safe glyphs come from the tested renderer. There's no browser engine and no DOM.
<pre>code with its language class; block quotes; rules; definition lists.<code>/<kbd>, strikethrough, links and images.<word>stays text..html,.htmand.xhtmlopen rendered;mshows the source.Never run or loaded
<head>are dropped with their contents.markup.ts).html.tsimports nothing that reads files or the network.Opt-in: HTML renders only in
/view. Agent replies, help and GitHub bodies still show tags as text.Also fixed here (separate commit): the Markdown wrap glued two words together when the second fit only without the space ("A calmerterminal"). It's present on
68c1cbb7in every Markdown surface.Not included: inline image graphics (kitty/iTerm). They would mean reading local files or fetching remote ones, so they need an explicit opt-in design; images show as text for now.
Tests:
tests/viewHtml.test.tscovers the README case, document structure, hostile markup, controls through text/entities/attributes, size, nesting and linearity bounds, no I/O imports, the opt-in boundary, narrow/NO_COLOR/Safe, and viewer integration. Plus a wrap regression inmarkdownRender. Rendering, viewer, agent, Ask and report suites: 604 pass, 0 fail. The project's own README renders with no literal tags left.Physical retest: A2 (
/view) and a short HTML walkthrough; see #444.