fix(desktop): prevent code blocks with no tag, text, or yaml from bei… - #77258
fix(desktop): prevent code blocks with no tag, text, or yaml from bei…#77258gfpyc wants to merge 2 commits into
Conversation
9d91de0 to
6cda16a
Compare
|
This was generated by AI during triage. Summary: Problems:
Solution: Evidenceno deterministic fact backs this claim — model belief, not executed or read evidence Checked against |
…ction
XpycT's repro matrix (text/markdown/gdscript/yaml fences whose content
looks prose-like, >=3 lines with zero code signals) is still broken on
main: the prose heuristics strip the fence and collapse the block into a
flat paragraph. The recent isLikelyStructuredText guard only protects
config/structured listings, not explicit-tag fences with prose-looking
content.
Respect any explicit, valid language tag in both isLikelyProseFence and
isLikelyProseCodeBlock: a fenced block with a real tag (text, plain,
plaintext, markdown, md, gdscript, yaml, ...) renders as code regardless
of how prose-like the body looks. Bare fences ('') keep the existing
behavior — untagged paragraph fences still unwrap, and config/key-value
listings stay fenced via isLikelyStructuredText.
Also exempt COMMON code languages from the bullet-prose heuristic in
isLikelyProseCodeBlock so yaml/markdown lists render as code, while
unknown tags (e.g. Streamdown's 'heads') still classify as prose.
The explicit-tag guard ran after the bullet-prose heuristic, so non-COMMON languages (gdscript/zsh) and NON_CODE tags (text/plain/plaintext) with bullet-list bodies were still prose-classified before the guard was reached. Move the explicit-tag guard ahead of the bullet heuristic, keeping the Streamdown 'heads' case (bullet + inline markdown emphasis) as prose per the upstream test. Adds whole-class bullet-list coverage plus the numbered Chinese prose repro reported on macOS (text/prompt tags).
6cda16a to
040b277
Compare
|
@spfcraze Thanks for the triage report — confirmed and fixed. You were right that the explicit-tag guard ran after the bullet-prose heuristic, and the gap was wider than reported: it covered not just gdscript/zsh but the whole NON_CODE family (text/plain/plaintext) too, since none of them are in COMMON_CODE_LANGUAGES. What changed in 040b277:
|
|
Hi @danspicytaco — thanks for cross-referencing this. Since #58023 and this PR both touch the fence-classification heuristics in apps/desktop/src/lib/markdown-code.ts from complementary angles, let me lay out the current coverage so we can consolidate rather than compete: This PR (#77258) — 30 vitest cases covering:
#58023 covers:
Neither is a strict superset of the other — they touch different guard branches in the same file, so both change sets can merge cleanly if the maintainers want to consolidate. I'm happy to rebase/coordinate so we land a single fix quickly; this bug has been open since early August and is reproducible on Windows 11 (XpycT) and macOS (Stone441). @alt-glitch @teknium1 — could we get a consolidation decision (and the workflows approved)? The P3 label may undersell this: it breaks code-card rendering for any non-COMMON tagged fence on Desktop. |
|
Merge this please! :) |
What does this PR do?
Fixes a bug where Hermes Desktop misclassifies fenced code blocks as prose — losing their CodeCard, stripping fence markers, and collapsing whitespace. Affected:
text/plain/plaintext,yamlwith bullet lists,markdown/mdfences (rich-rendered as prose instead of code), and any non-COMMON language tag (gdscript, zsh, ...) whose content looks prose-like.Root cause: Two functions in
markdown-code.ts:isLikelyProseFence—NON_CODE_FENCE_LANGUAGESincluded'',text,plain,plaintext,md,markdown, so explicit text-like tags were never treated as code;proseLines >= 3 && codeSignals === 0then misclassified zero-code-signal content as prose.isLikelyProseCodeBlock— thebulletLines >= 1prose check caught YAML list items; the fallthrough caught text/plain/plaintext and any non-COMMON explicit tag (gdscript, zsh, ...).Fix (2 files):
isLikelyProseFence— any explicit, valid language tag (VALID_LANGUAGE_RE) is respected and rendered as code. Covers text/plain/plaintext/md/markdown (previously inNON_CODE_FENCE_LANGUAGES) and gdscript/zsh and other non-COMMON tags.isLikelyProseCodeBlock—COMMON_CODE_LANGUAGES, e.g. yaml/markdown) from the bullet-prose heuristic so their lists render as code;isLikelyProseFence.Bare fences (
'') keep the existing behavior: untagged paragraph fences still unwrap to prose, and config/key-value listings (SSH config, .env, INI) stay fenced via the existingisLikelyStructuredTextguard. Unknown tags (e.g. Streamdown'sheads) still classify as prose.Related Issue
Fixes #77253
Type of Change
Changes Made
apps/desktop/src/lib/markdown-code.ts: classification logic — explicit-tag respect in both prose-detection pathsapps/desktop/src/lib/markdown-code.test.ts: extended repro matrix (22 assertions)How to Test
textfence with 3+ lines of keyword-free text — CodeCardyamlfence with a bullet list — CodeCardgdscript(or any non-COMMON tag) fence with prose-like lines — CodeCardmarkdown/mdfence — CodeCard with raw (highlighted) contenttextfence with SSH config / .env content — CodeCard (structured guard preserved)python``/bash` control — still renders normallyVerification
Trigger precision (verified): the misclassification fires at
proseLines >= 3 && codeSignals === 0... content with zero code signals (no JS keywords likefor/while, no operators=>}{``,};, no HTML tags). English sentences frequently containfor/while` and are accidentally immune, which is why line-count alone looked unreliable. No sticky state: after a misclassified block, subsequent well-formed blocks render fine.Behaviour table (tested on Windows 11, packaged app, after rebase onto latest main @ 1f8fdc7 desktop v0.17.0):
textwith keyword-free linesyamlwith bullet listgdscriptwith prose-like linesmarkdown/mdfencetextwith SSH config / .envpython`` /bash`Tests: 22/22 pass (
markdown-code.test.ts): explicit-tag matrix (text/plain/plaintext/markdown/md/gdscript/yaml) across both functions + upstream regression cases (SSH config, .env, bullet-prose with unknown tags, structured-text veto, bare-prose unwrap).Notes
Lebased onto latest
main(includes upstreamisLikelyStructuredTextguard, #84664). The fix was narrowed to explicit-tag respect — bare fences intentionally keep the upstream unwrap philosophy.