[luv-313] fix: strip stray trailing ``` fences from translated MDX (Mintlify deploy unblock)#313
Conversation
…X parser on RTL READMEs Streaming Sonnet runs of long pages sometimes append an unmatched ``` line to the end of the translation. The Mintlify MDX parser interprets that as opening a code block that consumes everything to EOF, including the wrapping `</div>` on RTL pages, surfacing as "Failed to parse page content at path i18n/README.he.md: Expected a closing tag for <div> (6:1-6:16)". New `stripStrayTrailingFence` helper in mdx-translator.ts detects the odd-fence-count case and removes only the last unmatched fence, preserving every balanced pair before it. Wired into both `translateMdxPage` and `translateReadme`. Surgical fix to the two already-broken files (`docs/i18n/README.he.md`, `docs/i18n/README.tr.md`) so Mintlify can deploy today without a full re-translate. Six-case unit test in __tests__/scripts/translate-docs/mdx-translator.test.ts. Refs: post-streaming-switch run 25542951106 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…elated to this PR) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Address CodeRabbit comment on PR #311. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughAdds ChangesTranslation Pipeline Fence Cleanup
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
Comment |
…ng on main) The auto-translate run on main (#312) regenerated docs/i18n/README.ar.md with the same trailing-fence bug observed on he/tr. Drop the stray fence so Mintlify can parse this file too. Sanitizer in the script will prevent recurrence on future runs. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@CHANGELOG.md`:
- Line 6: Update the PR number in the Unreleased changelog entry: locate the
bullet that references the new stripStrayTrailingFence helper (mentions
translateMdxPage and translateReadme) and replace the suffix "(`#311`)" with the
correct PR number "(`#313`)" so the Unreleased entry reflects the current PR.
In `@scripts/translate-docs/mdx-translator.ts`:
- Around line 81-90: stripStrayTrailingFence currently treats any line starting
with three backticks as a fence and can remove legitimate inner backtick lines
inside longer-fence blocks; update stripStrayTrailingFence to detect fenced code
blocks robustly by replacing the /^```/ test with a fence regex like /^(?:
{0,3})(`{3,})([^`]*)?$/ and track an "open" fence object (markerLength and
index) while iterating lines: on first fence set open, on a subsequent fence
close it only if its marker length is >= open.markerLength, and only remove the
unmatched opening fence (open.index) at the end if still open; keep references
to symbol names stripStrayTrailingFence, fenceRe, and open so you can locate and
implement the change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 8b679018-4431-4f0f-9669-db69098e8468
📒 Files selected for processing (6)
CHANGELOG.md__tests__/scripts/translate-docs/mdx-translator.test.tsdocs/i18n/README.he.mddocs/i18n/README.tr.mdscripts/translate-docs/mdx-translator.tsscripts/translate-docs/readme-translator.ts
💤 Files with no reviewable changes (2)
- docs/i18n/README.he.md
- docs/i18n/README.tr.md
… ref to #313 Address CodeRabbit findings on PR #313: 1. /^```/ matched 4-tick fence markers too, which would miscount inner ``` content inside a quad-tick block as a fence marker. Tightened to /^```(?!`)/ so only exactly-three-backtick lines are counted. 2. CHANGELOG entry referenced #311 (the predecessor of this PR); updated to #313. Added regression test for the quad-tick edge case. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Promote the six entries accumulated under `## Unreleased` to a versioned heading `## 0.0.10-beta.6 — 2026-05-08`. Add a fresh `## Unreleased` heading at the top for the next development cycle. package.json was already at 0.0.10-beta.6 (pre-bumped); no version edit needed here. The CHANGELOG cut completes the release-prep handshake. Entries promoted: - Cursor Stop hook enforcement fix (this PR) - 5 scripts/translate-docs fixes from #305, #306, #307, #312, #313 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…a.6 (#318) * [luv-319] fix: enforce Stop hook on Cursor Agent CLI (followup_message + SubagentStop parity) Cursor's `stop` hook ignores the flat `{permission: "deny"}` shape — that's honored on tool events only. The only force-retry channel for Stop is `{followup_message}` on stdout (exit 0), per https://cursor.com/docs/hooks. The instruct branch already used this shape correctly since #245; the deny path needed the same treatment, mirroring Copilot's #299 fix. Without this, the 5 require-*-before-stop builtins were observation-only on Cursor — the deny was logged but the agent stopped cleanly. User repro: session 1b510ad4-906c-4f30-9467-ff2e6c581cce at /home/nivedit/dev-purge. Also subscribes to `subagentStop` (CURSOR_HOOK_EVENT_TYPES + CURSOR_EVENT_MAP) and widens both deny and instruct branches to match it, for parity with the Copilot SubagentStop widening from #299. Cloud Agents caveat: Cursor Cloud Agent VMs do NOT run stop/subagentStop hooks at all, so this fix only covers local Cursor sessions. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * chore: cut 0.0.10-beta.6 release in CHANGELOG Promote the six entries accumulated under `## Unreleased` to a versioned heading `## 0.0.10-beta.6 — 2026-05-08`. Add a fresh `## Unreleased` heading at the top for the next development cycle. package.json was already at 0.0.10-beta.6 (pre-bumped); no version edit needed here. The CHANGELOG cut completes the release-prep handshake. Entries promoted: - Cursor Stop hook enforcement fix (this PR) - 5 scripts/translate-docs fixes from #305, #306, #307, #312, #313 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Summary
Same change set as the now-closed #311, rebased onto latest
main(which moved past939ad19via the auto-translate workflow runs #309/#310/#312). Force-push was blocked by repo policy, hence the new branch.stripStrayTrailingFence(content: string)helper inscripts/translate-docs/mdx-translator.ts: detects an odd count of```fence-line markers and drops only the last unmatched one, preserving every balanced pair before it.translateMdxPage(aftersanitizeJsxAttributes) andtranslateReadme(before the RTL<div>wrap).main:docs/i18n/README.he.md— initial offender from run 25542951106docs/i18n/README.tr.md— initial offender from run 25542951106docs/i18n/README.ar.md— regenerated by main's auto-translate run [auto] update translations #312 with the same bug; caught during the rebase__tests__/scripts/translate-docs/mdx-translator.test.ts.Why
Streamed Sonnet runs of long pages (post-#307) sometimes append an unmatched
```to the end of the translation. The Mintlify MDX parser interprets it as opening a code block that consumes everything to EOF — including the wrapping</div>for RTL pages — and surfaces as:Empirical signal scanning every translated file at HEAD before this PR:
docs/i18n/README.en.md(source)docs/i18n/README.he.mddocs/i18n/README.tr.mddocs/i18n/README.ar.mdSporadic LLM output noise, not deterministic. The sanitizer is the right shape because it only fires on odd counts (no false positives) and strips only the last fence-line.
Test plan
bunx tsc --noEmitcleanbun run test:run -- mdx-translator.test— 24 passed (6 new + 18 existing)mainsucceeds (was failing on the<div>parse error)gh workflow run translate-docs.yml -f force=trueexercises the sanitizer on a fresh translation🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes
Tests
Documentation
Chores