Skip to content

fix(web): preserve bare anchor placeholders in markdown - #16637

Merged
maria-rcks merged 4 commits into
pingdotgg:mainfrom
maria-rcks:fix/markdown-anchor-placeholder
Oct 7, 2026
Merged

maria-rcks merged 4 commits into
pingdotgg:mainfrom
maria-rcks:fix/markdown-anchor-placeholder

Conversation

@maria-rcks

@maria-rcks maria-rcks commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

bare <A> placeholders in assistant markdown were parsed as unclosed html anchors, dropping the placeholder and turning later paragraphs blue. preserve unmatched bare inline anchors as text before html parsing while keeping paired anchors and normal links intact. web and desktop share this renderer.

verified the supplied message through a real provider turn and client reload, plus normal markdown/raw links, inline code, opening html details, paired anchors closing inside larger html blocks, and self-closing bare anchors. checked light/dark themes and a narrower viewport. blacksmith: 147 scoped tests, targeted lint (three existing warnings), and web typecheck passed; the three original placeholder regression cases failed before the fix.

before: placeholder disappears and later paragraphs turn blue

after: placeholder remains visible and later paragraphs keep their text color

model: gpt-6.1-sol; harness: codex.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Oct 7, 2026
Comment thread apps/web/src/components/ChatMarkdown.tsx Outdated
@macroscopeapp

macroscopeapp Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at e410c0b

Macroscope's review found this PR approvable — This is a focused markdown-rendering bug fix confined to the existing web renderer, with regression tests covering unmatched placeholders and preserving valid links and raw HTML. It does not alter product defaults, schemas, infrastructure, or static-analysis configuration.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 6fab77ab-52a3-40f9-87a5-121e06de46df
📥 Commits

Reviewing files that changed from the base of the PR and between d70d933 and e410c0b.

📒 Files selected for processing (2)
  • apps/web/src/components/ChatMarkdown.test.tsx
  • apps/web/src/components/ChatMarkdown.tsx

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 4 remain after this review.


📝 Walkthrough

Walkthrough

The Markdown renderer now detects unmatched raw HTML anchor placeholders before raw HTML parsing and converts them to text. Tests cover unmatched and paired anchors, apparent closing tags in comments, attributes, and scripts, and preservation of related markup.

Changes

Markdown anchor handling

Layer / File(s) Summary
Preserve bare anchor placeholders
apps/web/src/components/ChatMarkdown.tsx, apps/web/src/components/ChatMarkdown.test.tsx
The renderer tracks raw HTML anchor openings and closings, skips comments and raw-text elements, and converts unmatched bare openings to text before rehypeRaw. Tests cover unmatched and paired anchors, apparent closing tags in comments, attributes, and scripts, and related markup.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Suggested reviewers: juliusmarminge, t3dotgg

Merge Risk: ⚪ Minimal · up to e410c

The change keeps unmatched bare anchor placeholders as text in the Markdown renderer. It also leaves paired anchors and normal links intact. No concrete merge-blocking risk was found.

Architecture Summary

Architecture risk: 🔵 Low · up to e410c

The change affects 1 system.

Changed systems: apps/web

Architecture concerns
No architecture-level concerns identified.

Review details

Systems and components

  • observed — apps/web (ui) was modified; 2 changed files map to changed impact.

Before / after behavior

  • observed — Modified behavior in apps/web/src/components/ChatMarkdown.test.tsx: Added the jsdom Vitest environment directive.
  • observed — Modified behavior in apps/web/src/components/ChatMarkdown.test.tsx: Added anchor-placeholder tests covering unmatched anchor tokens, closing tags in raw blocks, apparent closing tags inside comments, attributes, and scripts, and preservation of paired anchors alongside Markdown links, inline code, and details.
  • observed — Modified behavior in apps/web/src/components/ChatMarkdown.tsx: MarkdownImageHastNode gains an optional value field to represent raw-node text.
  • observed — Modified behavior in apps/web/src/components/ChatMarkdown.tsx: Adds a rehype plugin that scans raw HTML for anchor openings and closings, skipping comments and tracking raw-text elements so closing-anchor-like text within them is ignored. It converts unmatched bare opening-anchor placeholders to text after traversal.
🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the problem and fix, and gives detailed verification results with before-and-after screenshots. It does not include the required scope and approval information or explain why … Add a Scope and approval section. Link the triaged issue or maintainer approval, or explain why this is a small, focused fix of an obvious bug that qualifies without prior approval.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: preserving bare anchor placeholders in Markdown.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description explains the problem and fix, and gives detailed verification results with before-and-after screenshots. It does not include the required scope and approval information or explain why this focused fix needs no prior approval.

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added size:M 30-99 changed lines (additions + deletions). and removed size:S 10-29 changed lines (additions + deletions). labels Oct 7, 2026
@maria-rcks
maria-rcks merged commit 5886bd8 into pingdotgg:main Oct 7, 2026
29 checks passed
github-actions Bot added a commit to davidvanderklay/t3code-flake that referenced this pull request Oct 7, 2026
## What's Changed
* fix(web): show attempted paths in file preview errors by @maria-rcks in pingdotgg/t3code#15628
* fix(vcs): passive sidebar rows stop retaining remote pollers by @maria-rcks in pingdotgg/t3code#15666
* feat(web): group keybindings settings by area with a page toolbar by @maria-rcks in pingdotgg/t3code#12822
* feat(web): stop T3-owned subagents from Lineage by @Bil0000 in pingdotgg/t3code#15211
* feat(web): add fast actions to linked pull requests by @maria-rcks in pingdotgg/t3code#16627
* feat(web): open right panel tab menu with Mod+T by @Bil0000 in pingdotgg/t3code#15686
* fix(server): provider sessions clean up when their start is interrupted by @juliusmarminge in pingdotgg/t3code#15571
* fix(web): show "No project" near the top of the new thread picker by @juliusmarminge in pingdotgg/t3code#16628
* refactor(server): instrument WS RPCs in group middleware by @juliusmarminge in pingdotgg/t3code#15548
* chore(deps): upgrade @pierre/diffs to 1.5.2 and @pierre/trees to beta.6 by @juliusmarminge in pingdotgg/t3code#16644
* fix(relay): a host restarting onto a deleted tunnel gets a new one by @juliusmarminge in pingdotgg/t3code#16649
* fix(server): recover a deleted tunnel when Cloudflare says "Tunnel not found" by @juliusmarminge in pingdotgg/t3code#16648
* fix(web): iPhone Duo fold controls follow the phone's orientation by @gabrielelpidio in pingdotgg/t3code#16630
* fix(web): keep workspace options when expanding lineage by @maria-rcks in pingdotgg/t3code#16635
* fix(web): preserve bare anchor placeholders in markdown by @maria-rcks in pingdotgg/t3code#16637
* fix(pi): preserve provider identity in discovered models by @maria-rcks in pingdotgg/t3code#16661
* fix(auth): preserve explicitly granted pairing scopes by @juliusmarminge in pingdotgg/t3code#9785
* feat(auth): separate environment administration permissions by @juliusmarminge in pingdotgg/t3code#9786
* feat(auth): separate source control write permissions by @juliusmarminge in pingdotgg/t3code#9787
* feat(auth): separate filesystem read and write permissions by @juliusmarminge in pingdotgg/t3code#9788
* feat(auth): separate browser preview control permissions by @juliusmarminge in pingdotgg/t3code#9789
* feat(auth): separate diagnostics and usage permissions by @juliusmarminge in pingdotgg/t3code#9790
* feat(auth): allow passive terminal observation by @juliusmarminge in pingdotgg/t3code#9791
* fix(auth): keep old clients connected across scope changes by @juliusmarminge in pingdotgg/t3code#10298
* feat(server): hosted agents like ChatGPT can sign in to the T3 MCP server by @juliusmarminge in pingdotgg/t3code#16718


**Full Changelog**: pingdotgg/t3code@v0.0.46-nightly.20261006.2752...v0.0.46-nightly.20261007.2761

Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.46-nightly.20261007.2761
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant